Merge branch 'master' of ssh://git.eclipse.org/gitroot/eclipselink/eclipselink.utils.temp

Conflicts:
	tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/main.xml.vm
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkDatabase.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkDatabase.java
index 640ef47..1352ea5 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkDatabase.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkDatabase.java
@@ -26,9 +26,9 @@
 import org.eclipse.persistence.tools.gen.db.Database;
 import org.eclipse.persistence.tools.gen.db.Schema;
 import org.eclipse.persistence.tools.gen.db.Table;
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
-import org.eclipse.persistence.tools.utility.iterables.TransformationIterable;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
+import org.eclipse.persistence.tools.utility.iterable.TransformationIterable;
 
 /**
  * The concrete implementation of {@link Database}.
@@ -217,7 +217,7 @@
 	 */
 	@Override
 	public Iterable<Schema> getSchemata() {
-		return new TransformationIterable<Schema, String>(new Iterable<String>() {
+		return new TransformationIterable<String, Schema>(new Iterable<String>() {
 			@Override
 			public Iterator<String> iterator() {
 				return getMWDatabase().schemaNames();
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkForeignKey.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkForeignKey.java
index d4cccab..72051a6 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkForeignKey.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkForeignKey.java
@@ -21,9 +21,9 @@
 import org.eclipse.persistence.tools.gen.db.ConnectionProfile;
 import org.eclipse.persistence.tools.gen.db.ForeignKey;
 import org.eclipse.persistence.tools.gen.db.Table;
-import org.eclipse.persistence.tools.utility.iterables.FilteringIterable;
-import org.eclipse.persistence.tools.utility.iterables.TransformationIterable;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.iterable.FilteringIterable;
+import org.eclipse.persistence.tools.utility.iterable.TransformationIterable;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 
 /**
  * The concrete implementation of {@link ForeignKey}.
@@ -85,10 +85,10 @@
 	 */
 	@Override
 	public Iterable<Column> getBaseColumns() {
-		return new TransformationIterable<Column, ELColumn>(new Iterable<ELColumn>() {
+		return new TransformationIterable<ELColumn, Column>(new Iterable<ELColumn>() {
 			@Override
 			public Iterator<ELColumn> iterator() {
-				return new TransformationIterator<ELColumn, ELColumnPair>(EclipseLinkForeignKey.this.reference.columnPairs()) {
+				return new TransformationIterator<ELColumnPair, ELColumn>(EclipseLinkForeignKey.this.reference.columnPairs()) {
 					@Override
 					protected ELColumn transform(ELColumnPair column) {
 						return column.getSourceColumn();
@@ -127,12 +127,7 @@
 	 */
 	@Override
 	public Iterable<ColumnPair> getColumnPairs() {
-		return new TransformationIterable<ForeignKey.ColumnPair, ELColumnPair>(new Iterable<ELColumnPair>() {
-			@Override
-			public Iterator<ELColumnPair> iterator() {
-				return EclipseLinkForeignKey.this.reference.columnPairs();
-			}
-		}) {
+		return new TransformationIterable<ELColumnPair, ForeignKey.ColumnPair>(reference.columnPairs()) {
 			@Override
 			protected ColumnPair transform(ELColumnPair columnPair) {
 				return new EclipseLinkColumnPair(EclipseLinkForeignKey.this.table, columnPair);
@@ -283,10 +278,10 @@
 	 */
 	@Override
 	public Iterable<Column> getReferencedColumns() {
-		return new TransformationIterable<Column, ELColumn>(new Iterable<ELColumn>() {
+		return new TransformationIterable<ELColumn, Column>(new Iterable<ELColumn>() {
 			@Override
 			public Iterator<ELColumn> iterator() {
-				return new TransformationIterator<ELColumn, ELColumnPair>(EclipseLinkForeignKey.this.reference.columnPairs()) {
+				return new TransformationIterator<ELColumnPair, ELColumn>(EclipseLinkForeignKey.this.reference.columnPairs()) {
 					@Override
 					protected ELColumn transform(ELColumnPair column) {
 						return column.getTargetColumn();
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkSchema.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkSchema.java
index 33e8fc4..1137c47 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkSchema.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkSchema.java
@@ -21,10 +21,10 @@
 import org.eclipse.persistence.tools.gen.db.SchemaContainer;
 import org.eclipse.persistence.tools.gen.db.Sequence;
 import org.eclipse.persistence.tools.gen.db.Table;
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.TransformationIterable;
-import org.eclipse.persistence.tools.utility.iterators.FilteringIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.TransformationIterable;
+import org.eclipse.persistence.tools.utility.iterator.FilteringIterator;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
 
 /**
  * The concrete implementation of {@link Schema}.
@@ -144,7 +144,7 @@
 	 */
 	@Override
 	public Iterable<String> getSortedTableIdentifiers() {
-		return new TransformationIterable<String, Table>(getTables()) {
+		return new TransformationIterable<Table, String>(getTables()) {
 			@Override
 			protected String transform(Table table) {
 				return table.getName();
@@ -180,14 +180,14 @@
 	 */
 	@Override
 	public Iterable<Table> getTables() {
-		return new TransformationIterable<Table, ELTable>(new Iterable<ELTable>() {
+		return new TransformationIterable<ELTable, Table>(new Iterable<ELTable>() {
 			@Override
 			public Iterator<ELTable> iterator() {
 				return new FilteringIterator<ELTable>(EclipseLinkSchema.this.mwDatabase.tables()) {
 					@Override
 					protected boolean accept(ELTable table)
 					{
-						return StringTools.stringsAreEqual(EclipseLinkSchema.this.schemaName, table.getSchema());
+						return ObjectTools.equals(EclipseLinkSchema.this.schemaName, table.getSchema());
 					};
 				};
 			}
@@ -204,7 +204,7 @@
 	 */
 	@Override
 	public int getTablesSize() {
-		return CollectionTools.size(getTables().iterator());
+		return IteratorTools.size(getTables().iterator());
 	}
 
 	/**
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkTable.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkTable.java
index fd4e136..85a005d 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkTable.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkTable.java
@@ -21,7 +21,7 @@
 import org.eclipse.persistence.tools.gen.db.ConnectionProfile;
 import org.eclipse.persistence.tools.gen.db.ForeignKey;
 import org.eclipse.persistence.tools.gen.db.Table;
-import org.eclipse.persistence.tools.utility.iterables.TransformationIterable;
+import org.eclipse.persistence.tools.utility.iterable.TransformationIterable;
 
 /**
  * The concrete implementation of {@link Column}.
@@ -77,12 +77,7 @@
 	 */
 	@Override
 	public Iterable<Column> getColumns() {
-		return new TransformationIterable<Column, ELColumn>(new Iterable<ELColumn>() {
-			@Override
-			public Iterator<ELColumn> iterator() {
-				return EclipseLinkTable.this.table.columns();
-			}
-		}) {
+		return new TransformationIterable<ELColumn, Column>(table.columns()) {
 			@Override
 			protected Column transform(ELColumn column) {
 				return new EclipseLinkColumn(EclipseLinkTable.this, column);
@@ -119,12 +114,7 @@
 	 */
 	@Override
 	public Iterable<ForeignKey> getForeignKeys() {
-		return new TransformationIterable<ForeignKey, ELReference>(new Iterable<ELReference>() {
-			@Override
-			public Iterator<ELReference> iterator() {
-				return EclipseLinkTable.this.table.references();
-			}
-		}) {
+		return new TransformationIterable<ELReference, ForeignKey>(table.references()) {
 			@Override
 			protected ForeignKey transform(ELReference reference) {
 				return new EclipseLinkForeignKey(EclipseLinkTable.this, reference);
@@ -162,7 +152,7 @@
 	@Override
 	public ForeignKey getJoinTableNonOwningForeignKey() {
 		if (isPossibleJoinTable()) {
-			Iterator<ELReference> references = this.table.references();
+			Iterator<ELReference> references = this.table.references().iterator();
 			ELReference fk0 = references.next();
 			String name0 = fk0.getTargetTable().getName();
 			ELReference fk1 = references.next();
@@ -190,7 +180,7 @@
 	@Override
 	public ForeignKey getJoinTableOwningForeignKey() {
 		if (isPossibleJoinTable()) {
-			Iterator<ELReference> references = this.table.references();
+			Iterator<ELReference> references = this.table.references().iterator();
 			ELReference fk0 = references.next();
 			String name0 = fk0.getTargetTable().getName();
 
@@ -233,7 +223,7 @@
 	 */
 	@Override
 	public Iterable<Column> getPrimaryKeyColumns() {
-		return new TransformationIterable<Column, ELColumn>(new Iterable<ELColumn>() {
+		return new TransformationIterable<ELColumn, Column>(new Iterable<ELColumn>() {
 			@Override
 			public Iterator<ELColumn> iterator() {
 				return EclipseLinkTable.this.table.primaryKeyColumns();
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/AbstractWorkbenchDriverAdapter.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/AbstractWorkbenchDriverAdapter.java
index 52d595c..94eb773 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/AbstractWorkbenchDriverAdapter.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/AbstractWorkbenchDriverAdapter.java
@@ -33,9 +33,10 @@
 import org.eclipse.persistence.tools.gen.db.Sequence;
 import org.eclipse.persistence.tools.gen.db.Table;
 import org.eclipse.persistence.tools.utility.ArrayTools;
-import org.eclipse.persistence.tools.utility.CollectionTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.ResultSetIterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterator.ResultSetIterator;
 
 /**
  * Consolidate the behavior common to the typical DTP drivers.
@@ -310,7 +311,7 @@
 	 * double-quotes; but some databases allow otherwise (e.g. Sybase).
 	 */
 	boolean identifierIsDelimited(String identifier) {
-		return StringTools.stringIsQuoted(identifier);
+		return StringTools.isQuoted(identifier);
 	}
 
 
@@ -481,6 +482,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.database);
+		return ObjectTools.toString(this, this.database);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/LowerCaseFoldingStrategy.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/LowerCaseFoldingStrategy.java
index 8181dc6..eb243c6 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/LowerCaseFoldingStrategy.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/LowerCaseFoldingStrategy.java
@@ -51,7 +51,7 @@
 	 */
 	@Override
 	public boolean nameIsFolded(String name) {
-		return StringTools.stringIsLowercase(name);
+		return StringTools.isLowercase(name);
 	}
 
 	/**
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/MySQL.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/MySQL.java
index e936d63..b1ecbc2 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/MySQL.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/MySQL.java
@@ -20,8 +20,9 @@
 import org.eclipse.persistence.tools.gen.db.Schema;
 import org.eclipse.persistence.tools.gen.db.Table;
 import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.Tools;
+import org.eclipse.persistence.tools.utility.SystemTools;
 
 /**
  * MySQL is a bit unusual in that it does <em>not</em> fold <em>regular</em>
@@ -139,8 +140,8 @@
 	 */
 	@Override
 	boolean identifierIsDelimited(String identifier) {
-		return StringTools.stringIsDelimited(identifier, BACKTICK)
-					|| (StringTools.stringIsQuoted(identifier) && this.doubleQuoteIsIdentifierDelimiter());
+		return StringTools.isDelimited(identifier, BACKTICK) ||
+		      (StringTools.isQuoted(identifier) && this.doubleQuoteIsIdentifierDelimiter());
 	}
 	private static final char BACKTICK = '`';
 
@@ -233,7 +234,7 @@
 			return -1;
 		}
 		Map<String, Object> row = rows.get(0);
-		if (Tools.valuesAreEqual(row.get("Variable_name"), "lower_case_table_names")) {
+		if (ObjectTools.equals(row.get("Variable_name"), "lower_case_table_names")) {
 			return Integer.valueOf((String) row.get("Value")).intValue();
 		}
 		return -1;
@@ -245,10 +246,10 @@
 	 * client O/S, not the MySQL Server O/S...).
 	 */
 	private int getLowerCaseTableNamesFromOS() {
-		if (Tools.osIsMac()) {
+		if (SystemTools.osIsMac()) {
 			return 2;
 		}
-		if (Tools.osIsWindows()) {
+		if (SystemTools.osIsWindows()) {
 			return 1;
 		}
 		return 0;  // Linux etc.
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/SQLServer.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/SQLServer.java
index 437f15c..6f74d74 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/SQLServer.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/SQLServer.java
@@ -95,7 +95,7 @@
 	//TODO query database for delimiter setting
 	@Override
 	boolean identifierIsDelimited(String identifier) {
-		return StringTools.stringIsBracketed(identifier)
+		return StringTools.isBracketed(identifier)
 					|| super.identifierIsDelimited(identifier);
 	}
 
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/Sybase.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/Sybase.java
index dcd9934..f9fb423 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/Sybase.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/Sybase.java
@@ -116,7 +116,7 @@
 	//TODO query database for delimiter setting
 	@Override
 	boolean identifierIsDelimited(String identifier) {
-		return StringTools.stringIsBracketed(identifier)
+		return StringTools.isBracketed(identifier)
 					|| super.identifierIsDelimited(identifier);
 	}
 
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/UpperCaseFoldingStrategy.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/UpperCaseFoldingStrategy.java
index f7559b3..bedd9c8 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/UpperCaseFoldingStrategy.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/UpperCaseFoldingStrategy.java
@@ -51,7 +51,7 @@
 	 */
 	@Override
 	public boolean nameIsFolded(String name) {
-		return StringTools.stringIsUppercase(name);
+		return StringTools.isUppercase(name);
 	}
 
 	/**
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELDatabase.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELDatabase.java
index 29219a9..872f659 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELDatabase.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELDatabase.java
@@ -34,11 +34,11 @@
 import org.eclipse.persistence.tools.db.model.spi.ExternalTableDescription;
 import org.eclipse.persistence.tools.db.model.spi.jdbc.JDBCExternalDatabaseFactory;
 import org.eclipse.persistence.tools.schemaframework.SchemaManager;
-import org.eclipse.persistence.tools.utility.CollectionTools;
 import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterable.LiveCloneIterable;
+import org.eclipse.persistence.tools.utility.iterator.ArrayIterator;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 import org.eclipse.persistence.tools.utility.node.Node;
 
 /**
@@ -192,8 +192,8 @@
 
 	// ********** login specs **********
 
-	public Iterator<ELLoginSpec> loginSpecs() {
-		return new CloneIterator<ELLoginSpec>(this.loginSpecs) {
+	public Iterable<ELLoginSpec> loginSpecs() {
+		return new LiveCloneIterable<ELLoginSpec>(this.loginSpecs) {
 			@Override
 			protected void remove(ELLoginSpec current) {
 				ELDatabase.this.removeLoginSpec(current);
@@ -241,7 +241,7 @@
 	}
 
 	public Iterator<String> loginSpecNames() {
-		return new TransformationIterator<String, ELLoginSpec>(this.loginSpecs()) {
+		return new TransformationIterator<ELLoginSpec, String>(this.loginSpecs()) {
 			@Override
 			protected String transform(ELLoginSpec next) {
 				return next.getName();
@@ -278,8 +278,8 @@
 
 	// ********** tables **********
 
-	public Iterator<ELTable> tables() {
-		return new CloneIterator<ELTable>(this.tables) {
+	public Iterable<ELTable> tables() {
+		return new LiveCloneIterable<ELTable>(this.tables) {
 			@Override
 			protected void remove(ELTable current) {
 				ELDatabase.this.removeTable(current);
@@ -377,7 +377,7 @@
 	 * used to prevent adding a duplicate table
 	 */
 	public Iterator<String> tableNames() {
-		return new TransformationIterator<String, ELTable>(this.tables()) {
+		return new TransformationIterator<ELTable, String>(this.tables()) {
 			@Override
 			protected String transform(ELTable next) {
 				return next.getName();
@@ -834,7 +834,7 @@
 
 	// ********** SubComponentContainer implementation **********
 
-	public Iterator projectSubFileComponents() {
+	public Iterable projectSubFileComponents() {
 		return this.tables();
 	}
 
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELLoginSpec.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELLoginSpec.java
index eafd00f..8559116 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELLoginSpec.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELLoginSpec.java
@@ -29,12 +29,13 @@
 import org.eclipse.persistence.sessions.DatabaseLogin;
 import org.eclipse.persistence.sessions.Session;
 import org.eclipse.persistence.tools.db.model.platformsmodel.DatabasePlatform;
-import org.eclipse.persistence.tools.utility.CollectionTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
-import org.eclipse.persistence.tools.utility.iterators.CloneListIterator;
-import org.eclipse.persistence.tools.utility.iterators.EmptyIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.ArrayIterator;
+import org.eclipse.persistence.tools.utility.iterator.CloneListIterator;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 import org.eclipse.persistence.tools.utility.node.Node;
 
 /**
@@ -84,7 +85,7 @@
 	 * Returns the driver class names we know about
 	 */
 	public static Iterator<String> commonDriverClassNames() {
-		return new TransformationIterator<String, DriverSpec>(driverSpecs()) {
+		return new TransformationIterator<DriverSpec, String>(driverSpecs()) {
 			@Override
 			protected String transform(DriverSpec next) {
 				return next.getDriverClassName();
@@ -324,7 +325,7 @@
 	}
 
 	public void addDriverClasspathEntries(ListIterator<String> entries) {
-		this.addDriverClasspathEntries(CollectionTools.list(entries));
+		this.addDriverClasspathEntries(ListTools.list(entries));
 	}
 
 	public String removeDriverClasspathEntry(int index) {
@@ -502,7 +503,7 @@
 
 		@Override
 		public String toString() {
-			return StringTools.buildToStringFor(this, this.driverClassName);
+			return ObjectTools.toString(this, this.driverClassName);
 		}
 	}
 
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELModel.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELModel.java
index d2df17a..43bc941 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELModel.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELModel.java
@@ -16,8 +16,7 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
 import org.eclipse.persistence.tools.utility.node.AbstractNode;
 import org.eclipse.persistence.tools.utility.node.Node;
 
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELReference.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELReference.java
index 6f3fb79..da037c2 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELReference.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELReference.java
@@ -22,8 +22,8 @@
 import org.eclipse.persistence.tools.db.model.handles.MWTableHandle;
 import org.eclipse.persistence.tools.db.model.spi.ExternalForeignKey;
 import org.eclipse.persistence.tools.db.model.spi.ExternalForeignKeyColumnPair;
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterable.LiveCloneIterable;
 import org.eclipse.persistence.tools.utility.node.Node;
 
 /**
@@ -121,8 +121,8 @@
 	}
 
 	// ********** column pairs
-	public Iterator<ELColumnPair> columnPairs() {
-		return new CloneIterator<ELColumnPair>(this.columnPairs) {
+	public Iterable<ELColumnPair> columnPairs() {
+		return new LiveCloneIterable<ELColumnPair>(this.columnPairs) {
 			@Override
 			protected void remove(ELColumnPair current) {
 				ELReference.this.removeColumnPair(current);
@@ -164,10 +164,7 @@
 	}
 
 	private void clearColumnPairs() {
-		for (Iterator stream = this.columnPairs(); stream.hasNext(); ) {
-			stream.next();
-			stream.remove();
-		}
+		this.clearCollection(this.columnPairs, COLUMN_PAIRS_COLLECTION);
 	}
 
 	/**
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELTable.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELTable.java
index 02b7a5c..a6f765a 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELTable.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELTable.java
@@ -26,10 +26,10 @@
 import org.eclipse.persistence.tools.db.model.spi.ExternalTableDescription;
 import org.eclipse.persistence.tools.utility.NameTools;
 import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.iterators.CompositeIterator;
-import org.eclipse.persistence.tools.utility.iterators.FilteringIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.iterable.LiveCloneIterable;
+import org.eclipse.persistence.tools.utility.iterator.CompositeIterator;
+import org.eclipse.persistence.tools.utility.iterator.FilteringIterator;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 import org.eclipse.persistence.tools.utility.node.Node;
 
 /**
@@ -141,8 +141,8 @@
 	private void qualifiedNameChanged() {
 		this.firePropertyChanged(QUALIFIED_NAME_PROPERTY, this.qualifiedName());
 		this.getParent().nodeRenamed(this);
-		for (Iterator<ELColumn> stream = this.columns(); stream.hasNext(); ) {
-			stream.next().qualifiedNameChanged();
+		for (ELColumn column : this.columns()) {
+			column.qualifiedNameChanged();
 		}
 	}
 
@@ -168,8 +168,8 @@
 
 	// ********** columns **********
 
-	public Iterator<ELColumn> columns() {
-		return new CloneIterator<ELColumn>(this.columns) {
+	public Iterable<ELColumn> columns() {
+		return new LiveCloneIterable<ELColumn>(this.columns) {
 			@Override
 			protected void remove(ELColumn current) {
 				ELTable.this.removeColumn(current);
@@ -236,7 +236,7 @@
 	}
 
 	public Iterator<String> columnNames() {
-		return new TransformationIterator<String, ELColumn>(this.columns()) {
+		return new TransformationIterator<ELColumn, String>(this.columns()) {
 			@Override
 			protected String transform(ELColumn next) {
 				return next.getName();
@@ -266,7 +266,7 @@
 	}
 
 	public Iterator<String> primaryKeyColumnNames() {
-		return new TransformationIterator<String, ELColumn>(this.primaryKeyColumns()) {
+		return new TransformationIterator<ELColumn, String>(this.primaryKeyColumns()) {
 			@Override
 			protected String transform(ELColumn next) {
 				return next.getName();
@@ -295,8 +295,8 @@
 
 	// ********** references **********
 
-	public Iterator<ELReference> references() {
-		return new CloneIterator<ELReference>(this.references) {
+	public Iterable<ELReference> references() {
+		return new LiveCloneIterable<ELReference>(this.references) {
 			@Override
 			protected void remove(ELReference current) {
 				ELTable.this.removeReference(current);
@@ -372,7 +372,7 @@
 	}
 
 	public Iterator<String> referenceNames(){
-		return new TransformationIterator<String, ELReference>(this.references()) {
+		return new TransformationIterator<ELReference, String>(this.references()) {
 			@Override
 			protected String transform(ELReference next) {
 				return next.getName();
@@ -441,9 +441,9 @@
 	}
 
 	boolean nameMatchesIgnoreCase(String cat, String sch, String sn) {
-		return StringTools.stringsAreEqualIgnoreCase(this.catalog, cat) &&
-			StringTools.stringsAreEqualIgnoreCase(this.schema, sch) &&
-			StringTools.stringsAreEqualIgnoreCase(this.shortName, sn);
+		return StringTools.equalsIgnoreCase(this.catalog, cat) &&
+		       StringTools.equalsIgnoreCase(this.schema, sch) &&
+		       StringTools.equalsIgnoreCase(this.shortName, sn);
 	}
 
 	/**
@@ -465,7 +465,7 @@
 	}
 
 	public String qualifiedName() {
-		return NameTools.buildQualifiedDatabaseObjectName(this.catalog, this.schema, this.shortName);
+		return NameTools.buildQualifiedName(this.catalog, this.schema, this.shortName);
 	}
 
 	public String unqualifiedName() {
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/handles/MWHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/handles/MWHandle.java
index b10a2ca..ba5baa7 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/handles/MWHandle.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/handles/MWHandle.java
@@ -17,13 +17,12 @@
 import java.util.List;
 import java.util.ListIterator;
 import org.eclipse.persistence.tools.db.model.ELNode;
-import org.eclipse.persistence.tools.utility.iterators.EmptyIterator;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
 import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.TreeChangeListener;
 import org.eclipse.persistence.tools.utility.node.Node;
 import org.eclipse.persistence.tools.utility.node.Problem;
 
@@ -419,16 +418,6 @@
 			ListChangeListener listener) {
 	}
 
-	@Override
-	public void addTreeChangeListener(String treeName,
-			TreeChangeListener listener) {
-	}
-
-	@Override
-	public void removeTreeChangeListener(String treeName,
-			TreeChangeListener listener) {
-	}
-
 	// ********** member interface **********
 
 	/**
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java
index 89627e2..620369a 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java
@@ -79,11 +79,11 @@
 
 	private void read(Node node) throws CorruptXMLException {
 		try {
-			this.jdbcType = this.jdbcTypeNamed(XMLTools.childTextContent(node, "jdbc-type", null));
+			this.jdbcType = this.jdbcTypeNamed(XMLTools.getChildTextContent(node, "jdbc-type", null));
 		} catch (IllegalArgumentException ex) {
 			throw new CorruptXMLException(ex);
 		}
-		this.javaTypeDeclaration = new JavaTypeDeclaration(this, XMLTools.child(node, "java-type-declaration"));
+		this.javaTypeDeclaration = new JavaTypeDeclaration(this, XMLTools.getChild(node, "java-type-declaration"));
 	}
 
 	/**
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatform.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatform.java
index 790fee1..2803a73 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatform.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatform.java
@@ -18,11 +18,12 @@
 import java.util.List;
 import java.util.TreeSet;
 import java.util.Vector;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
 import org.eclipse.persistence.tools.utility.XMLTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterable.LiveCloneIterable;
+import org.eclipse.persistence.tools.utility.iterator.CloneIterator;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 import org.eclipse.persistence.tools.utility.node.AbstractNode;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
@@ -143,8 +144,8 @@
 	 * build an empty mapping for every JDBC type in the JDBC type repository
 	 */
 	private void initializeJDBCTypeToDatabaseTypeMappings() {
-		for (Iterator<JDBCType> stream = this.jdbcTypeRepository().jdbcTypes(); stream.hasNext(); ) {
-			this.jdbcTypeToDatabaseTypeMappings.add(new JDBCTypeToDatabaseTypeMapping(this, stream.next()));
+		for (JDBCType jdbcType : this.jdbcTypeRepository().jdbcTypes()) {
+			this.jdbcTypeToDatabaseTypeMappings.add(new JDBCTypeToDatabaseTypeMapping(this, jdbcType));
 		}
 	}
 
@@ -248,8 +249,8 @@
 
 
 	// ***** database types
-	public Iterator<DatabaseType> databaseTypes() {
-		return new CloneIterator<DatabaseType>(this.databaseTypes) {
+	public Iterable<DatabaseType> databaseTypes() {
+		return new LiveCloneIterable<DatabaseType>(this.databaseTypes) {
 			@Override
 			protected void remove(DatabaseType current) {
 				DatabasePlatform.this.removeDatabaseType(current);
@@ -332,8 +333,8 @@
 	 * adding and removing mappings is PRIVATE;
 	 * these are done only in response to changes to the JDBC type repository
 	 */
-	private Iterator<JDBCTypeToDatabaseTypeMapping> internalJDBCTypeToDatabaseTypeMappings() {
-		return new CloneIterator<JDBCTypeToDatabaseTypeMapping>(this.jdbcTypeToDatabaseTypeMappings) {
+	private Iterable<JDBCTypeToDatabaseTypeMapping> internalJDBCTypeToDatabaseTypeMappings() {
+		return new LiveCloneIterable<JDBCTypeToDatabaseTypeMapping>(this.jdbcTypeToDatabaseTypeMappings) {
 			@Override
 			protected void remove(JDBCTypeToDatabaseTypeMapping current) {
 				DatabasePlatform.this.removeJDBCTypeToDatabaseTypeMapping(current);
@@ -412,7 +413,7 @@
 	}
 
 	private Iterator<String> databaseTypeNames() {
-		return new TransformationIterator<String, DatabaseType>(this.databaseTypes()) {
+		return new TransformationIterator<DatabaseType, String>(this.databaseTypes()) {
 			@Override
 			protected String transform(DatabaseType next) {
 				return next.getName();
@@ -506,7 +507,7 @@
 	@Override
 	public void nodeRemoved(org.eclipse.persistence.tools.utility.node.Node node) {
 		super.nodeRemoved(node);
-		for (Iterator<JDBCTypeToDatabaseTypeMapping> stream = this.internalJDBCTypeToDatabaseTypeMappings(); stream.hasNext(); ) {
+		for (Iterator<JDBCTypeToDatabaseTypeMapping> stream = this.internalJDBCTypeToDatabaseTypeMappings().iterator(); stream.hasNext(); ) {
 			if (stream.next().getJDBCType() == node) {
 				stream.remove();
 				break;	// there should be only one...
@@ -528,7 +529,7 @@
 		this.supportsNativeSequencing = originalPlatform.supportsNativeSequencing();
 		this.supportsNativeReturning = originalPlatform.supportsNativeReturning();
 		this.supportsIdentityClause = originalPlatform.supportsIdentityClause();
-		for (Iterator<DatabaseType> stream = originalPlatform.databaseTypes(); stream.hasNext(); ) {
+		for (Iterator<DatabaseType> stream = originalPlatform.databaseTypes().iterator(); stream.hasNext(); ) {
 			DatabaseType originalType = stream.next();
 			DatabaseType cloneType = this.addDatabaseType(originalType.getName());
 			cloneType.cloneFrom(originalType);
@@ -555,7 +556,7 @@
 		if ((databaseTypeName == null) || (databaseTypeName.length() == 0)) {
 			throw new IllegalArgumentException("database type name is required");
 		}
-		if (CollectionTools.contains(this.databaseTypeNames(), databaseTypeName)) {
+		if (IteratorTools.contains(this.databaseTypeNames(), databaseTypeName)) {
 			throw new IllegalArgumentException("duplicate database type name: " + databaseTypeName);
 		}
 	}
@@ -567,39 +568,37 @@
 	private void read(File file) throws CorruptXMLException {
 		this.shortFileName = file.getName();
 		Document doc = XMLTools.parse(file);
-		Node root = XMLTools.child(doc, "database-platform");
+		Node root = XMLTools.getChild(doc, "database-platform");
 		if (root == null) {
 			throw new CorruptXMLException("missing root node: database-platform (" + file.getPath() + ")");
 		}
 
-		this.name = XMLTools.childTextContent(root, "name", null);
+		this.name = XMLTools.getChildTextContent(root, "name", null);
 		if ((this.name == null) || (this.name.length() == 0)) {
 			throw new CorruptXMLException("name is required (" + file.getPath() + ")");
 		}
 
-		this.runtimePlatformClassName = XMLTools.childTextContent(root, "runtime-platform-class", null);
+		this.runtimePlatformClassName = XMLTools.getChildTextContent(root, "runtime-platform-class", null);
 		if ((this.runtimePlatformClassName == null) || (this.runtimePlatformClassName.length() == 0)) {
 			throw this.buildCorruptXMLException("run-time platform class name is required");
 		}
 
-		this.supportsNativeSequencing = XMLTools.childBooleanContent(root, "supports-native-sequencing", false);
-		this.supportsNativeReturning = XMLTools.childBooleanContent(root, "supports-native-returning", false);
-		this.supportsIdentityClause = XMLTools.childBooleanContent(root, "supports-identity-clause", false);
+		this.supportsNativeSequencing = XMLTools.getChildBooleanContent(root, "supports-native-sequencing", false);
+		this.supportsNativeReturning = XMLTools.getChildBooleanContent(root, "supports-native-returning", false);
+		this.supportsIdentityClause = XMLTools.getChildBooleanContent(root, "supports-identity-clause", false);
 		if (this.supportsIdentityClause && ( ! this.supportsNativeSequencing)) {
 			throw this.buildCorruptXMLException("platform must support native sequencing if it supports the IDENTITY clause");
 		}
 
-		this.readDatabaseTypeNodes(XMLTools.child(root, "database-types"));
+		this.readDatabaseTypeNodes(XMLTools.getChild(root, "database-types"));
 
 		// wait until the database types have been read in before building the JDBC mappings
-		this.readJDBCMappingNodes(XMLTools.child(root, "jdbc-mappings"));
+		this.readJDBCMappingNodes(XMLTools.getChild(root, "jdbc-mappings"));
 	}
 
 	private void readDatabaseTypeNodes(Node databaseTypesNode) throws CorruptXMLException {
-		Node[] databaseTypeNodes = XMLTools.children(databaseTypesNode, "database-type");
-		int len = databaseTypeNodes.length;
-		for (int i = 0; i < len; i++) {
-			DatabaseType databaseType = new DatabaseType(this, databaseTypeNodes[i]);
+		for (Node databaseTypeNode : XMLTools.getChildren(databaseTypesNode, "database-type")) {
+			DatabaseType databaseType = new DatabaseType(this, databaseTypeNode);
 			try {
 				this.checkDatabaseType(databaseType);	// check for duplicates
 			} catch (IllegalArgumentException ex) {
@@ -610,10 +609,8 @@
 	}
 
 	private void readJDBCMappingNodes(Node mappingsNode) throws CorruptXMLException {
-		Node[] mappingNodes = XMLTools.children(mappingsNode, "jdbc-mapping");
-		int len = mappingNodes.length;
-		for (int i = 0; i < len; i++) {
-			JDBCTypeToDatabaseTypeMapping mapping = new JDBCTypeToDatabaseTypeMapping(this, mappingNodes[i]);
+		for (Node mappingNode : XMLTools.getChildren(mappingsNode, "jdbc-mapping")) {
+			JDBCTypeToDatabaseTypeMapping mapping = new JDBCTypeToDatabaseTypeMapping(this, mappingNode);
 			// check for duplicates
 			if (this.maps(mapping.getJDBCType())) {
 				throw this.buildCorruptXMLException("duplicate JDBC to database type mapping: " + mapping);
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatformRepository.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatformRepository.java
index 4d536b3..ae3cb4e 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatformRepository.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatformRepository.java
@@ -20,13 +20,13 @@
 import java.util.List;
 import java.util.Set;
 import java.util.Vector;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.FileTools;
-import org.eclipse.persistence.tools.utility.HashBag;
 import org.eclipse.persistence.tools.utility.XMLTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.io.FileTools;
+import org.eclipse.persistence.tools.utility.iterable.LiveCloneIterable;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 import org.eclipse.persistence.tools.utility.node.AbstractNode;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
@@ -212,8 +212,8 @@
 	}
 
 
-	public Iterator<DatabasePlatform> platforms() {
-		return new CloneIterator<DatabasePlatform>(this.platforms) {
+	public Iterable<DatabasePlatform> platforms() {
+		return new LiveCloneIterable<DatabasePlatform>(this.platforms) {
 			@Override
 			protected void remove(DatabasePlatform current) {
 				DatabasePlatformRepository.this.removePlatform(current);
@@ -323,7 +323,7 @@
 	}
 
 	private Iterator<String> platformNames() {
-		return new TransformationIterator<String, DatabasePlatform>(this.platforms()) {
+		return new TransformationIterator<DatabasePlatform, String>(this.platforms()) {
 			@Override
 			protected String transform(DatabasePlatform next) {
 				return next.getName();
@@ -332,7 +332,7 @@
 	}
 
 	private Iterator<String> platformShortFileNames() {
-		return new TransformationIterator<String, DatabasePlatform>(this.platforms()) {
+		return new TransformationIterator<DatabasePlatform, String>(this.platforms()) {
 			@Override
 			protected String transform(DatabasePlatform next) {
 				return next.getShortFileName();
@@ -447,7 +447,7 @@
 		if ((platformName == null) || (platformName.length() == 0)) {
 			throw new IllegalArgumentException("platform name is required");
 		}
-		if (CollectionTools.contains(this.platformNames(), platformName)) {
+		if (IteratorTools.contains(this.platformNames(), platformName)) {
 			throw new IllegalArgumentException("duplicate platform name: " + platformName);
 		}
 	}
@@ -465,7 +465,7 @@
 		if (FileTools.fileNameIsInvalid(platformShortFileName)) {
 			throw new IllegalArgumentException("invalid file name: " + platformShortFileName);
 		}
-		if (CollectionTools.contains(this.lowerCasePlatformShortFileNames(), platformShortFileName.toLowerCase())) {
+		if (IteratorTools.contains(this.lowerCasePlatformShortFileNames(), platformShortFileName.toLowerCase())) {
 			throw new IllegalArgumentException("duplicate file name: " + platformShortFileName);
 		}
 	}
@@ -476,22 +476,22 @@
 	// ***** read
 	private void read() throws CorruptXMLException {
 		Document document = XMLTools.parse(this.file);
-		Node root = XMLTools.child(document, "platforms");
+		Node root = XMLTools.getChild(document, "platforms");
 		if (root == null) {
 			throw this.buildCorruptXMLException("missing root node: platforms");
 		}
 
-		this.name = XMLTools.childTextContent(root, "name", null);
+		this.name = XMLTools.getChildTextContent(root, "name", null);
 		if ((this.name == null) || (this.name.length() == 0)) {
 			throw this.buildCorruptXMLException("name is required");
 		}
 
 		// read up the JDBC repository first, since the JDBC types are referenced elsewhere
-		this.jdbcTypeRepository = new JDBCTypeRepository(this, XMLTools.child(root, "jdbc-type-repository"));
+		this.jdbcTypeRepository = new JDBCTypeRepository(this, XMLTools.getChild(root, "jdbc-type-repository"));
 
 		this.readPlatforms();
 
-		String defaultPlatformName = XMLTools.childTextContent(root, "default-platform", null);
+		String defaultPlatformName = XMLTools.getChildTextContent(root, "default-platform", null);
 		if ((defaultPlatformName == null) || (defaultPlatformName.length() == 0)) {
 			if (this.platforms.size() == 0) {
 				// no problem
@@ -647,7 +647,7 @@
 	}
 
 	public void toString(StringBuffer sb) {
-		for (Iterator<DatabasePlatform> stream = this.platforms(); stream.hasNext(); ) {
+		for (Iterator<DatabasePlatform> stream = this.platforms().iterator(); stream.hasNext(); ) {
 			DatabasePlatform platform = stream.next();
 			platform.toString(sb);
 			if (stream.hasNext()) {
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabaseType.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabaseType.java
index d07eaba..ffe393a 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabaseType.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabaseType.java
@@ -12,8 +12,6 @@
 ******************************************************************************/
 package org.eclipse.persistence.tools.db.model.platformsmodel;
 
-import java.util.Iterator;
-
 import org.eclipse.persistence.tools.utility.XMLTools;
 import org.eclipse.persistence.tools.utility.node.AbstractNode;
 import org.w3c.dom.Node;
@@ -255,7 +253,7 @@
 	 * Returns all the JDBC types that the database type
 	 * could be mapped to. Simplifies UI code....
 	 */
-	public Iterator<JDBCType> jdbcTypes() {
+	public Iterable<JDBCType> jdbcTypes() {
 		return this.jdbcTypeRepository().jdbcTypes();
 	}
 
@@ -291,21 +289,21 @@
 		if (node == null) {
 			throw this.buildCorruptXMLException("missing node");
 		}
-		this.name = XMLTools.childTextContent(node, "name", null);
+		this.name = XMLTools.getChildTextContent(node, "name", null);
 		if ((this.name == null) || (this.name.length() == 0)) {
 			throw this.buildCorruptXMLException("name is required");
 		}
 
-		String jdbcTypeName = XMLTools.childTextContent(node, "jdbc-type", null);
+		String jdbcTypeName = XMLTools.getChildTextContent(node, "jdbc-type", null);
 		try {
 			this.jdbcType = this.jdbcTypeNamed(jdbcTypeName);
 		} catch (IllegalArgumentException ex) {
 			throw this.buildCorruptXMLException(ex);
 		}
 
-		this.allowsSize = XMLTools.childBooleanContent(node, "allows-size", false);
+		this.allowsSize = XMLTools.getChildBooleanContent(node, "allows-size", false);
 
-		this.requiresSize = XMLTools.childBooleanContent(node, "requires-size", false);
+		this.requiresSize = XMLTools.getChildBooleanContent(node, "requires-size", false);
 		if (( ! this.allowsSize) && this.requiresSize) {
 			throw this.buildCorruptXMLException("size cannot be required when it is not allowed");
 		}
@@ -315,12 +313,12 @@
 			throw this.buildCorruptXMLException("initial size cannot be specified when size is not required");
 		}
 
-		this.allowsSubSize = XMLTools.childBooleanContent(node, "allows-sub-size", false);
+		this.allowsSubSize = XMLTools.getChildBooleanContent(node, "allows-sub-size", false);
 		if (( ! this.allowsSize) && this.allowsSubSize) {
 			throw this.buildCorruptXMLException("sub-size cannot be allowed when size is not allowed");
 		}
 
-		this.allowsNull = XMLTools.childBooleanContent(node, "allows-null", false);
+		this.allowsNull = XMLTools.getChildBooleanContent(node, "allows-null", false);
 	}
 
 	/**
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCType.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCType.java
index 0862c25..17d8910 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCType.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCType.java
@@ -111,7 +111,7 @@
 		if (node == null) {
 			throw new CorruptXMLException("missing node");
 		}
-		this.name = XMLTools.childTextContent(node, "name", null);
+		this.name = XMLTools.getChildTextContent(node, "name", null);
 		if ((this.name == null) || (this.name.length() == 0)) {
 			throw new CorruptXMLException("name is required");
 		}
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeRepository.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeRepository.java
index ce639a5..d9ab561 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeRepository.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeRepository.java
@@ -14,17 +14,18 @@
 
 import java.lang.reflect.Field;
 import java.sql.Types;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.TreeSet;
 import java.util.Vector;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
 import org.eclipse.persistence.tools.utility.StringTools;
 import org.eclipse.persistence.tools.utility.XMLTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterable.LiveCloneIterable;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 import org.eclipse.persistence.tools.utility.node.AbstractNode;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
@@ -163,7 +164,7 @@
 			} catch (IllegalAccessException ex) {
 				throw new RuntimeException(ex);	// shouldn't happen...
 			}
-			if ( ! CollectionTools.contains(CollectionTools.list(DEFAULT_UNUSED_JDBC_TYPE_CODES), code)) {
+			if (Arrays.binarySearch(DEFAULT_UNUSED_JDBC_TYPE_CODES, code) < 0) {
 				this.checkJDBCType(name, code);	// check for duplicates
 				this.jdbcTypes.add(new JDBCType(this, name, code));
 			}
@@ -179,45 +180,44 @@
 	 *     or
 	 * 	http://java.sun.com/j2se/1.4.2/docs/guide/jdbc/getstart/GettingStartedTOC.fm.html
 	 */
-	// TODO uncomment 6 new Types when we start compiling with jdk1.6
 	private void initializeDefaultJDBCToJavaMappings() {
-		this.addJDBCToJavaMapping(Types.ARRAY,				java.sql.Array.class);
-		this.addJDBCToJavaMapping(Types.BIGINT,				long.class);
-		this.addJDBCToJavaMapping(Types.BINARY,				byte.class, 1);	// byte[]
-		this.addJDBCToJavaMapping(Types.BIT,					boolean.class);
-		this.addJDBCToJavaMapping(Types.BLOB,				java.sql.Blob.class);
-		this.addJDBCToJavaMapping(Types.BOOLEAN,			boolean.class);
-		this.addJDBCToJavaMapping(Types.CHAR,				java.lang.String.class);
-		this.addJDBCToJavaMapping(Types.CLOB,				java.sql.Clob.class);
-		this.addJDBCToJavaMapping(Types.DATALINK,			java.net.URL.class);
-		this.addJDBCToJavaMapping(Types.DATE,				java.sql.Date.class);
-		this.addJDBCToJavaMapping(Types.DECIMAL,			java.math.BigDecimal.class);
-		this.addJDBCToJavaMapping(Types.DISTINCT,			java.lang.Object.class);
-		this.addJDBCToJavaMapping(Types.DOUBLE,			double.class);
-		this.addJDBCToJavaMapping(Types.FLOAT,				double.class);
-		this.addJDBCToJavaMapping(Types.INTEGER,			int.class);
-		this.addJDBCToJavaMapping(Types.JAVA_OBJECT,	java.lang.Object.class);
-//		this.addJDBCToJavaMapping(Types.LONGNVARCHAR,					java.lang.String.class); // JDK1.6
-		this.addJDBCToJavaMapping(Types.LONGVARBINARY,	byte.class, 1);	// byte[]
-		this.addJDBCToJavaMapping(Types.LONGVARCHAR,	java.lang.String.class);
-//		this.addJDBCToJavaMapping(Types.NCHAR,					java.lang.String.class); // JDK1.6
-//		this.addJDBCToJavaMapping(Types.NCLOB,					java.sql.NClob.class); // JDK1.6
-//		this.addJDBCToJavaMapping(Types.NVARCHAR,					java.lang.String.class); // JDK1.6
+		this.addJDBCToJavaMapping(Types.ARRAY,         java.sql.Array.class);
+		this.addJDBCToJavaMapping(Types.BIGINT,        long.class);
+		this.addJDBCToJavaMapping(Types.BINARY,        byte.class, 1); // byte[]
+		this.addJDBCToJavaMapping(Types.BIT,           boolean.class);
+		this.addJDBCToJavaMapping(Types.BLOB,          java.sql.Blob.class);
+		this.addJDBCToJavaMapping(Types.BOOLEAN,       boolean.class);
+		this.addJDBCToJavaMapping(Types.CHAR,          java.lang.String.class);
+		this.addJDBCToJavaMapping(Types.CLOB,          java.sql.Clob.class);
+		this.addJDBCToJavaMapping(Types.DATALINK,      java.net.URL.class);
+		this.addJDBCToJavaMapping(Types.DATE,          java.sql.Date.class);
+		this.addJDBCToJavaMapping(Types.DECIMAL,       java.math.BigDecimal.class);
+		this.addJDBCToJavaMapping(Types.DISTINCT,      java.lang.Object.class);
+		this.addJDBCToJavaMapping(Types.DOUBLE,        double.class);
+		this.addJDBCToJavaMapping(Types.FLOAT,         double.class);
+		this.addJDBCToJavaMapping(Types.INTEGER,       int.class);
+		this.addJDBCToJavaMapping(Types.JAVA_OBJECT,   java.lang.Object.class);
+		this.addJDBCToJavaMapping(Types.LONGNVARCHAR,  java.lang.String.class); // JDK1.6
+		this.addJDBCToJavaMapping(Types.LONGVARBINARY, byte.class, 1);	// byte[]
+		this.addJDBCToJavaMapping(Types.LONGVARCHAR,   java.lang.String.class);
+		this.addJDBCToJavaMapping(Types.NCHAR,         java.lang.String.class); // JDK1.6
+		this.addJDBCToJavaMapping(Types.NCLOB,         java.sql.NClob.class);   // JDK1.6
+		this.addJDBCToJavaMapping(Types.NVARCHAR,      java.lang.String.class); // JDK1.6
 		// not sure why this is defined in java.sql.Types
-//		this.addJDBCToJavaMapping(Types.NULL,					java.lang.Object.class);
-		this.addJDBCToJavaMapping(Types.NUMERIC,			java.math.BigDecimal.class);
-		this.addJDBCToJavaMapping(Types.OTHER,				java.lang.Object.class);	// ???
-		this.addJDBCToJavaMapping(Types.REAL,				float.class);
-		this.addJDBCToJavaMapping(Types.REF,					java.sql.Ref.class);
-//		this.addJDBCToJavaMapping(Types.ROWID,					java.sql.RowId.class); // JDK1.6
-		this.addJDBCToJavaMapping(Types.SMALLINT,			short.class);
-//		this.addJDBCToJavaMapping(Types.SQLXML,					java.sql.SQLXML.class); // JDK1.6
-		this.addJDBCToJavaMapping(Types.STRUCT,			java.sql.Struct.class);
-		this.addJDBCToJavaMapping(Types.TIME,				java.sql.Time.class);
-		this.addJDBCToJavaMapping(Types.TIMESTAMP,		java.sql.Timestamp.class);
-		this.addJDBCToJavaMapping(Types.TINYINT,			byte.class);
-		this.addJDBCToJavaMapping(Types.VARBINARY,		byte.class, 1);	// byte[]
-		this.addJDBCToJavaMapping(Types.VARCHAR,			java.lang.String.class);
+		this.addJDBCToJavaMapping(Types.NULL,          java.lang.Object.class);
+		this.addJDBCToJavaMapping(Types.NUMERIC,       java.math.BigDecimal.class);
+		this.addJDBCToJavaMapping(Types.OTHER,         java.lang.Object.class); // ???
+		this.addJDBCToJavaMapping(Types.REAL,          float.class);
+		this.addJDBCToJavaMapping(Types.REF,           java.sql.Ref.class);
+		this.addJDBCToJavaMapping(Types.ROWID,         java.sql.RowId.class); // JDK1.6
+		this.addJDBCToJavaMapping(Types.SMALLINT,      short.class);
+		this.addJDBCToJavaMapping(Types.SQLXML,        java.sql.SQLXML.class); // JDK1.6
+		this.addJDBCToJavaMapping(Types.STRUCT,        java.sql.Struct.class);
+		this.addJDBCToJavaMapping(Types.TIME,          java.sql.Time.class);
+		this.addJDBCToJavaMapping(Types.TIMESTAMP,     java.sql.Timestamp.class);
+		this.addJDBCToJavaMapping(Types.TINYINT,       byte.class);
+		this.addJDBCToJavaMapping(Types.VARBINARY,     byte.class, 1); // byte[]
+		this.addJDBCToJavaMapping(Types.VARCHAR,       java.lang.String.class);
 	}
 
 	private void addJDBCToJavaMapping(int jdbcTypeCode, Class<?> javaClass) {
@@ -306,8 +306,8 @@
 	}
 
 
-	public Iterator<JDBCType> jdbcTypes() {
-		return new CloneIterator<JDBCType>(this.jdbcTypes) {
+	public Iterable<JDBCType> jdbcTypes() {
+		return new LiveCloneIterable<JDBCType>(this.jdbcTypes) {
 			@Override
 			protected void remove(JDBCType current) {
 				JDBCTypeRepository.this.removeJDBCType(current);
@@ -346,13 +346,13 @@
 	}
 
 	private void jdbcTypeRemoved(JDBCType removedJDBCType) {
-		for (Iterator<JDBCTypeToJavaTypeDeclarationMapping> stream = this.jdbcTypeToJavaTypeDeclarationMappings(); stream.hasNext(); ) {
+		for (Iterator<JDBCTypeToJavaTypeDeclarationMapping> stream = this.jdbcTypeToJavaTypeDeclarationMappings().iterator(); stream.hasNext(); ) {
 			if (stream.next().getJDBCType() == removedJDBCType) {
 				stream.remove();
 				break;	// there should be only one...
 			}
 		}
-		for (Iterator<JavaTypeDeclarationToJDBCTypeMapping> stream = this.javaTypeDeclarationToJDBCTypeMappings(); stream.hasNext(); ) {
+		for (Iterator<JavaTypeDeclarationToJDBCTypeMapping> stream = this.javaTypeDeclarationToJDBCTypeMappings().iterator(); stream.hasNext(); ) {
 			JavaTypeDeclarationToJDBCTypeMapping mapping = stream.next();
 			if (mapping.getJDBCType() == removedJDBCType) {
 				mapping.setJDBCType(this.defaultJDBCType);		// hmmm...
@@ -402,8 +402,8 @@
 
 
 	// JDBC => Java mappings
-	public Iterator<JDBCTypeToJavaTypeDeclarationMapping> jdbcTypeToJavaTypeDeclarationMappings() {
-		return new CloneIterator<JDBCTypeToJavaTypeDeclarationMapping>(this.jdbcTypeToJavaTypeDeclarationMappings) {
+	public Iterable<JDBCTypeToJavaTypeDeclarationMapping> jdbcTypeToJavaTypeDeclarationMappings() {
+		return new LiveCloneIterable<JDBCTypeToJavaTypeDeclarationMapping>(this.jdbcTypeToJavaTypeDeclarationMappings) {
 			@Override
 			protected void remove(JDBCTypeToJavaTypeDeclarationMapping current) {
 				JDBCTypeRepository.this.removeJDBCTypeToJavaTypeDeclarationMapping(current);
@@ -439,8 +439,8 @@
 
 
 	// Java => JDBC mappings
-	public Iterator<JavaTypeDeclarationToJDBCTypeMapping> javaTypeDeclarationToJDBCTypeMappings() {
-		return new CloneIterator<JavaTypeDeclarationToJDBCTypeMapping>(this.javaTypeDeclarationToJDBCTypeMappings) {
+	public Iterable<JavaTypeDeclarationToJDBCTypeMapping> javaTypeDeclarationToJDBCTypeMappings() {
+		return new LiveCloneIterable<JavaTypeDeclarationToJDBCTypeMapping>(this.javaTypeDeclarationToJDBCTypeMappings) {
 			@Override
 			protected void remove(JavaTypeDeclarationToJDBCTypeMapping current) {
 				JDBCTypeRepository.this.removeJavaTypeDeclarationToJDBCTypeMapping(current);
@@ -582,7 +582,7 @@
 	}
 
 	private Iterator<String> jdbcTypeNames() {
-		return new TransformationIterator<String, JDBCType>(this.jdbcTypes()) {
+		return new TransformationIterator<JDBCType, String>(this.jdbcTypes()) {
 			@Override
 			protected String transform(JDBCType next) {
 				return next.getName();
@@ -626,7 +626,7 @@
 		if (jdbcTypeName == null) {
 			throw new NullPointerException();
 		}
-		if (CollectionTools.contains(this.jdbcTypeNames(), jdbcTypeName)) {
+		if (IteratorTools.contains(this.jdbcTypeNames(), jdbcTypeName)) {
 			throw new IllegalArgumentException("duplicate JDBC type name: " + jdbcTypeName);
 		}
 	}
@@ -677,32 +677,30 @@
 			throw new CorruptXMLException("missing node");
 		}
 
-		this.readJDBCTypeNodes(XMLTools.child(node, "jdbc-types"));
+		this.readJDBCTypeNodes(XMLTools.getChild(node, "jdbc-types"));
 		if (this.jdbcTypes.isEmpty()) {
 			throw new CorruptXMLException("the JDBC type repository is empty");
 		}
 
-		String defaultJDBCTypeName = XMLTools.childTextContent(node, "default-jdbc-type", null);
+		String defaultJDBCTypeName = XMLTools.getChildTextContent(node, "default-jdbc-type", null);
 		try {
 			this.defaultJDBCType = this.jdbcTypeNamed(defaultJDBCTypeName);
 		} catch (IllegalArgumentException ex) {
 			throw new CorruptXMLException("default JDBC type", ex);
 		}
 
-		this.readJDBCToJavaMappingNodes(XMLTools.child(node, "jdbc-type-to-java-type-declaration-mappings"));
+		this.readJDBCToJavaMappingNodes(XMLTools.getChild(node, "jdbc-type-to-java-type-declaration-mappings"));
 		// make sure we have mapped ALL the JDBC types (there are no duplicates at this point)
 		if (this.jdbcTypeToJavaTypeDeclarationMappings.size() != this.jdbcTypes.size()) {
 			throw new CorruptXMLException("all the JDBC types must be mapped to Java type declarations");
 		}
 
-		this.readJavaToJDBCMappingNodes(XMLTools.child(node, "java-type-declaration-to-jdbc-type-mappings"));
+		this.readJavaToJDBCMappingNodes(XMLTools.getChild(node, "java-type-declaration-to-jdbc-type-mappings"));
 	}
 
 	private void readJDBCTypeNodes(Node jdbcTypesNode) throws CorruptXMLException {
-		Node[] jdbcTypeNodes = XMLTools.children(jdbcTypesNode, "jdbc-type");
-		int len = jdbcTypeNodes.length;
-		for (int i = 0; i < len; i++) {
-			JDBCType jdbcType = new JDBCType(this, jdbcTypeNodes[i]);
+		for (Node jdbcTypeNode : XMLTools.getChildren(jdbcTypesNode, "jdbc-type")) {
+			JDBCType jdbcType = new JDBCType(this, jdbcTypeNode);
 			try {
 				this.checkJDBCType(jdbcType);	// check for duplicates
 			} catch (IllegalArgumentException ex) {
@@ -713,10 +711,8 @@
 	}
 
 	private void readJDBCToJavaMappingNodes(Node mappingsNode) throws CorruptXMLException {
-		Node[] mappingNodes = XMLTools.children(mappingsNode, "jdbc-type-to-java-type-declaration-mapping");
-		int len = mappingNodes.length;
-		for (int i = 0; i < len; i++) {
-			JDBCTypeToJavaTypeDeclarationMapping mapping = new JDBCTypeToJavaTypeDeclarationMapping(this, mappingNodes[i]);
+		for (Node mappingNode : XMLTools.getChildren(mappingsNode, "jdbc-type-to-java-type-declaration-mapping")) {
+			JDBCTypeToJavaTypeDeclarationMapping mapping = new JDBCTypeToJavaTypeDeclarationMapping(this, mappingNode);
 			try {
 				this.checkJDBCToJavaMapping(mapping.getJDBCType());	// check for duplicates
 			} catch (IllegalArgumentException ex) {
@@ -727,10 +723,8 @@
 	}
 
 	private void readJavaToJDBCMappingNodes(Node mappingsNode) throws CorruptXMLException {
-		Node[] mappingNodes = XMLTools.children(mappingsNode, "java-type-declaration-to-jdbc-type-mapping");
-		int len = mappingNodes.length;
-		for (int i = 0; i < len; i++) {
-			JavaTypeDeclarationToJDBCTypeMapping mapping = new JavaTypeDeclarationToJDBCTypeMapping(this, mappingNodes[i]);
+		for (Node mappingNode : XMLTools.getChildren(mappingsNode, "java-type-declaration-to-jdbc-type-mapping")) {
+			JavaTypeDeclarationToJDBCTypeMapping mapping = new JavaTypeDeclarationToJDBCTypeMapping(this, mappingNode);
 			try {
 				this.checkJavaToJDBCMapping(mapping.getJavaTypeDeclaration());	// check for duplicates
 			} catch (IllegalArgumentException ex) {
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeToDatabaseTypeMapping.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeToDatabaseTypeMapping.java
index 9c16142..67beff9 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeToDatabaseTypeMapping.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeToDatabaseTypeMapping.java
@@ -115,11 +115,11 @@
 
 	private void read(Node node) throws CorruptXMLException {
 		try {
-			this.jdbcType = this.jdbcTypeNamed(XMLTools.childTextContent(node, "jdbc-type", null));
+			this.jdbcType = this.jdbcTypeNamed(XMLTools.getChildTextContent(node, "jdbc-type", null));
 		} catch (IllegalArgumentException ex) {
 			throw new CorruptXMLException("platform: " + this.getPlatform().getName(), ex);
 		}
-		String databaseTypeName = XMLTools.childTextContent(node, "database-type", null);
+		String databaseTypeName = XMLTools.getChildTextContent(node, "database-type", null);
 		if (databaseTypeName != null) {
 			try {
 				this.databaseType = this.databaseTypeNamed(databaseTypeName);
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JavaTypeDeclaration.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JavaTypeDeclaration.java
index e8285c4..f95d990 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JavaTypeDeclaration.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JavaTypeDeclaration.java
@@ -130,7 +130,7 @@
 		if (node == null) {
 			throw new CorruptXMLException("missing node");
 		}
-		this.javaClassName = XMLTools.childTextContent(node, "java-class-name", null);
+		this.javaClassName = XMLTools.getChildTextContent(node, "java-class-name", null);
 		this.arrayDepth = XMLTools.childIntContent(node, "array-depth", 0);
 		try {
 			this.checkState();
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalColumn.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalColumn.java
index bbe605d..448cf91 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalColumn.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalColumn.java
@@ -16,7 +16,7 @@
 import java.sql.SQLException;
 import java.sql.Types;
 import org.eclipse.persistence.tools.db.model.spi.ExternalColumn;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  * @see comment about defensive programming at JDBCExternalDatabase
@@ -199,7 +199,7 @@
 	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.name);
+		return ObjectTools.toString(this, this.name);
 	}
 
 
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabase.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabase.java
index 9c8ed7f..221bbfc 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabase.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabase.java
@@ -19,9 +19,9 @@
 import java.util.List;
 import org.eclipse.persistence.tools.db.model.spi.ExternalDatabase;
 import org.eclipse.persistence.tools.db.model.spi.ExternalTableDescription;
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.ResultSetIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.ResultSetIterator;
 
 /**
  * This external database derives all of its metadata from a client-supplied JDBC connection.
@@ -123,7 +123,7 @@
 			// if #getTables() does not work, there's not much we can do...
 			throw new RuntimeException(ex);
 		}
-		List<ExternalTableDescription> tableDescriptions = CollectionTools.list(new ResultSetIterator<ExternalTableDescription>(
+		List<ExternalTableDescription> tableDescriptions = ListTools.list(new ResultSetIterator<ExternalTableDescription>(
 			resultSet,
 			new ExternalTableDescriptionResultSetAdapter())
 		);
@@ -163,7 +163,7 @@
 	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this);
+		return ObjectTools.toString(this);
 	}
 
 
@@ -173,7 +173,7 @@
 	 * convert the specified single-column result set to an array of strings
 	 */
 	private String[] buildStringArray(ResultSet resultSet) {
-		List<String> strings = CollectionTools.list(new ResultSetIterator<String>(resultSet, new StringResultSetAdapter()));
+		List<String> strings = ListTools.list(new ResultSetIterator<String>(resultSet, new StringResultSetAdapter()));
 		return strings.toArray(new String[strings.size()]);
 	}
 
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabaseFactory.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabaseFactory.java
index 7d0e8f7..0410c18 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabaseFactory.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabaseFactory.java
@@ -15,7 +15,7 @@
 import java.sql.Connection;
 import org.eclipse.persistence.tools.db.model.spi.ExternalDatabase;
 import org.eclipse.persistence.tools.db.model.spi.ExternalDatabaseFactory;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  * Not much to say here: This is a factory for generating instances of
@@ -60,6 +60,6 @@
 	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, "singleton");
+		return ObjectTools.toString(this, "singleton");
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKey.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKey.java
index e5c765a..5a137bc 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKey.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKey.java
@@ -17,7 +17,7 @@
 import org.eclipse.persistence.tools.db.model.spi.ExternalForeignKey;
 import org.eclipse.persistence.tools.db.model.spi.ExternalForeignKeyColumnPair;
 import org.eclipse.persistence.tools.db.model.spi.ExternalTableDescription;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  *
@@ -126,6 +126,6 @@
 	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.name);
+		return ObjectTools.toString(this, this.name);
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKeyColumnPair.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKeyColumnPair.java
index 369dab4..fd0316a 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKeyColumnPair.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKeyColumnPair.java
@@ -16,7 +16,7 @@
 import java.sql.SQLException;
 import org.eclipse.persistence.tools.db.model.spi.ExternalColumn;
 import org.eclipse.persistence.tools.db.model.spi.ExternalForeignKeyColumnPair;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  * Associate a pair of columns from a foreign key that is made
@@ -110,7 +110,7 @@
 	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.sourceColumnName() + "=>" + this.targetColumnName());
+		return ObjectTools.toString(this, this.sourceColumnName() + "=>" + this.targetColumnName());
 	}
 
 
@@ -159,7 +159,7 @@
 		}
 		@Override
 		public String toString() {
-			return StringTools.buildToStringFor(this, this.name);
+			return ObjectTools.toString(this, this.name);
 		}
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTable.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTable.java
index 6837faf..f8d3704 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTable.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTable.java
@@ -22,7 +22,7 @@
 import org.eclipse.persistence.tools.db.model.spi.ExternalColumn;
 import org.eclipse.persistence.tools.db.model.spi.ExternalForeignKey;
 import org.eclipse.persistence.tools.db.model.spi.ExternalTable;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  * see comment about defensive programming at JDBCExternalDatabase
@@ -202,6 +202,6 @@
 	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.tableDescription.getQualifiedName());
+		return ObjectTools.toString(this, this.tableDescription.getQualifiedName());
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTableDescription.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTableDescription.java
index 5068a80..c74930f 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTableDescription.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTableDescription.java
@@ -18,7 +18,7 @@
 import org.eclipse.persistence.tools.db.model.spi.ExternalTable;
 import org.eclipse.persistence.tools.db.model.spi.ExternalTableDescription;
 import org.eclipse.persistence.tools.utility.NameTools;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  * @version 2.5
@@ -72,7 +72,7 @@
 	}
 
 	private String buildQualifiedName() {
-		return NameTools.buildQualifiedDatabaseObjectName(this.catalogName, this.schemaName, this.name);
+		return NameTools.buildQualifiedName(this.catalogName, this.schemaName, this.name);
 	}
 
 
@@ -157,6 +157,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.qualifiedName);
+		return ObjectTools.toString(this, this.qualifiedName);
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELColumn.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELColumn.java
index 0fce922..e9a9d3f 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELColumn.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELColumn.java
@@ -13,7 +13,6 @@
 package org.eclipse.persistence.tools.db.relational;
 
 import java.util.List;
-
 import org.eclipse.persistence.tools.db.relational.platformsmodel.DatabasePlatform;
 import org.eclipse.persistence.tools.db.relational.platformsmodel.DatabaseType;
 import org.eclipse.persistence.tools.db.relational.platformsmodel.JavaTypeDeclaration;
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELColumnPair.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELColumnPair.java
index fe4cb9e..4e71741 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELColumnPair.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELColumnPair.java
@@ -13,7 +13,6 @@
 package org.eclipse.persistence.tools.db.relational;
 
 import java.util.List;
-
 import org.eclipse.persistence.tools.db.relational.handles.MWColumnHandle;
 import org.eclipse.persistence.tools.db.relational.handles.MWHandle;
 import org.eclipse.persistence.tools.db.relational.handles.MWHandle.NodeReferenceScrubber;
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELDatabase.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELDatabase.java
index d899424..c9706d5 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELDatabase.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELDatabase.java
@@ -34,11 +34,11 @@
 import org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription;
 import org.eclipse.persistence.tools.db.relational.spi.jdbc.JDBCExternalDatabaseFactory;
 import org.eclipse.persistence.tools.schemaframework.SchemaManager;
-import org.eclipse.persistence.tools.utility.CollectionTools;
 import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterable.LiveCloneIterable;
+import org.eclipse.persistence.tools.utility.iterator.ArrayIterator;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 import org.eclipse.persistence.tools.utility.node.Node;
 
 /**
@@ -192,8 +192,8 @@
 
 	// ********** login specs **********
 
-	public Iterator<ELLoginSpec> loginSpecs() {
-		return new CloneIterator<ELLoginSpec>(this.loginSpecs) {
+	public Iterable<ELLoginSpec> loginSpecs() {
+		return new LiveCloneIterable<ELLoginSpec>(this.loginSpecs) {
 			@Override
 			protected void remove(ELLoginSpec current) {
 				ELDatabase.this.removeLoginSpec(current);
@@ -241,7 +241,7 @@
 	}
 
 	public Iterator<String> loginSpecNames() {
-		return new TransformationIterator<String, ELLoginSpec>(this.loginSpecs()) {
+		return new TransformationIterator<ELLoginSpec, String>(this.loginSpecs()) {
 			@Override
 			protected String transform(ELLoginSpec next) {
 				return next.getName();
@@ -278,8 +278,8 @@
 
 	// ********** tables **********
 
-	public Iterator<ELTable> tables() {
-		return new CloneIterator<ELTable>(this.tables) {
+	public Iterable<ELTable> tables() {
+		return new LiveCloneIterable<ELTable>(this.tables) {
 			@Override
 			protected void remove(ELTable current) {
 				ELDatabase.this.removeTable(current);
@@ -377,7 +377,7 @@
 	 * used to prevent adding a duplicate table
 	 */
 	public Iterator<String> tableNames() {
-		return new TransformationIterator<String, ELTable>(this.tables()) {
+		return new TransformationIterator<ELTable, String>(this.tables()) {
 			@Override
 			protected String transform(ELTable next) {
 				return next.getName();
@@ -834,7 +834,7 @@
 
 	// ********** SubComponentContainer implementation **********
 
-	public Iterator projectSubFileComponents() {
+	public Iterable projectSubFileComponents() {
 		return this.tables();
 	}
 
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELLoginSpec.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELLoginSpec.java
index c633983..2c2d665 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELLoginSpec.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELLoginSpec.java
@@ -29,12 +29,13 @@
 import org.eclipse.persistence.sessions.DatabaseLogin;
 import org.eclipse.persistence.sessions.Session;
 import org.eclipse.persistence.tools.db.relational.platformsmodel.DatabasePlatform;
-import org.eclipse.persistence.tools.utility.CollectionTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
-import org.eclipse.persistence.tools.utility.iterators.CloneListIterator;
-import org.eclipse.persistence.tools.utility.iterators.EmptyIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.ArrayIterator;
+import org.eclipse.persistence.tools.utility.iterator.CloneListIterator;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 import org.eclipse.persistence.tools.utility.node.Node;
 
 /**
@@ -84,7 +85,7 @@
 	 * Returns the driver class names we know about
 	 */
 	public static Iterator<String> commonDriverClassNames() {
-		return new TransformationIterator<String, DriverSpec>(driverSpecs()) {
+		return new TransformationIterator<DriverSpec, String>(driverSpecs()) {
 			@Override
 			protected String transform(DriverSpec next) {
 				return next.getDriverClassName();
@@ -324,7 +325,7 @@
 	}
 
 	public void addDriverClasspathEntries(ListIterator<String> entries) {
-		this.addDriverClasspathEntries(CollectionTools.list(entries));
+		this.addDriverClasspathEntries(ListTools.list(entries));
 	}
 
 	public String removeDriverClasspathEntry(int index) {
@@ -502,7 +503,7 @@
 
 		@Override
 		public String toString() {
-			return StringTools.buildToStringFor(this, this.driverClassName);
+			return ObjectTools.toString(this, this.driverClassName);
 		}
 	}
 
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELModel.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELModel.java
index d950547..7b98251 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELModel.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELModel.java
@@ -16,8 +16,7 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
 import org.eclipse.persistence.tools.utility.node.AbstractNode;
 import org.eclipse.persistence.tools.utility.node.Node;
 
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELReference.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELReference.java
index 5941071..11d1524 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELReference.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELReference.java
@@ -17,14 +17,13 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Vector;
-
 import org.eclipse.persistence.tools.db.relational.handles.MWHandle;
-import org.eclipse.persistence.tools.db.relational.handles.MWTableHandle;
 import org.eclipse.persistence.tools.db.relational.handles.MWHandle.NodeReferenceScrubber;
+import org.eclipse.persistence.tools.db.relational.handles.MWTableHandle;
 import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKey;
 import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKeyColumnPair;
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterable.LiveCloneIterable;
 import org.eclipse.persistence.tools.utility.node.Node;
 
 /**
@@ -122,8 +121,8 @@
 	}
 
 	// ********** column pairs
-	public Iterator<ELColumnPair> columnPairs() {
-		return new CloneIterator<ELColumnPair>(this.columnPairs) {
+	public Iterable<ELColumnPair> columnPairs() {
+		return new LiveCloneIterable<ELColumnPair>(this.columnPairs) {
 			@Override
 			protected void remove(ELColumnPair current) {
 				ELReference.this.removeColumnPair(current);
@@ -154,21 +153,18 @@
 		this.removeItemFromCollection(columnPair, this.columnPairs, COLUMN_PAIRS_COLLECTION);
 	}
 
-	public void removeColumnPairs(Iterator pairs) {
+	public void removeColumnPairs(Iterator<ELColumnPair> pairs) {
 		while (pairs.hasNext()) {
-			this.removeColumnPair((ELColumnPair) pairs.next());
+			this.removeColumnPair(pairs.next());
 		}
 	}
 
-	public void removeColumnPairs(Collection pairs) {
+	public void removeColumnPairs(Collection<ELColumnPair> pairs) {
 		this.removeColumnPairs(pairs.iterator());
 	}
 
 	private void clearColumnPairs() {
-		for (Iterator stream = this.columnPairs(); stream.hasNext(); ) {
-			stream.next();
-			stream.remove();
-		}
+		clearCollection(this.columnPairs, COLUMN_PAIRS_COLLECTION);
 	}
 
 	/**
@@ -176,10 +172,9 @@
 	 */
 	public ELColumnPair columnPairNamed(String columnPairName) {
 		synchronized (this.columnPairs) {
-			for (Iterator stream = this.columnPairs.iterator(); stream.hasNext(); ) {
-				ELColumnPair pair = (ELColumnPair) stream.next();
-				if (pair.getName().equals(columnPairName)) {
-					return pair;
+			for (ELColumnPair columnPair : this.columnPairs) {
+				if (columnPair.getName().equals(columnPairName)) {
+					return columnPair;
 				}
 			}
 		}
@@ -188,10 +183,9 @@
 
 	public ELColumnPair columnPairFor(ELColumn sourceColumn, ELColumn targetColumn) {
 		synchronized (this.columnPairs) {
-			for (Iterator stream = this.columnPairs.iterator(); stream.hasNext(); ) {
-				ELColumnPair pair = (ELColumnPair) stream.next();
-				if (pair.pairs(sourceColumn, targetColumn)) {
-					return pair;
+			for (ELColumnPair columnPair : this.columnPairs) {
+				if (columnPair.pairs(sourceColumn, targetColumn)) {
+					return columnPair;
 				}
 			}
 		}
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELTable.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELTable.java
index ef0479f..7d7cfa2 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELTable.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELTable.java
@@ -18,7 +18,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Vector;
-
 import org.eclipse.persistence.tools.db.relational.platformsmodel.DatabasePlatform;
 import org.eclipse.persistence.tools.db.relational.spi.ExternalColumn;
 import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKey;
@@ -27,10 +26,10 @@
 import org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription;
 import org.eclipse.persistence.tools.utility.NameTools;
 import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.iterators.CompositeIterator;
-import org.eclipse.persistence.tools.utility.iterators.FilteringIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.iterable.LiveCloneIterable;
+import org.eclipse.persistence.tools.utility.iterator.CompositeIterator;
+import org.eclipse.persistence.tools.utility.iterator.FilteringIterator;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 import org.eclipse.persistence.tools.utility.node.Node;
 
 /**
@@ -142,8 +141,8 @@
 	private void qualifiedNameChanged() {
 		this.firePropertyChanged(QUALIFIED_NAME_PROPERTY, this.qualifiedName());
 		this.getParent().nodeRenamed(this);
-		for (Iterator<ELColumn> stream = this.columns(); stream.hasNext(); ) {
-			stream.next().qualifiedNameChanged();
+		for (ELColumn column : this.columns()) {
+			column.qualifiedNameChanged();
 		}
 	}
 
@@ -169,8 +168,8 @@
 
 	// ********** columns **********
 
-	public Iterator<ELColumn> columns() {
-		return new CloneIterator<ELColumn>(this.columns) {
+	public Iterable<ELColumn> columns() {
+		return new LiveCloneIterable<ELColumn>(this.columns) {
 			@Override
 			protected void remove(ELColumn current) {
 				ELTable.this.removeColumn(current);
@@ -237,7 +236,7 @@
 	}
 
 	public Iterator<String> columnNames() {
-		return new TransformationIterator<String, ELColumn>(this.columns()) {
+		return new TransformationIterator<ELColumn, String>(this.columns()) {
 			@Override
 			protected String transform(ELColumn next) {
 				return next.getName();
@@ -267,7 +266,7 @@
 	}
 
 	public Iterator<String> primaryKeyColumnNames() {
-		return new TransformationIterator<String, ELColumn>(this.primaryKeyColumns()) {
+		return new TransformationIterator<ELColumn, String>(this.primaryKeyColumns()) {
 			@Override
 			protected String transform(ELColumn next) {
 				return next.getName();
@@ -296,8 +295,8 @@
 
 	// ********** references **********
 
-	public Iterator<ELReference> references() {
-		return new CloneIterator<ELReference>(this.references) {
+	public Iterable<ELReference> references() {
+		return new LiveCloneIterable<ELReference>(this.references) {
 			@Override
 			protected void remove(ELReference current) {
 				ELTable.this.removeReference(current);
@@ -373,7 +372,7 @@
 	}
 
 	public Iterator<String> referenceNames(){
-		return new TransformationIterator<String, ELReference>(this.references()) {
+		return new TransformationIterator<ELReference, String>(this.references()) {
 			@Override
 			protected String transform(ELReference next) {
 				return next.getName();
@@ -442,9 +441,9 @@
 	}
 
 	boolean nameMatchesIgnoreCase(String cat, String sch, String sn) {
-		return StringTools.stringsAreEqualIgnoreCase(this.catalog, cat) &&
-			StringTools.stringsAreEqualIgnoreCase(this.schema, sch) &&
-			StringTools.stringsAreEqualIgnoreCase(this.shortName, sn);
+		return StringTools.equalsIgnoreCase(this.catalog, cat) &&
+		       StringTools.equalsIgnoreCase(this.schema, sch) &&
+		       StringTools.equalsIgnoreCase(this.shortName, sn);
 	}
 
 	/**
@@ -466,7 +465,7 @@
 	}
 
 	public String qualifiedName() {
-		return NameTools.buildQualifiedDatabaseObjectName(this.catalog, this.schema, this.shortName);
+		return NameTools.buildQualifiedName(this.catalog, this.schema, this.shortName);
 	}
 
 	public String unqualifiedName() {
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWHandle.java
index f6e5a02..7eb67ca 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWHandle.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWHandle.java
@@ -16,15 +16,13 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
-
 import org.eclipse.persistence.tools.db.relational.ELNode;
-import org.eclipse.persistence.tools.utility.iterators.EmptyIterator;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
 import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.TreeChangeListener;
 import org.eclipse.persistence.tools.utility.node.Node;
 import org.eclipse.persistence.tools.utility.node.Problem;
 
@@ -420,15 +418,6 @@
 			ListChangeListener listener) {
 	}
 
-	@Override
-	public void addTreeChangeListener(String treeName,
-			TreeChangeListener listener) {
-	}
-
-	@Override
-	public void removeTreeChangeListener(String treeName,
-			TreeChangeListener listener) {
-	}
 
 	// ********** member interface **********
 
@@ -458,5 +447,4 @@
 			}
 		};
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java
index 21501ec..002f515 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java
@@ -79,11 +79,11 @@
 
 	private void read(Node node) throws CorruptXMLException {
 		try {
-			this.jdbcType = this.jdbcTypeNamed(XMLTools.childTextContent(node, "jdbc-type", null));
+			this.jdbcType = this.jdbcTypeNamed(XMLTools.getChildTextContent(node, "jdbc-type", null));
 		} catch (IllegalArgumentException ex) {
 			throw new CorruptXMLException(ex);
 		}
-		this.javaTypeDeclaration = new JavaTypeDeclaration(this, XMLTools.child(node, "java-type-declaration"));
+		this.javaTypeDeclaration = new JavaTypeDeclaration(this, XMLTools.getChild(node, "java-type-declaration"));
 	}
 
 	/**
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabasePlatform.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabasePlatform.java
index fe4933e..891d1db 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabasePlatform.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabasePlatform.java
@@ -18,11 +18,12 @@
 import java.util.List;
 import java.util.TreeSet;
 import java.util.Vector;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
 import org.eclipse.persistence.tools.utility.XMLTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterable.LiveCloneIterable;
+import org.eclipse.persistence.tools.utility.iterator.CloneIterator;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 import org.eclipse.persistence.tools.utility.node.AbstractNode;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
@@ -143,8 +144,8 @@
 	 * build an empty mapping for every JDBC type in the JDBC type repository
 	 */
 	private void initializeJDBCTypeToDatabaseTypeMappings() {
-		for (Iterator<JDBCType> stream = this.jdbcTypeRepository().jdbcTypes(); stream.hasNext(); ) {
-			this.jdbcTypeToDatabaseTypeMappings.add(new JDBCTypeToDatabaseTypeMapping(this, stream.next()));
+		for (JDBCType jdbcType : this.jdbcTypeRepository().jdbcTypes()) {
+			this.jdbcTypeToDatabaseTypeMappings.add(new JDBCTypeToDatabaseTypeMapping(this, jdbcType));
 		}
 	}
 
@@ -248,8 +249,8 @@
 
 
 	// ***** database types
-	public Iterator<DatabaseType> databaseTypes() {
-		return new CloneIterator<DatabaseType>(this.databaseTypes) {
+	public Iterable<DatabaseType> databaseTypes() {
+		return new LiveCloneIterable<DatabaseType>(this.databaseTypes) {
 			@Override
 			protected void remove(DatabaseType current) {
 				DatabasePlatform.this.removeDatabaseType(current);
@@ -332,8 +333,8 @@
 	 * adding and removing mappings is PRIVATE;
 	 * these are done only in response to changes to the JDBC type repository
 	 */
-	private Iterator<JDBCTypeToDatabaseTypeMapping> internalJDBCTypeToDatabaseTypeMappings() {
-		return new CloneIterator<JDBCTypeToDatabaseTypeMapping>(this.jdbcTypeToDatabaseTypeMappings) {
+	private Iterable<JDBCTypeToDatabaseTypeMapping> internalJDBCTypeToDatabaseTypeMappings() {
+		return new LiveCloneIterable<JDBCTypeToDatabaseTypeMapping>(this.jdbcTypeToDatabaseTypeMappings) {
 			@Override
 			protected void remove(JDBCTypeToDatabaseTypeMapping current) {
 				DatabasePlatform.this.removeJDBCTypeToDatabaseTypeMapping(current);
@@ -412,7 +413,7 @@
 	}
 
 	private Iterator<String> databaseTypeNames() {
-		return new TransformationIterator<String, DatabaseType>(this.databaseTypes()) {
+		return new TransformationIterator<DatabaseType, String>(this.databaseTypes()) {
 			@Override
 			protected String transform(DatabaseType next) {
 				return next.getName();
@@ -506,7 +507,7 @@
 	@Override
 	public void nodeRemoved(org.eclipse.persistence.tools.utility.node.Node node) {
 		super.nodeRemoved(node);
-		for (Iterator<JDBCTypeToDatabaseTypeMapping> stream = this.internalJDBCTypeToDatabaseTypeMappings(); stream.hasNext(); ) {
+		for (Iterator<JDBCTypeToDatabaseTypeMapping> stream = this.internalJDBCTypeToDatabaseTypeMappings().iterator(); stream.hasNext(); ) {
 			if (stream.next().getJDBCType() == node) {
 				stream.remove();
 				break;	// there should be only one...
@@ -528,7 +529,7 @@
 		this.supportsNativeSequencing = originalPlatform.supportsNativeSequencing();
 		this.supportsNativeReturning = originalPlatform.supportsNativeReturning();
 		this.supportsIdentityClause = originalPlatform.supportsIdentityClause();
-		for (Iterator<DatabaseType> stream = originalPlatform.databaseTypes(); stream.hasNext(); ) {
+		for (Iterator<DatabaseType> stream = originalPlatform.databaseTypes().iterator(); stream.hasNext(); ) {
 			DatabaseType originalType = stream.next();
 			DatabaseType cloneType = this.addDatabaseType(originalType.getName());
 			cloneType.cloneFrom(originalType);
@@ -555,7 +556,7 @@
 		if ((databaseTypeName == null) || (databaseTypeName.length() == 0)) {
 			throw new IllegalArgumentException("database type name is required");
 		}
-		if (CollectionTools.contains(this.databaseTypeNames(), databaseTypeName)) {
+		if (IteratorTools.contains(this.databaseTypeNames(), databaseTypeName)) {
 			throw new IllegalArgumentException("duplicate database type name: " + databaseTypeName);
 		}
 	}
@@ -567,39 +568,37 @@
 	private void read(File file) throws CorruptXMLException {
 		this.shortFileName = file.getName();
 		Document doc = XMLTools.parse(file);
-		Node root = XMLTools.child(doc, "database-platform");
+		Node root = XMLTools.getChild(doc, "database-platform");
 		if (root == null) {
 			throw new CorruptXMLException("missing root node: database-platform (" + file.getPath() + ")");
 		}
 
-		this.name = XMLTools.childTextContent(root, "name", null);
+		this.name = XMLTools.getChildTextContent(root, "name", null);
 		if ((this.name == null) || (this.name.length() == 0)) {
 			throw new CorruptXMLException("name is required (" + file.getPath() + ")");
 		}
 
-		this.runtimePlatformClassName = XMLTools.childTextContent(root, "runtime-platform-class", null);
+		this.runtimePlatformClassName = XMLTools.getChildTextContent(root, "runtime-platform-class", null);
 		if ((this.runtimePlatformClassName == null) || (this.runtimePlatformClassName.length() == 0)) {
 			throw this.buildCorruptXMLException("run-time platform class name is required");
 		}
 
-		this.supportsNativeSequencing = XMLTools.childBooleanContent(root, "supports-native-sequencing", false);
-		this.supportsNativeReturning = XMLTools.childBooleanContent(root, "supports-native-returning", false);
-		this.supportsIdentityClause = XMLTools.childBooleanContent(root, "supports-identity-clause", false);
+		this.supportsNativeSequencing = XMLTools.getChildBooleanContent(root, "supports-native-sequencing", false);
+		this.supportsNativeReturning = XMLTools.getChildBooleanContent(root, "supports-native-returning", false);
+		this.supportsIdentityClause = XMLTools.getChildBooleanContent(root, "supports-identity-clause", false);
 		if (this.supportsIdentityClause && ( ! this.supportsNativeSequencing)) {
 			throw this.buildCorruptXMLException("platform must support native sequencing if it supports the IDENTITY clause");
 		}
 
-		this.readDatabaseTypeNodes(XMLTools.child(root, "database-types"));
+		this.readDatabaseTypeNodes(XMLTools.getChild(root, "database-types"));
 
 		// wait until the database types have been read in before building the JDBC mappings
-		this.readJDBCMappingNodes(XMLTools.child(root, "jdbc-mappings"));
+		this.readJDBCMappingNodes(XMLTools.getChild(root, "jdbc-mappings"));
 	}
 
 	private void readDatabaseTypeNodes(Node databaseTypesNode) throws CorruptXMLException {
-		Node[] databaseTypeNodes = XMLTools.children(databaseTypesNode, "database-type");
-		int len = databaseTypeNodes.length;
-		for (int i = 0; i < len; i++) {
-			DatabaseType databaseType = new DatabaseType(this, databaseTypeNodes[i]);
+		for (Node databaseTypeNode : XMLTools.getChildren(databaseTypesNode, "database-type")) {
+			DatabaseType databaseType = new DatabaseType(this, databaseTypeNode);
 			try {
 				this.checkDatabaseType(databaseType);	// check for duplicates
 			} catch (IllegalArgumentException ex) {
@@ -610,10 +609,8 @@
 	}
 
 	private void readJDBCMappingNodes(Node mappingsNode) throws CorruptXMLException {
-		Node[] mappingNodes = XMLTools.children(mappingsNode, "jdbc-mapping");
-		int len = mappingNodes.length;
-		for (int i = 0; i < len; i++) {
-			JDBCTypeToDatabaseTypeMapping mapping = new JDBCTypeToDatabaseTypeMapping(this, mappingNodes[i]);
+		for (Node mappingNode : XMLTools.getChildren(mappingsNode, "jdbc-mapping")) {
+			JDBCTypeToDatabaseTypeMapping mapping = new JDBCTypeToDatabaseTypeMapping(this, mappingNode);
 			// check for duplicates
 			if (this.maps(mapping.getJDBCType())) {
 				throw this.buildCorruptXMLException("duplicate JDBC to database type mapping: " + mapping);
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabasePlatformRepository.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabasePlatformRepository.java
index c18d5a1..884fc18 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabasePlatformRepository.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabasePlatformRepository.java
@@ -20,13 +20,13 @@
 import java.util.List;
 import java.util.Set;
 import java.util.Vector;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.FileTools;
-import org.eclipse.persistence.tools.utility.HashBag;
 import org.eclipse.persistence.tools.utility.XMLTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.io.FileTools;
+import org.eclipse.persistence.tools.utility.iterable.LiveCloneIterable;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 import org.eclipse.persistence.tools.utility.node.AbstractNode;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
@@ -212,8 +212,8 @@
 	}
 
 
-	public Iterator<DatabasePlatform> platforms() {
-		return new CloneIterator<DatabasePlatform>(this.platforms) {
+	public Iterable<DatabasePlatform> platforms() {
+		return new LiveCloneIterable<DatabasePlatform>(this.platforms) {
 			@Override
 			protected void remove(DatabasePlatform current) {
 				DatabasePlatformRepository.this.removePlatform(current);
@@ -323,7 +323,7 @@
 	}
 
 	private Iterator<String> platformNames() {
-		return new TransformationIterator<String, DatabasePlatform>(this.platforms()) {
+		return new TransformationIterator<DatabasePlatform, String>(this.platforms()) {
 			@Override
 			protected String transform(DatabasePlatform next) {
 				return next.getName();
@@ -332,7 +332,7 @@
 	}
 
 	private Iterator<String> platformShortFileNames() {
-		return new TransformationIterator<String, DatabasePlatform>(this.platforms()) {
+		return new TransformationIterator<DatabasePlatform, String>(this.platforms()) {
 			@Override
 			protected String transform(DatabasePlatform next) {
 				return next.getShortFileName();
@@ -447,7 +447,7 @@
 		if ((platformName == null) || (platformName.length() == 0)) {
 			throw new IllegalArgumentException("platform name is required");
 		}
-		if (CollectionTools.contains(this.platformNames(), platformName)) {
+		if (IteratorTools.contains(this.platformNames(), platformName)) {
 			throw new IllegalArgumentException("duplicate platform name: " + platformName);
 		}
 	}
@@ -465,7 +465,7 @@
 		if (FileTools.fileNameIsInvalid(platformShortFileName)) {
 			throw new IllegalArgumentException("invalid file name: " + platformShortFileName);
 		}
-		if (CollectionTools.contains(this.lowerCasePlatformShortFileNames(), platformShortFileName.toLowerCase())) {
+		if (IteratorTools.contains(this.lowerCasePlatformShortFileNames(), platformShortFileName.toLowerCase())) {
 			throw new IllegalArgumentException("duplicate file name: " + platformShortFileName);
 		}
 	}
@@ -476,22 +476,22 @@
 	// ***** read
 	private void read() throws CorruptXMLException {
 		Document document = XMLTools.parse(this.file);
-		Node root = XMLTools.child(document, "platforms");
+		Node root = XMLTools.getChild(document, "platforms");
 		if (root == null) {
 			throw this.buildCorruptXMLException("missing root node: platforms");
 		}
 
-		this.name = XMLTools.childTextContent(root, "name", null);
+		this.name = XMLTools.getChildTextContent(root, "name", null);
 		if ((this.name == null) || (this.name.length() == 0)) {
 			throw this.buildCorruptXMLException("name is required");
 		}
 
 		// read up the JDBC repository first, since the JDBC types are referenced elsewhere
-		this.jdbcTypeRepository = new JDBCTypeRepository(this, XMLTools.child(root, "jdbc-type-repository"));
+		this.jdbcTypeRepository = new JDBCTypeRepository(this, XMLTools.getChild(root, "jdbc-type-repository"));
 
 		this.readPlatforms();
 
-		String defaultPlatformName = XMLTools.childTextContent(root, "default-platform", null);
+		String defaultPlatformName = XMLTools.getChildTextContent(root, "default-platform", null);
 		if ((defaultPlatformName == null) || (defaultPlatformName.length() == 0)) {
 			if (this.platforms.size() == 0) {
 				// no problem
@@ -647,7 +647,7 @@
 	}
 
 	public void toString(StringBuffer sb) {
-		for (Iterator<DatabasePlatform> stream = this.platforms(); stream.hasNext(); ) {
+		for (Iterator<DatabasePlatform> stream = this.platforms().iterator(); stream.hasNext(); ) {
 			DatabasePlatform platform = stream.next();
 			platform.toString(sb);
 			if (stream.hasNext()) {
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabaseType.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabaseType.java
index 3e1eb17..17b6ca0 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabaseType.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabaseType.java
@@ -12,8 +12,6 @@
 ******************************************************************************/
 package org.eclipse.persistence.tools.db.relational.platformsmodel;
 
-import java.util.Iterator;
-
 import org.eclipse.persistence.tools.utility.XMLTools;
 import org.eclipse.persistence.tools.utility.node.AbstractNode;
 import org.w3c.dom.Node;
@@ -255,7 +253,7 @@
 	 * Returns all the JDBC types that the database type
 	 * could be mapped to. Simplifies UI code....
 	 */
-	public Iterator<JDBCType> jdbcTypes() {
+	public Iterable<JDBCType> jdbcTypes() {
 		return this.jdbcTypeRepository().jdbcTypes();
 	}
 
@@ -291,21 +289,21 @@
 		if (node == null) {
 			throw this.buildCorruptXMLException("missing node");
 		}
-		this.name = XMLTools.childTextContent(node, "name", null);
+		this.name = XMLTools.getChildTextContent(node, "name", null);
 		if ((this.name == null) || (this.name.length() == 0)) {
 			throw this.buildCorruptXMLException("name is required");
 		}
 
-		String jdbcTypeName = XMLTools.childTextContent(node, "jdbc-type", null);
+		String jdbcTypeName = XMLTools.getChildTextContent(node, "jdbc-type", null);
 		try {
 			this.jdbcType = this.jdbcTypeNamed(jdbcTypeName);
 		} catch (IllegalArgumentException ex) {
 			throw this.buildCorruptXMLException(ex);
 		}
 
-		this.allowsSize = XMLTools.childBooleanContent(node, "allows-size", false);
+		this.allowsSize = XMLTools.getChildBooleanContent(node, "allows-size", false);
 
-		this.requiresSize = XMLTools.childBooleanContent(node, "requires-size", false);
+		this.requiresSize = XMLTools.getChildBooleanContent(node, "requires-size", false);
 		if (( ! this.allowsSize) && this.requiresSize) {
 			throw this.buildCorruptXMLException("size cannot be required when it is not allowed");
 		}
@@ -315,12 +313,12 @@
 			throw this.buildCorruptXMLException("initial size cannot be specified when size is not required");
 		}
 
-		this.allowsSubSize = XMLTools.childBooleanContent(node, "allows-sub-size", false);
+		this.allowsSubSize = XMLTools.getChildBooleanContent(node, "allows-sub-size", false);
 		if (( ! this.allowsSize) && this.allowsSubSize) {
 			throw this.buildCorruptXMLException("sub-size cannot be allowed when size is not allowed");
 		}
 
-		this.allowsNull = XMLTools.childBooleanContent(node, "allows-null", false);
+		this.allowsNull = XMLTools.getChildBooleanContent(node, "allows-null", false);
 	}
 
 	/**
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCType.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCType.java
index 94350b8..a65ba02 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCType.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCType.java
@@ -111,7 +111,7 @@
 		if (node == null) {
 			throw new CorruptXMLException("missing node");
 		}
-		this.name = XMLTools.childTextContent(node, "name", null);
+		this.name = XMLTools.getChildTextContent(node, "name", null);
 		if ((this.name == null) || (this.name.length() == 0)) {
 			throw new CorruptXMLException("name is required");
 		}
@@ -142,5 +142,4 @@
 	public void toString(StringBuffer sb) {
 		sb.append(this.name);
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeRepository.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeRepository.java
index bdc2c36..d6f44f4 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeRepository.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeRepository.java
@@ -14,17 +14,18 @@
 
 import java.lang.reflect.Field;
 import java.sql.Types;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.TreeSet;
 import java.util.Vector;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
 import org.eclipse.persistence.tools.utility.StringTools;
 import org.eclipse.persistence.tools.utility.XMLTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterable.LiveCloneIterable;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 import org.eclipse.persistence.tools.utility.node.AbstractNode;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
@@ -163,7 +164,7 @@
 			} catch (IllegalAccessException ex) {
 				throw new RuntimeException(ex);	// shouldn't happen...
 			}
-			if ( ! CollectionTools.contains(CollectionTools.list(DEFAULT_UNUSED_JDBC_TYPE_CODES), code)) {
+			if (Arrays.binarySearch(DEFAULT_UNUSED_JDBC_TYPE_CODES, code) < 0) {
 				this.checkJDBCType(name, code);	// check for duplicates
 				this.jdbcTypes.add(new JDBCType(this, name, code));
 			}
@@ -306,8 +307,8 @@
 	}
 
 
-	public Iterator<JDBCType> jdbcTypes() {
-		return new CloneIterator<JDBCType>(this.jdbcTypes) {
+	public Iterable<JDBCType> jdbcTypes() {
+		return new LiveCloneIterable<JDBCType>(this.jdbcTypes) {
 			@Override
 			protected void remove(JDBCType current) {
 				JDBCTypeRepository.this.removeJDBCType(current);
@@ -346,13 +347,13 @@
 	}
 
 	private void jdbcTypeRemoved(JDBCType removedJDBCType) {
-		for (Iterator<JDBCTypeToJavaTypeDeclarationMapping> stream = this.jdbcTypeToJavaTypeDeclarationMappings(); stream.hasNext(); ) {
+		for (Iterator<JDBCTypeToJavaTypeDeclarationMapping> stream = this.jdbcTypeToJavaTypeDeclarationMappings().iterator(); stream.hasNext(); ) {
 			if (stream.next().getJDBCType() == removedJDBCType) {
 				stream.remove();
 				break;	// there should be only one...
 			}
 		}
-		for (Iterator<JavaTypeDeclarationToJDBCTypeMapping> stream = this.javaTypeDeclarationToJDBCTypeMappings(); stream.hasNext(); ) {
+		for (Iterator<JavaTypeDeclarationToJDBCTypeMapping> stream = this.javaTypeDeclarationToJDBCTypeMappings().iterator(); stream.hasNext(); ) {
 			JavaTypeDeclarationToJDBCTypeMapping mapping = stream.next();
 			if (mapping.getJDBCType() == removedJDBCType) {
 				mapping.setJDBCType(this.defaultJDBCType);		// hmmm...
@@ -402,8 +403,8 @@
 
 
 	// JDBC => Java mappings
-	public Iterator<JDBCTypeToJavaTypeDeclarationMapping> jdbcTypeToJavaTypeDeclarationMappings() {
-		return new CloneIterator<JDBCTypeToJavaTypeDeclarationMapping>(this.jdbcTypeToJavaTypeDeclarationMappings) {
+	public Iterable<JDBCTypeToJavaTypeDeclarationMapping> jdbcTypeToJavaTypeDeclarationMappings() {
+		return new LiveCloneIterable<JDBCTypeToJavaTypeDeclarationMapping>(this.jdbcTypeToJavaTypeDeclarationMappings) {
 			@Override
 			protected void remove(JDBCTypeToJavaTypeDeclarationMapping current) {
 				JDBCTypeRepository.this.removeJDBCTypeToJavaTypeDeclarationMapping(current);
@@ -439,8 +440,8 @@
 
 
 	// Java => JDBC mappings
-	public Iterator<JavaTypeDeclarationToJDBCTypeMapping> javaTypeDeclarationToJDBCTypeMappings() {
-		return new CloneIterator<JavaTypeDeclarationToJDBCTypeMapping>(this.javaTypeDeclarationToJDBCTypeMappings) {
+	public Iterable<JavaTypeDeclarationToJDBCTypeMapping> javaTypeDeclarationToJDBCTypeMappings() {
+		return new LiveCloneIterable<JavaTypeDeclarationToJDBCTypeMapping>(this.javaTypeDeclarationToJDBCTypeMappings) {
 			@Override
 			protected void remove(JavaTypeDeclarationToJDBCTypeMapping current) {
 				JDBCTypeRepository.this.removeJavaTypeDeclarationToJDBCTypeMapping(current);
@@ -582,7 +583,7 @@
 	}
 
 	private Iterator<String> jdbcTypeNames() {
-		return new TransformationIterator<String, JDBCType>(this.jdbcTypes()) {
+		return new TransformationIterator<JDBCType, String>(this.jdbcTypes()) {
 			@Override
 			protected String transform(JDBCType next) {
 				return next.getName();
@@ -626,7 +627,7 @@
 		if (jdbcTypeName == null) {
 			throw new NullPointerException();
 		}
-		if (CollectionTools.contains(this.jdbcTypeNames(), jdbcTypeName)) {
+		if (IteratorTools.contains(this.jdbcTypeNames(), jdbcTypeName)) {
 			throw new IllegalArgumentException("duplicate JDBC type name: " + jdbcTypeName);
 		}
 	}
@@ -677,32 +678,30 @@
 			throw new CorruptXMLException("missing node");
 		}
 
-		this.readJDBCTypeNodes(XMLTools.child(node, "jdbc-types"));
+		this.readJDBCTypeNodes(XMLTools.getChild(node, "jdbc-types"));
 		if (this.jdbcTypes.isEmpty()) {
 			throw new CorruptXMLException("the JDBC type repository is empty");
 		}
 
-		String defaultJDBCTypeName = XMLTools.childTextContent(node, "default-jdbc-type", null);
+		String defaultJDBCTypeName = XMLTools.getChildTextContent(node, "default-jdbc-type", null);
 		try {
 			this.defaultJDBCType = this.jdbcTypeNamed(defaultJDBCTypeName);
 		} catch (IllegalArgumentException ex) {
 			throw new CorruptXMLException("default JDBC type", ex);
 		}
 
-		this.readJDBCToJavaMappingNodes(XMLTools.child(node, "jdbc-type-to-java-type-declaration-mappings"));
+		this.readJDBCToJavaMappingNodes(XMLTools.getChild(node, "jdbc-type-to-java-type-declaration-mappings"));
 		// make sure we have mapped ALL the JDBC types (there are no duplicates at this point)
 		if (this.jdbcTypeToJavaTypeDeclarationMappings.size() != this.jdbcTypes.size()) {
 			throw new CorruptXMLException("all the JDBC types must be mapped to Java type declarations");
 		}
 
-		this.readJavaToJDBCMappingNodes(XMLTools.child(node, "java-type-declaration-to-jdbc-type-mappings"));
+		this.readJavaToJDBCMappingNodes(XMLTools.getChild(node, "java-type-declaration-to-jdbc-type-mappings"));
 	}
 
 	private void readJDBCTypeNodes(Node jdbcTypesNode) throws CorruptXMLException {
-		Node[] jdbcTypeNodes = XMLTools.children(jdbcTypesNode, "jdbc-type");
-		int len = jdbcTypeNodes.length;
-		for (int i = 0; i < len; i++) {
-			JDBCType jdbcType = new JDBCType(this, jdbcTypeNodes[i]);
+		for (Node jdbcTypeNode : XMLTools.getChildren(jdbcTypesNode, "jdbc-type")) {
+			JDBCType jdbcType = new JDBCType(this, jdbcTypeNode);
 			try {
 				this.checkJDBCType(jdbcType);	// check for duplicates
 			} catch (IllegalArgumentException ex) {
@@ -713,10 +712,8 @@
 	}
 
 	private void readJDBCToJavaMappingNodes(Node mappingsNode) throws CorruptXMLException {
-		Node[] mappingNodes = XMLTools.children(mappingsNode, "jdbc-type-to-java-type-declaration-mapping");
-		int len = mappingNodes.length;
-		for (int i = 0; i < len; i++) {
-			JDBCTypeToJavaTypeDeclarationMapping mapping = new JDBCTypeToJavaTypeDeclarationMapping(this, mappingNodes[i]);
+		for (Node mappingNode : XMLTools.getChildren(mappingsNode, "jdbc-type-to-java-type-declaration-mapping")) {
+			JDBCTypeToJavaTypeDeclarationMapping mapping = new JDBCTypeToJavaTypeDeclarationMapping(this, mappingNode);
 			try {
 				this.checkJDBCToJavaMapping(mapping.getJDBCType());	// check for duplicates
 			} catch (IllegalArgumentException ex) {
@@ -727,10 +724,8 @@
 	}
 
 	private void readJavaToJDBCMappingNodes(Node mappingsNode) throws CorruptXMLException {
-		Node[] mappingNodes = XMLTools.children(mappingsNode, "java-type-declaration-to-jdbc-type-mapping");
-		int len = mappingNodes.length;
-		for (int i = 0; i < len; i++) {
-			JavaTypeDeclarationToJDBCTypeMapping mapping = new JavaTypeDeclarationToJDBCTypeMapping(this, mappingNodes[i]);
+		for (Node mappingNode : XMLTools.getChildren(mappingsNode, "java-type-declaration-to-jdbc-type-mapping")) {
+			JavaTypeDeclarationToJDBCTypeMapping mapping = new JavaTypeDeclarationToJDBCTypeMapping(this, mappingNode);
 			try {
 				this.checkJavaToJDBCMapping(mapping.getJavaTypeDeclaration());	// check for duplicates
 			} catch (IllegalArgumentException ex) {
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeToDatabaseTypeMapping.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeToDatabaseTypeMapping.java
index 42f48e5..5ab108a 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeToDatabaseTypeMapping.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeToDatabaseTypeMapping.java
@@ -115,11 +115,11 @@
 
 	private void read(Node node) throws CorruptXMLException {
 		try {
-			this.jdbcType = this.jdbcTypeNamed(XMLTools.childTextContent(node, "jdbc-type", null));
+			this.jdbcType = this.jdbcTypeNamed(XMLTools.getChildTextContent(node, "jdbc-type", null));
 		} catch (IllegalArgumentException ex) {
 			throw new CorruptXMLException("platform: " + this.getPlatform().getName(), ex);
 		}
-		String databaseTypeName = XMLTools.childTextContent(node, "database-type", null);
+		String databaseTypeName = XMLTools.getChildTextContent(node, "database-type", null);
 		if (databaseTypeName != null) {
 			try {
 				this.databaseType = this.databaseTypeNamed(databaseTypeName);
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JavaTypeDeclaration.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JavaTypeDeclaration.java
index 01cb2d8..1ee9ef6 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JavaTypeDeclaration.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JavaTypeDeclaration.java
@@ -130,7 +130,7 @@
 		if (node == null) {
 			throw new CorruptXMLException("missing node");
 		}
-		this.javaClassName = XMLTools.childTextContent(node, "java-class-name", null);
+		this.javaClassName = XMLTools.getChildTextContent(node, "java-class-name", null);
 		this.arrayDepth = XMLTools.childIntContent(node, "array-depth", 0);
 		try {
 			this.checkState();
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalColumn.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalColumn.java
index 4b4fb4a..c47e477 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalColumn.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalColumn.java
@@ -15,9 +15,8 @@
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Types;
-
 import org.eclipse.persistence.tools.db.relational.spi.ExternalColumn;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  * @see comment about defensive programming at JDBCExternalDatabase
@@ -200,7 +199,7 @@
 	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.name);
+		return ObjectTools.toString(this, this.name);
 	}
 
 
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalDatabase.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalDatabase.java
index 0773b47..bfc9245 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalDatabase.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalDatabase.java
@@ -17,12 +17,11 @@
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.List;
-
 import org.eclipse.persistence.tools.db.relational.spi.ExternalDatabase;
 import org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription;
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.ResultSetIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.ResultSetIterator;
 
 /**
  * This external database derives all of its metadata from a client-supplied JDBC connection.
@@ -124,7 +123,7 @@
 			// if #getTables() does not work, there's not much we can do...
 			throw new RuntimeException(ex);
 		}
-		List<ExternalTableDescription> tableDescriptions = CollectionTools.list(new ResultSetIterator<ExternalTableDescription>(
+		List<ExternalTableDescription> tableDescriptions = ListTools.list(new ResultSetIterator<ExternalTableDescription>(
 			resultSet,
 			new ExternalTableDescriptionResultSetAdapter())
 		);
@@ -164,7 +163,7 @@
 	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this);
+		return ObjectTools.toString(this);
 	}
 
 
@@ -174,7 +173,7 @@
 	 * convert the specified single-column result set to an array of strings
 	 */
 	private String[] buildStringArray(ResultSet resultSet) {
-		List<String> strings = CollectionTools.list(new ResultSetIterator<String>(resultSet, new StringResultSetAdapter()));
+		List<String> strings = ListTools.list(new ResultSetIterator<String>(resultSet, new StringResultSetAdapter()));
 		return strings.toArray(new String[strings.size()]);
 	}
 
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalDatabaseFactory.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalDatabaseFactory.java
index dc560f1..024b7f8 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalDatabaseFactory.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalDatabaseFactory.java
@@ -13,10 +13,9 @@
 package org.eclipse.persistence.tools.db.relational.spi.jdbc;
 
 import java.sql.Connection;
-
 import org.eclipse.persistence.tools.db.relational.spi.ExternalDatabase;
 import org.eclipse.persistence.tools.db.relational.spi.ExternalDatabaseFactory;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  * Not much to say here: This is a factory for generating instances of
@@ -61,6 +60,6 @@
 	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, "singleton");
+		return ObjectTools.toString(this, "singleton");
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalForeignKey.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalForeignKey.java
index 67c73d7..0114a2f 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalForeignKey.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalForeignKey.java
@@ -14,11 +14,10 @@
 
 import java.sql.ResultSet;
 import java.sql.SQLException;
-
 import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKey;
 import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKeyColumnPair;
 import org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  *
@@ -127,6 +126,6 @@
 	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.name);
+		return ObjectTools.toString(this, this.name);
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalForeignKeyColumnPair.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalForeignKeyColumnPair.java
index 11ea660..e4a3332 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalForeignKeyColumnPair.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalForeignKeyColumnPair.java
@@ -14,10 +14,9 @@
 
 import java.sql.ResultSet;
 import java.sql.SQLException;
-
 import org.eclipse.persistence.tools.db.relational.spi.ExternalColumn;
 import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKeyColumnPair;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  * Associate a pair of columns from a foreign key that is made
@@ -111,7 +110,7 @@
 	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.sourceColumnName() + "=>" + this.targetColumnName());
+		return ObjectTools.toString(this, this.sourceColumnName() + "=>" + this.targetColumnName());
 	}
 
 
@@ -160,7 +159,7 @@
 		}
 		@Override
 		public String toString() {
-			return StringTools.buildToStringFor(this, this.name);
+			return ObjectTools.toString(this, this.name);
 		}
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalTable.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalTable.java
index 9dd734b..2f9c667 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalTable.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalTable.java
@@ -19,11 +19,10 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
-
 import org.eclipse.persistence.tools.db.relational.spi.ExternalColumn;
 import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKey;
 import org.eclipse.persistence.tools.db.relational.spi.ExternalTable;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  * see comment about defensive programming at JDBCExternalDatabase
@@ -203,6 +202,6 @@
 	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.tableDescription.getQualifiedName());
+		return ObjectTools.toString(this, this.tableDescription.getQualifiedName());
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalTableDescription.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalTableDescription.java
index 51831d3..211df3d 100644
--- a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalTableDescription.java
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalTableDescription.java
@@ -15,11 +15,10 @@
 import java.sql.DatabaseMetaData;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-
 import org.eclipse.persistence.tools.db.relational.spi.ExternalTable;
 import org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription;
 import org.eclipse.persistence.tools.utility.NameTools;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  * @version 2.5
@@ -73,7 +72,7 @@
 	}
 
 	private String buildQualifiedName() {
-		return NameTools.buildQualifiedDatabaseObjectName(this.catalogName, this.schemaName, this.name);
+		return NameTools.buildQualifiedName(this.catalogName, this.schemaName, this.name);
 	}
 
 
@@ -158,6 +157,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.qualifiedName);
+		return ObjectTools.toString(this, this.qualifiedName);
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.gen.db/resource/property_files/jpt_gen.properties b/tools/org.eclipse.persistence.tools.gen.db/resource/property_files/jpt_gen.properties
deleted file mode 100644
index db907a2..0000000
--- a/tools/org.eclipse.persistence.tools.gen.db/resource/property_files/jpt_gen.properties
+++ /dev/null
@@ -1,20 +0,0 @@
-################################################################################
-# Copyright (c) 2008, 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
-################################################################################
-
-PackageGenerator_taskName=Generate Entities
-GenScope_taskName=Build Database Model
-EntityGenerator_taskName=Generate Entity: {0}
-Error_Generating_Entities = Error Generating Entities
-
-Delete_Folder_Error = "The directory {0} could not be deleted."
-Delete_File_Error = "The file {0} could not be deleted."
-File_Read_Only_Error= "The file {0} could not be modified because write access is denied.\nPlease make sure that the file is not marked as readonly in the file system."
-
-Templates_notFound = Unable to find JPA entities generation templates in plugin
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/header.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/header.vm
index aed7d68..08d5702 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/header.vm
+++ b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/header.vm
@@ -1,4 +1,4 @@
 #### Top-level ####
 <?xml version="1.0" encoding="UTF-8"?>
-<entity-mappings version="2.4" xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_2_4.xsd">
+<entity-mappings version="${customizer.platformVersion}" xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_${customizer.platformVersionWithUnderscore}.xsd">
 ##  <package></package>
diff --git a/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/main.xml.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/main.xml.vm
index 7492930..35a950e 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/main.xml.vm
+++ b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/main.xml.vm
@@ -1,7 +1,6 @@
 #### Entity ####
 	<entity class="${table.qualifiedClassName}" access="VIRTUAL">
-		<table name=$customizer.convertToXmlStringLiteral(${table.name})/>
-#end
+	<table name=$customizer.convertToXmlStringLiteral(${table.name})/>
 #### Mappings ####
 		<attributes>
 ##Check for embedded-id
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/RelationalEntityGenerator.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/RelationalEntityGenerator.java
index b2e8604..d0ab117 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/RelationalEntityGenerator.java
+++ b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/RelationalEntityGenerator.java
@@ -25,9 +25,9 @@
 import org.eclipse.persistence.tools.gen.internal.GenericEntityGeneratorDatabaseAnnotationNameBuilder;
 import org.eclipse.persistence.tools.gen.internal.MappingFileGenerator;
 import org.eclipse.persistence.tools.gen.internal.ORMGenCustomizer;
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.iterables.TransformationIterable;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterable.TransformationIterable;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 
 /**
  * This class is an entry point for dynamic entity generation. It provides API for discovering
@@ -115,7 +115,7 @@
 	 * @return {@link List} of the schema names associated with the database.
 	 */
 	public List<String> getSchemaNames(){
-		return CollectionTools.list(new TransformationIterator<String, Schema>(database.getSchemata()) {
+		return ListTools.list(new TransformationIterator<Schema, String>(database.getSchemata()) {
 			@Override
 			protected String transform(Schema next) {
 				return next.getName();
@@ -137,7 +137,7 @@
 	 * Creates a {@link List} of table names based on the provided {@link Table}s.
 	 */
 	private List<String> transformToTableNames(Iterable<Table> tables) {
-		return CollectionTools.list(new TransformationIterable<String, Table>(tables) {
+		return ListTools.list(new TransformationIterable<Table, String>(tables) {
 			@Override
 			protected String transform(Table table) {
 				return table.getName();
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionAdapter.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionAdapter.java
index b575100..c7ea5c6 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionAdapter.java
+++ b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionAdapter.java
@@ -13,7 +13,7 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.gen.db;
 
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  * An empty implementation of {@link ConnectionListener}.
@@ -128,6 +128,6 @@
 	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this);
+		return ObjectTools.toString(this);
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionProfile.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionProfile.java
index c23586d..82aecc0 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionProfile.java
+++ b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionProfile.java
@@ -14,7 +14,6 @@
 package org.eclipse.persistence.tools.gen.db;
 
 import java.sql.Connection;
-
 import org.eclipse.persistence.tools.utility.status.IStatus;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/DatabaseIdentifierAdapter.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/DatabaseIdentifierAdapter.java
index e364d28..022ef6f 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/DatabaseIdentifierAdapter.java
+++ b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/DatabaseIdentifierAdapter.java
@@ -13,7 +13,7 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.gen.db;
 
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  * This interface allows clients of the Dali db package to control whether
@@ -53,7 +53,7 @@
 		}
 		@Override
 		public String toString() {
-			return StringTools.buildToStringFor(this);
+			return ObjectTools.toString(this);
 		}
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/DatabaseObject.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/DatabaseObject.java
index 2a9edfb..8e5e74b 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/DatabaseObject.java
+++ b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/DatabaseObject.java
@@ -15,8 +15,7 @@
 
 import java.text.Collator;
 import java.util.Comparator;
-
-import org.eclipse.persistence.tools.utility.Transformer;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
 
 /**
  * Behavior common to all database objects.
@@ -86,8 +85,8 @@
 				}
 			};
 
-	Transformer<String, DatabaseObject> NAME_TRANSFORMER =
-			new Transformer<String, DatabaseObject>() {
+	Transformer<DatabaseObject, String> NAME_TRANSFORMER =
+			new Transformer<DatabaseObject, String>() {
 				@Override
 				public String transform(DatabaseObject dbObject) {
 					return dbObject.getName();
@@ -98,8 +97,8 @@
 				}
 			};
 
-	Transformer<String, DatabaseObject> IDENTIFIER_TRANSFORMER =
-			new Transformer<String, DatabaseObject>() {
+	Transformer<DatabaseObject, String> IDENTIFIER_TRANSFORMER =
+			new Transformer<DatabaseObject, String>() {
 				@Override
 				public String transform(DatabaseObject dbObject) {
 					return dbObject.getIdentifier();
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/Association.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/Association.java
index 30c219e..115c863 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/Association.java
+++ b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/Association.java
@@ -369,6 +369,10 @@
 		return this.mForeignKey;
 	}
 	@Override
+	public int hashCode() {
+		return super.hashCode();
+	}
+	@Override
 	public boolean equals(Object obj) {
 		if( this == obj )
 			return true;
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/AssociationRole.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/AssociationRole.java
index f9a3722..8a5670a 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/AssociationRole.java
+++ b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/AssociationRole.java
@@ -15,7 +15,6 @@
 
 import java.util.Iterator;
 import java.util.List;
-
 import org.eclipse.persistence.tools.utility.StringTools;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/DatabaseAnnotationNameBuilder.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/DatabaseAnnotationNameBuilder.java
index c448a09..d44015b 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/DatabaseAnnotationNameBuilder.java
+++ b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/DatabaseAnnotationNameBuilder.java
@@ -16,7 +16,7 @@
 import org.eclipse.persistence.tools.gen.db.Column;
 import org.eclipse.persistence.tools.gen.db.ForeignKey;
 import org.eclipse.persistence.tools.gen.db.Table;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  * Provide a pluggable way to determine whether and how the entity generator prints the names of
@@ -116,7 +116,7 @@
 		}
 		@Override
 		public String toString() {
-			return StringTools.buildSingletonToString(this);
+			return ObjectTools.toString(this);
 		}
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/JptGenMessages.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/JptGenMessages.java
deleted file mode 100644
index a0d31e3..0000000
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/JptGenMessages.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.gen.internal;
-
-/**
- * Localized messages used by Dali entity generation.
- */
-@SuppressWarnings("nls")
-public class JptGenMessages {
-
-	public static String PackageGenerator_taskName;
-	public static String GenScope_taskName;
-	public static String EntityGenerator_taskName;
-	public static String Templates_notFound;
-	public static String Error_Generating_Entities;
-	public static String Delete_Folder_Error;
-	public static String Delete_File_Error;
-	public static String File_Read_Only_Error;
-
-	private static final String BUNDLE_NAME = "jpt_gen";
-	private static final Class<?> BUNDLE_CLASS = JptGenMessages.class;
-
-	private JptGenMessages() {
-		throw new UnsupportedOperationException();
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/MappingFileGenerator.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/MappingFileGenerator.java
index 7d07c84..7a5ac7e 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/MappingFileGenerator.java
+++ b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/MappingFileGenerator.java
@@ -18,7 +18,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Properties;
-
 import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.VelocityEngine;
 
@@ -61,26 +60,27 @@
 		List<String> tableNames = this.customizer.getGenTableNames();
 
 		try {
-		
 			Properties vep = new Properties();
 			vep.setProperty("resource.loader", "class");
 			vep.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+
 			VelocityEngine ve = new VelocityEngine();
-		    ve.init(vep);
+			ve.init(vep);
 
-		    StringBuilder xmlFileContents = new StringBuilder();
+			StringBuilder xmlFileContents = new StringBuilder();
 
-		    // Build mapping file header
-		    xmlFileContents.append(generateXmlHeaderFooter(ve, "header.vm"));
+			// Build mapping file header
+			xmlFileContents.append(generateXmlHeaderFooter(ve, "header.vm"));
 
-		    // Build sample named queries
-		    for (Iterator<String> names = tableNames.iterator(); names.hasNext();) {
-		    	ORMGenTable table = this.customizer.getTable(names.next());
-		    	xmlFileContents.append(generateXmlTypeMetadata(table, ve, "namedQuery.vm"));
-		    }
+			// Build sample named queries
+			for (Iterator<String> names = tableNames.iterator(); names.hasNext();) {
+				ORMGenTable table = this.customizer.getTable(names.next());
+				xmlFileContents.append(generateXmlTypeMetadata(table, ve, "namedQuery.vm"));
+			}
 
-		    // Build entities
-		    List<ORMGenTable> compositeKeyTables = new ArrayList<ORMGenTable>();
+			// Build entities
+			List<ORMGenTable> compositeKeyTables = new ArrayList<ORMGenTable>();
+
 			for (Iterator<String> names = tableNames.iterator(); names.hasNext();) {
 				ORMGenTable table = this.customizer.getTable(names.next());
 				xmlFileContents.append(generateXmlTypeMetadata(table, ve, "main.xml.vm"));
@@ -89,19 +89,18 @@
 				}
 			}
 
-			//Embeddables need to come after entities in the XML
+			// Embeddables need to come after entities in the XML
 			for (ORMGenTable table : compositeKeyTables) {
-			    if (table.isCompositeKey()) {
-			    	xmlFileContents.append(generateXmlTypeMetadata(table, ve, "embeddable.vm"));
-			    }
+				if (table.isCompositeKey()) {
+					xmlFileContents.append(generateXmlTypeMetadata(table, ve, "embeddable.vm"));
+				}
 			}
 
-			//Build mapping file closing tag
+			// Build mapping file closing tag
 			xmlFileContents.append(generateXmlHeaderFooter(ve, "footer.vm"));
-
 			return xmlFileContents.toString();
-
-		} catch (Throwable e) {
+		}
+		catch (Throwable e) {
 			throw new RuntimeException("Entity generation failed", e);
 		}
 	}
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/ORMGenCustomizer.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/ORMGenCustomizer.java
index 7fd9fd3..e60f4df 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/ORMGenCustomizer.java
+++ b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/ORMGenCustomizer.java
@@ -274,11 +274,13 @@
 		} finally {
 			try {
 				if (oos!=null) oos.close();
-				if (fos!=null) fos.close();
-				if (deleteIt) {
-					mFile.delete();
-				}
 			} catch (java.io.IOException ex2) {}
+			try {
+				if (fos!=null) fos.close();
+			} catch (java.io.IOException ex2) {}
+			if (deleteIt) {
+				mFile.delete();
+			}
 		}
 	}
 
@@ -564,7 +566,10 @@
 		return StringTools.convertToJavaStringLiteral(s);
 	}
 	public String convertToXmlStringLiteral(String s) {
-		return StringTools.convertToXmlStringLiteral(s);
+		return StringTools.convertToXmlAttributeValue(s);
+	}
+	public String platformVersion() {
+		return "2.4";
 	}
 	/**
 	 * Appends an annotation member name and value to an existing annotation.
@@ -886,4 +891,4 @@
 	public void setUpdatePersistenceXml(boolean updatePersistenceXml) {
 		this.mUpdatePersistenceXml = updatePersistenceXml;
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/OverwriteConfirmer.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/OverwriteConfirmer.java
index 51002a5..eb641d0 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/OverwriteConfirmer.java
+++ b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/OverwriteConfirmer.java
@@ -13,7 +13,7 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.gen.internal;
 
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  *
@@ -53,7 +53,7 @@
 
 		@Override
 		public String toString() {
-			return StringTools.buildSingletonToString(this);
+			return ObjectTools.toString(this);
 		}
 	}
 
@@ -78,7 +78,7 @@
 
 		@Override
 		public String toString() {
-			return StringTools.buildSingletonToString(this);
+			return ObjectTools.toString(this);
 		}
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/EntityGenTools.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/EntityGenTools.java
index b6b152b..0395adf 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/EntityGenTools.java
+++ b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/EntityGenTools.java
@@ -14,7 +14,6 @@
 package org.eclipse.persistence.tools.gen.internal.util;
 
 import java.util.Collection;
-
 import org.eclipse.persistence.tools.utility.NameTools;
 import org.eclipse.persistence.tools.utility.StringTools;
 
@@ -60,16 +59,16 @@
 	 */
 	public static String convertToUniqueJavaStyleIdentifier(String identifier, boolean capitalizeFirstLetter, Collection<String> identifiers) {
 		String result = identifier;
-		if (StringTools.stringIsUppercase(result) || StringTools.stringIsLowercase(result)) {
+		if (StringTools.isUppercase(result) || StringTools.isLowercase(result)) {
 			// leave mixed case identifiers alone?
-			result = StringTools.convertUnderscoresToCamelCase(result, capitalizeFirstLetter);
+			result = StringTools.convertAllCapsToCamelCase(result, capitalizeFirstLetter);
 		} else {
 			result = capitalizeFirstLetter ? StringTools.capitalize(result) : StringTools.uncapitalize(result);
 		}
 		result = NameTools.convertToJavaIdentifier(result);
 		// assume that converting to a unique name will not result in a Java reserved word
 		// (since no Java reserved words end with a number)
-		result = NameTools.uniqueNameForIgnoreCase(result, identifiers);
+		result = NameTools.uniqueNameIgnoreCase(result, identifiers);
 		return result;
 	}
 
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/StringUtil.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/StringUtil.java
index d298e57..7b8de1e 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/StringUtil.java
+++ b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/StringUtil.java
@@ -20,7 +20,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-
 import org.eclipse.persistence.tools.utility.StringTools;
 
 @SuppressWarnings("nls")
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/UrlUtil.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/UrlUtil.java
index 90c04e9..4ccd98c 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/UrlUtil.java
+++ b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/UrlUtil.java
@@ -64,8 +64,11 @@
 	 * Returns true if the specified url protocol is http.
 	 */
 	public static boolean isHttpUrl(URL url) {
+		if (url == null) {
+			return false;
+		}
 		String protocol = url.getProtocol();
-		return url != null && (HTTP_PROTOCOL.equals(protocol) || HTTPS_PROTOCOL.equals(protocol));
+		return HTTP_PROTOCOL.equals(protocol) || HTTPS_PROTOCOL.equals(protocol);
 	}
 
 	/**
diff --git a/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/MongoEntityGenerator.java b/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/MongoEntityGenerator.java
index 47e752e..d42d9f0 100644
--- a/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/MongoEntityGenerator.java
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/MongoEntityGenerator.java
@@ -1,5 +1,3 @@
-package org.eclipse.persistence.tools.gen.nosql.mongo;
-
 /*******************************************************************************
  * Copyright (c) 2012 Oracle. All rights reserved.
  * This program and the accompanying materials are made available under the
@@ -13,6 +11,17 @@
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
+package org.eclipse.persistence.tools.gen.nosql.mongo;
+
+import com.mongodb.BasicDBList;
+import com.mongodb.BasicDBObject;
+import com.mongodb.DB;
+import com.mongodb.DBCollection;
+import com.mongodb.DBCursor;
+import com.mongodb.DBObject;
+import com.mongodb.Mongo;
+import com.mongodb.MongoException;
+import com.mongodb.ServerAddress;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.StringWriter;
@@ -25,9 +34,8 @@
 import java.util.Properties;
 import java.util.Set;
 import java.util.Vector;
-
+import java.util.regex.Pattern;
 import javax.persistence.AccessType;
-
 import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.VelocityEngine;
 import org.eclipse.persistence.tools.gen.nosql.mongo.meta.CollectionDescriptor;
@@ -45,22 +53,13 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalORMConfiguration;
 import org.eclipse.persistence.tools.mapping.orm.ORMDocumentType;
 import org.eclipse.persistence.tools.mapping.orm.dom.ORMRepository;
-import org.eclipse.persistence.tools.utility.CollectionTools;
 import org.eclipse.persistence.tools.utility.NameTools;
-
-import com.mongodb.BasicDBList;
-import com.mongodb.BasicDBObject;
-import com.mongodb.DB;
-import com.mongodb.DBCollection;
-import com.mongodb.DBCursor;
-import com.mongodb.DBObject;
-import com.mongodb.Mongo;
-import com.mongodb.MongoException;
-import com.mongodb.ServerAddress;
+import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
 
 /**
- * This class is an entry point for dynamic entity xml and source generation for 
- * MongoDB. It also provides API for discovering metadata (table names, etc) and generating 
+ * This class is an entry point for dynamic entity xml and source generation for
+ * MongoDB. It also provides API for discovering metadata (table names, etc) and generating
  * EclipseLink-JPA NoSql, mapping files.
  * <p>
  * Provisional API: This interface is part of an interim API that is still under development and
@@ -71,32 +70,33 @@
  * @author John Bracken
  * @version 2.5
  */
+@SuppressWarnings("nls")
 public class MongoEntityGenerator {
 
 	/** Mongo database connection to use in generation. */
 	private Mongo connection;
-	
+
 	/** Mongo database instance to use in generation. */
 	private DB database;
-	
+
 	/** Number of rows in each collection to sample during generation. */
 	private int rowSampleSize;
-	
+
 	/**
-	 * Constructs a new {@link MongoEntityGenerator} based on the provided 
+	 * Constructs a new {@link MongoEntityGenerator} based on the provided
 	 * db connection information.
-	 * 
+	 *
 	 * @param host the MongoDB network host.
 	 * @param port the port of the Mongo database.
 	 * @param dbName the name of the Mongo database.
-	 * @param rowSampleSize number of rows in each collection to sample to determine the 
+	 * @param rowSampleSize number of rows in each collection to sample to determine the
 	 * 		  table structure.  Since not all rows may have all possible values explicitly
 	 * 		  defined, it's important to use a sufficient sample size.
-	 * 
+	 *
 	 * @throws MongoException
 	 * @throws UnknownHostException
 	 */
-	public MongoEntityGenerator(String host, int port, String dbName, int rowSampleSize) 
+	public MongoEntityGenerator(String host, int port, String dbName, int rowSampleSize)
 														throws MongoException, UnknownHostException {
 		super();
 		this.rowSampleSize = rowSampleSize;
@@ -107,35 +107,35 @@
 	/**
 	 * Builds a list of {@link CollectionDescriptor}s that describe the collection and associated
 	 * column metadata of the Mongo collections named in <code>collectionNames</code>.
-	 *  
+	 *
 	 * @param collectionNames names of the Mongo collections to build descriptors for.
-	 * 
+	 *
 	 * @return {@link List} of {@link CollectionDescriptor}s.
 	 */
 	private List<CollectionDescriptor> buildCollectionDescriptors(Collection<String> collectionNames) {
 		List<CollectionDescriptor> collectionDescriptors = new LinkedList<CollectionDescriptor>();
-		
+
 		for (String collectionName : collectionNames) {
 			CollectionDescriptor collectionDescriptor = new CollectionDescriptor(collectionName);
 			collectionDescriptors.add(collectionDescriptor);
 			updateColumnDescriptors(collectionDescriptor);
 		}
-		
+
 		return collectionDescriptors;
 	}
-	
+
 	/**
-	 * Updates the {@link CollectionDescriptor}s associated with the provided 
+	 * Updates the {@link CollectionDescriptor}s associated with the provided
 	 * {@link CollectionDescriptor}.
-	 * 
+	 *
 	 * @param collectionDescriptor the {@link CollectionDescriptor} to update.
 	 */
 	private void updateColumnDescriptors(CollectionDescriptor collectionDescriptor) {
 		// Read the collection from the database
 		DBCollection collection = this.database.getCollection(collectionDescriptor.getName());
-		
+
 		// Read a sampling of the rows to determine the super set of column keys
-		// that are in the collection.  
+		// that are in the collection.
 		DBCursor cursor = collection.find().limit(this.rowSampleSize);
 		for ( ;cursor.hasNext();) {
 			DBObject row = cursor.next();
@@ -143,28 +143,28 @@
 		}
 
 	}
-	
+
 	/**
-	 * Generates a set of EclipseLink, java entity files mapped to the underlying Mongo 
+	 * Generates a set of EclipseLink, java entity files mapped to the underlying Mongo
 	 * database for the given <code>collectionNames</code>.
-	 * 
-	 * @param collectionNames names of the Mongo collections to generate entities for. 
+	 *
+	 * @param collectionNames names of the Mongo collections to generate entities for.
 	 * @param packageName java package to use for the generated code.
 	 * @param baseDirectory the base directory to use for the generated code.
 	 * @param type the access type to use (method versus field annotations).
-	 * 
+	 *
 	 * @throws Exception
 	 */
-	public void generateSource(Collection<String> collectionNames, String packageName, 
+	public void generateSource(Collection<String> collectionNames, String packageName,
 													  File baseDirectory, AccessType type) throws Exception {
 		// Create metadata descriptors for the specified collections.
 		List<CollectionDescriptor> collectionDescriptors = buildCollectionDescriptors(collectionNames);
 		ExternalORMConfiguration config = generate(collectionDescriptors);
-		
+
 		// Ensure that the provided gen directory and package folders exists
 		File packageDirectory = new File(baseDirectory, packageName.replace('.', '/') + "/");
 		packageDirectory.mkdirs();
-		
+
 		// Build up the velocity generator
 		Properties vep = new Properties();
 		vep.setProperty("resource.loader", "class");
@@ -177,7 +177,7 @@
 	    for (ExternalEntity entity : config.entities()) {
 	    	generateSource(entity, type, "entity.java.vm", packageName, packageDirectory, ve);
 	    }
-	    
+
 	    // Generate source for embeddables
 	    for (ExternalEmbeddableEntity entity : config.embeddableEntities()) {
 	    	generateSource(entity, type, "embeddable.java.vm", packageName, packageDirectory, ve);
@@ -186,31 +186,31 @@
 
 	/**
 	 *  Generates the entity source file for the provided mapping metadata.
-	 * 
+	 *
 	 * @param entity the metadata representation of the entity.
 	 * @param accessType the {@link AccessType} to use (method or field) for annotations.
 	 * @param templateName the source gen template to use (embeddable, entity, etc).
 	 * @param packageName the package name to use.
 	 * @param packageDirectory the directory to generate the source file in.
 	 * @param ve the velocity engine to use.
-	 * 
+	 *
 	 * @throws Exception
 	 */
-	private void generateSource(ExternalEmbeddableEntity entity, AccessType accessType, 
-														 String templateName, String packageName, 
+	private void generateSource(ExternalEmbeddableEntity entity, AccessType accessType,
+														 String templateName, String packageName,
 														 File packageDirectory, VelocityEngine ve) throws Exception {
 		VelocityContext context = new VelocityContext();
-        context.put("entity", entity);
-        context.put("mappings", CollectionTools.list(entity.mappings()));
-        context.put("packageName", packageName);
+		context.put("entity", entity);
+		context.put("mappings", ListTools.list(entity.mappings()));
+		context.put("packageName", packageName);
 		context.put("accessType", accessType);
-        StringWriter w = new StringWriter();
+		StringWriter w = new StringWriter();
 		ve.mergeTemplate(templateName, context, w);
-		
+
 		String fileContent = w.toString();
-		
+
 		File javaFile = new File(packageDirectory, entity.getClassName() + ".java");
-		
+
 		byte[] content = fileContent.getBytes("UTF-8");
 		javaFile.createNewFile();
 		FileOutputStream writer = new FileOutputStream(javaFile);
@@ -218,17 +218,17 @@
 		writer.flush();
 		writer.close();
 	}
-	
+
 	/**
-	 * Generates and adds to the specified entity a mapping for the leaf mapping described by the 
+	 * Generates and adds to the specified entity a mapping for the leaf mapping described by the
 	 * {@link CollectionDescriptor}.
-	 * 
+	 *
 	 * @param exEntity entity to add the mapping to.
 	 * @param column the column to generate the mapping from.
 	 * @param columnName the name of the column.
 	 * @param javaColumnName the java identifier name to use for the column.
 	 */
-	private void generateLeafMapping(ExternalEmbeddableEntity exEntity, LeafColumnDescriptor column, 
+	private void generateLeafMapping(ExternalEmbeddableEntity exEntity, LeafColumnDescriptor column,
 															  String columnName, String javaColumnName) {
 		ExternalColumnMapping mapping;
 		// If this is a list-type column, then a collection based mapping is required.
@@ -238,7 +238,7 @@
 				setTargetClassName(column.getColumnType().getName());
 			mapping.setAttributeType(Vector.class.getName());
 		} else {
-			// special case where _id is reserved as a pk name in mongo.  
+			// special case where _id is reserved as a pk name in mongo.
 			// this is always intended to be an ID mapping.
 			if (columnName.equals("_id")) {
 				mapping = exEntity.addIdMapping(javaColumnName);
@@ -253,22 +253,22 @@
 	/**
 	 * Generates mappings for the provided mapped class ({@link ExternalEmbeddableEntity}) based on
 	 * the columns enumerated in the provided {@link CollectionDescriptor}.
-	 * 
+	 *
 	 * @param exEntity the entity to generate mappings on.
 	 * @param collection the Mongo DB collection descriptor to derive rows from.
 	 * @param config the orm configuration.
 	 * @param allEntityNames a {@link Set} of all of the entity names already in use.
 	 */
-	private void generateMappings(ExternalEmbeddableEntity exEntity, CollectionDescriptor collection, 
+	private void generateMappings(ExternalEmbeddableEntity exEntity, CollectionDescriptor collection,
 														   ExternalORMConfiguration config, Set<String> allEntityNames) {
 		for (ColumnDescriptor column : collection.columns()) {
 			String columnName = column.getColumnName();
-			String javaColumnName = NameTools.javaNameFromDatabaseName(columnName);
+			String javaColumnName = NameToolsTemp.javaNameFromDatabaseName(columnName);
 			if (column instanceof LeafColumnDescriptor) {
-				generateLeafMapping(exEntity, (LeafColumnDescriptor)column, 
+				generateLeafMapping(exEntity, (LeafColumnDescriptor)column,
 									columnName, javaColumnName);
 			} else if (column instanceof NestedColumnDescriptor) {
-				generateNestedMapping(exEntity, config, allEntityNames, 
+				generateNestedMapping(exEntity, config, allEntityNames,
 									  (NestedColumnDescriptor)column, columnName, javaColumnName);
 			}
 		}
@@ -277,7 +277,7 @@
 	/**
 	 * Generates a mapping on the provided mapped class that represents the nested mapping. This will
 	 * also involved generating an {@link Embeddable} to represent the nested value.
-	 * 
+	 *
 	 * @param exEntity the entity to generate the mapping on.
 	 * @param config the {@link ExternalORMConfiguration} that the entity is associated with.
 	 * @param allEntityNames the existing used namespace for all mapped classes.
@@ -285,25 +285,25 @@
 	 * @param columnName the name of the column.
 	 * @param javaColumnName the java identifier name for the column.
 	 */
-	private void generateNestedMapping(ExternalEmbeddableEntity exEntity,ExternalORMConfiguration config, 
+	private void generateNestedMapping(ExternalEmbeddableEntity exEntity,ExternalORMConfiguration config,
 									   Set<String> allEntityNames, NestedColumnDescriptor column, String columnName, String javaColumnName) {
 		// Create the embeddable for the nested value
-		String embeddableName = NameTools.javaNameFromDatabaseName(columnName, true);
-		embeddableName = NameTools.uniqueNameFor(embeddableName, allEntityNames);
+		String embeddableName = NameToolsTemp.javaNameFromDatabaseName(columnName, true);
+		embeddableName = NameTools.uniqueName(embeddableName, allEntityNames);
 		allEntityNames.add(embeddableName);
 		ExternalEmbeddableEntity embeddable = config.addEmbeddableEntity(embeddableName);
 		embeddable.addNoSql().setDataFormat(DataFormatType.MAPPED);
 		embeddable.setAccessType("VIRTUAL");
 		// generate mappings for the embeddable
 		generateMappings(embeddable, column.getColumnDescriptor(), config, allEntityNames);
-		
+
 		// if a collection, generate an Element Collection
 		if (column.isList()) {
 			ExternalElementCollectionMapping mapping = exEntity.addElementCollectionMapping(javaColumnName);
 			mapping.setNoSqlField(columnName);
 			mapping.setAttributeType(Vector.class.getName());
 			mapping.setTargetClassName(embeddableName);
-		} 
+		}
 		// otherwise, just an embedded mapping.
 		else {
 			ExternalEmbeddedMapping mapping = exEntity.addEmbeddedMapping(javaColumnName);
@@ -315,7 +315,7 @@
 	/**
 	 * Generates and adds a root level named query for each entity
 	 * enumerate in the {@link ExternalORMConfiguration}.
-	 * 
+	 *
 	 * @param config the configuration to generate and add queries from.
 	 */
 	private void generateQueries(ExternalORMConfiguration config) {
@@ -324,16 +324,16 @@
 			ExternalNamedQuery query = config.addNamedQuery(entityName + ".findAll");
 			char identifier = Character.toLowerCase(entityName.charAt(0));
 			query.setQuery("select " + identifier + " from " + entityName + " "  + identifier);
-			
+
 		}
 	}
 
 	/**
 	 * Generates a {@link String} representation of an eclipselink-orm.xml descriptor based
-	 * on the provided MongoDB {@link CollectionDescriptor} definitions.  
-	 * 
+	 * on the provided MongoDB {@link CollectionDescriptor} definitions.
+	 *
 	 * @param collectionDescriptors the MongoDB collections to generate entities from.
-	 * 
+	 *
 	 * @return a {@link String} representation of the eclipselink-orm.xml.
 	 */
 	private ExternalORMConfiguration generate(List<CollectionDescriptor> collectionDescriptors) {
@@ -345,8 +345,8 @@
 		for (CollectionDescriptor collection : collectionDescriptors) {
 			// add an entity with a unique name
 			String collectionName = collection.getName();
-			String entityName = NameTools.javaNameFromDatabaseName(collectionName, true);
-			entityName = NameTools.uniqueNameFor(entityName, allEntityNames);
+			String entityName = NameToolsTemp.javaNameFromDatabaseName(collectionName, true);
+			entityName = NameTools.uniqueName(entityName, allEntityNames);
 			allEntityNames.add(entityName);
 			ExternalEntity exEntity = config.addEntity(entityName);
 			// access type is virtual
@@ -358,24 +358,24 @@
 			// add mappings
 			generateMappings(exEntity, collection, config, allEntityNames);
 		}
-		
+
 		// Generate a default, read all query for all entities
-		generateQueries(config);		
-		
+		generateQueries(config);
+
 		return config;
 	}
-	
+
 	/**
 	 * Creates an eclipselink-orm.xml descriptor mapping the provided <code>collectionNames</code>
 	 * as EclipseLink dynamic entities.
-	 * 
+	 *
 	 * @param collectionNames
 	 * @return a {@link String} representation of the eclipselink-orm.xml.
 	 */
 	public String generateXML(Collection<String> collectionNames) {
 		// Create metadata descriptors for the specified collections.
 		List<CollectionDescriptor> collectionDescriptors = buildCollectionDescriptors(collectionNames);
-		
+
 		// Generate an eclpselink-orm.xml from the collection descriptors
 		return generate(collectionDescriptors).getXML();
 	}
@@ -383,7 +383,7 @@
 	/**
 	 * Updates the give {@link CollectionDescriptor} with the leaf column information defined
 	 * by row value.
-	 * 
+	 *
 	 * @param collectionDescriptor the {@link CollectionDescriptor} to update.
 	 * @param columnName the name of the column.
 	 * @param value the row value of the column.
@@ -396,7 +396,7 @@
 		}
 		Class<?> valueClass = value.getClass();
 		// Special case for an id-type column. If one is not explicitly defined,
-		// Mongo auto-generates one and uses the noted class for the type. This 
+		// Mongo auto-generates one and uses the noted class for the type. This
 		// should be considered a String in java.
 		valueClass = valueClass.getName().equals("org.bson.types.ObjectId") ? String.class : valueClass;
 		// if the column type isn't consistent, just use Object as the type.
@@ -408,14 +408,14 @@
 	}
 
 	/**
-	 * Updates the given {@link CollectionDescriptor} with the a column representing 
+	 * Updates the given {@link CollectionDescriptor} with the a column representing
 	 * the list-type value.
-	 * 
+	 *
 	 * @param collectionDescriptor the {@link CollectionDescriptor} to update.
 	 * @param columnName the name of the column to update.
 	 * @param value the row value, or in this case the list value row.
 	 */
-	private void handleListColumn(CollectionDescriptor collectionDescriptor, String columnName, 
+	private void handleListColumn(CollectionDescriptor collectionDescriptor, String columnName,
 																		    	Object value) {
 		ColumnDescriptor columnDescriptor = collectionDescriptor.getColumn(columnName);
 		BasicDBList listValue = (BasicDBList)value;
@@ -427,7 +427,7 @@
 				NestedColumnDescriptor nestedColumnDesc;
 				if (columnDescriptor == null) {
 					nestedColumnDesc  = collectionDescriptor.addNestedColumn(columnName);
-				} else { 
+				} else {
 					nestedColumnDesc = (NestedColumnDescriptor)columnDescriptor;
 				}
 				nestedColumnDesc.setList(true);
@@ -438,17 +438,17 @@
 					valueFromList = listValues.next();
 					updateCollectionDescriptor(nestedColumnDesc.getColumnDescriptor(), (DBObject)valueFromList);
 				}
-								
-			} 
+
+			}
 			// Handle leaf list
 			else {
 				LeafColumnDescriptor leafColumnDescriptor;
 				if (columnDescriptor == null) {
 					leafColumnDescriptor  = collectionDescriptor.addLeafColumn(columnName);
-				} else { 
+				} else {
 					leafColumnDescriptor = (LeafColumnDescriptor)columnDescriptor;
 				}
-				
+
 				leafColumnDescriptor.setList(true);
 				leafColumnDescriptor.setColumnType(valueFromList.getClass());
 				// Iterate over subsequent elements. If the element type isn't the same as the last, default to Object
@@ -467,41 +467,41 @@
 	/**
 	 * Updates the given {@link CollectionDescriptor} with the nested column information
 	 * derived from the provided row value.
-	 * 
+	 *
 	 * @param collectionDescriptor the {@link CollectionDescriptor} to update.
 	 * @param columnName name of the column.
 	 * @param value row value of the column, or in this case the nest row.
 	 */
 	private void handleNestedColumn(CollectionDescriptor collectionDescriptor,
 								   					   String columnName, Object value) {
-		NestedColumnDescriptor columnDescriptor = 
+		NestedColumnDescriptor columnDescriptor =
 				(NestedColumnDescriptor)collectionDescriptor.getColumn(columnName);
-		
+
 		if (columnDescriptor == null) {
 			columnDescriptor = collectionDescriptor.addNestedColumn(columnName);
 		}
-		
+
 		updateCollectionDescriptor(columnDescriptor.getColumnDescriptor(), (DBObject)value);
 	}
-	
+
 	/**
 	 * Returns the names of the Mongo collections on the specified
 	 * database.
-	 * 
+	 *
 	 * @return the name of the Mongo collections.
 	 */
 	public Set<String> listCollectionNames() {
 		Set<String> collectionNames = this.database.getCollectionNames();
 		// Remove the internall system.indexes table name
 		collectionNames.remove("system.indexes");
-		
+
 		return collectionNames;
 	}
 
 	/**
-	 * Updates the given {@link CollectionDescriptor} with columns implied by the provided row 
+	 * Updates the given {@link CollectionDescriptor} with columns implied by the provided row
 	 * or {@link DBObject}.
-	 * 
+	 *
 	 * @param collectionDescriptor the {@link CollectionDescriptor} to update.
 	 * @param dbObject the row to infer columns from.
 	 */
@@ -514,11 +514,11 @@
 				// List type
 				if (value instanceof BasicDBList) {
 					handleListColumn(collectionDescriptor, columnName, value);
-				} 
+				}
 				// Single Nested
 				else if (value instanceof BasicDBObject) {
 					handleNestedColumn(collectionDescriptor, columnName, value);
-				} 
+				}
 				// Leaf Value
 				else {
 					handleLeafColumn(collectionDescriptor, columnName, value);
@@ -526,4 +526,47 @@
 			}
 		}
 	}
-}
+
+	/**
+	 * TODO: Taken from the old NameTools, I have no idea how to convert this to use the new code.
+	 */
+	private static class NameToolsTemp {
+
+		/** regex used to replace characters in a database identifier that are invalid in java identifiers */
+		private static final Pattern DB_IDENTIFIER_EXCLUSIONS = Pattern.compile("[@$# .]");
+
+		/**
+		 * Generates a Java identifier name based on the provided database name.
+		 * Camel-cases the Java identifier on _ characters and on characters that
+		 * are valid in DB identifiers but not Java identifiers (the @ symbol, for
+		 * example). Does not capitalize the first letter of the generated
+		 * identifier.
+		 *
+		 * @param databaseName - <code>String</code> representing the database
+		 * identifier that should be used to produce a Java identifier.
+		 */
+		public static String javaNameFromDatabaseName(String databaseName) {
+			return javaNameFromDatabaseName(databaseName, false);
+		}
+
+		/**
+		 * Generates a Java identifier name based on the provided database name.
+		 * Camel-cases the Java identifier on _ characters and on characters that are
+		 * valid in DB identifiers but not Java identifiers (the @ symbol, for
+		 * example).
+		 * @param databaseName - <code>String</code> representing the database
+		 * identifier that should be used to produce a Java identifier.
+		 *
+		 * @param capitalizeFirstLetter - <code>boolean</code> indicating whether
+		 * the first letter of the identifier should be capitalized.
+		 */
+		public static String javaNameFromDatabaseName(String databaseName, boolean capitalizeFirstLetter) {
+			return StringTools.convertAllCapsToCamelCase(
+				NameTools.convertToJavaIdentifier(
+					DB_IDENTIFIER_EXCLUSIONS.matcher(databaseName).replaceAll("_")
+				),
+				capitalizeFirstLetter
+			);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternaNoSqlJoinFieldMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternaNoSqlJoinFieldMapping.java
index 9e2617f..7c3c29c 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternaNoSqlJoinFieldMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternaNoSqlJoinFieldMapping.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * This inter
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalAssociationOverride.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalAssociationOverride.java
index c0949e4..9a506b8 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalAssociationOverride.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalAssociationOverride.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * This interface describes the configurable properties for an association override in the ORM xml.
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddableEntity.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddableEntity.java
index 5f1b434..9a86817 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddableEntity.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddableEntity.java
@@ -13,9 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import javax.persistence.AccessType;
 import org.eclipse.persistence.annotations.ChangeTrackingType;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
 
 /**
  * This interface describes the configurable properties for an embeddable entity. One or more
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedIDMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedIDMapping.java
index c63236a..1f38dcf 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedIDMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedIDMapping.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * This interface and inherited describes the configurable properties for an embedded ID mapping. An
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedMapping.java
index a081bc5..0ba83a7 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedMapping.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * This interface and inherited describes the configurable properties for an embedded mapping.
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntity.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntity.java
index cb8d3e9..1dcea6d 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntity.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntity.java
@@ -7,8 +7,7 @@
 package org.eclipse.persistence.tools.mapping.orm;
 
 import javax.persistence.InheritanceType;
-
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
 
 /**
  * This interface and inherited behavior describes the configurable properties for an entity. One or
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntityListenerHolder.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntityListenerHolder.java
index 1a7ee71..426ca88 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntityListenerHolder.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntityListenerHolder.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * Defines an external ORM object that holds on to {@link ExternalEntityListener}. Implementors of
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntityResult.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntityResult.java
index 522de5d..64f9d35 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntityResult.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntityResult.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * This interface and describes the configurable properties defined for a entity result in the ORM
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntitySecondaryTable.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntitySecondaryTable.java
index ad30d9d..3fa7e72 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntitySecondaryTable.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntitySecondaryTable.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * This interface and inherited behavior describe the configurable properties defined for a
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntityTable.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntityTable.java
index e459a13..28003c3 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntityTable.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEntityTable.java
@@ -14,8 +14,7 @@
 package org.eclipse.persistence.tools.mapping.orm;
 
 import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
 
 /**
  * This interface and inherited behavior describe the configurable properties
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalJoinTable.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalJoinTable.java
index b6ac4b7..0dd6374 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalJoinTable.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalJoinTable.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * This interface and inherited behavior describe the configurable properties defined for a join
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalManyToOneMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalManyToOneMapping.java
index a0f6b84..22ef15a 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalManyToOneMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalManyToOneMapping.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * This interface and inherited behavior describe the configurable properties defined for a
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMappedSuperClassEntity.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMappedSuperClassEntity.java
index 48469a3..1afb92e 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMappedSuperClassEntity.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMappedSuperClassEntity.java
@@ -14,7 +14,7 @@
 package org.eclipse.persistence.tools.mapping.orm;
 
 import org.eclipse.persistence.annotations.ExistenceType;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
 
 /**
  * This interface and inherited behavior describe the configurable properties defined for a
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMapping.java
index 5e27acb..c85436b 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMapping.java
@@ -13,10 +13,6 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import javax.persistence.Basic;
-import javax.persistence.ElementCollection;
-import javax.persistence.Embedded;
-import javax.persistence.Id;
 
 /**
  * This interface represents the basis for all mapping types defined by the JPA spec that are
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalNamedQuery.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalNamedQuery.java
index 7a4759c..1ee8501 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalNamedQuery.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalNamedQuery.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * This interface defines all properties and behavior associated with named query configuration in
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalNonTransientMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalNonTransientMapping.java
index 418b8dd..e42c274 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalNonTransientMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalNonTransientMapping.java
@@ -14,8 +14,7 @@
 package org.eclipse.persistence.tools.mapping.orm;
 
 import javax.persistence.AccessType;
-
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
 
 /**
  * This interface represents the basis for all non-transient mapping types defined by the
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalORMConfiguration.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalORMConfiguration.java
index beebe9c..716131a 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalORMConfiguration.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalORMConfiguration.java
@@ -14,8 +14,7 @@
 package org.eclipse.persistence.tools.mapping.orm;
 
 import javax.persistence.AccessType;
-
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
 
 /**
  * This interface defines the root-level contract for providing ORM.xml metadata. The properties
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalObjectCollectionMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalObjectCollectionMapping.java
index 42aa1cd..d430986 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalObjectCollectionMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalObjectCollectionMapping.java
@@ -15,7 +15,7 @@
 
 import javax.persistence.EnumType;
 import javax.persistence.TemporalType;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
 
 /**
  * This interface represents some common API for one-to-many, many-to-many, and element collection mappings.
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalObjectTypeConverter.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalObjectTypeConverter.java
index 07eaca5..8125b88 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalObjectTypeConverter.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalObjectTypeConverter.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * This interface and inherited behavior describes the configurable properties for an object type
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalOneToOneMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalOneToOneMapping.java
index efe31d3..afafcc4 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalOneToOneMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalOneToOneMapping.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * This interface and inherited behavior describe all of the configurable properties defined for a
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalOptimisticLocking.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalOptimisticLocking.java
index 9db70f1..52f92ce 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalOptimisticLocking.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalOptimisticLocking.java
@@ -14,7 +14,7 @@
 package org.eclipse.persistence.tools.mapping.orm;
 
 import org.eclipse.persistence.annotations.OptimisticLockingType;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
 
 /**
  * This interface and inherited behavior describe the configurable properties defined for an
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalPrimaryKey.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalPrimaryKey.java
index a7b2ff8..bbae604 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalPrimaryKey.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalPrimaryKey.java
@@ -15,7 +15,7 @@
 
 import org.eclipse.persistence.annotations.CacheKeyType;
 import org.eclipse.persistence.annotations.IdValidation;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
 
 /**
  * This interface and inherited behavior describe the configurable properties defined for a primary
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalReferenceTable.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalReferenceTable.java
index 8e57f8a..e422bfd 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalReferenceTable.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalReferenceTable.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * This interface and inherited behavior describe the configurable properties defined for a table
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalRelationshipMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalRelationshipMapping.java
index 6fd8fcc..5c7644e 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalRelationshipMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalRelationshipMapping.java
@@ -15,7 +15,7 @@
 
 import javax.persistence.CascadeType;
 import org.eclipse.persistence.annotations.JoinFetchType;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
 
 /**
  * Captures the common properties associated with all relationship mappings defined by the JPA
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalSQLResultSetMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalSQLResultSetMapping.java
index 6c98033..ce4d860 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalSQLResultSetMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalSQLResultSetMapping.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * Defines in the ORM.xml, how to map a SQL result set to an Entity view-type object. This object
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalStoredProcedureQuery.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalStoredProcedureQuery.java
index 2102243..96bc61b 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalStoredProcedureQuery.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalStoredProcedureQuery.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * This interface and inherited behavior describe the configurable properties defined for a stored
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTableGenerator.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTableGenerator.java
index 7d31089..20b4de4 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTableGenerator.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTableGenerator.java
@@ -14,8 +14,7 @@
 package org.eclipse.persistence.tools.mapping.orm;
 
 import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
 
 /**
  * Defines the properties of a Table Generator defined in the ORM.xml. A Table Generator may be
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTenantDiscriminatorColumnProvider.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTenantDiscriminatorColumnProvider.java
index 42a63dc..2533364 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTenantDiscriminatorColumnProvider.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTenantDiscriminatorColumnProvider.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * Defines an external ORM object that holds on to {@link ExternalTenantDiscriminatorColumn}.
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTransformationMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTransformationMapping.java
index 285de83..a86ec72 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTransformationMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTransformationMapping.java
@@ -13,7 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm;
 
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
 
 /**
  * This interface represents the transformation mapping defined by the EclipseLink JPA spec that are
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalUniqueConstraint.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalUniqueConstraint.java
index 32019a3..8f52a70 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalUniqueConstraint.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalUniqueConstraint.java
@@ -14,8 +14,7 @@
 package org.eclipse.persistence.tools.mapping.orm;
 
 import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
 
 /**
  * Defines the properties of a Unique Constraint in the ORM.xml. A Unique Constraint defines a group
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalVariableOneToOneMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalVariableOneToOneMapping.java
index c80ade5..63beb10 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalVariableOneToOneMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalVariableOneToOneMapping.java
@@ -14,8 +14,7 @@
 package org.eclipse.persistence.tools.mapping.orm;
 
 import javax.persistence.CascadeType;
-
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
 
 /**
  * This interface represents the basis for all variable one to one mapping types defined by the
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ORMDocumentType.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ORMDocumentType.java
index 48d464c..11cc593 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ORMDocumentType.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ORMDocumentType.java
@@ -15,29 +15,10 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.utility.StringTools;
 
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.ECLIPSELINK_ORM_NAMESPACE_URI;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.ECLIPSELINK_ORM_XSD_URI_1_2;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.ECLIPSELINK_ORM_XSD_URI_2_0;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.ECLIPSELINK_ORM_XSD_URI_2_1;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.ECLIPSELINK_ORM_XSD_URI_2_2;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.ECLIPSELINK_ORM_XSD_URI_2_3;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.ECLIPSELINK_ORM_XSD_URI_2_4;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.ECLIPSELINK_ORM_XSD_URI_2_5;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.ORM_NAMESPACE_URI;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.ORM_XSD_URI_1_0;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.ORM_XSD_URI_2_0;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.ORM_XSD_URI_2_1;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.VERSION_1_2;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.VERSION_2_1;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.VERSION_2_2;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.VERSION_2_3;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.VERSION_2_4;
-import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.VERSION_2_5;
-import static org.eclipse.persistence.tools.mapping.orm.XmlConstants.VERSION_1_0;
-import static org.eclipse.persistence.tools.mapping.orm.XmlConstants.VERSION_2_0;
+import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.*;
+import static org.eclipse.persistence.tools.mapping.orm.XmlConstants.*;
 
 /**
  * Represents the document version of orm XML files.
@@ -49,6 +30,7 @@
  *
  * @version 2.5
  */
+@SuppressWarnings("unused") // unused used for the import statement: see bug 330740
 public enum ORMDocumentType {
 
 	/**
@@ -64,7 +46,7 @@
 	/**
 	 * Indicates the JPA doc version is EclipseLink 2.1.
 	 */
-	ECLIPELINK_2_1(ECLIPSELINK_ORM_NAMESPACE_URI, VERSION_2_1, ECLIPSELINK_ORM_XSD_URI_2_1),
+	ECLIPELINK_2_1(ECLIPSELINK_ORM_NAMESPACE_URI, XmlConstants.VERSION_2_1, ECLIPSELINK_ORM_XSD_URI_2_1),
 
 	/**
 	 * Indicates the JPA doc version is EclipseLink 2.2.
@@ -99,7 +81,7 @@
 	/**
 	 * Indicates the JPA doc version is 2.1.
 	 */
-	JPA_2_1(ORM_NAMESPACE_URI, VERSION_2_1, ORM_XSD_URI_2_1),
+	JPA_2_1(ORM_NAMESPACE_URI, XmlConstants.VERSION_2_1, ORM_XSD_URI_2_1),
 
 	/**
 	 * Indicates the JPA doc version unknown or unsupported.
@@ -168,9 +150,10 @@
 
 		for (ORMDocumentType type : types()) {
 
-			if (StringTools.stringsAreEqualIgnoreCase(schemaURI, type.schemaURI) ||
-					(StringTools.stringsAreEqualIgnoreCase(type.xmlNamespace, xmlNamespace)
-							&& StringTools.stringsAreEqualIgnoreCase(type.version, version))) {
+			if (StringTools.equalsIgnoreCase(schemaURI, type.schemaURI) ||
+			   (StringTools.equalsIgnoreCase(type.xmlNamespace, xmlNamespace) &&
+			    StringTools.equalsIgnoreCase(type.version, version))) {
+
 				return type;
 			}
 		}
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AbstractColumn.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AbstractColumn.java
index 73c6079..5e0b877 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AbstractColumn.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AbstractColumn.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalBasicColumn;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AbstractExternalForm.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AbstractExternalForm.java
index ab74faf..b9c04e3 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AbstractExternalForm.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AbstractExternalForm.java
@@ -19,8 +19,8 @@
 import java.util.Iterator;
 import java.util.List;
 import org.eclipse.persistence.tools.mapping.orm.ExternalForm;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.Tools;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -371,7 +371,7 @@
 
 		// It seems we can't create a text node with a value only containing
 		// white spaces, so we ignore the addition
-		if (StringTools.stringIsEmpty(value)) {
+		if (StringTools.isBlank(value)) {
 			return null;
 		}
 
@@ -817,7 +817,7 @@
 	 */
 	protected final Element getChild(Node node, String elementName) {
 		for (Element child : getChildren(node)) {
-			if (Tools.valuesAreEqual(child.getNodeName(), elementName)) {
+			if (ObjectTools.equals(child.getNodeName(), elementName)) {
 				return child;
 			}
 		}
@@ -1106,7 +1106,7 @@
 		for (Iterator<Element> iter = children.iterator(); iter.hasNext();) {
 			Element element = iter.next();
 
-			if (Tools.valuesAreDifferent(element.getNodeName(), elementName)) {
+			if (ObjectTools.notEquals(element.getNodeName(), elementName)) {
 				iter.remove();
 			}
 		}
@@ -1515,7 +1515,7 @@
 		if (element == null) {
 			// First make sure there are no root element with a different name
 			for (Element child : getChildren(document)) {
-				if (Tools.valuesAreDifferent(child.getNodeName(), rootElementName)) {
+				if (ObjectTools.notEquals(child.getNodeName(), rootElementName)) {
 					// A root element was found, simply rename it to comply
 					// with the document's XSD
 					setElementName(child, rootElementName);
@@ -1825,7 +1825,7 @@
 			for (int index = namesOrder.indexOf(nodeName) + 1; index < count; index++) {
 				String name = namesOrder.get(index);
 
-				if (Tools.valuesAreEqual(childName, name)) {
+				if (ObjectTools.equals(childName, name)) {
 					return child;
 				}
 			}
@@ -3059,7 +3059,7 @@
 		// It seems we can't create a text node with a value only containing
 		// white spaces, so we convert it into null. Maybe there is a way to
 		// remove the validation?!?
-		if (StringTools.stringIsEmpty(value)) {
+		if (StringTools.isBlank(value)) {
 			value = null;
 		}
 
@@ -3071,7 +3071,7 @@
 			return;
 		}
 
-		boolean valueNotEmpty = !StringTools.stringIsEmpty(value);
+		boolean valueNotEmpty = !StringTools.isBlank(value);
 
 		// Add a text node if the element is null and the value isn't
 		if ((childElement == null) && valueNotEmpty) {
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AccessMethods.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AccessMethods.java
index 756e512..c776927 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AccessMethods.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AccessMethods.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalAccessMethods;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AssociationOverride.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AssociationOverride.java
index e02fee4..a77e750 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AssociationOverride.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AssociationOverride.java
@@ -15,12 +15,11 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalAssociationOverride;
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinTable;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AttributeOverride.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AttributeOverride.java
index f9cdf92..dd09399 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AttributeOverride.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AttributeOverride.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalAttributeOverride;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityColumn;
 import org.w3c.dom.Element;
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ClassConverter.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ClassConverter.java
index 973a9f9..d98ccda 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ClassConverter.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ClassConverter.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalClassConverter;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/CloneCopyPolicy.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/CloneCopyPolicy.java
index 27d6d80..16ca82d 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/CloneCopyPolicy.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/CloneCopyPolicy.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalCloneCopyPolicy;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/CollectionTable.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/CollectionTable.java
index a25ca1b..9a6bc81 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/CollectionTable.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/CollectionTable.java
@@ -15,11 +15,10 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalCollectionTable;
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinColumn;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ColumnResult.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ColumnResult.java
index 04de824..32e9338 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ColumnResult.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ColumnResult.java
@@ -14,7 +14,6 @@
 package org.eclipse.persistence.tools.mapping.orm.dom;
 
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalColumnResult;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ConversionValue.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ConversionValue.java
index cc3d800..717ab3d 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ConversionValue.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ConversionValue.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalConversionValue;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Converter.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Converter.java
index 9cd5bf1..0bdc653 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Converter.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Converter.java
@@ -14,7 +14,6 @@
 package org.eclipse.persistence.tools.mapping.orm.dom;
 
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalConverter;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ConvertibleMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ConvertibleMapping.java
index 6bb3e8f..71a2728 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ConvertibleMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ConvertibleMapping.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalConverter;
 import org.eclipse.persistence.tools.mapping.orm.ExternalConvertibleMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalObjectTypeConverter;
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/CopyPolicy.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/CopyPolicy.java
index 31f819b..c07e52f 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/CopyPolicy.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/CopyPolicy.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalCopyPolicy;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/DiscriminatorClass.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/DiscriminatorClass.java
index d49e232..65c5422 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/DiscriminatorClass.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/DiscriminatorClass.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalDiscriminatorClass;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/DiscriminatorColumn.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/DiscriminatorColumn.java
index 8ea4e0d..21526a0 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/DiscriminatorColumn.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/DiscriminatorColumn.java
@@ -16,7 +16,6 @@
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.DiscriminatorType;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalDiscriminatorColumn;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ElementCollectionMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ElementCollectionMapping.java
index 972be04..e0464bf 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ElementCollectionMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ElementCollectionMapping.java
@@ -32,9 +32,9 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalOrderColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalStructConverter;
 import org.eclipse.persistence.tools.mapping.orm.ExternalTypeConverter;
-import org.eclipse.persistence.tools.utility.ClassName;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.ClassNameTools;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
@@ -625,13 +625,13 @@
 	public String getTargetClassName() {
 		return getAttribute(TARGET_CLASS);
 	}
-	
+
 	/**
 	 * {@inheritDoc}
 	 */
 	@Override
 	public String getTargetClassShortName() {
-		return ClassName.getSimpleName(getTargetClassName());
+		return ClassNameTools.simpleName(getTargetClassName());
 	}
 
 	/**
@@ -641,7 +641,7 @@
 	public TemporalType getTemporalType() {
 		return getChildEnumNode(TEMPORAL, TemporalType.class);
 	}
-	
+
 	/**
 	 * {@inheritDoc}
 	 */
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddableEntity.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddableEntity.java
index c2d757c..1ddaee1 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddableEntity.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddableEntity.java
@@ -16,7 +16,6 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
-
 import org.eclipse.persistence.annotations.ChangeTrackingType;
 import org.eclipse.persistence.tools.mapping.orm.ExternalAccessMethods;
 import org.eclipse.persistence.tools.mapping.orm.ExternalBasicCollectionMapping;
@@ -41,11 +40,11 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalStructConverter;
 import org.eclipse.persistence.tools.mapping.orm.ExternalTransientMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalTypeConverter;
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.Tools;
-import org.eclipse.persistence.tools.utility.iterables.EmptyListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterable.EmptyListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
@@ -225,15 +224,15 @@
 	/**
 	 * Embeddables don't currently support ID, but the implementation
 	 * is here for convenience.
-	 * 
+	 *
 	 * {@inheritDoc}
 	 */
 	@Override
 	public ExternalIDMapping addIdMapping(String name) {
 		throw new UnsupportedOperationException();
 	}
-		
-		
+
+
 	/**
 	 * {@inheritDoc}
 	 */
@@ -449,52 +448,52 @@
 	Mapping buildMapping(String elementName, int index) {
 
 		// Basic
-		if (Tools.valuesAreEqual(elementName, BasicMapping.BASIC)) {
+		if (ObjectTools.equals(elementName, BasicMapping.BASIC)) {
 			return buildBasicMapping(index);
 		}
 
 		// Basic Collection
-		if (Tools.valuesAreEqual(elementName, BasicCollectionMapping.BASIC_COLLECTION)) {
+		if (ObjectTools.equals(elementName, BasicCollectionMapping.BASIC_COLLECTION)) {
 			return buildBasicCollectionMapping(index);
 		}
 
 		// Basic Map
-		if (Tools.valuesAreEqual(elementName, BasicMapMapping.BASIC_MAP)) {
+		if (ObjectTools.equals(elementName, BasicMapMapping.BASIC_MAP)) {
 			return buildBasicMapMapping(index);
 		}
 
 		// Embedded
-		if (Tools.valuesAreEqual(elementName, EmbeddedMapping.EMBEDDED)) {
+		if (ObjectTools.equals(elementName, EmbeddedMapping.EMBEDDED)) {
 			return buildEmbeddedMapping(index);
 		}
 
 		// Element Collection
-		if (Tools.valuesAreEqual(elementName, ElementCollectionMapping.ELEMENT_COLLECTION)) {
+		if (ObjectTools.equals(elementName, ElementCollectionMapping.ELEMENT_COLLECTION)) {
 			return buildElementCollectionMapping(index);
 		}
 
 		// M:M
-		if (Tools.valuesAreEqual(elementName, ManyToManyMapping.MANY_TO_MANY)) {
+		if (ObjectTools.equals(elementName, ManyToManyMapping.MANY_TO_MANY)) {
 			return buildManyToManyMapping(index);
 		}
 
 		// M:1
-		if (Tools.valuesAreEqual(elementName, ManyToOneMapping.MANY_TO_ONE)) {
+		if (ObjectTools.equals(elementName, ManyToOneMapping.MANY_TO_ONE)) {
 			return buildManyToOneMapping(index);
 		}
 
 		// 1:M
-		if (Tools.valuesAreEqual(elementName, OneToManyMapping.ONE_TO_MANY)) {
+		if (ObjectTools.equals(elementName, OneToManyMapping.ONE_TO_MANY)) {
 			return buildOneToManyMapping(index);
 		}
 
 		// 1:1
-		if (Tools.valuesAreEqual(elementName, OneToOneMapping.ONE_TO_ONE)) {
+		if (ObjectTools.equals(elementName, OneToOneMapping.ONE_TO_ONE)) {
 			return buildOneToOneMapping(index);
 		}
 
 		// Transient
-		if (Tools.valuesAreEqual(elementName, TransientMapping.TRANSIENT)) {
+		if (ObjectTools.equals(elementName, TransientMapping.TRANSIENT)) {
 			return buildTransientMapping(index);
 		}
 
@@ -720,9 +719,9 @@
 
 		return buildInstantiationCopyPolicy();
 	}
-	
+
 	public final List<ExternalMapping> getMappings() {
-		return CollectionTools.list(mappings());
+		return ListTools.list(mappings());
 	}
 
 	/**
@@ -733,7 +732,7 @@
 
 		// TODO: Speed up by creating a helper method that will retrieve the node directly
 		for (ExternalMapping mapping : mappings()) {
-			if (Tools.valuesAreEqual(name, mapping.getName())) {
+			if (ObjectTools.equals(name, mapping.getName())) {
 				return (Mapping) mapping;
 			}
 		}
@@ -851,7 +850,7 @@
 	public final Boolean isMetadataComplete() {
 		return getBooleanAttribute(METADATA_COMPLETE);
 	}
-	
+
 	/**
 	 * {@inheritDoc}
 	 */
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedIDMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedIDMapping.java
index f8d32c7..0002fd1 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedIDMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedIDMapping.java
@@ -15,12 +15,11 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalAttributeOverride;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddedIDMapping;
-import org.eclipse.persistence.tools.utility.iterables.EmptyListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.EmptyListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 
 /**
  * The external form for a embedded ID mapping, which is a child of an entity.
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedMapping.java
index c1e1339..dbb5caa 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedMapping.java
@@ -19,8 +19,8 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalAttributeOverride;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddedMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalNoSqlField;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Entity.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Entity.java
index 7584524..50dd016 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Entity.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Entity.java
@@ -28,9 +28,9 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalPrimaryKeyJoinColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalSQLResultSetMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalStoredProcedureQuery;
-import org.eclipse.persistence.tools.utility.Tools;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
@@ -476,7 +476,7 @@
 			return null;
 		}
 
-		if (Tools.valuesAreDifferent(name, namedQuery.getName())) {
+		if (ObjectTools.notEquals(name, namedQuery.getName())) {
 			namedQuery = null;
 		}
 
@@ -510,7 +510,7 @@
 			return null;
 		}
 
-		if (Tools.valuesAreDifferent(name, nativeQuery.getName())) {
+		if (ObjectTools.notEquals(name, nativeQuery.getName())) {
 			nativeQuery = null;
 		}
 
@@ -604,7 +604,7 @@
 			return null;
 		}
 
-		if (Tools.valuesAreDifferent(name, storedProcedureQuery.getName())) {
+		if (ObjectTools.notEquals(name, storedProcedureQuery.getName())) {
 			storedProcedureQuery = null;
 		}
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityColumn.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityColumn.java
index 2930016..23f27d2 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityColumn.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityColumn.java
@@ -14,7 +14,6 @@
 package org.eclipse.persistence.tools.mapping.orm.dom;
 
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityColumn;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityIDGeneratedValue.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityIDGeneratedValue.java
index 238adb0..7d2369f 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityIDGeneratedValue.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityIDGeneratedValue.java
@@ -16,7 +16,6 @@
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.GenerationType;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityIDGeneratedValue;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityListener.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityListener.java
index 1ab9cf2..3e7886d 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityListener.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityListener.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityListener;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityResult.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityResult.java
index 4f87b6d..b14bde4 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityResult.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EntityResult.java
@@ -15,11 +15,10 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityResult;
 import org.eclipse.persistence.tools.mapping.orm.ExternalFieldResult;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/FetchGroup.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/FetchGroup.java
index e4f3e7f..9670117 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/FetchGroup.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/FetchGroup.java
@@ -14,7 +14,6 @@
 package org.eclipse.persistence.tools.mapping.orm.dom;
 
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalFetchGroup;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/FieldResult.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/FieldResult.java
index 7e4a7d0..121224d 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/FieldResult.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/FieldResult.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalFieldResult;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/IdMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/IdMapping.java
index 4763c17..e0df0cc 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/IdMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/IdMapping.java
@@ -224,7 +224,7 @@
 	public TemporalType getTemporalType() {
 		return getChildEnumNode(TEMPORAL, TemporalType.class);
 	}
-	
+
 	/**
 	 * {@inheritDoc}
 	 */
@@ -280,6 +280,7 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	@SuppressWarnings("null")
 	public void setColumn(String columnName) {
 
 		AbstractColumn column = getColumn();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/JoinColumn.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/JoinColumn.java
index a2e7982..175acd4 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/JoinColumn.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/JoinColumn.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinColumn;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/JoinTable.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/JoinTable.java
index 574d759..49b880a 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/JoinTable.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/JoinTable.java
@@ -15,11 +15,10 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinTable;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToManyMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToManyMapping.java
index 780834a..0663f8a 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToManyMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToManyMapping.java
@@ -17,8 +17,8 @@
 import java.util.List;
 import org.eclipse.persistence.tools.mapping.orm.ExternalManyToManyMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalNoSqlJoinField;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 
 /**
  * The external form for a M:M mapping, which is a child of an entity.
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToOneMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToOneMapping.java
index 9fff205..8590745 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToOneMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToOneMapping.java
@@ -18,8 +18,8 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalManyToOneMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalNoSqlJoinField;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/MappedSuperClassEntity.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/MappedSuperClassEntity.java
index ff64abc..415f621 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/MappedSuperClassEntity.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/MappedSuperClassEntity.java
@@ -31,10 +31,10 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalTransformationMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalVariableOneToOneMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalVersionMapping;
-import org.eclipse.persistence.tools.utility.Tools;
-import org.eclipse.persistence.tools.utility.iterables.EmptyListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.EmptyListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
@@ -394,27 +394,27 @@
 	Mapping buildMapping(String elementName, int index) {
 
 		// Embedded ID
-		if (Tools.valuesAreEqual(elementName, EmbeddedIDMapping.EMBEDDED_ID)) {
+		if (ObjectTools.equals(elementName, EmbeddedIDMapping.EMBEDDED_ID)) {
 			return buildEmbeddedIdMapping(index);
 		}
 
 		// ID
-		if (Tools.valuesAreEqual(elementName, IdMapping.ID)) {
+		if (ObjectTools.equals(elementName, IdMapping.ID)) {
 			return buildIdMapping(index);
 		}
 
 		// Transformation
-		if (Tools.valuesAreEqual(elementName, TransformationMapping.TRANSFORMATION)) {
+		if (ObjectTools.equals(elementName, TransformationMapping.TRANSFORMATION)) {
 			return buildTransformationMapping(index);
 		}
 
 		// Variable 1:1
-		if (Tools.valuesAreEqual(elementName, VariableOneToOneMapping.VARIABLE_ONE_TO_ONE)) {
+		if (ObjectTools.equals(elementName, VariableOneToOneMapping.VARIABLE_ONE_TO_ONE)) {
 			return buildVariableOneToOneMapping(index);
 		}
 
 		// Version
-		if (Tools.valuesAreEqual(elementName, VersionMapping.VERSION)) {
+		if (ObjectTools.equals(elementName, VersionMapping.VERSION)) {
 			return buildVersionMapping(index);
 		}
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Mapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Mapping.java
index 1eefe57..f2b6692 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Mapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Mapping.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -15,10 +15,9 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalMapping;
-import org.eclipse.persistence.tools.utility.ClassName;
-import org.eclipse.persistence.tools.utility.NameTools;
+import org.eclipse.persistence.tools.utility.ClassNameTools;
+import org.eclipse.persistence.tools.utility.StringTools;
 import org.w3c.dom.Element;
 
 /**
@@ -108,13 +107,13 @@
 	public final String getAttributeType() {
 		return getAttribute(ATTRIBUTE_TYPE);
 	}
-	
+
 	/**
 	 * {@inheritDoc}
 	 */
 	@Override
 	public final String getAttributeTypeShortName() {
-		return ClassName.getSimpleName(getAttributeType());
+		return ClassNameTools.simpleName(getAttributeType());
 	}
 
 	/**
@@ -131,13 +130,13 @@
 
 		return getChild(element, index);
 	}
-	
+
 	/**
 	 * {@inheritDoc}
 	 */
 	@Override
 	public final String getGetMethodName() {
-		return NameTools.javabeanAccessorName("get", getName(), "");
+		return javabeanAccessorName("get", getName(), StringTools.EMPTY_STRING);
 	}
 
 	/**
@@ -170,9 +169,9 @@
 	 */
 	@Override
 	public final String getSetMethodName() {
-		return NameTools.javabeanAccessorName("set", getName(), "");
+		return javabeanAccessorName("set", getName(), StringTools.EMPTY_STRING);
 	}
-	
+
 	/**
 	 * {@inheritDoc}
 	 */
@@ -180,7 +179,7 @@
 	public boolean isBasicMapping() {
 		return false;
 	}
-	
+
 	/**
 	 * {@inheritDoc}
 	 */
@@ -188,7 +187,7 @@
 	public boolean isElementCollectionMapping() {
 		return false;
 	}
-	
+
 	/**
 	 * {@inheritDoc}
 	 */
@@ -196,7 +195,7 @@
 	public boolean isEmbeddedMapping() {
 		return false;
 	}
-	
+
 	/**
 	 * {@inheritDoc}
 	 */
@@ -206,6 +205,40 @@
 	}
 
 	/**
+	 * Generates a JavaBean compliant method name based on the provided property name. Does not alter
+	 * the case of the property name if the second character is capitalized, e.g.:
+	 * <ul>
+	 *    <li>javabeanMethodName("get", "URL", "") produces "getURL"
+	 *    <li>javabeanMethodName("get", "fName", "") produces "getfName"
+	 *    <li>javabeanMethodName("get", "fname", "") produces "getFname"
+	 *    <li>javabeanMethodName("get", "firstName", "") produces "getFirstName"
+	 * </ul>
+	 *
+	 * The "fName" example in particular may seem strange, but is required by JDev ADF interpretation
+	 * of the JavaBean naming conventions.<p>
+	 * See bug #4572393.
+	 *
+	 * @param prefix <code>String</code> representing the prefix for the method name (for example,
+	 * "get" to produce a getter method)
+	 * @param propertyName <code>String</code> representing the name of the property for which an
+	 * accessor name is being generated
+	 * @param suffix <code>String</code> representing the suffix for the accessor being generated
+	 * (for example, "Holder" for ValueHolder accessors)
+	 */
+	private String javabeanAccessorName(String prefix, String propertyName, String suffix) {
+		StringBuilder sb = new StringBuilder(propertyName.length() + 10);
+		sb.append(prefix);
+		if (propertyName.length() >=  2 && Character.isUpperCase(propertyName.charAt(1))) {
+			sb.append(propertyName);
+		}
+		else {
+			sb.append(StringTools.capitalize(propertyName));
+		}
+		sb.append(suffix);
+		return sb.toString();
+	}
+
+	/**
 	 * {@inheritDoc}
 	 */
 	@Override
@@ -228,9 +261,9 @@
 	@Override
 	public void setAttributeType(String attributeType) {
 		setAttribute(ATTRIBUTE_TYPE, attributeType);
-		
+
 	}
-	
+
 	/**
 	 * {@inheritDoc}
 	 */
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/MultitenancyPolicy.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/MultitenancyPolicy.java
index 03e594a..5cfa678 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/MultitenancyPolicy.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/MultitenancyPolicy.java
@@ -18,8 +18,8 @@
 import org.eclipse.persistence.annotations.MultitenantType;
 import org.eclipse.persistence.tools.mapping.orm.ExternalMultitenancyPolicy;
 import org.eclipse.persistence.tools.mapping.orm.ExternalTenantDiscriminatorColumn;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NamedNativeQuery.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NamedNativeQuery.java
index 824d02c..e6e9e68 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NamedNativeQuery.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NamedNativeQuery.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalNativeQuery;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NamedQuery.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NamedQuery.java
index aed5994..1797bc4 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NamedQuery.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NamedQuery.java
@@ -16,7 +16,6 @@
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.LockModeType;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalBasicNamedQuery;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NamedStoredProcedureQuery.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NamedStoredProcedureQuery.java
index 9a7014a..30d9cae 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NamedStoredProcedureQuery.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NamedStoredProcedureQuery.java
@@ -15,11 +15,10 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalStoredProcedureParameter;
 import org.eclipse.persistence.tools.mapping.orm.ExternalStoredProcedureQuery;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NonTransientMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NonTransientMapping.java
index c017854..5fef92d 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NonTransientMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/NonTransientMapping.java
@@ -16,12 +16,11 @@
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.AccessType;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalAccessMethods;
 import org.eclipse.persistence.tools.mapping.orm.ExternalNonTransientMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalProperty;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ORMConfiguration.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ORMConfiguration.java
index a70fd27..3477db6 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ORMConfiguration.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ORMConfiguration.java
@@ -23,7 +23,6 @@
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalBasicNamedQuery;
 import org.eclipse.persistence.tools.mapping.orm.ExternalConverter;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddableEntity;
@@ -42,14 +41,14 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalTenantDiscriminatorColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalTypeConverter;
 import org.eclipse.persistence.tools.mapping.orm.ORMDocumentType;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.Tools;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.*;
+import static org.eclipse.persistence.tools.mapping.orm.XmlConstants.*;
 
 /**
  * The external form interacting with the XML document for the ORM Configuration file.
@@ -58,7 +57,7 @@
  * @author Les Davis
  * @author Pascal Filion
  */
-@SuppressWarnings("nls")
+@SuppressWarnings({"nls", "unused"}) // unused used for the import statement: see bug 330740
 final class ORMConfiguration extends AbstractExternalForm
                              implements ExternalORMConfiguration {
 
@@ -134,7 +133,7 @@
 		entity.addSelf();
 		entity.setClassName(className);
 	}
-	
+
 	/**
 	 * {@inheritDoc}
 	 */
@@ -143,7 +142,7 @@
 		EmbeddableEntity entity = buildEmbeddableEntity(embeddableEntitiesSize());
 		entity.addSelf();
 		entity.setClassName(className);
-		
+
 		return entity;
 	}
 
@@ -162,13 +161,11 @@
 	 */
 	@Override
 	public ExternalEntity addEntity(String entityClassName) {
-		if (entityClassName == null) {
-			System.err.println();
-		}
+
 		Entity entity = buildEntity(entitiesSize());
 		entity.addSelf();
 		entity.setClassName(entityClassName);
-		
+
 		return entity;
 	}
 
@@ -200,7 +197,6 @@
 		NamedQuery namedQuery = buildNamedQuery(index);
 		namedQuery.addSelf();
 		namedQuery.setName(name);
-
 		return namedQuery;
 	}
 
@@ -212,7 +208,6 @@
 		NamedQuery namedQuery = buildNamedQuery(namedQueriesSize());
 		namedQuery.addSelf();
 		namedQuery.setName(name);
-
 		return namedQuery;
 	}
 
@@ -242,10 +237,10 @@
 
 		Document document = getDocument();
 
-		Element element = document.createElementNS(ORM_NAMESPACE_URI, elementName);
+		Element element = document.createElementNS(ECLIPSELINK_ORM_NAMESPACE_URI, elementName);
 		element.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", ECLIPSELINK_ORM_NAMESPACE_URI);
 		addXmlns(element, "xsi", XSI_URI);
-		element.setAttributeNS(XSI_URI, XSD_URI_ATTRIBUTE, buildSchemaLocation(ORMDocumentType.ECLIPELINK_2_4));
+		element.setAttributeNS(XSI_URI, XSD_URI_ATTRIBUTE, buildSchemaLocation(ORMDocumentType.ECLIPELINK_2_5));
 		element.setAttribute(VERSION, getBuildVersion());
 
 		document.appendChild(element);
@@ -636,19 +631,17 @@
 
 		return buildEntity(index);
 	}
-	
+
 	@Override
 	public ExternalEntity getEntity(String className) {
 		for (ExternalEntity entity : entities()) {
-			if (StringTools.stringsAreEqual(entity.getClassName(), className)) {
+			if (ObjectTools.equals(entity.getClassName(), className)) {
 				return entity;
 			}
 		}
-		
+
 		return null;
 	}
-	
-	
 
 	/**
 	 * {@inheritDoc}
@@ -811,7 +804,7 @@
 			return null;
 		}
 
-		if (Tools.valuesAreDifferent(name, storedProcedureQuery.getName())) {
+		if (ObjectTools.notEquals(name, storedProcedureQuery.getName())) {
 			storedProcedureQuery = null;
 		}
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ORMRepository.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ORMRepository.java
index 85ed667..feed239 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ORMRepository.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ORMRepository.java
@@ -14,10 +14,8 @@
 package org.eclipse.persistence.tools.mapping.orm.dom;
 
 import java.io.ByteArrayInputStream;
-
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalORMConfiguration;
 import org.eclipse.persistence.tools.mapping.orm.ExternalORMRepository;
 import org.eclipse.persistence.tools.mapping.orm.ORMDocumentType;
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ObjectCollectionMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ObjectCollectionMapping.java
index 300e4da..a9af6cc 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ObjectCollectionMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ObjectCollectionMapping.java
@@ -17,15 +17,14 @@
 import java.util.List;
 import javax.persistence.EnumType;
 import javax.persistence.TemporalType;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalAssociationOverride;
 import org.eclipse.persistence.tools.mapping.orm.ExternalAttributeOverride;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalObjectCollectionMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalOrderColumn;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ObjectTypeConverter.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ObjectTypeConverter.java
index cff38f1..ac7abb3 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ObjectTypeConverter.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ObjectTypeConverter.java
@@ -15,11 +15,10 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalConversionValue;
 import org.eclipse.persistence.tools.mapping.orm.ExternalObjectTypeConverter;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToManyMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToManyMapping.java
index 617c846..c3f5eb8 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToManyMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToManyMapping.java
@@ -18,8 +18,8 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalNoSqlJoinField;
 import org.eclipse.persistence.tools.mapping.orm.ExternalOneToManyMapping;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToOneMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToOneMapping.java
index e52a8b8..a2bc9e9 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToOneMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToOneMapping.java
@@ -19,8 +19,8 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalNoSqlJoinField;
 import org.eclipse.persistence.tools.mapping.orm.ExternalOneToOneMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalPrimaryKeyJoinColumn;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OptimisticLocking.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OptimisticLocking.java
index cf1d6de..8773d99 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OptimisticLocking.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OptimisticLocking.java
@@ -18,8 +18,8 @@
 import org.eclipse.persistence.annotations.OptimisticLockingType;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalOptimisticLocking;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OrderColumn.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OrderColumn.java
index 1f5140b..ed53354 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OrderColumn.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OrderColumn.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalOrderColumn;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PersistenceUnit.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PersistenceUnit.java
index 95935f1..6e2488b 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PersistenceUnit.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PersistenceUnit.java
@@ -16,12 +16,11 @@
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.AccessType;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityListener;
 import org.eclipse.persistence.tools.mapping.orm.ExternalPersistenceUnit;
 import org.eclipse.persistence.tools.mapping.orm.ExternalTenantDiscriminatorColumn;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PrimaryKey.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PrimaryKey.java
index 2b5c8c9..6ee76d9 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PrimaryKey.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PrimaryKey.java
@@ -19,8 +19,8 @@
 import org.eclipse.persistence.annotations.IdValidation;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalPrimaryKey;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PrimaryKeyGenerator.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PrimaryKeyGenerator.java
index e74c0a0..a354b0c 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PrimaryKeyGenerator.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PrimaryKeyGenerator.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalPrimaryKeyGenerator;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PrimaryKeyJoinColumn.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PrimaryKeyJoinColumn.java
index d9daf3c..6572d66 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PrimaryKeyJoinColumn.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/PrimaryKeyJoinColumn.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalPrimaryKeyJoinColumn;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Property.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Property.java
index 68e339b..6f567c2 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Property.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Property.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalProperty;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Query.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Query.java
index 48e70fb..f89885b 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Query.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Query.java
@@ -15,11 +15,10 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalNamedQuery;
 import org.eclipse.persistence.tools.mapping.orm.ExternalQueryHint;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/QueryHint.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/QueryHint.java
index f921470..5afe087 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/QueryHint.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/QueryHint.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalQueryHint;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/RelationshipMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/RelationshipMapping.java
index dd5325e..08ce5f7 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/RelationshipMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/RelationshipMapping.java
@@ -21,10 +21,10 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalBatchFetch;
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinTable;
 import org.eclipse.persistence.tools.mapping.orm.ExternalRelationshipMapping;
-import org.eclipse.persistence.tools.utility.Tools;
-import org.eclipse.persistence.tools.utility.iterables.EmptyListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.EmptyListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
@@ -187,27 +187,27 @@
 
 		String elementName = getNodeName(element);
 
-		if (Tools.valuesAreEqual(elementName, CASCADE_ALL)) {
+		if (ObjectTools.equals(elementName, CASCADE_ALL)) {
 			return CascadeType.ALL;
 		}
 
-		if (Tools.valuesAreEqual(elementName, CASCADE_DETACH)) {
+		if (ObjectTools.equals(elementName, CASCADE_DETACH)) {
 			return CascadeType.DETACH;
 		}
 
-		if (Tools.valuesAreEqual(elementName, CASCADE_MERGE)) {
+		if (ObjectTools.equals(elementName, CASCADE_MERGE)) {
 			return CascadeType.MERGE;
 		}
 
-		if (Tools.valuesAreEqual(elementName, CASCADE_PERSIST)) {
+		if (ObjectTools.equals(elementName, CASCADE_PERSIST)) {
 			return CascadeType.PERSIST;
 		}
 
-		if (Tools.valuesAreEqual(elementName, CASCADE_REFRESH)) {
+		if (ObjectTools.equals(elementName, CASCADE_REFRESH)) {
 			return CascadeType.REFRESH;
 		}
 
-		if (Tools.valuesAreEqual(elementName, CASCADE_REMOVE)) {
+		if (ObjectTools.equals(elementName, CASCADE_REMOVE)) {
 			return CascadeType.REMOVE;
 		}
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/SQLResultSetMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/SQLResultSetMapping.java
index 25c52d8..842c10c 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/SQLResultSetMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/SQLResultSetMapping.java
@@ -15,12 +15,11 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalColumnResult;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityResult;
 import org.eclipse.persistence.tools.mapping.orm.ExternalSQLResultSetMapping;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/SecondaryTable.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/SecondaryTable.java
index 129401d..4ff630e 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/SecondaryTable.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/SecondaryTable.java
@@ -15,11 +15,10 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntitySecondaryTable;
 import org.eclipse.persistence.tools.mapping.orm.ExternalPrimaryKeyJoinColumn;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/SequenceGenerator.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/SequenceGenerator.java
index b45ca17..24835b0 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/SequenceGenerator.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/SequenceGenerator.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalSequenceGenerator;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/StructConverter.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/StructConverter.java
index 9dd9bac..8f331fe 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/StructConverter.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/StructConverter.java
@@ -14,7 +14,6 @@
 package org.eclipse.persistence.tools.mapping.orm.dom;
 
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalStructConverter;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Table.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Table.java
index 36de5a3..ea52519 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Table.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Table.java
@@ -16,11 +16,10 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.ListIterator;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityTable;
 import org.eclipse.persistence.tools.mapping.orm.ExternalUniqueConstraint;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TableGenerator.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TableGenerator.java
index f8ca7e6..5bc9371 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TableGenerator.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TableGenerator.java
@@ -16,11 +16,10 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.ListIterator;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalTableGenerator;
 import org.eclipse.persistence.tools.mapping.orm.ExternalUniqueConstraint;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TenantDiscriminatorColumn.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TenantDiscriminatorColumn.java
index 2dfb311..dda83a1 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TenantDiscriminatorColumn.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TenantDiscriminatorColumn.java
@@ -14,7 +14,6 @@
 package org.eclipse.persistence.tools.mapping.orm.dom;
 
 import javax.persistence.DiscriminatorType;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalTenantDiscriminatorColumn;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TimeOfDay.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TimeOfDay.java
index 7f7fb95..e8bf0bd 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TimeOfDay.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TimeOfDay.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalTimeOfDay;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TransformationMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TransformationMapping.java
index 9082aaf..83642f6 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TransformationMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TransformationMapping.java
@@ -16,12 +16,11 @@
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.FetchType;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalTransformationMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalTransformer;
 import org.eclipse.persistence.tools.mapping.orm.ExternalWriteTransformer;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Transformer.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Transformer.java
index 2ab26dd..0f252b7 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Transformer.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Transformer.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalTransformer;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TypeConverter.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TypeConverter.java
index 3303a5d..6868b22 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TypeConverter.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TypeConverter.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalTypeConverter;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/UniqueConstraint.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/UniqueConstraint.java
index 84b995e..900e4d4 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/UniqueConstraint.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/UniqueConstraint.java
@@ -15,10 +15,9 @@
 
 import java.util.List;
 import java.util.ListIterator;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalUniqueConstraint;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/VariableOneToOneMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/VariableOneToOneMapping.java
index eef2120..15c1a4d 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/VariableOneToOneMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/VariableOneToOneMapping.java
@@ -17,15 +17,14 @@
 import java.util.List;
 import javax.persistence.CascadeType;
 import javax.persistence.FetchType;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalDiscriminatorClass;
 import org.eclipse.persistence.tools.mapping.orm.ExternalDiscriminatorColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalVariableOneToOneMapping;
-import org.eclipse.persistence.tools.utility.Tools;
-import org.eclipse.persistence.tools.utility.iterables.EmptyListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.EmptyListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Element;
 
 /**
@@ -230,27 +229,27 @@
 
 		String elementName = getNodeName(element);
 
-		if (Tools.valuesAreEqual(elementName, CASCADE_ALL)) {
+		if (ObjectTools.equals(elementName, CASCADE_ALL)) {
 			return CascadeType.ALL;
 		}
 
-		if (Tools.valuesAreEqual(elementName, CASCADE_MERGE)) {
+		if (ObjectTools.equals(elementName, CASCADE_MERGE)) {
 			return CascadeType.MERGE;
 		}
 
-		if (Tools.valuesAreEqual(elementName, CASCADE_DETACH)) {
+		if (ObjectTools.equals(elementName, CASCADE_DETACH)) {
 			return CascadeType.DETACH;
 		}
 
-		if (Tools.valuesAreEqual(elementName, CASCADE_PERSIST)) {
+		if (ObjectTools.equals(elementName, CASCADE_PERSIST)) {
 			return CascadeType.PERSIST;
 		}
 
-		if (Tools.valuesAreEqual(elementName, CASCADE_REFRESH)) {
+		if (ObjectTools.equals(elementName, CASCADE_REFRESH)) {
 			return CascadeType.REFRESH;
 		}
 
-		if (Tools.valuesAreEqual(elementName, CASCADE_REMOVE)) {
+		if (ObjectTools.equals(elementName, CASCADE_REMOVE)) {
 			return CascadeType.REMOVE;
 		}
 
@@ -319,8 +318,8 @@
 		for (int index = count; --index >= 0;) {
 			ExternalDiscriminatorClass discriminatorClass = buildDiscriminatorClass(index);
 
-			if (Tools.valuesAreEqual(discriminator, discriminatorClass.getDiscriminator()) &&
-			    Tools.valuesAreEqual(value, discriminatorClass.getValue())) {
+			if (ObjectTools.equals(discriminator, discriminatorClass.getDiscriminator()) &&
+			    ObjectTools.equals(value, discriminatorClass.getValue())) {
 
 				return discriminatorClass;
 			}
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/WriteTransfomer.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/WriteTransfomer.java
index 3a0723b..316a60c 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/WriteTransfomer.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/WriteTransfomer.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalWriteTransformer;
 import org.w3c.dom.Element;
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/ExternalPersistenceConfiguration.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/ExternalPersistenceConfiguration.java
index e2b3613..9cfa4ce 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/ExternalPersistenceConfiguration.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/ExternalPersistenceConfiguration.java
Binary files differ
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/ExternalPersistenceUnit.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/ExternalPersistenceUnit.java
index 2259b06..ed3380a 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/ExternalPersistenceUnit.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/ExternalPersistenceUnit.java
Binary files differ
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/PersistenceDocumentType.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/PersistenceDocumentType.java
index fddbf74..3a7aa0b 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/PersistenceDocumentType.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/PersistenceDocumentType.java
@@ -15,7 +15,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.eclipse.persistence.tools.utility.StringTools;
 
 import static org.eclipse.persistence.tools.mapping.orm.XmlConstants.*;
@@ -109,9 +108,9 @@
 
 		for (PersistenceDocumentType type : types()) {
 
-			if (StringTools.stringsAreEqualIgnoreCase(schemaURI, type.schemaURI) ||
-			    (StringTools.stringsAreEqualIgnoreCase(type.xmlNamespace, xmlNamespace) &&
-			     StringTools.stringsAreEqualIgnoreCase(type.version, version))) {
+			if (StringTools.equalsIgnoreCase(schemaURI, type.schemaURI) ||
+			   (StringTools.equalsIgnoreCase(type.xmlNamespace, xmlNamespace) &&
+			    StringTools.equalsIgnoreCase(type.version, version))) {
 
 				return type;
 			}
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/dom/PersistenceConfiguration.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/dom/PersistenceConfiguration.java
index b07f24e..f1ef664 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/dom/PersistenceConfiguration.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/dom/PersistenceConfiguration.java
@@ -20,8 +20,8 @@
 import org.eclipse.persistence.tools.mapping.persistence.ExternalPersistenceConfiguration;
 import org.eclipse.persistence.tools.mapping.persistence.ExternalPersistenceUnit;
 import org.eclipse.persistence.tools.mapping.persistence.PersistenceDocumentType;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/dom/PersistenceRepository.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/dom/PersistenceRepository.java
index d97722a..bed73ce 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/dom/PersistenceRepository.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/dom/PersistenceRepository.java
Binary files differ
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/dom/PersistenceUnit.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/dom/PersistenceUnit.java
index f724504..7ea1ae5 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/dom/PersistenceUnit.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/persistence/dom/PersistenceUnit.java
Binary files differ
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/.classpath b/tools/org.eclipse.persistence.tools.utility.tests/.classpath
index d1f977c..9a48164 100644
--- a/tools/org.eclipse.persistence.tools.utility.tests/.classpath
+++ b/tools/org.eclipse.persistence.tools.utility.tests/.classpath
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="UTF-8"?>

-<classpath>

-	<classpathentry kind="src" path="src"/>

-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>

-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

-	<classpathentry kind="output" path="build/classes"/>

-</classpath>

+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="build/classes"/>
+</classpath>
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/.settings/org.eclipse.jdt.core.prefs b/tools/org.eclipse.persistence.tools.utility.tests/.settings/org.eclipse.jdt.core.prefs
index 8000cd6..54e493c 100644
--- a/tools/org.eclipse.persistence.tools.utility.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/tools/org.eclipse.persistence.tools.utility.tests/.settings/org.eclipse.jdt.core.prefs
@@ -1,11 +1,11 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.6
+eclipse.preferences.version=1

+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled

+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6

+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve

+org.eclipse.jdt.core.compiler.compliance=1.6

+org.eclipse.jdt.core.compiler.debug.lineNumber=generate

+org.eclipse.jdt.core.compiler.debug.localVariable=generate

+org.eclipse.jdt.core.compiler.debug.sourceFile=generate

+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

+org.eclipse.jdt.core.compiler.source=1.6

diff --git a/tools/org.eclipse.persistence.tools.utility.tests/CommonUtilityTests.launch b/tools/org.eclipse.persistence.tools.utility.tests/CommonUtilityTests.launch
index 960669e..17156e4 100644
--- a/tools/org.eclipse.persistence.tools.utility.tests/CommonUtilityTests.launch
+++ b/tools/org.eclipse.persistence.tools.utility.tests/CommonUtilityTests.launch
@@ -1,22 +1,22 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/CommonUtilityTests.java"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="1"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/>
-<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
-<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
-<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
-<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/>
-<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER&quot; javaProject=&quot;org.eclipse.persistence.tools.utility.tests&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;org.eclipse.persistence.tools.utility.tests&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;org.eclipse.persistence.tools.utility&quot; type=&quot;1&quot;/&gt;&#13;&#10;"/>
-</listAttribute>
-<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.persistence.tools.utility.tests.internal.CommonUtilityTests"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.persistence.tools.utility.tests"/>
-</launchConfiguration>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>

+<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">

+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">

+<listEntry value="/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CommonUtilityTests.java"/>

+</listAttribute>

+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">

+<listEntry value="1"/>

+</listAttribute>

+<stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/>

+<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>

+<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>

+<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>

+<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/>

+<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">

+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER&quot; javaProject=&quot;org.eclipse.persistence.tools.utility.tests&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>

+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;org.eclipse.persistence.tools.utility.tests&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/>

+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;org.eclipse.persistence.tools.utility&quot; type=&quot;1&quot;/&gt;&#13;&#10;"/>

+</listAttribute>

+<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>

+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.persistence.tools.utility.tests.CommonUtilityTests"/>

+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.persistence.tools.utility.tests"/>

+</launchConfiguration>

diff --git a/tools/org.eclipse.persistence.tools.utility.tests/META-INF/MANIFEST.MF b/tools/org.eclipse.persistence.tools.utility.tests/META-INF/MANIFEST.MF
index 654b616..8e995f3 100644
--- a/tools/org.eclipse.persistence.tools.utility.tests/META-INF/MANIFEST.MF
+++ b/tools/org.eclipse.persistence.tools.utility.tests/META-INF/MANIFEST.MF
@@ -1,13 +1,22 @@
 Manifest-Version: 1.0

-Export-Package: org.eclipse.persistence.tools.utility.tests.internal;x-internal:=true,

- org.eclipse.persistence.tools.utility.tests.internal.command;x-internal:=true,

- org.eclipse.persistence.tools.utility.tests.internal.enumerations;x-internal:=true,

- org.eclipse.persistence.tools.utility.tests.internal.iterables;x-internal:=true,

- org.eclipse.persistence.tools.utility.tests.internal.iterators;x-internal:=true,

- org.eclipse.persistence.tools.utility.tests.internal.model;x-internal:=true,

- org.eclipse.persistence.tools.utility.tests.internal.model.listener;x-internal:=true,

- org.eclipse.persistence.tools.utility.tests.internal.node;x-internal:=true,

- org.eclipse.persistence.tools.utility.tests.internal.synchronizers;x-internal:=true

+Export-Package: org.eclipse.persistence.tools.utility.tests,

+ org.eclipse.persistence.tools.utility.tests.collection,

+ org.eclipse.persistence.tools.utility.tests.command,

+ org.eclipse.persistence.tools.utility.tests.enumeration,

+ org.eclipse.persistence.tools.utility.tests.filter,

+ org.eclipse.persistence.tools.utility.tests.io,

+ org.eclipse.persistence.tools.utility.tests.iterable,

+ org.eclipse.persistence.tools.utility.tests.iterator,

+ org.eclipse.persistence.tools.utility.tests.jdbc,

+ org.eclipse.persistence.tools.utility.tests.model,

+ org.eclipse.persistence.tools.utility.tests.model.listener,

+ org.eclipse.persistence.tools.utility.tests.model.value,

+ org.eclipse.persistence.tools.utility.tests.model.value.prefs,

+ org.eclipse.persistence.tools.utility.tests.model.value.swing,

+ org.eclipse.persistence.tools.utility.tests.node,

+ org.eclipse.persistence.tools.utility.tests.reference,

+ org.eclipse.persistence.tools.utility.tests.swing,

+ org.eclipse.persistence.tools.utility.tests.transformer

 Bundle-RequiredExecutionEnvironment: JavaSE-1.6

 Require-Bundle: org.eclipse.persistence.tools.utility;bundle-version="2.5.0",

  org.junit;bundle-version="[4.0.0,5.0.0)"

diff --git a/tools/org.eclipse.persistence.tools.utility.tests/pom.xml b/tools/org.eclipse.persistence.tools.utility.tests/pom.xml
index 3eb6520..c161060 100644
--- a/tools/org.eclipse.persistence.tools.utility.tests/pom.xml
+++ b/tools/org.eclipse.persistence.tools.utility.tests/pom.xml
@@ -16,4 +16,18 @@
         <relativePath>../org.eclipse.persistence.tools.parent/pom.xml</relativePath>
     </parent>
 
+    <build>
+	   <plugins>
+	      <plugin>
+	         <groupId>org.eclipse.tycho</groupId>
+	         <artifactId>tycho-compiler-plugin</artifactId>
+	         <version>${tycho.version}</version>
+	         <configuration>
+	         	<!-- Remove the restriction to access restricted classes, such as Swing classes. -->
+	           <compilerArgument>-err:-forbidden</compilerArgument>
+	         </configuration>
+	       </plugin> 
+	    </plugins>
+    </build>
+
 </project>
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ArrayToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ArrayToolsTests.java
new file mode 100644
index 0000000..4fc5222
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ArrayToolsTests.java
@@ -0,0 +1,3694 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.ClassTools;
+import org.eclipse.persistence.tools.utility.Range;
+import org.eclipse.persistence.tools.utility.ReverseComparator;
+import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.command.InterruptibleParameterizedCommandAdapter;
+import org.eclipse.persistence.tools.utility.command.ParameterizedCommandAdapter;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.filter.FilterAdapter;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+import org.eclipse.persistence.tools.utility.transformer.TransformerAdapter;
+
+@SuppressWarnings("nls")
+public class ArrayToolsTests
+	extends TestCase
+{
+	public ArrayToolsTests(String name) {
+		super(name);
+	}
+
+	// ********** instantiation **********
+
+	public void testNewInstanceObjectArray() {
+		String[] array1 = new String[2];
+		String[] array2 = ArrayTools.newInstance(array1);
+		array2[0] = "foo";
+		array2[1] = "bar";
+		assertEquals(String.class, array2.getClass().getComponentType());
+		assertEquals(2, array2.length);
+	}
+
+	public void testNewInstanceObjectArrayInt() {
+		String[] array1 = new String[2];
+		String[] array2 = ArrayTools.newInstance(array1, 5);
+		array2[0] = "foo";
+		array2[4] = "bar";
+		assertEquals(String.class, array2.getClass().getComponentType());
+		assertEquals(5, array2.length);
+	}
+
+	public void testNewInstanceObjectArrayInt_Exception() {
+		String[] array1 = new String[2];
+		Object[] array2 = ArrayTools.newInstance(array1, 5);
+		boolean exCaught = false;
+		try {
+			array2[1] = Integer.valueOf(7);
+			fail("bogus array: " + Arrays.toString(array2));
+		} catch (ArrayStoreException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testNewInstanceClassInt() {
+		String[] array = ArrayTools.newInstance(String.class, 5);
+		array[0] = "foo";
+		array[4] = "bar";
+		assertEquals(String.class, array.getClass().getComponentType());
+		assertEquals(5, array.length);
+	}
+
+	public void testNewInstanceClassInt_Exception() {
+		Object[] array = ArrayTools.newInstance(String.class, 5);
+		boolean exCaught = false;
+		try {
+			array[1] = Integer.valueOf(7);
+			fail("bogus array: " + Arrays.toString(array));
+		} catch (ArrayStoreException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testNewInstanceClassInt_Primitive() {
+		boolean exCaught = false;
+		try {
+			Object[] array = ArrayTools.newInstance(int.class, 5);
+			fail("bogus array: " + Arrays.toString(array));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testNewInstanceClassInt_Super() {
+		Number[] array = ArrayTools.newInstance(Integer.class, 5);
+		Class<?> javaClass = array.getClass().getComponentType();
+		assertFalse(javaClass == Number.class);
+		assertTrue(javaClass == Integer.class);
+	}
+
+
+	// ********** factory methods **********
+
+	public void testArrayIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		Object[] a = ArrayTools.array(iterable);
+		assertEquals(3, a.length);
+		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
+	}
+
+	public void testArrayIterableInt() {
+		Iterable<String> iterable = this.buildStringList1();
+		Object[] a = ArrayTools.array(iterable, 3);
+		assertEquals(3, a.length);
+		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
+	}
+
+	public void testArrayIterableObjectArray_String() {
+		Iterable<String> iterable = this.buildStringList1();
+		String[] a = ArrayTools.array(iterable, new String[0]);
+		assertEquals(3, a.length);
+		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
+	}
+
+	public void testArrayIterableObjectArray_Object() {
+		Iterable<String> iterable = this.buildStringList1();
+		Object[] a = ArrayTools.array(iterable, new Object[0]);
+		assertEquals(3, a.length);
+		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
+	}
+
+	public void testArrayIterableIntObjectArray() {
+		Iterable<String> iterable = this.buildStringList1();
+		String[] a = ArrayTools.array(iterable, 3, new String[0]);
+		assertEquals(3, a.length);
+		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
+	}
+
+	public void testArrayIterator() {
+		Object[] a = ArrayTools.array(this.buildStringList1().iterator());
+		assertEquals(3, a.length);
+		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
+	}
+
+	public void testArrayIterator_Empty() {
+		Object[] a = ArrayTools.array(EmptyIterator.instance());
+		assertEquals(0, a.length);
+	}
+
+	public void testArrayIteratorInt() {
+		Object[] a = ArrayTools.array(this.buildStringList1().iterator(), 3);
+		assertEquals(3, a.length);
+		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
+	}
+
+	public void testArrayIteratorInt_Empty() {
+		Object[] a = ArrayTools.array(EmptyIterator.instance(), 3);
+		assertEquals(0, a.length);
+	}
+
+	public void testArrayIteratorObjectArray_String() {
+		String[] a = ArrayTools.array(this.buildStringList1().iterator(), new String[0]);
+		assertEquals(3, a.length);
+		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
+	}
+
+	public void testArrayIteratorObjectArray_Empty() {
+		String[] a = ArrayTools.array(EmptyIterator.<String>instance(), new String[0]);
+		assertEquals(0, a.length);
+	}
+
+	public void testArrayIteratorObjectArray_Empty_ClearArray() {
+		String[] a = ArrayTools.array(EmptyIterator.<String>instance(), new String[5]);
+		assertEquals(5, a.length);
+		assertNull(a[0]);
+	}
+
+	public void testArrayIteratorObjectArray_Object() {
+		Object[] a = ArrayTools.array(this.buildStringList1().iterator(), new Object[0]);
+		assertEquals(3, a.length);
+		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
+	}
+
+	public void testArrayIteratorIntObjectArray() {
+		String[] a = ArrayTools.array(this.buildStringList1().iterator(), 3, new String[0]);
+		assertEquals(3, a.length);
+		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
+	}
+
+	public void testArrayIteratorIntObjectArray_Empty() {
+		String[] a = ArrayTools.array(EmptyIterator.<String>instance(), 3, new String[0]);
+		assertEquals(0, a.length);
+	}
+
+
+	// ********** add **********
+
+	public void testAddObjectArrayObject_Object() {
+		Object[] a = ArrayTools.add(this.buildObjectArray1(), "twenty");
+		assertEquals(4, a.length);
+		assertTrue(ArrayTools.contains(a, "twenty"));
+		assertEquals("twenty", a[a.length-1]);
+	}
+
+	public void testAddObjectArrayObject_String() {
+		String[] a = ArrayTools.add(this.buildStringArray1(), "twenty");
+		assertEquals(4, a.length);
+		assertTrue(ArrayTools.contains(a, "twenty"));
+		assertEquals("twenty", a[a.length-1]);
+	}
+
+	public void testAddObjectArrayObject_EmptyArray() {
+		String[] a = new String[0];
+		a = ArrayTools.add(a, "twenty");
+		assertEquals(1, a.length);
+		assertTrue(ArrayTools.contains(a, "twenty"));
+		assertEquals("twenty", a[0]);
+	}
+
+	public void testAddObjectArrayIntObject_Object() {
+		Object[] a = new Object[] { "a", "b", "c", "d" };
+		a = ArrayTools.add(a, 2, "X");
+		assertEquals(5, a.length);
+		assertTrue(ArrayTools.contains(a, "X"));
+		assertTrue(Arrays.equals(new Object[] { "a", "b", "X", "c", "d" }, a));
+	}
+
+	public void testAddObjectArrayIntObject_String() {
+		String[] a = new String[] { "a", "b", "c", "d" };
+		a = ArrayTools.add(a, 2, "X");
+		assertEquals(5, a.length);
+		assertTrue(ArrayTools.contains(a, "X"));
+		assertTrue(Arrays.equals(new String[] { "a", "b", "X", "c", "d" }, a));
+	}
+
+	public void testAddObjectArrayIntObject_End() {
+		String[] a = new String[] { "a", "b", "c", "d" };
+		a = ArrayTools.add(a, 4, "X");
+		assertEquals(5, a.length);
+		assertTrue(ArrayTools.contains(a, "X"));
+		assertTrue(Arrays.equals(new String[] { "a", "b", "c", "d", "X" }, a));
+	}
+
+	public void testAddObjectArrayIntObject_Zero() {
+		String[] a = new String[] { "a", "b", "c", "d" };
+		a = ArrayTools.add(a, 0, "X");
+		assertEquals(5, a.length);
+		assertTrue(ArrayTools.contains(a, "X"));
+		assertTrue(Arrays.equals(new String[] { "X", "a", "b", "c", "d" }, a));
+	}
+
+	public void testAddObjectArrayIntObject_Exception() {
+		Object[] a = new Object[] { "a", "b", "c", "d" };
+		boolean exCaught = false;
+		try {
+			a = ArrayTools.add(a, 33, "X");
+		} catch (IndexOutOfBoundsException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddCharArrayChar() {
+		char[] a = ArrayTools.add(this.buildCharArray(), 'd');
+		assertEquals(4, a.length);
+		assertTrue(ArrayTools.contains(a, 'd'));
+	}
+
+	public void testAddCharArrayChar_Empty() {
+		char[] a = new char[0];
+		a = ArrayTools.add(a, 'd');
+		assertEquals(1, a.length);
+		assertTrue(ArrayTools.contains(a, 'd'));
+		assertTrue(Arrays.equals(new char[] { 'd' }, a));
+	}
+
+	public void testAddCharArrayIntChar() {
+		char[] a = new char[] { 'a', 'b', 'c', 'd' };
+		a = ArrayTools.add(a, 2, 'X');
+		assertEquals(5, a.length);
+		assertTrue(ArrayTools.contains(a, 'X'));
+		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'X', 'c', 'd' }, a));
+	}
+
+	public void testAddCharArrayIntChar_Zero() {
+		char[] a = new char[] { 'a', 'b', 'c', 'd' };
+		a = ArrayTools.add(a, 0, 'X');
+		assertEquals(5, a.length);
+		assertTrue(ArrayTools.contains(a, 'X'));
+		assertTrue(Arrays.equals(new char[] { 'X', 'a', 'b', 'c', 'd' }, a));
+	}
+
+	public void testAddCharArrayIntChar_End() {
+		char[] a = new char[] { 'a', 'b', 'c', 'd' };
+		a = ArrayTools.add(a, 4, 'X');
+		assertEquals(5, a.length);
+		assertTrue(ArrayTools.contains(a, 'X'));
+		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'c', 'd', 'X' }, a));
+	}
+
+	public void testAddIntArrayInt() {
+		int[] a = ArrayTools.add(this.buildIntArray(), 30);
+		assertEquals(4, a.length);
+		assertTrue(ArrayTools.contains(a, 30));
+	}
+
+	public void testAddIntArrayInt_Empty() {
+		int[] a = new int[0];
+		a = ArrayTools.add(a, 30);
+		assertEquals(1, a.length);
+		assertTrue(ArrayTools.contains(a, 30));
+		assertTrue(Arrays.equals(new int[] { 30 }, a));
+	}
+
+	public void testAddIntArrayIntInt() {
+		int[] a = new int[] { 1, 2, 3, 4 };
+		a = ArrayTools.add(a, 2, 99);
+		assertEquals(5, a.length);
+		assertTrue(ArrayTools.contains(a, 99));
+		assertTrue(Arrays.equals(new int[] { 1, 2, 99, 3, 4 }, a));
+	}
+
+	public void testAddIntArrayIntInt_Zero() {
+		int[] a = new int[] { 1, 2, 3, 4 };
+		a = ArrayTools.add(a, 0, 99);
+		assertEquals(5, a.length);
+		assertTrue(ArrayTools.contains(a, 99));
+		assertTrue(Arrays.equals(new int[] { 99, 1, 2, 3, 4 }, a));
+	}
+
+	public void testAddIntArrayIntInt_End() {
+		int[] a = new int[] { 1, 2, 3, 4 };
+		a = ArrayTools.add(a, 4, 99);
+		assertEquals(5, a.length);
+		assertTrue(ArrayTools.contains(a, 99));
+		assertTrue(Arrays.equals(new int[] { 1, 2, 3, 4, 99 }, a));
+	}
+
+
+	// ********** add all **********
+
+	public void testAddAllObjectArrayCollection_String() {
+		String[] a = this.buildStringArray1();
+		Collection<String> c = this.buildStringList2();
+		String[] newArray = ArrayTools.addAll(a, c);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, c));
+	}
+
+	public void testAddAllObjectArrayCollection_Object() {
+		Object[] a = this.buildObjectArray1();
+		Collection<String> c = this.buildStringList2();
+		Object[] newArray = ArrayTools.addAll(a, c);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, c));
+	}
+
+	public void testAddAllObjectArrayCollection_EmptyArray() {
+		String[] a = new String[0];
+		Collection<String> c = this.buildStringList2();
+		String[] newArray = ArrayTools.addAll(a, c);
+
+		assertEquals(3, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, c));
+	}
+
+	public void testAddAllObjectArrayCollection_EmptyCollection() {
+		String[] a = this.buildStringArray1();
+		Collection<String> c = new ArrayList<String>();
+		String[] newArray = ArrayTools.addAll(a, c);
+
+		assertEquals(3, newArray.length);
+	}
+
+	public void testAddAllObjectArrayIntCollection_String() {
+		String[] a = this.buildStringArray1();
+		Collection<String> c = this.buildStringList2();
+		String[] newArray = ArrayTools.addAll(a, 1, c);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, c));
+	}
+
+	public void testAddAllObjectArrayIntCollection_String_End() {
+		String[] a = this.buildStringArray1();
+		Collection<String> c = this.buildStringList2();
+		String[] newArray = ArrayTools.addAll(a, 3, c);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, c));
+	}
+
+	public void testAddAllObjectArrayIntCollection_EmptyArray() {
+		String[] a = new String[0];
+		Collection<String> c = this.buildStringList2();
+		String[] newArray = ArrayTools.addAll(a, 0, c);
+
+		assertEquals(3, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, c));
+	}
+
+	public void testAddAllObjectArrayIntCollection_EmptyArray_Exception() {
+		String[] a = new String[0];
+		Collection<String> c = this.buildStringList2();
+		boolean exCaught = false;
+		try {
+			String[] newArray = ArrayTools.addAll(a, 3, c);
+			fail("bogus array: " + Arrays.toString(newArray));
+		} catch (IndexOutOfBoundsException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddAllObjectArrayIntCollection_EmptyCollection() {
+		String[] a = this.buildStringArray1();
+		Collection<String> c = new ArrayList<String>();
+		String[] newArray = ArrayTools.addAll(a, 1, c);
+
+		assertEquals(3, newArray.length);
+	}
+
+	public void testAddAllObjectArrayIntIterable_String() {
+		String[] a = this.buildStringArray1();
+		Iterable<String> iterable = this.buildStringList2();
+		String[] newArray = ArrayTools.addAll(a, 1, iterable);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, iterable));
+	}
+
+	public void testAddAllObjectArrayIntIterable_EmptyArray() {
+		String[] a = new String[0];
+		Iterable<String> iterable = this.buildStringList2();
+		String[] newArray = ArrayTools.addAll(a, 0, iterable);
+
+		assertEquals(3, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, iterable));
+	}
+
+	public void testAddAllObjectArrayIntIterable_EmptyIterable() {
+		String[] a = this.buildStringArray1();
+		Iterable<String> iterable = new ArrayList<String>();
+		String[] newArray = ArrayTools.addAll(a, 1, iterable);
+
+		assertEquals(3, newArray.length);
+	}
+
+	public void testAddAllObjectArrayIntIterableInt_String() {
+		String[] a = this.buildStringArray1();
+		Iterable<String> iterable = this.buildStringList2();
+		String[] newArray = ArrayTools.addAll(a, 1, iterable, 3);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, iterable));
+	}
+
+	public void testAddAllObjectArrayIntIterableInt_EmptyArray() {
+		String[] a = new String[0];
+		Iterable<String> iterable = this.buildStringList2();
+		String[] newArray = ArrayTools.addAll(a, 0, iterable, 3);
+
+		assertEquals(3, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, iterable));
+	}
+
+	public void testAddAllObjectArrayIntIterableInt_EmptyIterable() {
+		String[] a = this.buildStringArray1();
+		Iterable<String> iterable = new ArrayList<String>();
+		String[] newArray = ArrayTools.addAll(a, 1, iterable, 0);
+
+		assertEquals(3, newArray.length);
+	}
+
+	public void testAddAllObjectArrayIntIterator_String() {
+		String[] a = this.buildStringArray1();
+		Iterator<String> iterator = this.buildStringList2().iterator();
+		String[] newArray = ArrayTools.addAll(a, 1, iterator);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList2()));
+	}
+
+	public void testAddAllObjectArrayIntIterator_EmptyArray() {
+		String[] a = new String[0];
+		Iterator<String> iterator = this.buildStringList2().iterator();
+		String[] newArray = ArrayTools.addAll(a, 0, iterator);
+
+		assertEquals(3, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList2()));
+	}
+
+	public void testAddAllObjectArrayIntIterator_EmptyIterable() {
+		String[] a = this.buildStringArray1();
+		Iterator<String> iterator = EmptyIterator.instance();
+		String[] newArray = ArrayTools.addAll(a, 1, iterator);
+
+		assertEquals(3, newArray.length);
+	}
+
+	public void testAddAllObjectArrayIntIteratorInt_String() {
+		String[] a = this.buildStringArray1();
+		Iterator<String> iterator = this.buildStringList2().iterator();
+		String[] newArray = ArrayTools.addAll(a, 1, iterator, 3);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList2()));
+	}
+
+	public void testAddAllObjectArrayIntIteratorInt_EmptyArray() {
+		String[] a = new String[0];
+		Iterator<String> iterator = this.buildStringList2().iterator();
+		String[] newArray = ArrayTools.addAll(a, 0, iterator, 3);
+
+		assertEquals(3, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList2()));
+	}
+
+	public void testAddAllObjectArrayIntIteratorInt_EmptyIterator() {
+		String[] a = this.buildStringArray1();
+		Iterator<String> iterator = EmptyIterator.instance();
+		String[] newArray = ArrayTools.addAll(a, 1, iterator, 0);
+
+		assertEquals(3, newArray.length);
+	}
+
+	public void testAddAllObjectArrayIterable() {
+		String[] a = this.buildStringArray1();
+		Iterable<String> iterable = this.buildStringList1();
+		String[] newArray = ArrayTools.addAll(a, iterable);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList1()));
+	}
+
+	public void testAddAllObjectArrayIterableInt() {
+		String[] a = this.buildStringArray1();
+		Iterable<String> iterable = this.buildStringList1();
+		String[] newArray = ArrayTools.addAll(a, iterable, 33);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList1()));
+	}
+
+	public void testAddAllObjectArrayIterator_String() {
+		String[] a = this.buildStringArray1();
+		Iterator<String> iterator = this.buildStringList1().iterator();
+		String[] newArray = ArrayTools.addAll(a, iterator);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList1()));
+	}
+
+	public void testAddAllObjectArrayIterator_Object() {
+		String[] a = this.buildStringArray1();
+		Iterator<Object> iterator = this.buildObjectList1().iterator();
+		Object[] newArray = ArrayTools.addAll(a, iterator);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, this.buildObjectList1()));
+	}
+
+	public void testAddAllObjectArrayIterator_EmptyIterator() {
+		String[] a = this.buildStringArray1();
+		Iterator<String> iterator = EmptyIterator.instance();
+		String[] newArray = ArrayTools.addAll(a, iterator);
+
+		assertEquals(3, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList1()));
+	}
+
+	public void testAddAllObjectArrayIteratorInt() {
+		String[] a = this.buildStringArray1();
+		Iterator<Object> iterator = this.buildObjectList1().iterator();
+		Object[] newArray = ArrayTools.addAll(a, iterator, 3);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, this.buildObjectList1()));
+	}
+
+	public void testAddAllObjectArrayIteratorInt_EmptyIterator() {
+		String[] a = this.buildStringArray1();
+		Iterator<String> iterator = EmptyIterator.instance();
+		String[] newArray = ArrayTools.addAll(a, iterator, 0);
+
+		assertEquals(3, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList1()));
+	}
+
+	public void testAddAllObjectArrayObjectArray_Object() {
+		Object[] a1 = this.buildObjectArray1();
+		Object[] a2 = this.buildObjectArray2();
+		Object[] newArray = ArrayTools.addAll(a1, a2);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, a1));
+		assertTrue(ArrayTools.containsAll(newArray, a2));
+	}
+
+	public void testAddAllObjectArrayObjectArray_String() {
+		String[] a1 = this.buildStringArray1();
+		String[] a2 = this.buildStringArray2();
+		String[] newArray = ArrayTools.addAll(a1, a2);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, (Object[]) a1));
+		assertTrue(ArrayTools.containsAll(newArray, (Object[]) a2));
+	}
+
+	public void testAddAllObjectArrayObjectArray_ObjectString() {
+		Object[] a1 = this.buildObjectArray1();
+		String[] a2 = this.buildStringArray2();
+		Object[] newArray = ArrayTools.addAll(a1, (Object[]) a2);
+
+		assertEquals(6, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, a1));
+		assertTrue(ArrayTools.containsAll(newArray, (Object[]) a2));
+	}
+
+	public void testAddAllObjectArrayObjectArray_EmptyArray1() {
+		Object[] a1 = new Object[0];
+		Object[] a2 = this.buildObjectArray2();
+		Object[] newArray = ArrayTools.addAll(a1, a2);
+
+		assertEquals(3, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, a2));
+	}
+
+	public void testAddAllObjectArrayObjectArray_EmptyArray2() {
+		Object[] a1 = this.buildObjectArray1();
+		Object[] a2 = new Object[0];
+		Object[] newArray = ArrayTools.addAll(a1, a2);
+
+		assertEquals(3, newArray.length);
+		assertTrue(ArrayTools.containsAll(newArray, a1));
+	}
+
+	public void testAddAllObjectArrayIntObjectArray_Object() {
+		Object[] a = new Object[] { "a", "b", "c", "d" };
+		a = ArrayTools.addAll(a, 2, new Object[] { "X", "X", "X" });
+		assertEquals(7, a.length);
+		assertTrue(ArrayTools.contains(a, "X"));
+		assertTrue(Arrays.equals(new Object[] { "a", "b", "X", "X", "X", "c", "d" }, a));
+	}
+
+	public void testAddAllObjectArrayIntObjectArray_String() {
+		String[] a = new String[] { "a", "b", "c", "d" };
+		a = ArrayTools.addAll(a, 2, new String[] { "X", "X", "X" });
+		assertEquals(7, a.length);
+		assertTrue(ArrayTools.contains(a, "X"));
+		assertTrue(Arrays.equals(new String[] { "a", "b", "X", "X", "X", "c", "d" }, a));
+	}
+
+	public void testAddAllObjectArrayIntObjectArray_ObjectString() {
+		Object[] a = new Object[] { "a", "b", "c", "d" };
+		a = ArrayTools.addAll(a, 2, (Object[]) new String[] { "X", "X", "X" });
+		assertEquals(7, a.length);
+		assertTrue(ArrayTools.contains(a, "X"));
+		assertTrue(Arrays.equals(new Object[] { "a", "b", "X", "X", "X", "c", "d" }, a));
+	}
+
+	public void testAddAllObjectArrayIntObjectArray_End() {
+		Object[] a = new Object[] { "a", "b", "c", "d" };
+		a = ArrayTools.addAll(a, 4, (Object[]) new String[] { "X", "X", "X" });
+		assertEquals(7, a.length);
+		assertTrue(ArrayTools.contains(a, "X"));
+		assertTrue(Arrays.equals(new Object[] { "a", "b", "c", "d", "X", "X", "X" }, a));
+	}
+
+	public void testAddAllObjectArrayIntObjectArray_Zero() {
+		Object[] a = new Object[0];
+		a = ArrayTools.addAll(a, 0, (Object[]) new String[] { "X", "X", "X" });
+		assertEquals(3, a.length);
+		assertTrue(ArrayTools.contains(a, "X"));
+		assertTrue(Arrays.equals(new Object[] { "X", "X", "X" }, a));
+	}
+
+	public void testAddAllObjectArrayIntObjectArray_EmptyArray2() {
+		Object[] a = new Object[] { "a", "b", "c", "d" };
+		a = ArrayTools.addAll(a, 4, (Object[]) new String[0]);
+		assertEquals(4, a.length);
+		assertTrue(Arrays.equals(new Object[] { "a", "b", "c", "d" }, a));
+	}
+
+	public void testAddAllObjectArrayIntObjectArray_EmptyArray1() {
+		Object[] a = new String[0];
+		a = ArrayTools.addAll(a, 0, new Object[] { "a", "b", "c", "d" });
+		assertEquals(4, a.length);
+		assertTrue(Arrays.equals(new Object[] { "a", "b", "c", "d" }, a));
+	}
+
+	public void testAddAllCharArrayCharArray() {
+		char[] a = ArrayTools.addAll(this.buildCharArray(), new char[] { 'd', 'e' });
+		assertEquals(5, a.length);
+		assertTrue(ArrayTools.contains(a, 'd'));
+		assertTrue(ArrayTools.contains(a, 'e'));
+	}
+
+	public void testAddAllCharArrayCharArray_EmptyArray2() {
+		char[] a = ArrayTools.addAll(this.buildCharArray(), new char[0]);
+		assertEquals(3, a.length);
+	}
+
+	public void testAddAllCharArrayCharArrayEmptyArray1() {
+		char[] a = ArrayTools.addAll(new char[0], new char[] { 'd', 'e' });
+		assertEquals(2, a.length);
+		assertTrue(ArrayTools.contains(a, 'd'));
+		assertTrue(ArrayTools.contains(a, 'e'));
+	}
+
+	public void testAddAllCharArrayIntCharArray() {
+		char[] a = new char[] { 'a', 'b', 'c', 'd' };
+		a = ArrayTools.addAll(a, 2, new char[] { 'X', 'X', 'X' });
+		assertEquals(7, a.length);
+		assertTrue(ArrayTools.contains(a, 'X'));
+		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'X', 'X', 'X', 'c', 'd' }, a));
+	}
+
+	public void testAddAllCharArrayIntCharArray_End() {
+		char[] a = new char[] { 'a', 'b', 'c', 'd' };
+		a = ArrayTools.addAll(a, 4, new char[] { 'X', 'X', 'X' });
+		assertEquals(7, a.length);
+		assertTrue(ArrayTools.contains(a, 'X'));
+		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'c', 'd', 'X', 'X', 'X' }, a));
+	}
+
+	public void testAddAllCharArrayIntCharArray_EmptyArray1() {
+		char[] a = new char[0];
+		a = ArrayTools.addAll(a, 0, new char[] { 'X', 'X', 'X' });
+		assertEquals(3, a.length);
+		assertTrue(ArrayTools.contains(a, 'X'));
+		assertTrue(Arrays.equals(new char[] { 'X', 'X', 'X' }, a));
+	}
+
+	public void testAddAllCharArrayIntCharArray_EmptyArray2() {
+		char[] a = new char[] { 'a', 'b', 'c', 'd' };
+		a = ArrayTools.addAll(a, 2, new char[0]);
+		assertEquals(4, a.length);
+		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'c', 'd' }, a));
+	}
+
+	public void testAddAllIntArrayIntArray() {
+		int[] a = ArrayTools.addAll(this.buildIntArray(), new int[] { 30, 40 });
+		assertEquals(5, a.length);
+		assertTrue(ArrayTools.contains(a, 30));
+		assertTrue(ArrayTools.contains(a, 40));
+	}
+
+	public void testAddAllIntArrayIntArray_EmptyArray2() {
+		int[] a = ArrayTools.addAll(this.buildIntArray(), new int[0]);
+		assertEquals(3, a.length);
+	}
+
+	public void testAddAllIntArrayIntArray_EmptyArray1() {
+		int[] a = ArrayTools.addAll(new int[0], new int[] { 30, 40 });
+		assertEquals(2, a.length);
+		assertTrue(ArrayTools.contains(a, 30));
+		assertTrue(ArrayTools.contains(a, 40));
+	}
+
+	public void testAddAllIntArrayIntIntArray() {
+		int[] a = new int[] { 1, 2, 3, 4 };
+		a = ArrayTools.addAll(a, 2, new int[] { 99, 99, 99 });
+		assertEquals(7, a.length);
+		assertTrue(ArrayTools.contains(a, 99));
+		assertTrue(Arrays.equals(new int[] { 1, 2, 99, 99, 99, 3, 4 }, a));
+	}
+
+	public void testAddAllIntArrayIntIntArray_End() {
+		int[] a = new int[] { 1, 2, 3, 4 };
+		a = ArrayTools.addAll(a, 4, new int[] { 99, 99, 99 });
+		assertEquals(7, a.length);
+		assertTrue(ArrayTools.contains(a, 99));
+		assertTrue(Arrays.equals(new int[] { 1, 2, 3, 4, 99, 99, 99 }, a));
+	}
+
+	public void testAddAllIntArrayIntIntArray_EmptyArray2() {
+		int[] a = new int[] { 1, 2, 3, 4 };
+		a = ArrayTools.addAll(a, 2, new int[0]);
+		assertEquals(4, a.length);
+		assertTrue(Arrays.equals(new int[] { 1, 2, 3, 4 }, a));
+	}
+
+	public void testAddAllIntArrayIntIntArray_EmptyArray1() {
+		int[] a = new int[0];
+		a = ArrayTools.addAll(a, 0, new int[] { 99, 99, 99 });
+		assertEquals(3, a.length);
+		assertTrue(ArrayTools.contains(a, 99));
+		assertTrue(Arrays.equals(new int[] { 99, 99, 99 }, a));
+	}
+
+
+	// ********** clear **********
+
+	public void testClearObjectArray() {
+		String[] a = this.buildStringArray1();
+		assertEquals(3, a.length);
+		a = ArrayTools.clear(a);
+		assertEquals(0, a.length);
+	}
+
+	public void testClearObjectArray_Empty() {
+		String[] a = new String[0];
+		assertEquals(0, a.length);
+		a = ArrayTools.clear(a);
+		assertEquals(0, a.length);
+	}
+
+
+	// ********** component type **********
+
+	public void testComponentType() {
+		String[] array = new String[2];
+		Class<? extends String> javaClass = ArrayTools.componentType(array);
+		assertEquals(String.class, javaClass);
+	}
+
+	public void testComponentType_Super() {
+		Number[] array = new Integer[2];
+		Class<? extends Number> javaClass = ArrayTools.componentType(array);
+		assertFalse(javaClass == Number.class);
+		assertTrue(javaClass == Integer.class);
+	}
+
+
+	// ********** concatenate **********
+
+	public void testConcatenateObjectArrayArray() {
+		String[] aArray = new String[] { "a", "b", "c", "d" };
+		String[] eArray = new String[] { "e", "f", "g", "h" };
+		String[] iArray = new String[] { "i", "j", "k", "l" };
+
+		String[] expected = new String[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l" };
+		String[] actual = ArrayTools.concatenate(aArray, eArray, iArray);
+		assertTrue(Arrays.equals(expected, actual));
+	}
+
+	public void testConcatenateObjectArrayArray_Empty() {
+		String[] aArray = new String[] {  };
+		String[] eArray = new String[0];
+		String[] iArray = new String[0];
+
+		String[] expected = new String[0];
+		String[] actual = ArrayTools.concatenate(aArray, eArray, iArray);
+		assertEquals(0, actual.length);
+		assertTrue(Arrays.equals(expected, actual));
+	}
+
+	public void testConcatenateCharArrayArray() {
+		char[] aArray = new char[] { 'a', 'b', 'c', 'd' };
+		char[] eArray = new char[] { 'e', 'f', 'g', 'h' };
+		char[] iArray = new char[] { 'i', 'j', 'k', 'l' };
+
+		char[] expected = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l' };
+		char[] actual = ArrayTools.concatenate(aArray, eArray, iArray);
+		assertTrue(Arrays.equals(expected, actual));
+	}
+
+	public void testConcatenateCharArrayArray_Empty() {
+		char[] aArray = new char[] {  };
+		char[] eArray = new char[0];
+		char[] iArray = new char[0];
+
+		char[] expected = new char[0];
+		char[] actual = ArrayTools.concatenate(aArray, eArray, iArray);
+		assertEquals(0, actual.length);
+		assertTrue(Arrays.equals(expected, actual));
+	}
+
+	public void testConcatenateIntArrayArray() {
+		int[] aArray = new int[] { 'a', 'b', 'c', 'd' };
+		int[] eArray = new int[] { 'e', 'f', 'g', 'h' };
+		int[] iArray = new int[] { 'i', 'j', 'k', 'l' };
+
+		int[] expected = new int[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l' };
+		int[] actual = ArrayTools.concatenate(aArray, eArray, iArray);
+		assertTrue(Arrays.equals(expected, actual));
+	}
+
+	public void testConcatenateIntArrayArray_Empty() {
+		int[] aArray = new int[] {  };
+		int[] eArray = new int[0];
+		int[] iArray = new int[0];
+
+		int[] expected = new int[0];
+		int[] actual = ArrayTools.concatenate(aArray, eArray, iArray);
+		assertEquals(0, actual.length);
+		assertTrue(Arrays.equals(expected, actual));
+	}
+
+
+	// ********** contains **********
+
+	public void testContainsObjectArrayObject() {
+		Object[] a = this.buildObjectArray1();
+		assertTrue(ArrayTools.contains(a, "one"));
+		assertFalse(ArrayTools.contains(a, null));
+		Object[] a2 = ArrayTools.add(a, null);
+		assertTrue(ArrayTools.contains(a2, null));
+	}
+
+	public void testContainsObjectArrayObject_EmptyArray() {
+		Object[] a = new Object[0];
+		assertFalse(ArrayTools.contains(a, "one"));
+		assertFalse(ArrayTools.contains(a, null));
+	}
+
+	public void testContainsCharArrayChar() {
+		char[] a = this.buildCharArray();
+		assertTrue(ArrayTools.contains(a, 'a'));
+		assertFalse(ArrayTools.contains(a, 'z'));
+		char[] a2 = ArrayTools.add(a, 'z');
+		assertTrue(ArrayTools.contains(a2, 'z'));
+	}
+
+	public void testContainsCharArrayObject_EmptyArray() {
+		char[] a = new char[0];
+		assertFalse(ArrayTools.contains(a, 'a'));
+	}
+
+	public void testContainsIntArrayInt() {
+		int[] a = this.buildIntArray();
+		assertTrue(ArrayTools.contains(a, 10));
+		assertFalse(ArrayTools.contains(a, 55));
+		int[] a2 = ArrayTools.add(a, 55);
+		assertTrue(ArrayTools.contains(a2, 55));
+	}
+
+	public void testContainsIntArrayObject_EmptyArray() {
+		int[] a = new int[0];
+		assertFalse(ArrayTools.contains(a, 'a'));
+	}
+
+
+	// ********** contains all **********
+
+	public void testContainsAllObjectArrayCollection() {
+		assertTrue(ArrayTools.containsAll(this.buildObjectArray1(), this.buildStringList1()));
+		assertFalse(ArrayTools.containsAll(this.buildObjectArray1(), this.buildStringList2()));
+	}
+
+	public void testContainsAllObjectArrayIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(ArrayTools.containsAll(this.buildObjectArray1(), iterable));
+		iterable = this.buildStringList2();
+		assertFalse(ArrayTools.containsAll(this.buildObjectArray1(), iterable));
+	}
+
+	public void testContainsAllObjectArrayIterator() {
+		assertTrue(ArrayTools.containsAll(this.buildObjectArray1(), this.buildStringList1().iterator()));
+		assertFalse(ArrayTools.containsAll(this.buildObjectArray1(), this.buildStringList2().iterator()));
+	}
+
+	public void testContainsAllObjectArrayIterator_Empty() {
+		assertTrue(ArrayTools.containsAll(this.buildObjectArray1(), EmptyIterator.instance()));
+	}
+
+	public void testContainsAllObjectArrayObjectArray() {
+		assertTrue(ArrayTools.containsAll(this.buildObjectArray1(), this.buildObjectArray1()));
+		assertFalse(ArrayTools.containsAll(this.buildObjectArray1(), this.buildObjectArray2()));
+	}
+
+	public void testContainsAllCharArrayCharArray() {
+		assertTrue(ArrayTools.containsAll(this.buildCharArray(), this.buildCharArray()));
+		assertFalse(ArrayTools.containsAll(this.buildCharArray(), new char[] { 'x', 'y' }));
+	}
+
+	public void testContainsAllIntArrayIntArray() {
+		assertTrue(ArrayTools.containsAll(this.buildIntArray(), this.buildIntArray()));
+		assertFalse(ArrayTools.containsAll(this.buildIntArray(), new int[] { 444, 888 }));
+	}
+
+
+	// ********** diff **********
+
+	public void testDiffEnd() {
+		String a = "a";
+		String b = "b";
+		String c = "c";
+		String d = "d";
+		String e = "e";
+		String a_ = new String("a");
+		String b_ = new String("b");
+		String c_ = new String("c");
+		String d_ = new String("d");
+		String e_ = new String("e");
+		assertTrue((a != a_) && a.equals(a_));
+		assertTrue((b != b_) && b.equals(b_));
+		assertTrue((c != c_) && c.equals(c_));
+		assertTrue((d != d_) && d.equals(d_));
+		assertTrue((e != e_) && e.equals(e_));
+		String[] array1;
+		String[] array2;
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(-1, ArrayTools.lastIndexOfDifference(array1, array2));
+
+		array1 = new String[] { a };
+		array2 = new String[] { a_ };
+		assertEquals(-1, ArrayTools.lastIndexOfDifference(array1, array2));
+
+		array1 = new String[] { b, c, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(4, ArrayTools.lastIndexOfDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { b_, c_, d_, e_ };
+		assertEquals(4, ArrayTools.lastIndexOfDifference(array1, array2));
+
+		array1 = new String[0];
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(4, ArrayTools.lastIndexOfDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[0];
+		assertEquals(4, ArrayTools.lastIndexOfDifference(array1, array2));
+
+		array1 = new String[0];
+		array2 = new String[0];
+		assertEquals(-1, ArrayTools.lastIndexOfDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { b_, c_, a_, d_, e_ };
+		assertEquals(2, ArrayTools.lastIndexOfDifference(array1, array2));
+
+		array1 = new String[] { b, c, d, e };
+		array2 = new String[] { a_, c_, d_, e_ };
+		assertEquals(0, ArrayTools.lastIndexOfDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, e };
+		array2 = new String[] { a_, b_, c_, d_ };
+		assertEquals(3, ArrayTools.lastIndexOfDifference(array1, array2));
+
+		String c__ = new String(c);
+		assertTrue((c != c__) && c.equals(c_));
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, c__, d_, e_ };
+		assertEquals(-1, ArrayTools.lastIndexOfDifference(array1, array2));
+
+		array1 = new String[] { a, b, null, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(2, ArrayTools.lastIndexOfDifference(array1, array2));
+
+		array1 = new String[] { a, b, null, d, e };
+		array2 = new String[] { a_, b_, null, d_, e_ };
+		assertEquals(-1, ArrayTools.lastIndexOfDifference(array1, array2));
+	}
+
+	public void testDiffRange() {
+		String a = "a";
+		String b = "b";
+		String c = "c";
+		String d = "d";
+		String e = "e";
+		String a_ = a;
+		String b_ = b;
+		String c_ = c;
+		String d_ = d;
+		String e_ = e;
+		assertTrue((a == a_) && a.equals(a_));
+		assertTrue((b == b_) && b.equals(b_));
+		assertTrue((c == c_) && c.equals(c_));
+		assertTrue((d == d_) && d.equals(d_));
+		assertTrue((e == e_) && e.equals(e_));
+		String[] array1;
+		String[] array2;
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(new Range(5, -1), ArrayTools.differenceRange(array1, array2));
+
+		array1 = new String[] { a };
+		array2 = new String[] { a_ };
+		assertEquals(new Range(1, -1), ArrayTools.differenceRange(array1, array2));
+
+		array1 = new String[] { b, c, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(new Range(0, 4), ArrayTools.differenceRange(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { b_, c_, d_, e_ };
+		assertEquals(new Range(0, 4), ArrayTools.differenceRange(array1, array2));
+
+		array1 = new String[0];
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(new Range(0, 4), ArrayTools.differenceRange(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[0];
+		assertEquals(new Range(0, 4), ArrayTools.differenceRange(array1, array2));
+
+		array1 = new String[0];
+		array2 = new String[0];
+		assertEquals(new Range(0, -1), ArrayTools.differenceRange(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { b_, c_, a_, d_, e_ };
+		assertEquals(new Range(0, 2), ArrayTools.differenceRange(array1, array2));
+
+		array1 = new String[] { b, c, d, e };
+		array2 = new String[] { a_, c_, d_, e_ };
+		assertEquals(new Range(0, 0), ArrayTools.differenceRange(array1, array2));
+
+		array1 = new String[] { a, b, c, e };
+		array2 = new String[] { a_, b_, c_, d_ };
+		assertEquals(new Range(3, 3), ArrayTools.differenceRange(array1, array2));
+
+		String c__ = new String(c);
+		assertTrue((c != c__) && c.equals(c_));
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, c__, d_, e_ };
+		assertEquals(new Range(5, -1), ArrayTools.differenceRange(array1, array2));
+
+		array1 = new String[] { a, b, null, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(new Range(2, 2), ArrayTools.differenceRange(array1, array2));
+
+		array1 = new String[] { a, b, null, d, e };
+		array2 = new String[] { a_, b_, null, d_, e_ };
+		assertEquals(new Range(5, -1), ArrayTools.differenceRange(array1, array2));
+	}
+
+	public void testDiffStart() {
+		String a = "a";
+		String b = "b";
+		String c = "c";
+		String d = "d";
+		String e = "e";
+		String a_ = new String("a");
+		String b_ = new String("b");
+		String c_ = new String("c");
+		String d_ = new String("d");
+		String e_ = new String("e");
+		assertTrue((a != a_) && a.equals(a_));
+		assertTrue((b != b_) && b.equals(b_));
+		assertTrue((c != c_) && c.equals(c_));
+		assertTrue((d != d_) && d.equals(d_));
+		assertTrue((e != e_) && e.equals(e_));
+		String[] array1;
+		String[] array2;
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(5, ArrayTools.indexOfDifference(array1, array2));
+
+		array1 = new String[] { a };
+		array2 = new String[] { a_ };
+		assertEquals(1, ArrayTools.indexOfDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, d };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(4, ArrayTools.indexOfDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, c_, d_ };
+		assertEquals(4, ArrayTools.indexOfDifference(array1, array2));
+
+		array1 = new String[0];
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(0, ArrayTools.indexOfDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[0];
+		assertEquals(0, ArrayTools.indexOfDifference(array1, array2));
+
+		array1 = new String[0];
+		array2 = new String[0];
+		assertEquals(0, ArrayTools.indexOfDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, e_, c_, d_ };
+		assertEquals(2, ArrayTools.indexOfDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, e };
+		array2 = new String[] { a_, b_, c_, d_ };
+		assertEquals(3, ArrayTools.indexOfDifference(array1, array2));
+
+		array1 = new String[] { b, c, d, e };
+		array2 = new String[] { a_, c_, d_, e_ };
+		assertEquals(0, ArrayTools.indexOfDifference(array1, array2));
+
+		String c__ = new String(c);
+		assertTrue((c != c__) && c.equals(c__));
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, c__, d_, e_ };
+		assertEquals(5, ArrayTools.indexOfDifference(array1, array2));
+
+		array1 = new String[] { a, b, null, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(2, ArrayTools.indexOfDifference(array1, array2));
+
+		array1 = new String[] { a, b, null, d, e };
+		array2 = new String[] { a_, b_, null, d_, e_ };
+		assertEquals(5, ArrayTools.indexOfDifference(array1, array2));
+	}
+
+
+	// ********** identity diff **********
+
+	public void testIdentityDiffEnd() {
+		String a = "a";
+		String b = "b";
+		String c = "c";
+		String d = "d";
+		String e = "e";
+		String a_ = a;
+		String b_ = b;
+		String c_ = c;
+		String d_ = d;
+		String e_ = e;
+		assertTrue((a == a_) && a.equals(a_));
+		assertTrue((b == b_) && b.equals(b_));
+		assertTrue((c == c_) && c.equals(c_));
+		assertTrue((d == d_) && d.equals(d_));
+		assertTrue((e == e_) && e.equals(e_));
+		String[] array1;
+		String[] array2;
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(-1, ArrayTools.lastIndexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a };
+		array2 = new String[] { a_ };
+		assertEquals(-1, ArrayTools.lastIndexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { b, c, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(4, ArrayTools.lastIndexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { b_, c_, d_, e_ };
+		assertEquals(4, ArrayTools.lastIndexOfIdentityDifference(array1, array2));
+
+		array1 = new String[0];
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(4, ArrayTools.lastIndexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[0];
+		assertEquals(4, ArrayTools.lastIndexOfIdentityDifference(array1, array2));
+
+		array1 = new String[0];
+		array2 = new String[0];
+		assertEquals(-1, ArrayTools.lastIndexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { b_, c_, a_, d_, e_ };
+		assertEquals(2, ArrayTools.lastIndexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { b, c, d, e };
+		array2 = new String[] { a_, c_, d_, e_ };
+		assertEquals(0, ArrayTools.lastIndexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, e };
+		array2 = new String[] { a_, b_, c_, d_ };
+		assertEquals(3, ArrayTools.lastIndexOfIdentityDifference(array1, array2));
+
+		String c__ = new String(c);
+		assertTrue((c != c__) && c.equals(c_));
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, c__, d_, e_ };
+		assertEquals(2, ArrayTools.lastIndexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a, b, null, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(2, ArrayTools.lastIndexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a, b, null, d, e };
+		array2 = new String[] { a_, b_, null, d_, e_ };
+		assertEquals(-1, ArrayTools.lastIndexOfIdentityDifference(array1, array2));
+	}
+
+	public void testIdentityDiffRange() {
+		String a = "a";
+		String b = "b";
+		String c = "c";
+		String d = "d";
+		String e = "e";
+		String a_ = a;
+		String b_ = b;
+		String c_ = c;
+		String d_ = d;
+		String e_ = e;
+		assertTrue((a == a_) && a.equals(a_));
+		assertTrue((b == b_) && b.equals(b_));
+		assertTrue((c == c_) && c.equals(c_));
+		assertTrue((d == d_) && d.equals(d_));
+		assertTrue((e == e_) && e.equals(e_));
+		String[] array1;
+		String[] array2;
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(new Range(5, -1), ArrayTools.identityDifferenceRange(array1, array2));
+
+		array1 = new String[] { a };
+		array2 = new String[] { a_ };
+		assertEquals(new Range(1, -1), ArrayTools.identityDifferenceRange(array1, array2));
+
+		array1 = new String[] { b, c, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(new Range(0, 4), ArrayTools.identityDifferenceRange(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { b_, c_, d_, e_ };
+		assertEquals(new Range(0, 4), ArrayTools.identityDifferenceRange(array1, array2));
+
+		array1 = new String[0];
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(new Range(0, 4), ArrayTools.identityDifferenceRange(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[0];
+		assertEquals(new Range(0, 4), ArrayTools.identityDifferenceRange(array1, array2));
+
+		array1 = new String[0];
+		array2 = new String[0];
+		assertEquals(new Range(0, -1), ArrayTools.identityDifferenceRange(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { b_, c_, a_, d_, e_ };
+		assertEquals(new Range(0, 2), ArrayTools.identityDifferenceRange(array1, array2));
+
+		array1 = new String[] { b, c, d, e };
+		array2 = new String[] { a_, c_, d_, e_ };
+		assertEquals(new Range(0, 0), ArrayTools.identityDifferenceRange(array1, array2));
+
+		array1 = new String[] { a, b, c, e };
+		array2 = new String[] { a_, b_, c_, d_ };
+		assertEquals(new Range(3, 3), ArrayTools.identityDifferenceRange(array1, array2));
+
+		String c__ = new String(c);
+		assertTrue((c != c__) && c.equals(c_));
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, c__, d_, e_ };
+		assertEquals(new Range(2, 2), ArrayTools.identityDifferenceRange(array1, array2));
+
+		array1 = new String[] { a, b, null, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(new Range(2, 2), ArrayTools.identityDifferenceRange(array1, array2));
+
+		array1 = new String[] { a, b, null, d, e };
+		array2 = new String[] { a_, b_, null, d_, e_ };
+		assertEquals(new Range(5, -1), ArrayTools.identityDifferenceRange(array1, array2));
+	}
+
+	public void testIdentityDiffStart() {
+		String a = "a";
+		String b = "b";
+		String c = "c";
+		String d = "d";
+		String e = "e";
+		String a_ = a;
+		String b_ = b;
+		String c_ = c;
+		String d_ = d;
+		String e_ = e;
+		assertTrue((a == a_) && a.equals(a_));
+		assertTrue((b == b_) && b.equals(b_));
+		assertTrue((c == c_) && c.equals(c_));
+		assertTrue((d == d_) && d.equals(d_));
+		assertTrue((e == e_) && e.equals(e_));
+		String[] array1;
+		String[] array2;
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(5, ArrayTools.indexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a };
+		array2 = new String[] { a_ };
+		assertEquals(1, ArrayTools.indexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, d };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(4, ArrayTools.indexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, c_, d_ };
+		assertEquals(4, ArrayTools.indexOfIdentityDifference(array1, array2));
+
+		array1 = new String[0];
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(0, ArrayTools.indexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[0];
+		assertEquals(0, ArrayTools.indexOfIdentityDifference(array1, array2));
+
+		array1 = new String[0];
+		array2 = new String[0];
+		assertEquals(0, ArrayTools.indexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, e_, c_, d_ };
+		assertEquals(2, ArrayTools.indexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a, b, c, e };
+		array2 = new String[] { a_, b_, c_, d_ };
+		assertEquals(3, ArrayTools.indexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { b, c, d, e };
+		array2 = new String[] { a_, c_, d_, e_ };
+		assertEquals(0, ArrayTools.indexOfIdentityDifference(array1, array2));
+
+		String c__ = new String(c);
+		assertTrue((c != c__) && c.equals(c_));
+		array1 = new String[] { a, b, c, d, e };
+		array2 = new String[] { a_, b_, c__, d_, e_ };
+		assertEquals(2, ArrayTools.indexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a, b, null, d, e };
+		array2 = new String[] { a_, b_, c_, d_, e_ };
+		assertEquals(2, ArrayTools.indexOfIdentityDifference(array1, array2));
+
+		array1 = new String[] { a, b, null, d, e };
+		array2 = new String[] { a_, b_, null, d_, e_ };
+		assertEquals(5, ArrayTools.indexOfIdentityDifference(array1, array2));
+	}
+
+
+	// ********** elements are identical **********
+
+	public void testElementsAreIdenticalObjectArrayObjectArray() {
+		Object[] a1 = new Object[4];
+		for (int i = 0; i < a1.length; i++) {
+			a1[i] = String.valueOf(i * 1000);
+		}
+
+		Object[] a2 = new Object[a1.length];
+		for (int i = 0; i < a2.length; i++) {
+			a2[i] = a1[i];
+		}
+
+		assertTrue(ArrayTools.elementsAreIdentical(a1, a2));
+		a2[2] = "2000";
+		assertFalse(ArrayTools.elementsAreIdentical(a1, a2));
+		assertTrue(Arrays.equals(a1, a2));
+	}
+
+	public void testElementsAreIdenticalObjectArrayObjectArray_BothNull() {
+		Object[] a1 = null;
+		Object[] a2 = null;
+		assertTrue(ArrayTools.elementsAreIdentical(a1, a2));
+	}
+
+	public void testElementsAreIdenticalObjectArrayObjectArray_OneNull() {
+		Object[] a1 = null;
+		Object[] a2 = new Object[0];
+		assertFalse(ArrayTools.elementsAreIdentical(a1, a2));
+	}
+
+	public void testElementsAreIdenticalObjectArrayObjectArray_DifferentLengths() {
+		Object[] a1 = new String[] {"foo", "bar"};
+		Object[] a2 = new String[] {"foo", "bar", "baz"};
+		assertFalse(ArrayTools.elementsAreIdentical(a1, a2));
+	}
+
+
+	// ********** index of **********
+
+	public void testIndexOfObjectArrayObject() {
+		Object[] a = this.buildObjectArray1();
+		assertEquals(1, ArrayTools.indexOf(a, "one"));
+	}
+
+	public void testIndexOfObjectArrayObject_NotFound() {
+		Object[] a = this.buildObjectArray1();
+		assertEquals(-1, ArrayTools.indexOf(a, "twenty"));
+	}
+
+	public void testIndexOfObjectArrayObject_Null() {
+		Object[] a = this.buildObjectArray1();
+		a = ArrayTools.add(a, null);
+		assertEquals(a.length - 1, ArrayTools.indexOf(a, null));
+	}
+
+	public void testIndexOfObjectArrayObject_Null_NotFound() {
+		Object[] a = this.buildObjectArray1();
+		assertEquals(-1, ArrayTools.indexOf(a, null));
+	}
+
+	public void testIdentityIndexOfObjectArrayObject() {
+		String foo = "foo";
+		String bar = "bar";
+		String baz = "baz";
+		Object[] a = new Object[3];
+		a[0] = foo;
+		a[1] = bar;
+		a[2] = baz;
+		assertEquals(1, ArrayTools.identityIndexOf(a, bar));
+	}
+
+	public void testIdentityIndexOfObjectArrayObject_NotFound() {
+		String foo = "foo";
+		String bar = "bar";
+		String baz = "baz";
+		Object[] a = new Object[3];
+		a[0] = foo;
+		a[1] = bar;
+		a[2] = baz;
+		assertEquals(-1, ArrayTools.identityIndexOf(a, new String("bar")));
+	}
+
+	public void testIndexOfCharArrayChar() {
+		char[] a = this.buildCharArray();
+		assertEquals(1, ArrayTools.indexOf(a, 'b'));
+		a = ArrayTools.add(a, 'd');
+		assertEquals(a.length - 1, ArrayTools.indexOf(a, 'd'));
+	}
+
+	public void testIndexOfCharArrayChar_NotFound() {
+		char[] a = this.buildCharArray();
+		assertEquals(-1, ArrayTools.indexOf(a, 'z'));
+	}
+
+	public void testIndexOfIntArrayInt() {
+		int[] a = this.buildIntArray();
+		assertEquals(1, ArrayTools.indexOf(a, 10));
+		a = ArrayTools.add(a, 30);
+		assertEquals(a.length - 1, ArrayTools.indexOf(a, 30));
+	}
+
+	public void testIndexOfIntArrayInt_NotFound() {
+		int[] a = this.buildIntArray();
+		assertEquals(-1, ArrayTools.indexOf(a, 1000));
+	}
+
+
+	// ********** insertion index of **********
+
+	public void testInsertionIndexOfObjectArrayComparable() {
+		String[] a = new String[] { "A", "C", "D" };
+		assertEquals(1, ArrayTools.insertionIndexOf(a, "B"));
+
+		a = new String[] { "A", "B", "C", "D" };
+		assertEquals(1, ArrayTools.insertionIndexOf(a, "B"));
+
+		a = new String[] { "A", "B", "B", "B", "C", "D" };
+		assertEquals(1, ArrayTools.insertionIndexOf(a, "B"));
+
+		a = new String[] { "A", "B", "B", "B", "C", "D" };
+		assertEquals(6, ArrayTools.insertionIndexOf(a, "E"));
+
+		a = new String[] { "B", "B", "B", "C", "D" };
+		assertEquals(0, ArrayTools.insertionIndexOf(a, "A"));
+
+		a = new String[] { "A", "A", "B", "B", "C", "D" };
+		assertEquals(0, ArrayTools.insertionIndexOf(a, "A"));
+	}
+
+	public void testInsertionIndexOfObjectArrayObjectComparator() {
+		Comparator<String> c = new ReverseComparator<String>();
+		String[] a = new String[] { "D", "C", "A" };
+		assertEquals(2, ArrayTools.insertionIndexOf(a, "B", c));
+
+		a = new String[] { "D", "C", "B", "A" };
+		assertEquals(2, ArrayTools.insertionIndexOf(a, "B", c));
+
+		a = new String[] { "D", "C", "B", "B", "B", "A" };
+		assertEquals(2, ArrayTools.insertionIndexOf(a, "B", c));
+
+		a = new String[] { "D", "C", "B", "B", "B", "A" };
+		assertEquals(0, ArrayTools.insertionIndexOf(a, "E", c));
+
+		a = new String[] { "D", "C", "B", "B", "B" };
+		assertEquals(5, ArrayTools.insertionIndexOf(a, "A", c));
+
+		a = new String[] { "D", "C", "B", "B", "A", "A" };
+		assertEquals(4, ArrayTools.insertionIndexOf(a, "A", c));
+	}
+
+
+	// ********** last insertion index of **********
+
+	public void testLastInsertionIndexOfObjectArrayComparable() {
+		String[] a = new String[] { "A", "C", "D" };
+		assertEquals(1, ArrayTools.lastInsertionIndexOf(a, "B"));
+
+		a = new String[] { "A", "B", "C", "D" };
+		assertEquals(2, ArrayTools.lastInsertionIndexOf(a, "B"));
+
+		a = new String[] { "A", "B", "B", "B", "C", "D" };
+		assertEquals(4, ArrayTools.lastInsertionIndexOf(a, "B"));
+
+		a = new String[] { "A", "B", "B", "B", "C", "D" };
+		assertEquals(6, ArrayTools.lastInsertionIndexOf(a, "E"));
+
+		a = new String[] { "B", "B", "B", "C", "D" };
+		assertEquals(0, ArrayTools.lastInsertionIndexOf(a, "A"));
+
+		a = new String[] { "A", "A", "B", "B", "C", "D" };
+		assertEquals(2, ArrayTools.lastInsertionIndexOf(a, "A"));
+	}
+
+	public void testLastInsertionIndexOfObjectArrayObjectComparator() {
+		Comparator<String> c = new ReverseComparator<String>();
+		String[] a = new String[] { "D", "C", "A" };
+		assertEquals(2, ArrayTools.lastInsertionIndexOf(a, "B", c));
+
+		a = new String[] { "D", "C", "B", "A" };
+		assertEquals(3, ArrayTools.lastInsertionIndexOf(a, "B", c));
+
+		a = new String[] { "D", "C", "B", "B", "B", "A" };
+		assertEquals(5, ArrayTools.lastInsertionIndexOf(a, "B", c));
+
+		a = new String[] { "D", "C", "B", "B", "B", "A" };
+		assertEquals(0, ArrayTools.lastInsertionIndexOf(a, "E", c));
+
+		a = new String[] { "D", "C", "B", "B", "B" };
+		assertEquals(5, ArrayTools.lastInsertionIndexOf(a, "A", c));
+
+		a = new String[] { "D", "C", "B", "B", "A", "A" };
+		assertEquals(6, ArrayTools.lastInsertionIndexOf(a, "A", c));
+	}
+
+
+	// ********** last index of **********
+
+	public void testLastIndexOfObjectArrayObject() {
+		Object[] a = this.buildObjectArray1();
+		assertEquals(1, ArrayTools.lastIndexOf(a, "one"));
+	}
+
+	public void testLastIndexOfObjectArrayObject_NotFound() {
+		Object[] a = this.buildObjectArray1();
+		assertEquals(-1, ArrayTools.lastIndexOf(a, "twenty"));
+	}
+
+	public void testLastIndexOfObjectArrayObject_Null() {
+		Object[] a = this.buildObjectArray1();
+		a = ArrayTools.add(a, null);
+		assertEquals(a.length - 1, ArrayTools.lastIndexOf(a, null));
+	}
+
+	public void testLastIndexOfObjectArrayObject_Null_NotFound() {
+		Object[] a = this.buildObjectArray1();
+		assertEquals(-1, ArrayTools.lastIndexOf(a, null));
+	}
+
+	public void testLastIndexOfCharArrayChar() {
+		char[] a = this.buildCharArray();
+		assertEquals(1, ArrayTools.lastIndexOf(a, 'b'));
+		a = ArrayTools.add(a, 'd');
+		assertEquals(a.length - 1, ArrayTools.lastIndexOf(a, 'd'));
+	}
+
+	public void testLastIndexOfCharArrayChar_NotFound() {
+		char[] a = this.buildCharArray();
+		assertEquals(-1, ArrayTools.lastIndexOf(a, 'z'));
+	}
+
+	public void testLastIndexOfIntArrayInt() {
+		int[] a = this.buildIntArray();
+		assertEquals(1, ArrayTools.lastIndexOf(a, 10));
+		a = ArrayTools.add(a, 30);
+		assertEquals(a.length - 1, ArrayTools.lastIndexOf(a, 30));
+	}
+
+	public void testLastIndexOfIntArrayInt_NotFound() {
+		int[] a = this.buildIntArray();
+		assertEquals(-1, ArrayTools.lastIndexOf(a, 1000));
+	}
+
+
+	// ********** min/max **********
+
+	public void testMinCharArray() {
+		assertEquals('a', ArrayTools.min(this.buildCharArray()));
+	}
+
+	public void testMinCharArray_Exception() {
+		char[] array = new char[0];
+		boolean exCaught = false;
+		try {
+			char c = ArrayTools.min(array);
+			fail("bogus char: " + c);
+		} catch (IndexOutOfBoundsException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testMinIntArray() {
+		assertEquals(0, ArrayTools.min(this.buildIntArray()));
+	}
+
+	public void testMinIntArray_Exception() {
+		int[] array = new int[0];
+		boolean exCaught = false;
+		try {
+			int i = ArrayTools.min(array);
+			fail("bogus int: " + i);
+		} catch (IndexOutOfBoundsException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testMaxCharArray1() {
+		assertEquals('c', ArrayTools.max(this.buildCharArray()));
+	}
+
+	public void testMaxCharArray2() {
+		char[] array = new char[] { 'x', 'a', 'b', 'c' };
+		assertEquals('x', ArrayTools.max(array));
+	}
+
+	public void testMaxCharArray_Exception() {
+		char[] array = new char[0];
+		boolean exCaught = false;
+		try {
+			char c = ArrayTools.max(array);
+			fail("bogus char: " + c);
+		} catch (IndexOutOfBoundsException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testMaxIntArray1() {
+		assertEquals(20, ArrayTools.max(this.buildIntArray()));
+	}
+
+	public void testMaxIntArray2() {
+		int[] array = new int[] { 77, 3, 1, -3 };
+		assertEquals(77, ArrayTools.max(array));
+	}
+
+	public void testMaxIntArray_Exception() {
+		int[] array = new int[0];
+		boolean exCaught = false;
+		try {
+			int i = ArrayTools.max(array);
+			fail("bogus int: " + i);
+		} catch (IndexOutOfBoundsException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+
+	// ********** move **********
+
+	public void testMoveObjectArrayIntInt() {
+		String[] array = new String[] { "0", "1", "2", "3", "4", "5" };
+
+		String[] result = ArrayTools.move(array, 4, 2);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result));
+
+		result = ArrayTools.move(array, 0, 5);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result));
+
+		result = ArrayTools.move(array, 2, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result));
+
+		result = ArrayTools.move(array, 4, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result));
+	}
+
+	public void testMoveObjectArrayIntIntInt() {
+		String[] array = new String[] { "0", "1", "2", "3", "4", "5" };
+
+		String[] result = ArrayTools.move(array, 4, 2, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result));
+
+		result = ArrayTools.move(array, 0, 5, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result));
+
+		result = ArrayTools.move(array, 2, 4, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result));
+
+		result = ArrayTools.move(array, 2, 4, 2);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result));
+
+		result = ArrayTools.move(array, 0, 1, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "3", "2", "4", "5", "1" }, result));
+
+		result = ArrayTools.move(array, 1, 0, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result));
+
+		result = ArrayTools.move(array, 1, 1, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result));
+
+		result = ArrayTools.move(array, 1, 0, 0);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result));
+	}
+
+	public void testMoveIntArrayIntInt() {
+		int[] array = new int[] { 0, 1, 2, 3, 4, 5 };
+
+		int[] result = ArrayTools.move(array, 4, 2);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 0, 1, 3, 4, 2, 5 }, result));
+
+		result = ArrayTools.move(array, 0, 5);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 1, 3, 4, 2 }, result));
+
+		result = ArrayTools.move(array, 2, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 4, 1, 3, 2 }, result));
+
+		result = ArrayTools.move(array, 2, 2);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 4, 1, 3, 2 }, result));
+	}
+
+	public void testMoveIntArrayIntIntInt() {
+		int[] array = new int[] { 0, 1, 2, 3, 4, 5 };
+
+		int[] result = ArrayTools.move(array, 4, 2, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 0, 1, 3, 4, 2, 5 }, result));
+
+		result = ArrayTools.move(array, 0, 5, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 1, 3, 4, 2 }, result));
+
+		result = ArrayTools.move(array, 2, 4, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 4, 1, 3, 2 }, result));
+
+		result = ArrayTools.move(array, 2, 4, 2);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 3, 2, 4, 1 }, result));
+
+		result = ArrayTools.move(array, 0, 1, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 0, 3, 2, 4, 5, 1 }, result));
+
+		result = ArrayTools.move(array, 1, 0, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 3, 2, 4, 1 }, result));
+
+		result = ArrayTools.move(array, 1, 1, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 3, 2, 4, 1 }, result));
+
+		result = ArrayTools.move(array, 1, 0, 0);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 3, 2, 4, 1 }, result));
+	}
+
+	public void testMoveCharArrayIntInt() {
+		char[] array = new char[] { 'a', 'b', 'c', 'd', 'e', 'f' };
+
+		char[] result = ArrayTools.move(array, 4, 2);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'd', 'e', 'c', 'f' }, result));
+
+		result = ArrayTools.move(array, 0, 5);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'f', 'a', 'b', 'd', 'e', 'c' }, result));
+
+		result = ArrayTools.move(array, 2, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'f', 'a', 'e', 'b', 'd', 'c' }, result));
+
+		result = ArrayTools.move(array, 2, 2);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'f', 'a', 'e', 'b', 'd', 'c' }, result));
+	}
+
+	public void testMoveCharArrayIntIntInt() {
+		char[] array = new char[] { 'a', 'b', 'b', 'c', 'd', 'e' };
+
+		char[] result = ArrayTools.move(array, 4, 2, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'c', 'd', 'b', 'e' }, result));
+
+		result = ArrayTools.move(array, 0, 5, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'b', 'c', 'd', 'b' }, result));
+
+		result = ArrayTools.move(array, 2, 4, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'd', 'b', 'c', 'b' }, result));
+
+		result = ArrayTools.move(array, 2, 4, 2);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'c', 'b', 'd', 'b' }, result));
+
+		result = ArrayTools.move(array, 0, 1, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'a', 'c', 'b', 'd', 'e', 'b' }, result));
+
+		result = ArrayTools.move(array, 1, 0, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'c', 'b', 'd', 'b' }, result));
+
+		result = ArrayTools.move(array, 1, 1, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'c', 'b', 'd', 'b' }, result));
+
+		result = ArrayTools.move(array, 1, 0, 0);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'c', 'b', 'd', 'b' }, result));
+	}
+
+
+	// ********** remove **********
+
+	public void testRemoveObjectArrayObject_Object() {
+		Object[] a = this.buildObjectArray1();
+		a = ArrayTools.add(a, "three");
+		a = ArrayTools.add(a, "four");
+		a = ArrayTools.add(a, "five");
+
+		assertEquals(6, a.length);
+		assertTrue(ArrayTools.contains(a, "three"));
+		a = ArrayTools.remove(a, "three");
+		assertEquals(5, a.length);
+		assertFalse(ArrayTools.contains(a, "three"));
+		assertTrue(ArrayTools.contains(a, "four"));
+		assertTrue(ArrayTools.contains(a, "five"));
+	}
+
+	public void testRemoveObjectArrayObject_String() {
+		String[] a = this.buildStringArray1();
+		a = ArrayTools.add(a, "three");
+		a = ArrayTools.add(a, "four");
+		a = ArrayTools.add(a, "five");
+
+		assertEquals(6, a.length);
+		assertTrue(ArrayTools.contains(a, "three"));
+		a = ArrayTools.remove(a, "three");
+		assertEquals(5, a.length);
+		assertFalse(ArrayTools.contains(a, "three"));
+		assertTrue(ArrayTools.contains(a, "four"));
+		assertTrue(ArrayTools.contains(a, "five"));
+	}
+
+	public void testRemoveCharArrayChar() {
+		char[] a = this.buildCharArray();
+		a = ArrayTools.add(a, 'd');
+		a = ArrayTools.add(a, 'e');
+		a = ArrayTools.add(a, 'f');
+
+		assertEquals(6, a.length);
+		assertTrue(ArrayTools.contains(a, 'd'));
+		a = ArrayTools.remove(a, 'd');
+		assertEquals(5, a.length);
+		assertFalse(ArrayTools.contains(a, 'd'));
+		assertTrue(ArrayTools.contains(a, 'e'));
+		assertTrue(ArrayTools.contains(a, 'f'));
+	}
+
+	public void testRemoveIntArrayInt() {
+		int[] a = this.buildIntArray();
+		a = ArrayTools.add(a, 30);
+		a = ArrayTools.add(a, 40);
+		a = ArrayTools.add(a, 50);
+
+		assertEquals(6, a.length);
+		assertTrue(ArrayTools.contains(a, 30));
+		a = ArrayTools.remove(a, 30);
+		assertEquals(5, a.length);
+		assertFalse(ArrayTools.contains(a, 30));
+		assertTrue(ArrayTools.contains(a, 40));
+		assertTrue(ArrayTools.contains(a, 50));
+	}
+
+
+	// ********** remove all **********
+
+	public void testRemoveAllObjectArrayObjectArray() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		String[] a2 = new String[] { "E", "B" };
+		String[] a3 = ArrayTools.removeAll(a1, (Object[]) a2);
+		assertTrue(Arrays.equals(new String[] { "A", "A", "C", "C", "D", "D", "F", "F" }, a3));
+	}
+
+	public void testRemoveAllObjectArrayObjectArray_Empty() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		String[] a2 = new String[0];
+		String[] a3 = ArrayTools.removeAll(a1, (Object[]) a2);
+		assertTrue(Arrays.equals(a1, a3));
+	}
+
+	public void testRemoveAllObjectArrayObjectArray_NoMatches() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		String[] a2 = new String[] { "X", "Y", "Z" };
+		String[] a3 = ArrayTools.removeAll(a1, (Object[]) a2);
+		assertTrue(Arrays.equals(a1, a3));
+	}
+
+	public void testRemoveAllObjectArrayIterable() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Iterable<?> iterable = Arrays.asList(new String[] { "E", "B" });
+		String[] a3 = ArrayTools.removeAll(a1, iterable);
+		assertTrue(Arrays.equals(new String[] { "A", "A", "C", "C", "D", "D", "F", "F" }, a3));
+	}
+
+	public void testRemoveAllObjectArrayIterableInt() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Iterable<?> iterable = Arrays.asList(new String[] { "E", "B" });
+		String[] a3 = ArrayTools.removeAll(a1, iterable, 7);
+		assertTrue(Arrays.equals(new String[] { "A", "A", "C", "C", "D", "D", "F", "F" }, a3));
+	}
+
+	public void testRemoveAllObjectArrayIterator() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Iterable<?> iterable = Arrays.asList(new String[] { "E", "B" });
+		String[] a3 = ArrayTools.removeAll(a1, iterable.iterator());
+		assertTrue(Arrays.equals(new String[] { "A", "A", "C", "C", "D", "D", "F", "F" }, a3));
+	}
+
+	public void testRemoveAllObjectArrayIterator_Empty() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		String[] a3 = ArrayTools.removeAll(a1, EmptyIterator.instance());
+		assertTrue(Arrays.equals(a1, a3));
+	}
+
+	public void testRemoveAllObjectArrayIteratorInt() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Iterable<?> iterable = Arrays.asList(new String[] { "E", "B" });
+		String[] a3 = ArrayTools.removeAll(a1, iterable.iterator(), 7);
+		assertTrue(Arrays.equals(new String[] { "A", "A", "C", "C", "D", "D", "F", "F" }, a3));
+	}
+
+	public void testRemoveAllObjectArrayIteratorInt_Empty() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		String[] a3 = ArrayTools.removeAll(a1, EmptyIterator.instance(), 7);
+		assertTrue(Arrays.equals(a1, a3));
+	}
+
+	public void testRemoveAllObjectArrayCollection() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Collection<String> collection = Arrays.asList(new String[] { "E", "B" });
+		String[] a3 = ArrayTools.removeAll(a1, collection);
+		assertTrue(Arrays.equals(new String[] { "A", "A", "C", "C", "D", "D", "F", "F" }, a3));
+	}
+
+	public void testRemoveAllObjectArrayCollection_Empty() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Collection<String> collection = new ArrayList<String>();
+		String[] a3 = ArrayTools.removeAll(a1, collection);
+		assertTrue(Arrays.equals(a1, a3));
+	}
+
+	public void testRemoveAllObjectArrayCollection_EmptyArray() {
+		String[] a1 = new String[0];
+		Collection<String> collection = Arrays.asList(new String[] { "E", "B" });
+		String[] a3 = ArrayTools.removeAll(a1, collection);
+		assertTrue(Arrays.equals(a1, a3));
+		assertEquals(0, a3.length);
+	}
+
+	public void testRemoveAllObjectArrayCollection_NoMatches() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Collection<String> collection = Arrays.asList(new String[] { "X", "Y", "Z" });
+		String[] a3 = ArrayTools.removeAll(a1, collection);
+		assertTrue(Arrays.equals(a1, a3));
+	}
+
+	public void testRemoveAllCharArrayCharArray() {
+		char[] a1 = new char[] { 'A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'E', 'E', 'F', 'F' };
+		char[] a2 = new char[] { 'E', 'B' };
+		assertTrue(Arrays.equals(new char[] { 'A', 'A', 'C', 'C', 'D', 'D', 'F', 'F' }, ArrayTools.removeAll(a1, a2)));
+	}
+
+	public void testRemoveAllCharArrayCharArray_Empty1() {
+		char[] a1 = new char[0];
+		char[] a2 = new char[] { 'E', 'B' };
+		assertTrue(Arrays.equals(a1, ArrayTools.removeAll(a1, a2)));
+	}
+
+	public void testRemoveAllCharArrayCharArray_Empty2() {
+		char[] a1 = new char[] { 'A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'E', 'E', 'F', 'F' };
+		char[] a2 = new char[0];
+		assertTrue(Arrays.equals(a1, ArrayTools.removeAll(a1, a2)));
+	}
+
+	public void testRemoveAllCharArrayCharArray_NoMatches() {
+		char[] a1 = new char[] { 'A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'E', 'E', 'F', 'F' };
+		char[] a2 = new char[] { 'X', 'Z' };
+		assertTrue(Arrays.equals(a1, ArrayTools.removeAll(a1, a2)));
+	}
+
+	public void testRemoveAllIntArrayIntArray() {
+		int[] a1 = new int[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6 };
+		int[] a2 = new int[] { 5, 2 };
+		assertTrue(Arrays.equals(new int[] { 1, 1, 3, 3, 4, 4, 6, 6 }, ArrayTools.removeAll(a1, a2)));
+	}
+
+	public void testRemoveAllIntArrayIntArray_Empty1() {
+		int[] a1 = new int[0];
+		int[] a2 = new int[] { 5, 2 };
+		assertTrue(Arrays.equals(a1, ArrayTools.removeAll(a1, a2)));
+	}
+
+	public void testRemoveAllIntArrayIntArray_Empty2() {
+		int[] a1 = new int[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6 };
+		int[] a2 = new int[0];
+		assertTrue(Arrays.equals(a1, ArrayTools.removeAll(a1, a2)));
+	}
+
+	public void testRemoveAllIntArrayIntArray_NoMatches() {
+		int[] a1 = new int[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6 };
+		int[] a2 = new int[] { 52, 67 };
+		assertTrue(Arrays.equals(a1, ArrayTools.removeAll(a1, a2)));
+	}
+
+
+	// ********** remove all occurrences **********
+
+	public void testRemoveAllOccurrencesObjectArrayObject() {
+		String[] a = this.buildStringArray1();
+		assertEquals(3, a.length);
+		a = ArrayTools.removeAllOccurrences(a, "three");
+		assertEquals(3, a.length);
+		a = ArrayTools.removeAllOccurrences(a, "two");
+		assertEquals(2, a.length);
+		a = ArrayTools.removeAllOccurrences(a, "two");
+		assertEquals(2, a.length);
+
+		a = ArrayTools.add(a, "five");
+		a = ArrayTools.add(a, "five");
+		a = ArrayTools.add(a, "five");
+		assertEquals(5, a.length);
+		a = ArrayTools.removeAllOccurrences(a, "five");
+		assertEquals(2, a.length);
+		a = ArrayTools.removeAllOccurrences(a, "five");
+		assertEquals(2, a.length);
+
+		a = ArrayTools.add(a, null);
+		a = ArrayTools.add(a, null);
+		a = ArrayTools.add(a, null);
+		assertEquals(5, a.length);
+		a = ArrayTools.removeAllOccurrences(a, null);
+		assertEquals(2, a.length);
+		a = ArrayTools.removeAllOccurrences(a, null);
+		assertEquals(2, a.length);
+	}
+
+	public void testRemoveAllOccurrencesObjectArrayObject_Empty() {
+		String[] a = new String[0];
+		a = ArrayTools.removeAllOccurrences(a, "three");
+		assertEquals(0, a.length);
+	}
+
+	public void testRemoveAllOccurrencesCharArrayChar() {
+		char[] a = this.buildCharArray();
+		assertEquals(3, a.length);
+		a = ArrayTools.removeAllOccurrences(a, 'd');
+		assertEquals(3, a.length);
+		a = ArrayTools.removeAllOccurrences(a, 'b');
+		assertEquals(2, a.length);
+		a = ArrayTools.removeAllOccurrences(a, 'b');
+		assertEquals(2, a.length);
+
+		a = ArrayTools.add(a, 'g');
+		a = ArrayTools.add(a, 'g');
+		a = ArrayTools.add(a, 'g');
+		assertEquals(5, a.length);
+		a = ArrayTools.removeAllOccurrences(a, 'g');
+		assertEquals(2, a.length);
+		a = ArrayTools.removeAllOccurrences(a, 'g');
+		assertEquals(2, a.length);
+	}
+
+	public void testRemoveAllOccurrencesCharArrayChar_Empty() {
+		char[] a = new char[0];
+		a = ArrayTools.removeAllOccurrences(a, 'a');
+		assertEquals(0, a.length);
+	}
+
+	public void testRemoveAllOccurrencesIntArrayInt() {
+		int[] a = this.buildIntArray();
+		assertEquals(3, a.length);
+		a = ArrayTools.removeAllOccurrences(a, 55);
+		assertEquals(3, a.length);
+		a = ArrayTools.removeAllOccurrences(a, 10);
+		assertEquals(2, a.length);
+		a = ArrayTools.removeAllOccurrences(a, 10);
+		assertEquals(2, a.length);
+
+		a = ArrayTools.add(a, 77);
+		a = ArrayTools.add(a, 77);
+		a = ArrayTools.add(a, 77);
+		assertEquals(5, a.length);
+		a = ArrayTools.removeAllOccurrences(a, 77);
+		assertEquals(2, a.length);
+		a = ArrayTools.removeAllOccurrences(a, 77);
+		assertEquals(2, a.length);
+	}
+
+	public void testRemoveAllOccurrencesIntArrayInt_Empty() {
+		int[] a = new int[0];
+		a = ArrayTools.removeAllOccurrences(a, 22);
+		assertEquals(0, a.length);
+	}
+
+
+	// ********** remove duplicate elements **********
+
+	public void testRemoveDuplicateElementsObjectArray() {
+		List<String> list = this.buildStringVector1();
+		list.add("zero");
+		list.add("zero");
+		list.add("two");
+		list.add("zero");
+		String[] array = ArrayTools.removeDuplicateElements(list.toArray(new String[list.size()]));
+		int i = 0;
+		assertEquals("zero", array[i++]);
+		assertEquals("one", array[i++]);
+		assertEquals("two", array[i++]);
+		assertEquals(i, array.length);
+	}
+
+	public void testRemoveDuplicateElementsObjectArray_Empty() {
+		String[] array = ArrayTools.removeDuplicateElements(new String[0]);
+		assertEquals(0, array.length);
+	}
+
+	public void testRemoveDuplicateElementsObjectArray_SingleElement() {
+		String[] array = ArrayTools.removeDuplicateElements(new String[] { "foo" });
+		assertEquals(1, array.length);
+	}
+
+	public void testRemoveDuplicateElementsObjectArray_NoDuplicates() {
+		String[] a1 = new String[] { "foo", "bar", "baz" };
+		String[] a2 = ArrayTools.removeDuplicateElements(a1);
+		assertEquals(3, a2.length);
+		assertTrue(Arrays.equals(a1, a2));
+	}
+
+
+	// ********** remove element at index **********
+
+	public void testRemoveElementAtIndexObjectArrayInt() {
+		String[] a = new String[] { "A", "B", "A", "C", "A", "D" };
+		a = ArrayTools.removeElementAtIndex(a, 3);
+		assertTrue(Arrays.equals(new String[] { "A", "B", "A", "A", "D" }, a));
+	}
+
+	public void testRemoveElementAtIndexCharArrayInt() {
+		char[] a = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
+		a = ArrayTools.removeElementAtIndex(a, 3);
+		assertTrue(Arrays.equals(new char[] { 'A', 'B', 'A', 'A', 'D' }, a));
+	}
+
+	public void testRemoveElementAtIndexIntArrayInt() {
+		int[] a = new int[] { 8, 6, 7, 33, 2, 11 };
+		a = ArrayTools.removeElementsAtIndex(a, 3, 3);
+		assertTrue(Arrays.equals(new int[] { 8, 6, 7 }, a));
+	}
+
+	public void testRemoveFirstObjectArray() {
+		String[] a = new String[] { "A", "B", "A", "C", "A", "D" };
+		a = ArrayTools.removeFirst(a);
+		assertTrue(Arrays.equals(new String[] { "B", "A", "C", "A", "D" }, a));
+	}
+
+	public void testRemoveFirstCharArray() {
+		char[] a = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
+		a = ArrayTools.removeFirst(a);
+		assertTrue(Arrays.equals(new char[] { 'B', 'A', 'C', 'A', 'D' }, a));
+	}
+
+	public void testRemoveFirstIntArray() {
+		int[] a = new int[] { 8, 6, 7, 33, 2, 11 };
+		a = ArrayTools.removeFirst(a);
+		assertTrue(Arrays.equals(new int[] { 6, 7, 33, 2, 11 }, a));
+	}
+
+	public void testRemoveLastObjectArray() {
+		String[] a = new String[] { "A", "B", "A", "C", "A", "D" };
+		a = ArrayTools.removeLast(a);
+		assertTrue(Arrays.equals(new String[] { "A", "B", "A", "C", "A" }, a));
+	}
+
+	public void testRemoveLastCharArray() {
+		char[] a = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
+		a = ArrayTools.removeLast(a);
+		assertTrue(Arrays.equals(new char[] { 'A', 'B', 'A', 'C', 'A' }, a));
+	}
+
+	public void testRemoveLastIntArray() {
+		int[] a = new int[] { 8, 6, 7, 33, 2, 11 };
+		a = ArrayTools.removeLast(a);
+		assertTrue(Arrays.equals(new int[] { 8, 6, 7, 33, 2 }, a));
+	}
+
+
+	// ********** remove elements at index **********
+
+	public void testRemoveElementsAtIndexObjectArrayIntInt() {
+		String[] a = new String[] { "A", "B", "A", "C", "A", "D" };
+		a = ArrayTools.removeElementsAtIndex(a, 3, 2);
+		assertTrue(Arrays.equals(new String[] { "A", "B", "A", "D" }, a));
+	}
+
+	public void testRemoveElementsAtIndexObjectArrayIntInt_ZeroLength() {
+		String[] a1 = new String[] { "A", "B", "A", "C", "A", "D" };
+		String[] a2 = ArrayTools.removeElementsAtIndex(a1, 3, 0);
+		assertTrue(Arrays.equals(a1, a2));
+	}
+
+	public void testRemoveElementsAtIndexObjectArrayIntInt_Empty() {
+		String[] a = new String[] { "A", "B", "A", "C", "A", "D" };
+		a = ArrayTools.removeElementsAtIndex(a, 0, 6);
+		assertEquals(0, a.length);
+	}
+
+	public void testRemoveElementsAtIndexCharArrayIntInt() {
+		char[] a = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
+		a = ArrayTools.removeElementsAtIndex(a, 0, 5);
+		assertTrue(Arrays.equals(new char[] { 'D' }, a));
+	}
+
+	public void testRemoveElementsAtIndexCharArrayIntInt_ZeroLength() {
+		char[] a1 = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
+		char[] a2 = ArrayTools.removeElementsAtIndex(a1, 3, 0);
+		assertTrue(Arrays.equals(a1, a2));
+	}
+
+	public void testRemoveElementsAtIndexCharArrayIntInt_Empty() {
+		char[] a = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
+		a = ArrayTools.removeElementsAtIndex(a, 0, 6);
+		assertEquals(0, a.length);
+	}
+
+	public void testRemoveElementsAtIndexIntArrayIntInt() {
+		int[] a = new int[] { 8, 6, 7, 33, 2, 11 };
+		a = ArrayTools.removeElementsAtIndex(a, 3, 3);
+		assertTrue(Arrays.equals(new int[] { 8, 6, 7 }, a));
+	}
+
+	public void testRemoveElementsAtIndexIntArrayIntInt_ZeroLength() {
+		int[] a1 = new int[] { 8, 6, 7, 33, 2, 11 };
+		int[] a2 = ArrayTools.removeElementsAtIndex(a1, 3, 0);
+		assertTrue(Arrays.equals(a1, a2));
+	}
+
+	public void testRemoveElementsAtIndexIntArrayIntInt_Empty() {
+		int[] a = new int[] { 8, 6, 7, 33, 2, 11 };
+		a = ArrayTools.removeElementsAtIndex(a, 0, 6);
+		assertEquals(0, a.length);
+	}
+
+
+	// ********** replace all **********
+
+	public void testReplaceAllObjectArrayObjectObject_Object() {
+		Object[] a = new Object[] { "A", "B", "A", "C", "A", "D" };
+		a = ArrayTools.replaceAll(a, "A", "Z");
+		assertTrue(Arrays.equals(new Object[] { "Z", "B", "Z", "C", "Z", "D" }, a));
+	}
+
+	public void testReplaceAllObjectArrayObjectObject_String() {
+		String[] a = new String[] { "A", "B", "A", "C", "A", "D" };
+		a = ArrayTools.replaceAll(a, "A", "Z");
+		assertTrue(Arrays.equals(new String[] { "Z", "B", "Z", "C", "Z", "D" }, a));
+	}
+
+	public void testReplaceAllObjectArrayObjectObject_Null() {
+		String[] a = new String[] { null, "B", null, "C", null, "D" };
+		a = ArrayTools.replaceAll(a, null, "Z");
+		assertTrue(Arrays.equals(new String[] { "Z", "B", "Z", "C", "Z", "D" }, a));
+	}
+
+	public void testReplaceAllCharArrayCharChar() {
+		char[] a = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
+		a = ArrayTools.replaceAll(a, 'A', 'Z');
+		assertTrue(Arrays.equals(new char[] { 'Z', 'B', 'Z', 'C', 'Z', 'D' }, a));
+	}
+
+	public void testReplaceAllIntArrayIntInt() {
+		int[] a = new int[] { 0, 1, 0, 7, 0, 99 };
+		a = ArrayTools.replaceAll(a, 0, 13);
+		assertTrue(Arrays.equals(new int[] { 13, 1, 13, 7, 13, 99 }, a));
+	}
+
+
+	// ********** retain all **********
+
+	public void testRetainAllObjectArrayObjectArray() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Object[] a2 = new Object[] { "E", "B", new Integer(7) };
+		assertTrue(Arrays.equals(new String[] { "B", "B", "E", "E" }, ArrayTools.retainAll(a1, a2)));
+	}
+
+	public void testRetainAllObjectArrayObjectArray_EmptyObjectArray1() {
+		String[] a1 = new String[0];
+		String[] a2 = new String[] { "E", "B", "" };
+		String[] a3 = ArrayTools.retainAll(a1, a2);
+		assertEquals(0, a3.length);
+	}
+
+	public void testRetainAllObjectArrayObjectArray_EmptyObjectArray2() {
+		String[] a1 = new String[] { "E", "B", "" };
+		String[] a2 = new String[0];
+		String[] a3 = ArrayTools.retainAll(a1, a2);
+		assertEquals(0, a3.length);
+	}
+
+	public void testRetainAllObjectArrayObjectArray_BothEmpty() {
+		String[] a1 = new String[0];
+		String[] a2 = new String[0];
+		String[] a3 = ArrayTools.retainAll(a1, a2);
+		assertEquals(0, a3.length);
+	}
+
+	public void testRetainAllObjectArrayIterable() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Iterable<String> iterable = Arrays.asList(new String[] { "E", "B", "" });
+		assertTrue(Arrays.equals(new String[] { "B", "B", "E", "E" }, ArrayTools.retainAll(a1, iterable)));
+	}
+
+	public void testRetainAllObjectArrayIterable_EmptyObjectArray() {
+		String[] a1 = new String[0];
+		Iterable<String> iterable = Arrays.asList(new String[] { "E", "B", "" });
+		String[] a3 = ArrayTools.retainAll(a1, iterable);
+		assertEquals(0, a3.length);
+	}
+
+	public void testRetainAllObjectArrayIterableInt() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Iterable<String> iterable = Arrays.asList(new String[] { "E", "B", "" });
+		assertTrue(Arrays.equals(new String[] { "B", "B", "E", "E" }, ArrayTools.retainAll(a1, iterable, 3)));
+	}
+
+	public void testRetainAllObjectArrayIterableInt_EmptyObjectArray() {
+		String[] a1 = new String[0];
+		Iterable<String> iterable = Arrays.asList(new String[] { "E", "B", "" });
+		String[] a3 = ArrayTools.retainAll(a1, iterable, 3);
+		assertEquals(0, a3.length);
+	}
+
+	public void testRetainAllObjectArrayIterator() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Iterator<String> iterator = Arrays.asList(new String[] { "E", "B", "" }).iterator();
+		assertTrue(Arrays.equals(new String[] { "B", "B", "E", "E" }, ArrayTools.retainAll(a1, iterator)));
+	}
+
+	public void testRetainAllObjectArrayIterator_EmptyObjectArray() {
+		String[] a1 = new String[0];
+		Iterator<String> iterator = Arrays.asList(new String[] { "E", "B", "" }).iterator();
+		String[] a3 = ArrayTools.retainAll(a1, iterator);
+		assertEquals(0, a3.length);
+	}
+
+	public void testRetainAllObjectArrayIterator_EmptyIterator() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		assertTrue(Arrays.equals(new String[0], ArrayTools.retainAll(a1, EmptyIterator.instance())));
+	}
+
+	public void testRetainAllObjectArrayIteratorInt() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Iterator<String> iterator = Arrays.asList(new String[] { "E", "B", "" }).iterator();
+		assertTrue(Arrays.equals(new String[] { "B", "B", "E", "E" }, ArrayTools.retainAll(a1, iterator, 3)));
+	}
+
+	public void testRetainAllObjectArrayIteratorInt_EmptyIterator() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		assertTrue(Arrays.equals(new String[0], ArrayTools.retainAll(a1, EmptyIterator.instance(), 3)));
+	}
+
+	public void testRetainAllObjectArrayIteratorInt_EmptyObjectArray() {
+		String[] a1 = new String[0];
+		Iterator<String> iterator = Arrays.asList(new String[] { "E", "B", "" }).iterator();
+		String[] a3 = ArrayTools.retainAll(a1, iterator, 3);
+		assertEquals(0, a3.length);
+	}
+
+	public void testRetainAllObjectArrayCollection() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Collection<String> collection = Arrays.asList(new String[] { "E", "B", "" });
+		assertTrue(Arrays.equals(new String[] { "B", "B", "E", "E" }, ArrayTools.retainAll(a1, collection)));
+	}
+
+	public void testRetainAllObjectArrayCollection_EmptyObjectArray() {
+		String[] a1 = new String[0];
+		Collection<String> collection = Arrays.asList(new String[] { "E", "B", "" });
+		String[] a3 = ArrayTools.retainAll(a1, collection);
+		assertEquals(0, a3.length);
+	}
+
+	public void testRetainAllObjectArrayCollection_EmptyCollection() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Collection<String> collection = new ArrayList<String>();
+		String[] a3 = ArrayTools.retainAll(a1, collection);
+		assertEquals(0, a3.length);
+	}
+
+	public void testRetainAllObjectArrayCollection_All() {
+		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
+		Collection<String> collection = Arrays.asList(new String[] { "A", "B", "C", "D", "E", "F" });
+		assertTrue(Arrays.equals(a1, ArrayTools.retainAll(a1, collection)));
+	}
+
+	public void testRetainAllCharArrayCharArray() {
+		char[] a1 = new char[] { 'A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'E', 'E', 'F', 'F' };
+		char[] a2 = new char[] { 'E', 'B' };
+		assertTrue(Arrays.equals(new char[] { 'B', 'B', 'E', 'E' }, ArrayTools.retainAll(a1, a2)));
+	}
+
+	public void testRetainAllCharArrayCharArray_EmptyCharArray1() {
+		char[] a1 = new char[0];
+		char[] a2 = new char[] { 'E', 'B' };
+		assertSame(a1, ArrayTools.retainAll(a1, a2));
+	}
+
+	public void testRetainAllCharArrayCharArray_EmptyCharArray2() {
+		char[] a1 = new char[] { 'E', 'B' };
+		char[] a2 = new char[0];
+		assertEquals(0, ArrayTools.retainAll(a1, a2).length);
+	}
+
+	public void testRetainAllCharArrayCharArray_RetainAll() {
+		char[] a1 = new char[] { 'E', 'B', 'E', 'B', 'E', 'B', 'E', 'B', 'E' };
+		char[] a2 = new char[] { 'E', 'B' };
+		assertSame(a1, ArrayTools.retainAll(a1, a2));
+	}
+
+	public void testRetainAllIntArrayIntArray() {
+		int[] a1 = new int[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6 };
+		int[] a2 = new int[] { 5, 2 };
+		assertTrue(Arrays.equals(new int[] { 2, 2, 5, 5 }, ArrayTools.retainAll(a1, a2)));
+	}
+
+	public void testRetainAllIntArrayIntArray_EmptyIntArray1() {
+		int[] a1 = new int[0];
+		int[] a2 = new int[] { 5, 2 };
+		assertSame(a1, ArrayTools.retainAll(a1, a2));
+	}
+
+	public void testRetainAllIntArrayIntArray_EmptyIntArray2() {
+		int[] a1 = new int[] { 5, 2 };
+		int[] a2 = new int[0];
+		assertEquals(0, ArrayTools.retainAll(a1, a2).length);
+	}
+
+	public void testRetainAllIntArrayIntArray_RetainAll() {
+		int[] a1 = new int[] { 5, 2, 5, 2, 5, 2, 5, 2, 5, 2, 5 };
+		int[] a2 = new int[] { 5, 2 };
+		assertSame(a1, ArrayTools.retainAll(a1, a2));
+	}
+
+
+	// ********** reverse **********
+
+	public void testReverseObjectArray_Object() {
+		Object[] a = this.buildObjectArray1();
+		a = ArrayTools.reverse(a);
+		assertEquals("two", a[0]);
+		assertEquals("one", a[1]);
+		assertEquals("zero", a[2]);
+	}
+
+	public void testReverseObjectArray_String() {
+		String[] a = this.buildStringArray1();
+		a = ArrayTools.reverse(a);
+		assertEquals("two", a[0]);
+		assertEquals("one", a[1]);
+		assertEquals("zero", a[2]);
+	}
+
+	public void testReverseObjectArray_Singleton() {
+		String[] a1 = new String[] { "foo" };
+		String[] a2 = ArrayTools.reverse(a1);
+		assertTrue(Arrays.equals(a1, a2));
+	}
+
+	public void testReverseCharArray() {
+		char[] a = this.buildCharArray();
+		a = ArrayTools.reverse(a);
+		assertEquals('c', a[0]);
+		assertEquals('b', a[1]);
+		assertEquals('a', a[2]);
+	}
+
+	public void testReverseCharArray_Singleton() {
+		char[] a1 = new char[] { 'f' };
+		char[] a2 = ArrayTools.reverse(a1);
+		assertTrue(Arrays.equals(a1, a2));
+	}
+
+	public void testReverseIntArray() {
+		int[] a = this.buildIntArray();
+		a = ArrayTools.reverse(a);
+		assertEquals(20, a[0]);
+		assertEquals(10, a[1]);
+		assertEquals(0, a[2]);
+	}
+
+	public void testReverseIntArray_Singleton() {
+		int[] a1 = new int[] { 7 };
+		int[] a2 = ArrayTools.reverse(a1);
+		assertTrue(Arrays.equals(a1, a2));
+	}
+
+
+	// ********** rotate **********
+
+	public void testRotateObjectArray() {
+		String[] a = this.buildStringArray1();
+		a = ArrayTools.rotate(a);
+		assertEquals("two", a[0]);
+		assertEquals("zero", a[1]);
+		assertEquals("one", a[2]);
+	}
+
+	public void testRotateObjectArray_Zero() {
+		String[] a1 = new String[0];
+		String[] a2 = ArrayTools.rotate(a1);
+		assertSame(a1, a2);
+	}
+
+	public void testRotateObjectArray_One() {
+		String[] a1 = new String[] { "foo  " };
+		String[] a2 = ArrayTools.rotate(a1);
+		assertSame(a1, a2);
+	}
+
+	public void testRotateObjectArrayInt() {
+		String[] a = this.buildStringArray1();
+		a = ArrayTools.rotate(a, 2);
+		assertEquals("one", a[0]);
+		assertEquals("two", a[1]);
+		assertEquals("zero", a[2]);
+	}
+
+	public void testRotateObjectArrayInt_ZeroDistance() {
+		String[] a1 = this.buildStringArray1();
+		String[] a2 = ArrayTools.rotate(a1, 0);
+		assertSame(a1, a2);
+	}
+
+	public void testRotateObjectArrayInt_NegativeDistance() {
+		String[] a1 = this.buildStringArray1();
+		String[] a2 = ArrayTools.rotate(a1, -1);
+		assertEquals("one", a2[0]);
+		assertEquals("two", a2[1]);
+		assertEquals("zero", a2[2]);
+	}
+
+	public void testRotateObjectArrayInt_Zero() {
+		String[] a1 = new String[0];
+		String[] a2 = ArrayTools.rotate(a1, 7);
+		assertSame(a1, a2);
+	}
+
+	public void testRotateObjectArrayInt_One() {
+		String[] a1 = new String[] { "foo  " };
+		String[] a2 = ArrayTools.rotate(a1, 8);
+		assertSame(a1, a2);
+	}
+
+	public void testRotateCharArray() {
+		char[] a = this.buildCharArray();
+		a = ArrayTools.rotate(a);
+		assertEquals('c', a[0]);
+		assertEquals('a', a[1]);
+		assertEquals('b', a[2]);
+	}
+
+	public void testRotateCharArray_Zero() {
+		char[] a1 = new char[0];
+		char[] a2 = ArrayTools.rotate(a1);
+		assertSame(a1, a2);
+	}
+
+	public void testRotateCharArray_One() {
+		char[] a1 = new char[] { 'a' };
+		char[] a2 = ArrayTools.rotate(a1);
+		assertSame(a1, a2);
+	}
+
+	public void testRotateCharArrayInt() {
+		char[] a = this.buildCharArray();
+		a = ArrayTools.rotate(a, 2);
+		assertEquals('b', a[0]);
+		assertEquals('c', a[1]);
+		assertEquals('a', a[2]);
+	}
+
+	public void testRotateCharArrayInt_ZeroDistance() {
+		char[] a1 = new char[] { 'a', 'b', 'c' };
+		char[] a2 = ArrayTools.rotate(a1, 0);
+		assertSame(a1, a2);
+	}
+
+	public void testRotateCharArrayInt_NegativeDistance() {
+		char[] a = this.buildCharArray();
+		a = ArrayTools.rotate(a, -1);
+		assertEquals('b', a[0]);
+		assertEquals('c', a[1]);
+		assertEquals('a', a[2]);
+	}
+
+	public void testRotateCharArrayInt_Zero() {
+		char[] a1 = new char[0];
+		char[] a2 = ArrayTools.rotate(a1, 2001);
+		assertSame(a1, a2);
+	}
+
+	public void testRotateCharArrayInt_One() {
+		char[] a1 = new char[] { 'a' };
+		char[] a2 = ArrayTools.rotate(a1, 22);
+		assertSame(a1, a2);
+	}
+
+	public void testRotateIntArray() {
+		int[] a = this.buildIntArray();
+		a = ArrayTools.rotate(a);
+		assertEquals(20, a[0]);
+		assertEquals(0, a[1]);
+		assertEquals(10, a[2]);
+	}
+
+	public void testRotateIntArray_Zero() {
+		int[] a1 = new int[0];
+		int[] a2 = ArrayTools.rotate(a1);
+		assertSame(a1, a2);
+	}
+
+	public void testRotateIntArray_One() {
+		int[] a1 = new int[] { 77 };
+		int[] a2 = ArrayTools.rotate(a1);
+		assertSame(a1, a2);
+	}
+
+	public void testRotateIntArrayInt() {
+		int[] a = this.buildIntArray();
+		a = ArrayTools.rotate(a, 2);
+		assertEquals(10, a[0]);
+		assertEquals(20, a[1]);
+		assertEquals(0, a[2]);
+	}
+
+	public void testRotateIntArrayInt_ZeroDistance() {
+		int[] a1 = new int[] { 3, 2, 1 };
+		int[] a2 = ArrayTools.rotate(a1, 0);
+		assertSame(a1, a2);
+	}
+
+	public void testRotateIntArrayInt_NegativeDistance() {
+		int[] a = this.buildIntArray();
+		a = ArrayTools.rotate(a, -1);
+		assertEquals(10, a[0]);
+		assertEquals(20, a[1]);
+		assertEquals(0, a[2]);
+	}
+
+	public void testRotateIntArrayInt_Zero() {
+		int[] a1 = new int[0];
+		int[] a2 = ArrayTools.rotate(a1, 3);
+		assertSame(a1, a2);
+	}
+
+	public void testRotateIntArrayInt_One() {
+		int[] a1 = new int[] { 77 };
+		int[] a2 = ArrayTools.rotate(a1, 44);
+		assertSame(a1, a2);
+	}
+
+
+	// ********** shuffle **********
+
+	public void testShuffleObjectArray() {
+		String[] array1 = this.buildStringArray1();
+		String[] array2 = ArrayTools.shuffle(this.buildStringArray1());
+		assertEquals(array1.length, array2.length);
+		assertTrue(ArrayTools.containsAll(array1, (Object[]) array2));
+	}
+
+	public void testShuffleObjectArray_Singleton() {
+		String[] array1 = new String[] { "foo" };
+		String[] array2 = ArrayTools.shuffle(new String[] { "foo" });
+		assertEquals(array1.length, array2.length);
+		assertTrue(ArrayTools.containsAll(array1, (Object[]) array2));
+	}
+
+	public void testShuffleCharArray() {
+		char[] array1 = this.buildCharArray();
+		char[] array2 = ArrayTools.shuffle(this.buildCharArray());
+		assertEquals(array1.length, array2.length);
+		assertTrue(ArrayTools.containsAll(array1, array2));
+	}
+
+	public void testShuffleCharArray_Singleton() {
+		char[] array1 = new char[] { 'f' };
+		char[] array2 = ArrayTools.shuffle(new char[] { 'f' });
+		assertEquals(array1.length, array2.length);
+		assertTrue(ArrayTools.containsAll(array1, array2));
+	}
+
+	public void testShuffleIntArray() {
+		int[] array1 = this.buildIntArray();
+		int[] array2 = ArrayTools.shuffle(this.buildIntArray());
+		assertEquals(array1.length, array2.length);
+		assertTrue(ArrayTools.containsAll(array1, array2));
+	}
+
+	public void testShuffleIntArray_Singleton() {
+		int[] array1 = new int[] { 7 };
+		int[] array2 = ArrayTools.shuffle(new int[] { 7 });
+		assertEquals(array1.length, array2.length);
+		assertTrue(ArrayTools.containsAll(array1, array2));
+	}
+
+
+	// ********** sub-array **********
+
+	public void testSubArrayObjectArrayIntInt() {
+		String[] array = new String[] {"foo", "bar", "baz", "joo", "jar", "jaz"};
+		String[] result = new String[] {"foo", "bar", "baz", "joo"};
+		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 0, 4)));
+
+		result = new String[] {"jar"};
+		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 4, 5)));
+
+		result = new String[0];
+		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 5, 5)));
+
+		result = new String[] {"joo", "jar", "jaz"};
+		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 3, 6)));
+	}
+
+	public void testSubArrayIntArrayIntInt() {
+		int[] array = new int[] {77, 99, 333, 4, 9090, 42};
+		int[] result = new int[] {77, 99, 333, 4};
+		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 0, 4)));
+
+		result = new int[] {9090};
+		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 4, 5)));
+
+		result = new int[0];
+		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 5, 5)));
+
+		result = new int[] {4, 9090, 42};
+		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 3, 6)));
+	}
+
+	public void testSubArrayCharArrayIntInt() {
+		char[] array = new char[] {'a', 'b', 'c', 'd', 'e', 'f'};
+		char[] result = new char[] {'a', 'b', 'c', 'd'};
+		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 0, 4)));
+
+		result = new char[] {'e'};
+		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 4, 5)));
+
+		result = new char[0];
+		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 5, 5)));
+
+		result = new char[] {'d', 'e', 'f'};
+		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 3, 6)));
+	}
+
+
+	// ********** swap **********
+
+	public void testSwapObjectArray() {
+		String[] a = this.buildStringArray1();
+		a = ArrayTools.swap(a, 1, 2);
+		assertEquals("zero", a[0]);
+		assertEquals("two", a[1]);
+		assertEquals("one", a[2]);
+	}
+
+	public void testSwapObjectArray_SameIndices() {
+		String[] a1 = this.buildStringArray1();
+		String[] a2 = this.buildStringArray1();
+		a1 = ArrayTools.swap(a1, 1, 1);
+		assertTrue(Arrays.equals(a1, a2));
+	}
+
+	public void testSwapCharArray() {
+		char[] a = this.buildCharArray();
+		a = ArrayTools.swap(a, 1, 2);
+		assertEquals('a', a[0]);
+		assertEquals('c', a[1]);
+		assertEquals('b', a[2]);
+	}
+
+	public void testSwapCharArray_SameIndices() {
+		char[] a1 = this.buildCharArray();
+		char[] a2 = this.buildCharArray();
+		a1 = ArrayTools.swap(a1, 1, 1);
+		assertTrue(Arrays.equals(a1, a2));
+	}
+
+	public void testSwapIntArray() {
+		int[] a = this.buildIntArray();
+		a = ArrayTools.swap(a, 1, 2);
+		assertEquals(0, a[0]);
+		assertEquals(20, a[1]);
+		assertEquals(10, a[2]);
+	}
+
+	public void testSwapIntArray_SameIndices() {
+		int[] a1 = this.buildIntArray();
+		int[] a2 = this.buildIntArray();
+		a1 = ArrayTools.swap(a1, 1, 1);
+		assertTrue(Arrays.equals(a1, a2));
+	}
+
+
+	// ********** execute **********
+
+	public void testExecuteObjectArrayParmCommand() {
+		String[] a = this.buildStringArray1();
+		ConcatenateCommand command = new ConcatenateCommand();
+		ArrayTools.execute(a, command);
+		assertEquals("zeroonetwo", command.string);
+	}
+
+	public static class ConcatenateCommand
+		extends ParameterizedCommandAdapter<String>
+	{
+		public String string = StringTools.EMPTY_STRING;
+
+		@Override
+		public void execute(String s) {
+			this.string += s;
+		}
+	}
+
+	public void testExecuteObjectArrayInterruptibleParmCommand() throws Exception {
+		String[] a = this.buildStringArray1();
+		InterruptibleConcatenateCommand command = new InterruptibleConcatenateCommand();
+		ArrayTools.execute(a, command);
+		assertEquals("zeroonetwo", command.string);
+	}
+
+	public static class InterruptibleConcatenateCommand
+		extends InterruptibleParameterizedCommandAdapter<String>
+	{
+		public String string = StringTools.EMPTY_STRING;
+
+		@Override
+		public void execute(String s) throws InterruptedException {
+			this.string += s;
+		}
+	}
+
+
+	// ********** filter **********
+
+	public void testFilterObjectArrayFilter() {
+		String[] a = new String[] { "zero", "one", "two", "three", "four" };
+		String[] actual = ArrayTools.filter(a, new StringLengthFilter(3));
+		String[] expected = new String[] { "one", "two" };
+		assertEquals(Arrays.asList(expected), Arrays.asList(actual));
+	}
+
+	public void testFilterObjectArrayFilterTransparent() {
+		String[] a = new String[] { "zero", "one", "two", "three", "four" };
+		String[] actual = ArrayTools.filter(a, Filter.Transparent.<String>instance());
+		String[] expected = new String[] { "zero", "one", "two", "three", "four" };
+		assertEquals(Arrays.asList(expected), Arrays.asList(actual));
+		assertNotSame(expected, actual);
+	}
+
+	/**
+	 * Accept any string with the specified length.
+	 */
+	public static class StringLengthFilter
+		extends FilterAdapter<String>
+	{
+		private final int length;
+		public StringLengthFilter(int length) {
+			super();
+			this.length = length;
+		}
+		@Override
+		public boolean accept(String s) {
+			return s.length() == this.length;
+		}
+	}
+
+
+	// ********** transform **********
+
+	public void testTransformObjectArrayTransformer() {
+		String[] a = new String[] { "zero", "one", "two" };
+		Object[] actual = ArrayTools.transform(a, UPPER_CASE_TRANSFORMER);
+		Object[] expected = new Object[] { "ZERO", "ONE", "TWO" };
+		assertEquals(Arrays.asList(expected), Arrays.asList(actual));
+	}
+
+	public void testTransformObjectArrayTransformerClass() {
+		String[] a = new String[] { "zero", "one", "two" };
+		String[] actual = ArrayTools.transform(a, UPPER_CASE_TRANSFORMER, String.class);
+		String[] expected = new String[] { "ZERO", "ONE", "TWO" };
+		assertEquals(Arrays.asList(expected), Arrays.asList(actual));
+	}
+
+	public static final Transformer<String, String> UPPER_CASE_TRANSFORMER = new UpperCaseTransformer();
+
+	public static class UpperCaseTransformer
+		extends TransformerAdapter<String, String>
+	{
+		@Override
+		public String transform(String s) {
+			return s.toUpperCase();
+		}
+	}
+
+
+	// ********** Arrays enhancements **********
+
+	public void testFillBooleanArrayBoolean() {
+		boolean[] a1 = new boolean[9];
+		boolean[] a2 = ArrayTools.fill(a1, true);
+		for (boolean x : a1) {
+			assertTrue(x);
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testFillBooleanArrayIntIntBoolean() {
+		boolean[] a1 = new boolean[9];
+		boolean[] a2 = ArrayTools.fill(a1, false);
+		int from = 3;
+		int to = 6;
+		boolean[] a3 = ArrayTools.fill(a2, from, to, true);
+		for (int i = 0; i < a1.length; i++) {
+			boolean x = a1[i];
+			if (i < from || i >= to) {
+				assertFalse(x);
+			} else {
+				assertTrue(x);
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testFillByteArrayByte() {
+		byte[] a1 = new byte[9];
+		byte[] a2 = ArrayTools.fill(a1, (byte) 77);
+		for (byte x : a1) {
+			assertEquals(77, x);
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testFillByteArrayIntIntByte() {
+		byte[] a1 = new byte[9];
+		byte[] a2 = ArrayTools.fill(a1, (byte) 3);
+		int from = 3;
+		int to = 6;
+		byte[] a3 = ArrayTools.fill(a2, from, to, (byte) 77);
+		for (int i = 0; i < a1.length; i++) {
+			byte x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals(3, x);
+			} else {
+				assertEquals(77, x);
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testFillCharArrayChar() {
+		char[] a1 = new char[9];
+		char[] a2 = ArrayTools.fill(a1, 'c');
+		for (char x : a1) {
+			assertEquals('c', x);
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testFillCharArrayIntIntChar() {
+		char[] a1 = new char[9];
+		char[] a2 = ArrayTools.fill(a1, 'a');
+		int from = 3;
+		int to = 6;
+		char[] a3 = ArrayTools.fill(a2, from, to, 'c');
+		for (int i = 0; i < a1.length; i++) {
+			char x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals('a', x);
+			} else {
+				assertEquals('c', x);
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testFillDoubleArrayDouble() {
+		double[] a1 = new double[9];
+		double[] a2 = ArrayTools.fill(a1, 77.77);
+		for (double x : a1) {
+			assertEquals(77.77, x, 0.0);
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testFillDoubleArrayIntIntDouble() {
+		double[] a1 = new double[9];
+		double[] a2 = ArrayTools.fill(a1, 3.3);
+		int from = 3;
+		int to = 6;
+		double[] a3 = ArrayTools.fill(a2, from, to, 77.77);
+		for (int i = 0; i < a1.length; i++) {
+			double x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals(3.3, x, 0.0);
+			} else {
+				assertEquals(77.77, x, 0.0);
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testFillFloatArrayFloat() {
+		float[] a1 = new float[9];
+		float[] a2 = ArrayTools.fill(a1, 77.77f);
+		for (float x : a1) {
+			assertEquals(77.77f, x, 0.0);
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testFillFloatArrayIntIntFloat() {
+		float[] a1 = new float[9];
+		float[] a2 = ArrayTools.fill(a1, 3.3f);
+		int from = 3;
+		int to = 6;
+		float[] a3 = ArrayTools.fill(a2, from, to, 77.77f);
+		for (int i = 0; i < a1.length; i++) {
+			float x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals(3.3f, x, 0.0);
+			} else {
+				assertEquals(77.77f, x, 0.0);
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testFillIntArrayInt() {
+		int[] a1 = new int[9];
+		int[] a2 = ArrayTools.fill(a1, 77);
+		for (int x : a1) {
+			assertEquals(77, x);
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testFillIntArrayIntIntInt() {
+		int[] a1 = new int[9];
+		int[] a2 = ArrayTools.fill(a1, 3);
+		int from = 3;
+		int to = 6;
+		int[] a3 = ArrayTools.fill(a2, from, to, 77);
+		for (int i = 0; i < a1.length; i++) {
+			int x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals(3, x);
+			} else {
+				assertEquals(77, x);
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testFillObjectArrayObject() {
+		String[] a1 = new String[9];
+		String[] a2 = ArrayTools.fill(a1, "77");
+		for (String x : a1) {
+			assertEquals("77", x);
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testFillObjectArrayIntIntObject() {
+		String[] a1 = new String[9];
+		String[] a2 = ArrayTools.fill(a1, "3");
+		int from = 3;
+		int to = 6;
+		String[] a3 = ArrayTools.fill(a2, from, to, "77");
+		for (int i = 0; i < a1.length; i++) {
+			String x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals("3", x);
+			} else {
+				assertEquals("77", x);
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testFillLongArrayLong() {
+		long[] a1 = new long[9];
+		long[] a2 = ArrayTools.fill(a1, 77);
+		for (long x : a1) {
+			assertEquals(77, x);
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testFillLongArrayIntIntLong() {
+		long[] a1 = new long[9];
+		long[] a2 = ArrayTools.fill(a1, 3);
+		int from = 3;
+		int to = 6;
+		long[] a3 = ArrayTools.fill(a2, from, to, 77);
+		for (int i = 0; i < a1.length; i++) {
+			long x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals(3, x);
+			} else {
+				assertEquals(77, x);
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testFillShortArrayShort() {
+		short[] a1 = new short[9];
+		short[] a2 = ArrayTools.fill(a1, (short) 77);
+		for (short x : a1) {
+			assertEquals(77, x);
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testFillShortArrayIntIntShort() {
+		short[] a1 = new short[9];
+		short[] a2 = ArrayTools.fill(a1, (short) 3);
+		int from = 3;
+		int to = 6;
+		short[] a3 = ArrayTools.fill(a2, from, to, (short) 77);
+		for (int i = 0; i < a1.length; i++) {
+			short x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals(3, x);
+			} else {
+				assertEquals(77, x);
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testSortByteArray() {
+		byte[] a1 = new byte[3];
+		a1[0] = (byte) 33;
+		a1[1] = (byte) 11;
+		a1[2] = (byte) 22;
+		byte[] a2 = ArrayTools.sort(a1);
+		byte last = (byte) 0;
+		for (byte x : a1) {
+			assertTrue(last < x);
+			last = x;
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testSortByteArrayIntInt() {
+		byte[] a1 = new byte[9];
+		byte[] a2 = ArrayTools.fill(a1, (byte) 3);
+		a2[3] = (byte) 33;
+		a2[4] = (byte) 11;
+		a2[5] = (byte) 22;
+		int from = 3;
+		int to = 6;
+		byte[] a3 = ArrayTools.sort(a2, from, to);
+		byte last = (byte) 0;
+		for (int i = 0; i < a1.length; i++) {
+			byte x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals(3, x);
+			} else {
+				assertTrue(last < x);
+				last = x;
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testSortCharArray() {
+		char[] a1 = new char[3];
+		a1[0] = 'z';
+		a1[1] = 'b';
+		a1[2] = 'm';
+		char[] a2 = ArrayTools.sort(a1);
+		char last = 'a';
+		for (char x : a1) {
+			assertTrue(last < x);
+			last = x;
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testSortCharArrayIntInt() {
+		char[] a1 = new char[9];
+		char[] a2 = ArrayTools.fill(a1, 'c');
+		a2[3] = 'z';
+		a2[4] = 'b';
+		a2[5] = 'm';
+		int from = 3;
+		int to = 6;
+		char[] a3 = ArrayTools.sort(a2, from, to);
+		char last = 'a';
+		for (int i = 0; i < a1.length; i++) {
+			char x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals('c', x);
+			} else {
+				assertTrue(last < x);
+				last = x;
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testSortDoubleArray() {
+		double[] a1 = new double[3];
+		a1[0] = 33.33;
+		a1[1] = 11.11;
+		a1[2] = 22.22;
+		double[] a2 = ArrayTools.sort(a1);
+		double last = 0;
+		for (double x : a1) {
+			assertTrue(last < x);
+			last = x;
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testSortDoubleArrayIntInt() {
+		double[] a1 = new double[9];
+		double[] a2 = ArrayTools.fill(a1, 3.3);
+		a2[3] = 33.33;
+		a2[4] = 11.11;
+		a2[5] = 22.22;
+		int from = 3;
+		int to = 6;
+		double[] a3 = ArrayTools.sort(a2, from, to);
+		double last = 0;
+		for (int i = 0; i < a1.length; i++) {
+			double x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals(3.3, x, 0.0);
+			} else {
+				assertTrue(last < x);
+				last = x;
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testSortFloatArray() {
+		float[] a1 = new float[3];
+		a1[0] = 33.33f;
+		a1[1] = 11.11f;
+		a1[2] = 22.22f;
+		float[] a2 = ArrayTools.sort(a1);
+		float last = 0;
+		for (float x : a1) {
+			assertTrue(last < x);
+			last = x;
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testSortFloatArrayIntInt() {
+		float[] a1 = new float[9];
+		float[] a2 = ArrayTools.fill(a1, 3.3f);
+		a2[3] = 33.33f;
+		a2[4] = 11.11f;
+		a2[5] = 22.22f;
+		int from = 3;
+		int to = 6;
+		float[] a3 = ArrayTools.sort(a2, from, to);
+		float last = 0;
+		for (int i = 0; i < a1.length; i++) {
+			float x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals(3.3f, x, 0.0);
+			} else {
+				assertTrue(last < x);
+				last = x;
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testSortIntArray() {
+		int[] a1 = new int[3];
+		a1[0] = 33;
+		a1[1] = 11;
+		a1[2] = 22;
+		int[] a2 = ArrayTools.sort(a1);
+		int last = 0;
+		for (int x : a1) {
+			assertTrue(last < x);
+			last = x;
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testSortIntArrayIntInt() {
+		int[] a1 = new int[9];
+		int[] a2 = ArrayTools.fill(a1, 3);
+		a2[3] = 33;
+		a2[4] = 11;
+		a2[5] = 22;
+		int from = 3;
+		int to = 6;
+		int[] a3 = ArrayTools.sort(a2, from, to);
+		int last = 0;
+		for (int i = 0; i < a1.length; i++) {
+			int x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals(3, x);
+			} else {
+				assertTrue(last < x);
+				last = x;
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testSortObjectArray() {
+		String[] a1 = new String[3];
+		a1[0] = "y";
+		a1[1] = "b";
+		a1[2] = "m";
+		String[] a2 = ArrayTools.sort(a1);
+		String last = "a";
+		for (String x : a1) {
+			assertTrue(last.compareTo(x) < 0);
+			last = x;
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testSortObjectArrayComparator() {
+		String[] a1 = new String[3];
+		a1[0] = "y";
+		a1[1] = "b";
+		a1[2] = "m";
+		String[] a2 = ArrayTools.sort(a1, new ReverseComparator<String>());
+		String last = "z";
+		for (String x : a1) {
+			assertTrue(last.compareTo(x) > 0);
+			last = x;
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testSortObjectArrayIntInt() {
+		String[] a1 = new String[9];
+		String[] a2 = ArrayTools.fill(a1, "c");
+		a2[3] = "y";
+		a2[4] = "b";
+		a2[5] = "m";
+		int from = 3;
+		int to = 6;
+		String[] a3 = ArrayTools.sort(a2, from, to);
+		String last = "a";
+		for (int i = 0; i < a1.length; i++) {
+			String x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals("c", x);
+			} else {
+				assertTrue(last.compareTo(x) < 0);
+				last = x;
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testSortObjectArrayIntIntComparator() {
+		String[] a1 = new String[9];
+		String[] a2 = ArrayTools.fill(a1, "c");
+		a2[3] = "y";
+		a2[4] = "b";
+		a2[5] = "m";
+		int from = 3;
+		int to = 6;
+		String[] a3 = ArrayTools.sort(a2, from, to, new ReverseComparator<String>());
+		String last = "z";
+		for (int i = 0; i < a1.length; i++) {
+			String x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals("c", x);
+			} else {
+				assertTrue(last.compareTo(x) > 0);
+				last = x;
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testSortLongArray() {
+		long[] a1 = new long[3];
+		a1[0] = 33;
+		a1[1] = 11;
+		a1[2] = 22;
+		long[] a2 = ArrayTools.sort(a1);
+		long last = 0;
+		for (long x : a1) {
+			assertTrue(last < x);
+			last = x;
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testSortLongArrayIntInt() {
+		long[] a1 = new long[9];
+		long[] a2 = ArrayTools.fill(a1, 3);
+		a2[3] = 33;
+		a2[4] = 11;
+		a2[5] = 22;
+		int from = 3;
+		int to = 6;
+		long[] a3 = ArrayTools.sort(a2, from, to);
+		long last = 0;
+		for (int i = 0; i < a1.length; i++) {
+			long x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals(3, x);
+			} else {
+				assertTrue(last < x);
+				last = x;
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+	public void testSortShortArray() {
+		short[] a1 = new short[3];
+		a1[0] = (short) 33;
+		a1[1] = (short) 11;
+		a1[2] = (short) 22;
+		short[] a2 = ArrayTools.sort(a1);
+		short last = (short) 0;
+		for (short x : a1) {
+			assertTrue(last < x);
+			last = x;
+		}
+		assertSame(a1, a2);
+	}
+
+	public void testSortShortArrayIntInt() {
+		short[] a1 = new short[9];
+		short[] a2 = ArrayTools.fill(a1, (short) 3);
+		a2[3] = (short) 33;
+		a2[4] = (short) 11;
+		a2[5] = (short) 22;
+		int from = 3;
+		int to = 6;
+		short[] a3 = ArrayTools.sort(a2, from, to);
+		short last = (short) 0;
+		for (int i = 0; i < a1.length; i++) {
+			short x = a1[i];
+			if (i < from || i >= to) {
+				assertEquals(3, x);
+			} else {
+				assertTrue(last < x);
+				last = x;
+			}
+		}
+		assertSame(a1, a2);
+		assertSame(a1, a3);
+	}
+
+
+	// ********** constructor **********
+
+	public void testConstructor() {
+		boolean exCaught = false;
+		try {
+			Object at = ClassTools.newInstance(ArrayTools.class);
+			fail("bogus: " + at);
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof InvocationTargetException) {
+				if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+
+	// ********** utility **********
+
+	private Object[] buildObjectArray1() {
+		return new Object[] { "zero", "one", "two" };
+	}
+
+	private String[] buildStringArray1() {
+		return new String[] { "zero", "one", "two" };
+	}
+
+	private char[] buildCharArray() {
+		return new char[] { 'a', 'b', 'c' };
+	}
+
+	private int[] buildIntArray() {
+		return new int[] { 0, 10, 20 };
+	}
+
+	private Object[] buildObjectArray2() {
+		return new Object[] { "three", "four", "five" };
+	}
+
+	private String[] buildStringArray2() {
+		return new String[] { "three", "four", "five" };
+	}
+
+	private List<String> buildStringList1() {
+		List<String> l = new ArrayList<String>();
+		this.addToCollection1(l);
+		return l;
+	}
+
+	private List<Object> buildObjectList1() {
+		List<Object> l = new ArrayList<Object>();
+		this.addToCollection1(l);
+		return l;
+	}
+
+	private void addToCollection1(Collection<? super String> c) {
+		c.add("zero");
+		c.add("one");
+		c.add("two");
+	}
+
+	private List<String> buildStringList2() {
+		List<String> l = new ArrayList<String>();
+		this.addToCollection2(l);
+		return l;
+	}
+
+	private void addToCollection2(Collection<? super String> c) {
+		c.add("three");
+		c.add("four");
+		c.add("five");
+	}
+
+	private Vector<String> buildStringVector1() {
+		Vector<String> v = new Vector<String>();
+		this.addToCollection1(v);
+		return v;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/BitToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/BitToolsTests.java
new file mode 100644
index 0000000..e1102d1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/BitToolsTests.java
@@ -0,0 +1,340 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.lang.reflect.InvocationTargetException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.BitTools;
+import org.eclipse.persistence.tools.utility.ClassTools;
+
+
+public class BitToolsTests
+	extends TestCase
+{
+	public BitToolsTests(String name) {
+		super(name);
+	}
+
+	public void testFlagIsSetIntInt() {
+		assertTrue(BitTools.flagIsSet(0x0003, 0x0001));
+		assertTrue(BitTools.flagIsSet(0x0303, 0x0001));
+		assertTrue(BitTools.flagIsSet(0x0303, 0x0101));
+		assertTrue(BitTools.flagIsSet(0x0303, 0x0103));
+
+		assertFalse(BitTools.flagIsSet(0x0303, 0x1103));
+		assertFalse(BitTools.flagIsSet(0x0000, 0x1103));
+	}
+
+	public void testSetFlagIntInt() {
+		assertEquals(0x0003, BitTools.setFlag(0x0003, 0x0001));
+
+		assertEquals(0x1303, BitTools.setFlag(0x0303, 0x1103));
+		assertEquals(0x1103, BitTools.setFlag(0x0000, 0x1103));
+	}
+
+	public void testFlagIsOffIntInt() {
+		assertFalse(BitTools.flagIsOff(0x0003, 0x0001));
+		assertFalse(BitTools.flagIsOff(0x0303, 0x0001));
+		assertFalse(BitTools.flagIsOff(0x0303, 0x0101));
+		assertFalse(BitTools.flagIsOff(0x0303, 0x0103));
+
+		assertTrue(BitTools.flagIsOff(0x2204, 0x1103));
+		assertTrue(BitTools.flagIsOff(0x0000, 0x1103));
+	}
+
+	public void testClearFlagIntInt() {
+		assertEquals(0x0002, BitTools.clearFlag(0x0003, 0x0001));
+
+		assertEquals(0x0200, BitTools.clearFlag(0x0303, 0x1103));
+		assertEquals(0x0000, BitTools.clearFlag(0x0000, 0x1103));
+	}
+
+	public void testOnlyFlagIsSetIntInt() {
+		assertFalse(BitTools.onlyFlagIsSet(0x0003, 0x0001));
+		assertTrue(BitTools.onlyFlagIsSet(0x0001, 0x0001));
+
+		assertFalse(BitTools.onlyFlagIsSet(0x0303, 0x0001));
+		assertTrue(BitTools.onlyFlagIsSet(0x0001, 0x0001));
+
+		assertFalse(BitTools.onlyFlagIsSet(0x0303, 0x0101));
+		assertTrue(BitTools.onlyFlagIsSet(0x0101, 0x0101));
+
+		assertFalse(BitTools.onlyFlagIsSet(0x0303, 0x0103));
+		assertTrue(BitTools.onlyFlagIsSet(0x0103, 0x0103));
+
+		assertFalse(BitTools.onlyFlagIsSet(0x0303, 0x1103));
+		assertTrue(BitTools.onlyFlagIsSet(0x1103, 0x1103));
+
+		assertFalse(BitTools.onlyFlagIsSet(0x0000, 0x1103));
+		assertTrue(BitTools.onlyFlagIsSet(0x0103, 0x0103));
+	}
+
+	public void testOnlyFlagIsOffIntInt() {
+		assertFalse(BitTools.onlyFlagIsOff(0x0003, 0x0001));
+		assertFalse(BitTools.onlyFlagIsOff(0x0303, 0x0001));
+		assertTrue(BitTools.onlyFlagIsOff(0xFFFFFFFE, 0x0001));
+
+		assertFalse(BitTools.onlyFlagIsOff(0x0303, 0x0101));
+		assertTrue(BitTools.onlyFlagIsOff(0xFFFFFEFE, 0x0101));
+
+		assertFalse(BitTools.onlyFlagIsOff(0x0303, 0x0103));
+		assertTrue(BitTools.onlyFlagIsOff(0xFFFFFEFC, 0x0103));
+
+		assertFalse(BitTools.onlyFlagIsOff(0x0303, 0x1103));
+		assertTrue(BitTools.onlyFlagIsOff(0xFFFFEEFC, 0x1103));
+	}
+
+	public void testAllFlagsAreSetIntInt() {
+		assertTrue(BitTools.allFlagsAreSet(0x0003, 0x0001));
+		assertTrue(BitTools.allFlagsAreSet(0x0303, 0x0001));
+		assertTrue(BitTools.allFlagsAreSet(0x0303, 0x0101));
+		assertTrue(BitTools.allFlagsAreSet(0x0303, 0x0103));
+
+		assertFalse(BitTools.allFlagsAreSet(0x0303, 0x1103));
+		assertFalse(BitTools.allFlagsAreSet(0x0000, 0x1103));
+	}
+
+	public void testSetAllFlagsIntInt() {
+		assertEquals(0x0003, BitTools.setAllFlags(0x0003, 0x0001));
+
+		assertEquals(0x1303, BitTools.setAllFlags(0x0303, 0x1103));
+		assertEquals(0x1103, BitTools.setAllFlags(0x0000, 0x1103));
+	}
+
+	public void testAllFlagsAreOffIntInt() {
+		assertFalse(BitTools.allFlagsAreOff(0x0003, 0x0001));
+		assertFalse(BitTools.allFlagsAreOff(0x0303, 0x0001));
+		assertFalse(BitTools.allFlagsAreOff(0x0303, 0x0101));
+		assertFalse(BitTools.allFlagsAreOff(0x0303, 0x0103));
+
+		assertTrue(BitTools.allFlagsAreOff(0x2204, 0x1103));
+		assertTrue(BitTools.allFlagsAreOff(0x0000, 0x1103));
+	}
+
+	public void testClearAllFlagsIntInt() {
+		assertEquals(0x0002, BitTools.clearAllFlags(0x0003, 0x0001));
+
+		assertEquals(0x0200, BitTools.clearAllFlags(0x0303, 0x1103));
+		assertEquals(0x0000, BitTools.clearAllFlags(0x0000, 0x1103));
+	}
+
+	public void testOnlyFlagsAreSetIntInt() {
+		assertFalse(BitTools.onlyFlagsAreSet(0x0003, 0x0001));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0001, 0x0001));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, 0x0001));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0001, 0x0001));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, 0x0101));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0101, 0x0101));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, 0x0103));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0103, 0x0103));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, 0x1103));
+		assertTrue(BitTools.onlyFlagsAreSet(0x1103, 0x1103));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0000, 0x1103));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0103, 0x0103));
+	}
+
+	public void testOnlyFlagsAreOffIntInt() {
+		assertFalse(BitTools.onlyFlagsAreOff(0x0003, 0x0001));
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, 0x0001));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFFFE, 0x0001));
+
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, 0x0101));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFEFE, 0x0101));
+
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, 0x0103));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFEFC, 0x0103));
+
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, 0x1103));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFEEFC, 0x1103));
+	}
+
+	public void testAnyFlagsAreSetIntInt() {
+		assertTrue(BitTools.anyFlagsAreSet(0x0003, 0x0001));
+		assertTrue(BitTools.anyFlagsAreSet(0xFFFF, 0x0001));
+		assertTrue(BitTools.anyFlagsAreSet(0x0003, 0xFFFF));
+
+		assertFalse(BitTools.anyFlagsAreSet(0x0303, 0x1010));
+		assertFalse(BitTools.anyFlagsAreSet(0x0000, 0xFFFF));
+	}
+
+	public void testAnyFlagsAreOffIntInt() {
+		assertTrue(BitTools.anyFlagsAreOff(0x333E, 0x0001));
+		assertTrue(BitTools.anyFlagsAreOff(0xFFFE, 0x0001));
+		assertTrue(BitTools.anyFlagsAreOff(0x0003, 0xFFFF));
+
+		assertFalse(BitTools.anyFlagsAreOff(0x7373, 0x1010));
+		assertFalse(BitTools.anyFlagsAreOff(0xFFFF, 0xFFFF));
+	}
+
+	public void testAllFlagsAreSetIntIntArray() {
+		assertTrue(BitTools.allFlagsAreSet(0x0003, new int[] { 0x0001 }));
+		assertTrue(BitTools.allFlagsAreSet(0x0303, new int[] { 0x0001 }));
+		assertTrue(BitTools.allFlagsAreSet(0x0303, new int[] { 0x0100, 0x0001 }));
+		assertTrue(BitTools.allFlagsAreSet(0x0303, new int[] { 0x0100, 0x0002, 0x0001 }));
+
+		assertFalse(BitTools.allFlagsAreSet(0x0303, new int[] { 0x1000, 0x0100, 0x0002, 0x0001 }));
+		assertFalse(BitTools.allFlagsAreSet(0x0000, new int[] { 0x1000, 0x0100, 0x0002, 0x0001 }));
+	}
+
+	public void testSetAllFlagsIntIntArray() {
+		assertEquals(0x0003, BitTools.setAllFlags(0x0003, new int[] { 0x0001 }));
+
+		assertEquals(0x1303, BitTools.setAllFlags(0x0303, new int[] { 0x0003, 0x1100 }));
+		assertEquals(0x1103, BitTools.setAllFlags(0x0000, new int[] { 0x0003, 0x1100 }));
+	}
+
+	public void testAllFlagsAreOffIntIntArray() {
+		assertFalse(BitTools.allFlagsAreOff(0x0003, new int[] { 0x0001 }));
+		assertFalse(BitTools.allFlagsAreOff(0x0303, new int[] { 0x0001 }));
+		assertFalse(BitTools.allFlagsAreOff(0x0303, new int[] { 0x0100, 0x0001 }));
+		assertFalse(BitTools.allFlagsAreOff(0x0303, new int[] { 0x0100, 0x0002, 0x0001 }));
+
+		assertTrue(BitTools.allFlagsAreOff(0x0303, new int[] { 0x1000, 0x0400, 0x0020, 0x0000 }));
+		assertTrue(BitTools.allFlagsAreOff(0x0000, new int[] { 0x1000, 0x0100, 0x0002, 0x0001 }));
+	}
+
+	public void testClearAllFlagsIntIntArray() {
+		assertEquals(0x0002, BitTools.clearAllFlags(0x0003, new int[] { 0x0001 }));
+
+		assertEquals(0x0200, BitTools.clearAllFlags(0x0303, new int[] { 0x0003, 0x1100 }));
+		assertEquals(0x0000, BitTools.clearAllFlags(0x0000, new int[] { 0x0003, 0x1100 }));
+	}
+
+	public void testOnlyFlagsAreSetIntIntArray() {
+		assertFalse(BitTools.onlyFlagsAreSet(0x0003, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0001, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0001, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, new int[] { 0x001, 0x0100, 0x0000, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0101, new int[] { 0x001, 0x0100, 0x0000, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, new int[] { 0x001, 0x0100, 0x0002, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0103, new int[] { 0x001, 0x0100, 0x0002, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, new int[] { 0x011, 0x0100, 0x0002, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreSet(0x1103, new int[] { 0x1100, 0x0100, 0x0002, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0000, new int[] { 0x011, 0x0100, 0x0002, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0103, new int[] { 0x0101, 0x0100, 0x0002, 0x0001 }));
+	}
+
+	public void testOnlyFlagsAreOffIntIntArray() {
+		assertFalse(BitTools.onlyFlagsAreOff(0x0003, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFFFE, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, new int[] { 0x001, 0x0100, 0x0000, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFEFE, new int[] { 0x001, 0x0100, 0x0000, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, new int[] { 0x001, 0x0100, 0x0002, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFEFC, new int[] { 0x001, 0x0100, 0x0002, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, new int[] { 0x1100, 0x0100, 0x0002, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFEEFC, new int[] { 0x1100, 0x0100, 0x0002, 0x0001 }));
+	}
+
+	public void testAnyFlagsAreSetIntIntArray() {
+		assertTrue(BitTools.anyFlagsAreSet(0x0003, new int[] { 0x0001 }));
+		assertTrue(BitTools.anyFlagsAreSet(0xFFFF, new int[] { 0x0001 }));
+		assertTrue(BitTools.anyFlagsAreSet(0x0303, new int[] { 0xF000, 0x0F00, 0x00F0, 0x000F }));
+
+		assertFalse(BitTools.anyFlagsAreSet(0x0303, new int[] { 0x1000, 0x0010 }));
+		assertFalse(BitTools.anyFlagsAreSet(0x0000, new int[] { 0xF000, 0x0F00, 0x00F0, 0x000F }));
+	}
+
+	public void testAnyFlagsAreOffIntIntArray() {
+		assertFalse(BitTools.anyFlagsAreOff(0x0003, new int[] { 0x0001 }));
+		assertFalse(BitTools.anyFlagsAreOff(0xFFFF, new int[] { 0x0001 }));
+		assertFalse(BitTools.anyFlagsAreOff(0x0303, new int[] { 0x0100, 0x0200, 0x0003, 0x0002 }));
+
+		assertTrue(BitTools.anyFlagsAreOff(0x0303, new int[] { 0x0100, 0x0010 }));
+		assertTrue(BitTools.anyFlagsAreOff(0x0000, new int[] { 0xF000, 0x0F00, 0x00F0, 0x000F }));
+	}
+
+	public void testOrFlags() {
+		assertEquals(0x0001, BitTools.orFlags(new int[] { 0x0001, 0x0000 }));
+		assertEquals(0x0011, BitTools.orFlags(new int[] { 0x0001, 0x0011 }));
+		assertEquals(0xF011, BitTools.orFlags(new int[] { 0x0001, 0x0011, 0xF000 }));
+	}
+
+	public void testAndFlags() {
+		assertEquals(0x0001, BitTools.andFlags(new int[] { 0x0001, 0x0001 }));
+		assertEquals(0x0001, BitTools.andFlags(new int[] { 0x0001, 0x0011 }));
+		assertEquals(0x0000, BitTools.andFlags(new int[] { 0x0001, 0x0011, 0xF000 }));
+		assertEquals(0x0001, BitTools.andFlags(new int[] { 0x0001, 0x0011, 0xF001 }));
+	}
+
+	public void testXorFlags() {
+		assertEquals(0x0001, BitTools.xorFlags(new int[] { 0x0001, 0x0000 }));
+		assertEquals(0x0010, BitTools.xorFlags(new int[] { 0x0001, 0x0011 }));
+		assertEquals(0xF010, BitTools.xorFlags(new int[] { 0x0001, 0x0011, 0xF000 }));
+		assertEquals(0xFF11, BitTools.xorFlags(new int[] { 0x0001, 0x0011, 0xF000, 0x0F01 }));
+		assertEquals(0xF010, BitTools.xorFlags(new int[] { 0x0001, 0x0011, 0xF000, 0x0F01, 0x0F01 }));
+	}
+
+	public void testIsEven() {
+		assertTrue(BitTools.isEven(-22));
+		assertTrue(BitTools.isEven(0));
+		assertTrue(BitTools.isEven(22));
+
+		assertFalse(BitTools.isEven(-21));
+		assertFalse(BitTools.isEven(21));
+	}
+
+	public void testIsOdd() {
+		assertFalse(BitTools.isOdd(-22));
+		assertFalse(BitTools.isOdd(0));
+		assertFalse(BitTools.isOdd(22));
+
+		assertTrue(BitTools.isOdd(-21));
+		assertTrue(BitTools.isOdd(21));
+	}
+
+	public void testHalf() {
+		assertEquals(-11, BitTools.half(-22));
+		assertEquals(0, BitTools.half(0));
+		assertEquals(11, BitTools.half(22));
+
+		assertEquals(-11, BitTools.half(-21));
+		assertEquals(10, BitTools.half(21));
+	}
+
+	public void testTwice() {
+		assertEquals(-22, BitTools.twice(-11));
+		assertEquals(0, BitTools.twice(0));
+		assertEquals(22, BitTools.twice(11));
+	}
+
+	public void testConstructor() {
+		boolean exCaught = false;
+		try {
+			Object at = ClassTools.newInstance(BitTools.class);
+			fail("bogus: " + at); //$NON-NLS-1$
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof InvocationTargetException) {
+				if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/BooleanToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/BooleanToolsTests.java
new file mode 100644
index 0000000..70f2c8d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/BooleanToolsTests.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.lang.reflect.InvocationTargetException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.BooleanTools;
+import org.eclipse.persistence.tools.utility.ClassTools;
+
+
+public class BooleanToolsTests
+	extends TestCase
+{
+	private static final Boolean TRUE = Boolean.TRUE;
+	private static final Boolean FALSE = Boolean.FALSE;
+
+	public BooleanToolsTests(String name) {
+		super(name);
+	}
+
+	public void testNOT() {
+		assertEquals(FALSE, BooleanTools.not(TRUE));
+		assertEquals(TRUE, BooleanTools.not(FALSE));
+	}
+
+	public void testAND() {
+		assertEquals(TRUE, BooleanTools.and(TRUE, TRUE));
+		assertEquals(FALSE, BooleanTools.and(TRUE, FALSE));
+		assertEquals(FALSE, BooleanTools.and(FALSE, TRUE));
+		assertEquals(FALSE, BooleanTools.and(FALSE, FALSE));
+	}
+
+	public void testOR() {
+		assertEquals(TRUE, BooleanTools.or(TRUE, TRUE));
+		assertEquals(TRUE, BooleanTools.or(TRUE, FALSE));
+		assertEquals(TRUE, BooleanTools.or(FALSE, TRUE));
+		assertEquals(FALSE, BooleanTools.or(FALSE, FALSE));
+	}
+
+	public void testXOR() {
+		assertEquals(FALSE, BooleanTools.xor(TRUE, TRUE));
+		assertEquals(TRUE, BooleanTools.xor(TRUE, FALSE));
+		assertEquals(TRUE, BooleanTools.xor(FALSE, TRUE));
+		assertEquals(FALSE, BooleanTools.xor(FALSE, FALSE));
+	}
+
+	public void testNAND() {
+		assertEquals(FALSE, BooleanTools.nand(TRUE, TRUE));
+		assertEquals(TRUE, BooleanTools.nand(TRUE, FALSE));
+		assertEquals(TRUE, BooleanTools.nand(FALSE, TRUE));
+		assertEquals(TRUE, BooleanTools.nand(FALSE, FALSE));
+	}
+
+	public void testNOR() {
+		assertEquals(FALSE, BooleanTools.nor(TRUE, TRUE));
+		assertEquals(FALSE, BooleanTools.nor(TRUE, FALSE));
+		assertEquals(FALSE, BooleanTools.nor(FALSE, TRUE));
+		assertEquals(TRUE, BooleanTools.nor(FALSE, FALSE));
+	}
+
+	public void testXNOR() {
+		assertEquals(TRUE, BooleanTools.xnor(TRUE, TRUE));
+		assertEquals(FALSE, BooleanTools.xnor(TRUE, FALSE));
+		assertEquals(FALSE, BooleanTools.xnor(FALSE, TRUE));
+		assertEquals(TRUE, BooleanTools.xnor(FALSE, FALSE));
+	}
+
+	public void testConstructor() {
+		boolean exCaught = false;
+		try {
+			Object at = ClassTools.newInstance(BooleanTools.class);
+			fail("bogus: " + at); //$NON-NLS-1$
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof InvocationTargetException) {
+				if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ByteArrayToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ByteArrayToolsTests.java
new file mode 100644
index 0000000..f758a67
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ByteArrayToolsTests.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ByteArrayTools;
+
+
+@SuppressWarnings("nls")
+public class ByteArrayToolsTests
+	extends TestCase
+{
+	public ByteArrayToolsTests(String name) {
+		super(name);
+	}
+
+	// ********** convert to hex string **********
+
+	public void testConvertToHexString() throws Exception {
+		String s = "test";
+		assertEquals("74657374", ByteArrayTools.convertToHexString(s.getBytes())); // UTF-8 values
+	}
+
+	public void testConvertToHexString_negative() throws Exception {
+		String s = "caf\u00E9"; // cafe'
+		assertEquals(this.getHexCafe(), ByteArrayTools.convertToHexString(s.getBytes()));
+	}
+
+	public void testConvertToHexCharArray() throws Exception {
+		String s = "test";
+		TestTools.assertEquals("74657374", ByteArrayTools.convertToHexCharArray(s.getBytes()));
+	}
+
+	public void testConvertToHexCharArray_negative() throws Exception {
+		String s = "caf\u00E9"; // cafe'
+		TestTools.assertEquals(this.getHexCafe(), ByteArrayTools.convertToHexCharArray(s.getBytes()));
+	}
+
+	private String getHexCafe() {
+		return StringToolsTests.getHexCafe();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CancelExceptionTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CancelExceptionTests.java
new file mode 100644
index 0000000..595b6a5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CancelExceptionTests.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.CancelException;
+
+public class CancelExceptionTests
+	extends TestCase
+{
+	public CancelExceptionTests(String name) {
+		super(name);
+	}
+
+	public void testConstruction() {
+		CancelException ex = new CancelException();
+		assertNotNull(ex);
+	}
+
+	public void testToString() {
+		CancelException ex = new CancelException();
+		assertNotNull(ex.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CharArrayToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CharArrayToolsTests.java
new file mode 100644
index 0000000..ebaa8c7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CharArrayToolsTests.java
@@ -0,0 +1,589 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.util.Arrays;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ByteArrayTools;
+import org.eclipse.persistence.tools.utility.CharArrayTools;
+import org.eclipse.persistence.tools.utility.StringTools;
+
+@SuppressWarnings("nls")
+public class CharArrayToolsTests
+	extends TestCase
+{
+	// ********** padding/truncating/centering **********
+
+	public void testCenter() {
+		TestTools.assertEquals("fred", CharArrayTools.center("fred".toCharArray(), 4));
+		TestTools.assertEquals(" fred ", CharArrayTools.center("fred".toCharArray(), 6));
+		TestTools.assertEquals(" fred  ", CharArrayTools.center("fred".toCharArray(), 7));
+		TestTools.assertEquals("re", CharArrayTools.center("fred".toCharArray(), 2));
+		TestTools.assertEquals("fre", CharArrayTools.center("fred".toCharArray(), 3));
+	}
+
+	public void testPad() {
+		TestTools.assertEquals("fred", CharArrayTools.pad(new char[] { 'f', 'r', 'e', 'd' }, 4));
+		TestTools.assertEquals("fred  ", CharArrayTools.pad(new char[] { 'f', 'r', 'e', 'd' }, 6));
+		boolean exThrown = false;
+		try {
+			TestTools.assertEquals("fr", CharArrayTools.pad(new char[] { 'f', 'r', 'e', 'd' }, 2));
+		} catch (IllegalArgumentException ex) {
+			exThrown = true;
+		}
+		assertTrue(exThrown);
+	}
+
+	public void testFit() {
+		TestTools.assertEquals("fred", CharArrayTools.fit(new char[] { 'f', 'r', 'e', 'd' }, 4));
+		TestTools.assertEquals("fred  ", CharArrayTools.fit(new char[] { 'f', 'r', 'e', 'd' }, 6));
+		TestTools.assertEquals("fr", CharArrayTools.fit(new char[] { 'f', 'r', 'e', 'd' }, 2));
+	}
+
+	public void testZeroPad() {
+		TestTools.assertEquals("1234", CharArrayTools.zeroPad(new char[] { '1', '2', '3', '4' }, 4));
+		TestTools.assertEquals("001234", CharArrayTools.zeroPad(new char[] { '1', '2', '3', '4' }, 6));
+		boolean exThrown = false;
+		try {
+			TestTools.assertEquals("12", CharArrayTools.zeroPad(new char[] { '1', '2', '3', '4' }, 2));
+		} catch (IllegalArgumentException ex) {
+			exThrown = true;
+		}
+		assertTrue(exThrown);
+	}
+
+	public void testZeroFit() {
+		TestTools.assertEquals("1234", CharArrayTools.zeroFit(new char[] { '1', '2', '3', '4' }, 4));
+		TestTools.assertEquals("001234", CharArrayTools.zeroFit(new char[] { '1', '2', '3', '4' }, 6));
+		TestTools.assertEquals("34", CharArrayTools.zeroFit(new char[] { '1', '2', '3', '4' }, 2));
+	}
+
+	// ********** separating **********
+
+	public void testSeparate() {
+		this.verifySeparate("012345", '-', 22, "012345");
+		this.verifySeparate("012345", '-',  6, "012345");
+		this.verifySeparate("012345", '-',  5, "01234-5");
+		this.verifySeparate("012345", '-',  4, "0123-45");
+		this.verifySeparate("012345", '-',  3, "012-345");
+		this.verifySeparate("012345", '-',  2, "01-23-45");
+		this.verifySeparate("012345", '-',  1, "0-1-2-3-4-5");
+	}
+
+	private void verifySeparate(String string, char separator, int segmentLength, String expected) {
+		TestTools.assertEquals(expected, CharArrayTools.separate(string.toCharArray(), separator, segmentLength));
+	}
+
+	// ********** removing characters **********
+
+	public void testRemoveFirstOccurrence() {
+		this.verifyRemoveFirstOccurrence("Emplo&yee", '&', "Employee");
+		this.verifyRemoveFirstOccurrence("Emplo&yee&", '&', "Employee&");
+		this.verifyRemoveFirstOccurrence("Employee &Foo", '&', "Employee Foo");
+		this.verifyRemoveFirstOccurrence("Employee&", '&', "Employee");
+		this.verifyRemoveFirstOccurrence("&Employee", '&', "Employee");
+	}
+
+	private void verifyRemoveFirstOccurrence(String string, char charToRemove, String expectedString) {
+		TestTools.assertEquals(expectedString, CharArrayTools.removeFirstOccurrence(string.toCharArray(), charToRemove));
+	}
+
+	public void testRemoveAllOccurrences() {
+		this.verifyRemoveAllOccurrences("Employee Fred", ' ', "EmployeeFred");
+		this.verifyRemoveAllOccurrences(" Employee ", ' ', "Employee");
+		this.verifyRemoveAllOccurrences("Employee   Foo", ' ', "EmployeeFoo");
+		this.verifyRemoveAllOccurrences(" Emp loyee   Foo", ' ', "EmployeeFoo");
+	}
+
+	private void verifyRemoveAllOccurrences(String string, char charToRemove, String expectedString) {
+		TestTools.assertEquals(expectedString, CharArrayTools.removeAllOccurrences(string.toCharArray(), charToRemove));
+	}
+
+	public void testRemoveAllWhitespace() {
+		this.verifyRemoveAllWhitespace("Employee Fred\t", "EmployeeFred");
+		this.verifyRemoveAllWhitespace("\tEmployee\n", "Employee");
+		this.verifyRemoveAllWhitespace("Employee \t Foo", "EmployeeFoo");
+		this.verifyRemoveAllWhitespace(" Emp\tloyee \n Foo", "EmployeeFoo");
+	}
+
+	private void verifyRemoveAllWhitespace(String string, String expectedString) {
+		TestTools.assertEquals(expectedString, CharArrayTools.removeAllWhitespace(string.toCharArray()));
+	}
+
+	public void testCompressWhitespace() {
+		this.verifyCompressWhitespace("Employee      Fred\t", "Employee Fred ");
+		this.verifyCompressWhitespace("\tEmployee  \n", " Employee ");
+		this.verifyCompressWhitespace("Employee \t Foo", "Employee Foo");
+		this.verifyCompressWhitespace(" Emp\tloyee \n Foo ", " Emp loyee Foo ");
+	}
+
+	private void verifyCompressWhitespace(String string, String expectedString) {
+		TestTools.assertEquals(expectedString, CharArrayTools.compressWhitespace(string.toCharArray()));
+	}
+
+	// ********** common prefix **********
+
+	// ********** capitalization **********
+
+	public void testCapitalize() {
+		this.verifyCapitalize("Oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyCapitalize("Oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyCapitalize("   ", new char[] { ' ', ' ', ' ' });
+		this.verifyCapitalize("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
+		this.verifyCapitalize("", new char[0]);
+		this.verifyCapitalize("A", new char[] { 'a' });
+		this.verifyCapitalize("\u00C9cole", new char[] { '\u00E9', 'c', 'o', 'l', 'e' });
+	}
+
+	private void verifyCapitalize(String expected, char[] string) {
+		TestTools.assertEquals(expected, CharArrayTools.capitalize(string));
+	}
+
+	public void testUnapitalize() {
+		this.verifyUncapitalize("oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyUncapitalize("oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyUncapitalize("   ", new char[] { ' ', ' ', ' ' });
+		this.verifyUncapitalize("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
+		this.verifyUncapitalize("", new char[0]);
+		this.verifyUncapitalize("a", new char[] { 'A' });
+		this.verifyUncapitalize("\u00E9cole", new char[] { '\u00C9', 'c', 'o', 'l', 'e' });
+	}
+
+	private void verifyUncapitalize(String expected, char[] string) {
+		TestTools.assertEquals(expected, CharArrayTools.uncapitalize(string));
+	}
+
+	// ********** queries **********
+
+	public void testIsBlank() {
+		assertTrue(CharArrayTools.isBlank((char[]) null));
+		this.verifyIsBlank("");
+		this.verifyIsBlank("      \t\t   ");
+		this.verifyIsBlank("      ");
+		this.verifyIsBlank("      \t\t   " + StringTools.CR);
+	}
+
+	private void verifyIsBlank(String string) {
+		assertTrue(CharArrayTools.isBlank(string.toCharArray()));
+	}
+
+	public void testEqualsIgnoreCase() {
+		assertTrue(CharArrayTools.equalsIgnoreCase((char[]) null, (char[]) null));
+		assertFalse(CharArrayTools.equalsIgnoreCase((char[]) null, "asdf".toCharArray()));
+		assertFalse(CharArrayTools.equalsIgnoreCase("asdf".toCharArray(), (char[]) null));
+		assertTrue(CharArrayTools.equalsIgnoreCase("asdf".toCharArray(), "asdf".toCharArray()));
+		assertTrue(CharArrayTools.equalsIgnoreCase("asdf".toCharArray(), "ASDF".toCharArray()));
+	}
+
+	public void testStartsWithIgnoreCase() {
+		assertTrue(CharArrayTools.startsWithIgnoreCase("asdf".toCharArray(), "as".toCharArray()));
+		assertTrue(CharArrayTools.startsWithIgnoreCase("asdf".toCharArray(), "aS".toCharArray()));
+		assertTrue(CharArrayTools.startsWithIgnoreCase("asdf".toCharArray(), "".toCharArray()));
+		assertTrue(CharArrayTools.startsWithIgnoreCase("asdf".toCharArray(), "A".toCharArray()));
+		assertTrue(CharArrayTools.startsWithIgnoreCase("asdf".toCharArray(), "ASDF".toCharArray()));
+		assertTrue(CharArrayTools.startsWithIgnoreCase("asdf".toCharArray(), "asdf".toCharArray()));
+
+		assertFalse(CharArrayTools.startsWithIgnoreCase("asdf".toCharArray(), "bsdf".toCharArray()));
+		assertFalse(CharArrayTools.startsWithIgnoreCase("asdf".toCharArray(), "g".toCharArray()));
+		assertFalse(CharArrayTools.startsWithIgnoreCase("asdf".toCharArray(), "asdg".toCharArray()));
+		assertFalse(CharArrayTools.startsWithIgnoreCase("asdf".toCharArray(), "asdfg".toCharArray()));
+		assertFalse(CharArrayTools.startsWithIgnoreCase("asdf".toCharArray(), "asdfgggggg".toCharArray()));
+	}
+
+	public void testIsUppercase() {
+		this.verifyIsUppercase("FOO");
+		this.verifyIsUppercase("FOO2");
+		this.verifyIsUppercase("F O O");
+		this.denyIsUppercase("Foo");
+		this.denyIsUppercase("");
+	}
+
+	private void verifyIsUppercase(String s) {
+		assertTrue(CharArrayTools.isUppercase(s.toCharArray()));
+	}
+
+	private void denyIsUppercase(String s) {
+		assertFalse(CharArrayTools.isUppercase(s.toCharArray()));
+	}
+
+	public void testIsLowercase() {
+		this.verifyIsLowercase("foo");
+		this.verifyIsLowercase("foo2");
+		this.verifyIsLowercase("f o o");
+		this.denyIsLowercase("Foo");
+		this.denyIsLowercase("");
+	}
+
+	private void verifyIsLowercase(String s) {
+		assertTrue(CharArrayTools.isLowercase(s.toCharArray()));
+	}
+
+	private void denyIsLowercase(String s) {
+		assertFalse(CharArrayTools.isLowercase(s.toCharArray()));
+	}
+
+	// ********** byte arrays **********
+
+	public void testConvertHexStringToByteArray_empty() throws Exception {
+		char[] s = CharArrayTools.EMPTY_CHAR_ARRAY;
+		byte[] byteArray = CharArrayTools.convertHexStringToByteArray(s);
+		assertEquals(0, byteArray.length);
+		assertTrue(Arrays.equals(ByteArrayTools.EMPTY_BYTE_ARRAY, byteArray));
+	}
+
+	public void testConvertHexStringToByteArray_oddLength() throws Exception {
+		String s = "CAFEE";
+		boolean exCaught = false;
+		try {
+			byte[] byteArray = CharArrayTools.convertHexStringToByteArray(s.toCharArray());
+			fail("bogus byte array: " + Arrays.toString(byteArray));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testConvertHexStringToByteArray_illegalCharacter1() throws Exception {
+		this.verifyConvertHexStringToByteArray_illegalCharacter("CAFEX0CAFE");
+	}
+
+	public void testConvertHexStringToByteArray_illegalCharacter2() throws Exception {
+		this.verifyConvertHexStringToByteArray_illegalCharacter("CAFE0XCAFE");
+	}
+
+	private void verifyConvertHexStringToByteArray_illegalCharacter(String s) throws Exception {
+		boolean exCaught = false;
+		try {
+			byte[] byteArray = CharArrayTools.convertHexStringToByteArray(s.toCharArray());
+			fail("bogus byte array: " + Arrays.toString(byteArray));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testConvertHexStringToByteArray_ok() throws Exception {
+		String s = "74657374"; // UTF-8 values
+		TestTools.assertEquals("test", CharArrayTools.convertHexStringToByteArray(s.toCharArray()));
+	}
+
+	public void testConvertHexStringToByteArray_negative() throws Exception {
+		String s = this.getHexCafe();
+		TestTools.assertEquals("caf\u00E9", CharArrayTools.convertHexStringToByteArray(s.toCharArray()));
+	}
+
+	public void testConvertHexStringToByteArray_lowercase() throws Exception {
+		String s = this.getHexCafe().toLowerCase();
+		TestTools.assertEquals("caf\u00E9", CharArrayTools.convertHexStringToByteArray(s.toCharArray()));
+	}
+
+	private String getHexCafe() {
+		return StringToolsTests.getHexCafe();
+	}
+
+	// ********** convert camel-case to all-caps **********
+
+	// ********** convert all-caps to camel case **********
+
+	// ********** delimiting **********
+
+	public void testIsQuoted() {
+		this.denyIsQuoted("foo");
+		this.verifyIsQuoted("\"foo\"");
+
+		this.denyIsQuoted("");
+		this.verifyIsQuoted("\"\"");
+
+		this.denyIsQuoted("\"");
+		this.denyIsQuoted(" ");
+		this.denyIsQuoted("''");
+		this.denyIsQuoted("'foo'");
+	}
+
+	private void verifyIsQuoted(String s) {
+		assertTrue(CharArrayTools.isQuoted(s.toCharArray()));
+	}
+
+	private void denyIsQuoted(String s) {
+		assertFalse(CharArrayTools.isQuoted(s.toCharArray()));
+	}
+
+	public void testIsParenthetical() {
+		this.denyIsParenthetical("foo");
+		this.verifyIsParenthetical("(foo)");
+
+		this.denyIsParenthetical("");
+		this.verifyIsParenthetical("()");
+
+		this.denyIsParenthetical("(");
+		this.denyIsParenthetical(" ");
+		this.denyIsParenthetical("''");
+		this.denyIsParenthetical("'foo'");
+	}
+
+	private void verifyIsParenthetical(String s) {
+		assertTrue(CharArrayTools.isParenthetical(s.toCharArray()));
+	}
+
+	private void denyIsParenthetical(String s) {
+		assertFalse(CharArrayTools.isParenthetical(s.toCharArray()));
+	}
+
+	public void testIsBracketed() {
+		this.denyIsBracketed("foo");
+		this.verifyIsBracketed("[foo]");
+
+		this.denyIsBracketed("");
+		this.verifyIsBracketed("[]");
+
+		this.denyIsBracketed("[");
+		this.denyIsBracketed(" ");
+		this.denyIsBracketed("''");
+		this.denyIsBracketed("'foo'");
+	}
+
+	private void verifyIsBracketed(String s) {
+		assertTrue(CharArrayTools.isBracketed(s.toCharArray()));
+	}
+
+	private void denyIsBracketed(String s) {
+		assertFalse(CharArrayTools.isBracketed(s.toCharArray()));
+	}
+
+	public void testIsBraced() {
+		this.denyIsBraced("foo");
+		this.verifyIsBraced("{foo}");
+
+		this.denyIsBraced("");
+		this.verifyIsBraced("{}");
+
+		this.denyIsBraced("{");
+		this.denyIsBraced(" ");
+		this.denyIsBraced("''");
+		this.denyIsBraced("'foo'");
+	}
+
+	private void verifyIsBraced(String s) {
+		assertTrue(CharArrayTools.isBraced(s.toCharArray()));
+	}
+
+	private void denyIsBraced(String s) {
+		assertFalse(CharArrayTools.isBraced(s.toCharArray()));
+	}
+
+	public void testIsChevroned() {
+		this.denyIsChevroned("foo");
+		this.verifyIsChevroned("<foo>");
+
+		this.denyIsChevroned("");
+		this.verifyIsChevroned("<>");
+
+		this.denyIsChevroned("{");
+		this.denyIsChevroned(" ");
+		this.denyIsChevroned("''");
+		this.denyIsChevroned("'foo'");
+	}
+
+	private void verifyIsChevroned(String s) {
+		assertTrue(CharArrayTools.isChevroned(s.toCharArray()));
+	}
+
+	private void denyIsChevroned(String s) {
+		assertFalse(CharArrayTools.isChevroned(s.toCharArray()));
+	}
+
+	public void testIsDelimited() {
+		this.denyIsDelimited("foo", '?');
+		this.verifyIsDelimited("?foo?", '?');
+
+		this.denyIsDelimited("", '?');
+		this.verifyIsDelimited("\"\"", '"');
+		this.verifyIsDelimited("?xx?", '?');
+		this.denyIsDelimited("?xx]", '?');
+
+		this.denyIsDelimited("\"", '"');
+		this.denyIsDelimited(" ", ' ');
+		this.denyIsDelimited("''", '"');
+		this.denyIsDelimited("'foo'", '?');
+	}
+
+	private void verifyIsDelimited(String s, char c) {
+		assertTrue(CharArrayTools.isDelimited(s.toCharArray(), c));
+	}
+
+	private void denyIsDelimited(String s, char c) {
+		assertFalse(CharArrayTools.isDelimited(s.toCharArray(), c));
+	}
+
+	public void testIsDelimited2() {
+		this.denyIsDelimited2("foo", '[', ']');
+		this.verifyIsDelimited2("{foo}", '{', '}');
+
+		this.denyIsDelimited2("", '[', ']');
+		this.verifyIsDelimited2("[]", '[', ']');
+		this.verifyIsDelimited2("[xx]", '[', ']');
+		this.denyIsDelimited2("?xx]", '[', ']');
+
+		this.denyIsDelimited2("\"", '[', ']');
+		this.denyIsDelimited2(" ", '[', ']');
+		this.denyIsDelimited2("''", '[', ']');
+		this.denyIsDelimited2("'foo'", '[', ']');
+	}
+
+	private void verifyIsDelimited2(String s, char start, char end) {
+		assertTrue(CharArrayTools.isDelimited(s.toCharArray(), start, end));
+	}
+
+	private void denyIsDelimited2(String s, char start, char end) {
+		assertFalse(CharArrayTools.isDelimited(s.toCharArray(), start, end));
+	}
+
+	// ********** undelimiting **********
+
+	public void testUndelimit() {
+		this.verifyUndelimit("\"foo\"", "foo");
+		this.verifyUndelimit("\"\"", "");
+		this.verifyUndelimit("'foo'", "foo");
+		this.verifyUndelimit("\"fo\"\"o\"", "fo\"o");
+		this.verifyUndelimit("\"foo\"\"\"", "foo\"");
+		this.verifyUndelimit("\"\"\"foo\"", "\"foo");
+		this.verifyUndelimit("[foo]", "foo");
+		this.verifyUndelimit("\"\"\"", "\"");
+		this.verifyUndelimit("\"foo\"bar\"", "foo\"");
+		this.verifyUndelimit("\"foo\"\"", "foo\"");
+	}
+
+	private void verifyUndelimit(String s, String expected) {
+		TestTools.assertEquals(expected, CharArrayTools.undelimit(s.toCharArray()));
+	}
+
+	public void testUndelimitInt() {
+		this.verifyUndelimitInt("\"foo\"", 2, "o");
+		this.verifyUndelimitInt("\"\"foo\"\"", 2, "foo");
+		this.verifyUndelimitInt("'foo'", 2, "o");
+	}
+
+	private void verifyUndelimitInt(String s, int count, String expected) {
+		TestTools.assertEquals(expected, CharArrayTools.undelimit(s.toCharArray(), count));
+	}
+
+	public void testUndelimitIntException() {
+		this.denyUndelimitInt("\"\"", 2);
+		this.denyUndelimitInt("'o'", 2);
+	}
+
+	private void denyUndelimitInt(String s, int count) {
+		boolean exCaught = false;
+		try {
+			char[] bogus = CharArrayTools.undelimit(s.toCharArray(), count);
+			fail("invalid string: " + new String(bogus));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	// ********** converting to Java string literal **********
+
+	public void testConvertToJavaStringLiteral() {
+		this.verifyConvertToJavaStringLiteral("", "\"\"");
+		this.verifyConvertToJavaStringLiteral("\"\"", "\"\\\"\\\"\"");
+		this.verifyConvertToJavaStringLiteral("'foo'", "\"'foo'\"");
+		this.verifyConvertToJavaStringLiteral("foo\bbar", "\"foo\\bbar\"");
+		this.verifyConvertToJavaStringLiteral("foo\n\tbar", "\"foo\\n\\tbar\"");
+		this.verifyConvertToJavaStringLiteral("foo\"bar", "\"foo\\\"bar\"");
+		this.verifyConvertToJavaStringLiteral("foo\\bar", "\"foo\\\\bar\"");
+	}
+
+	private void verifyConvertToJavaStringLiteral(String s, String expected) {
+		TestTools.assertEquals(expected, CharArrayTools.convertToJavaStringLiteral(s.toCharArray()));
+	}
+
+	// ********** converting to XML **********
+
+	public void testConvertToXmlAttributeValue() {
+		this.verifyConvertToXmlAttributeValue("", "\"\"");
+		this.verifyConvertToXmlAttributeValue("\"", "'\"'");
+		this.verifyConvertToXmlAttributeValue("\"\"", "'\"\"'");
+		this.verifyConvertToXmlAttributeValue("'", "\"'\"");
+		this.verifyConvertToXmlAttributeValue("''", "\"''\"");
+		this.verifyConvertToXmlAttributeValue("\"'\"", "\"&quot;'&quot;\"");
+		this.verifyConvertToXmlAttributeValue("\"''\"", "\"&quot;''&quot;\"");
+		this.verifyConvertToXmlAttributeValue("'foo'", "\"'foo'\"");
+		this.verifyConvertToXmlAttributeValue("\"foo\"", "'\"foo\"'");
+		this.verifyConvertToXmlAttributeValue("\"foo\" 'bar'", "\"&quot;foo&quot; 'bar'\"");
+		this.verifyConvertToXmlAttributeValue("foo & bar", "\"foo &amp; bar\"");
+		this.verifyConvertToXmlAttributeValue("\"foo & bar\"", "'\"foo &amp; bar\"'");
+		this.verifyConvertToXmlAttributeValue("foo <<< bar", "\"foo &lt;&lt;&lt; bar\"");
+		this.verifyConvertToXmlAttributeValue("\"foo <<< bar\"", "'\"foo &lt;&lt;&lt; bar\"'");
+	}
+
+	private void verifyConvertToXmlAttributeValue(String s, String expected) {
+		TestTools.assertEquals(expected, CharArrayTools.convertToXmlAttributeValue(s.toCharArray()));
+	}
+
+	public void testConvertToXmlElementText() {
+		this.verifyConvertToXmlElementText("", "");
+		this.verifyConvertToXmlElementText("\"", "\"");
+		this.verifyConvertToXmlElementText("\"\"", "\"\"");
+		this.verifyConvertToXmlElementText("'", "'");
+		this.verifyConvertToXmlElementText("''", "''");
+		this.verifyConvertToXmlElementText("\"'\"", "\"'\"");
+		this.verifyConvertToXmlElementText("\"''\"", "\"''\"");
+		this.verifyConvertToXmlElementText("'foo'", "'foo'");
+		this.verifyConvertToXmlElementText("foo & bar", "foo &amp; bar");
+		this.verifyConvertToXmlElementText("foo &", "foo &amp;");
+		this.verifyConvertToXmlElementText("& bar", "&amp; bar");
+		this.verifyConvertToXmlElementText("\"foo & bar\"", "\"foo &amp; bar\"");
+		this.verifyConvertToXmlElementText("foo <<< bar", "foo &lt;&lt;&lt; bar");
+		this.verifyConvertToXmlElementText("\"foo <<< bar\"", "\"foo &lt;&lt;&lt; bar\"");
+	}
+
+	private void verifyConvertToXmlElementText(String s, String expected) {
+		TestTools.assertEquals(expected, CharArrayTools.convertToXmlElementText(s.toCharArray()));
+	}
+
+	public void testConvertToXmlElementCDATA() {
+		String START = "<![CDATA[";
+		String END = "]]>";
+		this.verifyConvertToXmlElementCDATA("", START + END);
+		this.verifyConvertToXmlElementCDATA("\"", START + "\"" + END);
+		this.verifyConvertToXmlElementCDATA("\"\"", START + "\"\"" + END);
+		this.verifyConvertToXmlElementCDATA("'", START + "'" + END);
+		this.verifyConvertToXmlElementCDATA("''", START + "''" + END);
+		this.verifyConvertToXmlElementCDATA("\"'\"", START + "\"'\"" + END);
+		this.verifyConvertToXmlElementCDATA("\"''\"", START + "\"''\"" + END);
+		this.verifyConvertToXmlElementCDATA("'foo'", START + "'foo'" + END);
+		this.verifyConvertToXmlElementCDATA("foo & bar", START + "foo & bar" + END);
+		this.verifyConvertToXmlElementCDATA("foo &", START + "foo &" + END);
+		this.verifyConvertToXmlElementCDATA("& bar", START + "& bar" + END);
+		this.verifyConvertToXmlElementCDATA("\"foo & bar\"", START + "\"foo & bar\"" + END);
+		this.verifyConvertToXmlElementCDATA("foo <<< bar", START + "foo <<< bar" + END);
+		this.verifyConvertToXmlElementCDATA("\"foo <<< bar\"", START + "\"foo <<< bar\"" + END);
+		this.verifyConvertToXmlElementCDATA("\"foo <&< bar\"", START + "\"foo <&< bar\"" + END);
+		this.verifyConvertToXmlElementCDATA("\"foo <]< bar\"", START + "\"foo <]< bar\"" + END);
+		this.verifyConvertToXmlElementCDATA("\"foo <]]< bar\"", START + "\"foo <]]< bar\"" + END);
+		this.verifyConvertToXmlElementCDATA("\"foo <]]>< bar\"", START + "\"foo <]]&gt;< bar\"" + END);
+		this.verifyConvertToXmlElementCDATA("foo <]", START + "foo <]" + END);
+		this.verifyConvertToXmlElementCDATA("foo <]]", START + "foo <]]" + END);
+		this.verifyConvertToXmlElementCDATA("foo <]]>", START + "foo <]]&gt;" + END);
+		this.verifyConvertToXmlElementCDATA("]foo", START + "]foo" + END);
+		this.verifyConvertToXmlElementCDATA("]]foo", START + "]]foo" + END);
+		this.verifyConvertToXmlElementCDATA("]]>foo", START + "]]&gt;foo" + END);
+	}
+
+	private void verifyConvertToXmlElementCDATA(String s, String expected) {
+		TestTools.assertEquals(expected, CharArrayTools.convertToXmlElementCDATA(s.toCharArray()));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CharacterToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CharacterToolsTests.java
new file mode 100644
index 0000000..d03f247
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CharacterToolsTests.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.CharacterTools;
+
+public class CharacterToolsTests
+	extends TestCase
+{
+	public void testEqualsIgnoreCase() {
+		assertTrue(CharacterTools.equalsIgnoreCase('a', 'a'));
+		assertTrue(CharacterTools.equalsIgnoreCase('a', 'A'));
+		assertTrue(CharacterTools.equalsIgnoreCase('A', 'a'));
+		assertTrue(CharacterTools.equalsIgnoreCase('A', 'A'));
+
+		assertFalse(CharacterTools.equalsIgnoreCase('a', 'b'));
+		assertFalse(CharacterTools.equalsIgnoreCase('A', 'b'));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ClassNameToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ClassNameToolsTests.java
new file mode 100644
index 0000000..b661b44
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ClassNameToolsTests.java
@@ -0,0 +1,720 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ClassNameTools;
+import org.eclipse.persistence.tools.utility.ClassTools;
+
+@SuppressWarnings("nls")
+public class ClassNameToolsTests
+	extends TestCase
+{
+	public ClassNameToolsTests(String name) {
+		super(name);
+	}
+
+	public void testIsArray() {
+		assertFalse(ClassNameTools.isArray(int.class.getName()));
+		assertTrue(ClassNameTools.isArray(int[].class.getName()));
+		assertTrue(ClassNameTools.isArray(int[][].class.getName()));
+
+		assertFalse(ClassNameTools.isArray(java.lang.String.class.getName()));
+		assertTrue(ClassNameTools.isArray(java.lang.String[].class.getName()));
+		assertTrue(ClassNameTools.isArray(java.lang.String[][].class.getName()));
+	}
+
+	public void testIsArrayCharArray() {
+		assertFalse(ClassNameTools.isArray(int.class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isArray(int[].class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isArray(int[][].class.getName().toCharArray()));
+
+		assertFalse(ClassNameTools.isArray(java.lang.String.class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isArray(java.lang.String[].class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isArray(java.lang.String[][].class.getName().toCharArray()));
+	}
+
+	public void testArrayDepth() {
+		assertEquals(0, ClassNameTools.arrayDepth(java.util.Vector.class.getName()));
+		assertEquals(0, ClassNameTools.arrayDepth(int.class.getName()));
+		assertEquals(0, ClassNameTools.arrayDepth(void.class.getName()));
+		assertEquals(1, ClassNameTools.arrayDepth(java.util.Vector[].class.getName()));
+		assertEquals(1, ClassNameTools.arrayDepth(int[].class.getName()));
+		assertEquals(3, ClassNameTools.arrayDepth(java.util.Vector[][][].class.getName()));
+		assertEquals(3, ClassNameTools.arrayDepth(int[][][].class.getName()));
+	}
+
+	public void testArrayDepthCharArray() {
+		assertEquals(0, ClassNameTools.arrayDepth(java.util.Vector.class.getName().toCharArray()));
+		assertEquals(0, ClassNameTools.arrayDepth(int.class.getName().toCharArray()));
+		assertEquals(0, ClassNameTools.arrayDepth(void.class.getName().toCharArray()));
+		assertEquals(1, ClassNameTools.arrayDepth(java.util.Vector[].class.getName().toCharArray()));
+		assertEquals(1, ClassNameTools.arrayDepth(int[].class.getName().toCharArray()));
+		assertEquals(3, ClassNameTools.arrayDepth(java.util.Vector[][][].class.getName().toCharArray()));
+		assertEquals(3, ClassNameTools.arrayDepth(int[][][].class.getName().toCharArray()));
+	}
+
+	public void testElementTypeName() {
+		assertEquals(java.util.Vector.class.getName(), ClassNameTools.elementTypeName(java.util.Vector.class.getName()));
+		assertEquals(int.class.getName(), ClassNameTools.elementTypeName(int.class.getName()));
+		assertEquals(void.class.getName(), ClassNameTools.elementTypeName(void.class.getName()));
+		assertEquals(java.util.Vector.class.getName(), ClassNameTools.elementTypeName(java.util.Vector[].class.getName()));
+		assertEquals(int.class.getName(), ClassNameTools.elementTypeName(int[].class.getName()));
+		assertEquals(java.util.Vector.class.getName(), ClassNameTools.elementTypeName(java.util.Vector[][][].class.getName()));
+		assertEquals(int.class.getName(), ClassNameTools.elementTypeName(int[][][].class.getName()));
+	}
+
+	public void testElementTypeNameCharArray() {
+		TestTools.assertEquals(java.util.Vector.class.getName(), ClassNameTools.elementTypeName(java.util.Vector.class.getName().toCharArray()));
+		TestTools.assertEquals(int.class.getName(), ClassNameTools.elementTypeName(int.class.getName().toCharArray()));
+		TestTools.assertEquals(void.class.getName(), ClassNameTools.elementTypeName(void.class.getName().toCharArray()));
+		TestTools.assertEquals(java.util.Vector.class.getName(), ClassNameTools.elementTypeName(java.util.Vector[].class.getName().toCharArray()));
+		TestTools.assertEquals(int.class.getName(), ClassNameTools.elementTypeName(int[].class.getName().toCharArray()));
+		TestTools.assertEquals(java.util.Vector.class.getName(), ClassNameTools.elementTypeName(java.util.Vector[][][].class.getName().toCharArray()));
+		TestTools.assertEquals(int.class.getName(), ClassNameTools.elementTypeName(int[][][].class.getName().toCharArray()));
+	}
+
+	public void testComponentTypeName() {
+		assertEquals(null, ClassNameTools.componentTypeName(java.lang.Object.class.getName()));
+		assertEquals(java.lang.Object.class.getName(), ClassNameTools.componentTypeName(java.lang.Object[].class.getName()));
+		assertEquals(java.lang.Object[].class.getName(), ClassNameTools.componentTypeName(java.lang.Object[][].class.getName()));
+
+		assertEquals(null, ClassNameTools.componentTypeName(int.class.getName()));
+		assertEquals(int.class.getName(), ClassNameTools.componentTypeName(int[].class.getName()));
+		assertEquals(int[].class.getName(), ClassNameTools.componentTypeName(int[][].class.getName()));
+	}
+
+	public void testComponentTypeNameCharArray() {
+		assertNull(ClassNameTools.componentTypeName(java.lang.Object.class.getName().toCharArray()));
+		TestTools.assertEquals(java.lang.Object.class.getName(), ClassNameTools.componentTypeName(java.lang.Object[].class.getName().toCharArray()));
+		TestTools.assertEquals(java.lang.Object[].class.getName(), ClassNameTools.componentTypeName(java.lang.Object[][].class.getName().toCharArray()));
+
+		assertNull(ClassNameTools.componentTypeName(int.class.getName().toCharArray()));
+		TestTools.assertEquals(int.class.getName(), ClassNameTools.componentTypeName(int[].class.getName().toCharArray()));
+		TestTools.assertEquals(int[].class.getName(), ClassNameTools.componentTypeName(int[][].class.getName().toCharArray()));
+	}
+
+	public void testTypeDeclaration() throws Exception {
+		TestTools.assertEquals("int", ClassNameTools.typeDeclaration("int".toCharArray()));
+		TestTools.assertEquals("int[]", ClassNameTools.typeDeclaration("[I".toCharArray()));
+		TestTools.assertEquals("int[][]", ClassNameTools.typeDeclaration("[[I".toCharArray()));
+
+		TestTools.assertEquals("java.lang.Object", ClassNameTools.typeDeclaration("java.lang.Object".toCharArray()));
+		TestTools.assertEquals("java.lang.Object[]", ClassNameTools.typeDeclaration("[Ljava.lang.Object;".toCharArray()));
+		TestTools.assertEquals("java.lang.Object[][]", ClassNameTools.typeDeclaration("[[Ljava.lang.Object;".toCharArray()));
+	}
+
+	public void testTypeDeclarationCharArray() throws Exception {
+		assertEquals("int", ClassNameTools.typeDeclaration("int"));
+		assertEquals("int[]", ClassNameTools.typeDeclaration("[I"));
+		assertEquals("int[][]", ClassNameTools.typeDeclaration("[[I"));
+
+		assertEquals("java.lang.Object", ClassNameTools.typeDeclaration("java.lang.Object"));
+		assertEquals("java.lang.Object[]", ClassNameTools.typeDeclaration("[Ljava.lang.Object;"));
+		assertEquals("java.lang.Object[][]", ClassNameTools.typeDeclaration("[[Ljava.lang.Object;"));
+	}
+
+	public void testSimpleName() throws Exception {
+		assertEquals("Object", ClassNameTools.simpleName(java.lang.Object.class.getName()));
+		assertEquals("Object[]", ClassNameTools.simpleName(java.lang.Object[].class.getName()));
+		assertEquals("Object[][]", ClassNameTools.simpleName(java.lang.Object[][].class.getName()));
+
+		assertEquals(java.util.Map.class.getSimpleName(), ClassNameTools.simpleName(java.util.Map.class.getName()));
+		assertEquals(java.util.Map.Entry.class.getSimpleName(), ClassNameTools.simpleName(java.util.Map.Entry.class.getName()));
+
+		assertEquals("int", ClassNameTools.simpleName(int.class.getName()));
+		assertEquals("int[]", ClassNameTools.simpleName(int[].class.getName()));
+		assertEquals("int[][]", ClassNameTools.simpleName(int[][].class.getName()));
+
+		Object anonObject = new Object() {
+			// anonymous class
+		};
+		assertEquals("", ClassNameTools.simpleName(anonObject.getClass().getName()));
+
+		class Local {
+			// anonymous class
+		}
+		Local localObject = new Local();
+		assertEquals("Local", ClassNameTools.simpleName(localObject.getClass().getName()));
+	}
+
+	public void testSimpleNameCharArray() throws Exception {
+		TestTools.assertEquals("Object", ClassNameTools.simpleName(java.lang.Object.class.getName().toCharArray()));
+		TestTools.assertEquals("Object[]", ClassNameTools.simpleName(java.lang.Object[].class.getName().toCharArray()));
+		TestTools.assertEquals("Object[][]", ClassNameTools.simpleName(java.lang.Object[][].class.getName().toCharArray()));
+
+		TestTools.assertEquals(java.util.Map.class.getSimpleName(), ClassNameTools.simpleName(java.util.Map.class.getName().toCharArray()));
+		TestTools.assertEquals(java.util.Map.Entry.class.getSimpleName(), ClassNameTools.simpleName(java.util.Map.Entry.class.getName().toCharArray()));
+
+		TestTools.assertEquals("int", ClassNameTools.simpleName(int.class.getName().toCharArray()));
+		TestTools.assertEquals("int[]", ClassNameTools.simpleName(int[].class.getName().toCharArray()));
+		TestTools.assertEquals("int[][]", ClassNameTools.simpleName(int[][].class.getName().toCharArray()));
+
+		Object anonObject = new Object() {
+			// anonymous class
+		};
+		TestTools.assertEquals("", ClassNameTools.simpleName(anonObject.getClass().getName().toCharArray()));
+
+		class Local {
+			// anonymous class
+		}
+		Local localObject = new Local();
+		TestTools.assertEquals("Local", ClassNameTools.simpleName(localObject.getClass().getName().toCharArray()));
+	}
+
+	public void testPackageName() throws Exception {
+		assertEquals(java.lang.Object.class.getPackage().getName(), ClassNameTools.packageName(java.lang.Object.class.getName()));
+		assertEquals("", ClassNameTools.packageName(java.lang.Object[].class.getName()));
+		assertEquals("", ClassNameTools.packageName(java.lang.Object[][].class.getName()));
+
+		assertEquals(java.util.Map.class.getPackage().getName(), ClassNameTools.packageName(java.util.Map.class.getName()));
+		assertEquals(java.util.Map.Entry.class.getPackage().getName(), ClassNameTools.packageName(java.util.Map.Entry.class.getName()));
+
+		assertEquals("", ClassNameTools.packageName(int.class.getName()));
+		assertEquals("", ClassNameTools.packageName(int[].class.getName()));
+		assertEquals("", ClassNameTools.packageName(int[][].class.getName()));
+
+		assertEquals("", ClassNameTools.packageName(void.class.getName()));
+
+		Object anonObject = new Object() {
+			// anonymous class
+		};
+		assertEquals(anonObject.getClass().getPackage().getName(), ClassNameTools.packageName(anonObject.getClass().getName()));
+	}
+
+	public void testPackageNameCharArray() throws Exception {
+		TestTools.assertEquals(java.lang.Object.class.getPackage().getName(), ClassNameTools.packageName(java.lang.Object.class.getName().toCharArray()));
+		TestTools.assertEquals("", ClassNameTools.packageName(java.lang.Object[].class.getName().toCharArray()));
+		TestTools.assertEquals("", ClassNameTools.packageName(java.lang.Object[][].class.getName().toCharArray()));
+
+		TestTools.assertEquals(java.util.Map.class.getPackage().getName(), ClassNameTools.packageName(java.util.Map.class.getName().toCharArray()));
+		TestTools.assertEquals(java.util.Map.Entry.class.getPackage().getName(), ClassNameTools.packageName(java.util.Map.Entry.class.getName().toCharArray()));
+
+		TestTools.assertEquals("", ClassNameTools.packageName(int.class.getName().toCharArray()));
+		TestTools.assertEquals("", ClassNameTools.packageName(int[].class.getName().toCharArray()));
+		TestTools.assertEquals("", ClassNameTools.packageName(int[][].class.getName().toCharArray()));
+
+		TestTools.assertEquals("", ClassNameTools.packageName(void.class.getName().toCharArray()));
+
+		Object anonObject = new Object() {
+			// anonymous class
+		};
+		TestTools.assertEquals(anonObject.getClass().getPackage().getName(), ClassNameTools.packageName(anonObject.getClass().getName().toCharArray()));
+	}
+
+	public void testIsTopLevel() throws Exception {
+		assertTrue(ClassNameTools.isTopLevel(java.util.Map.class.getName())); // top-level
+		assertFalse(ClassNameTools.isTopLevel(java.util.Map.Entry.class.getName())); // member
+		assertFalse(ClassNameTools.isTopLevel(Class.forName(this.getClass().getName() + "$1LocalClass").getName())); // local
+		assertFalse(ClassNameTools.isTopLevel(Class.forName("java.util.Vector$1").getName())); // anonymous
+
+		Object[] array = new java.util.Map[0]; // top-level
+		assertFalse(ClassNameTools.isTopLevel(array.getClass().getName()));
+		array = new java.util.Map.Entry[0]; // member
+		assertFalse(ClassNameTools.isTopLevel(array.getClass().getName()));
+		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
+		array = (Object[]) Array.newInstance(localClass, 0);
+		assertFalse(ClassNameTools.isTopLevel(array.getClass().getName()));
+		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
+		array = (Object[]) Array.newInstance(anonClass, 0);
+		assertFalse(ClassNameTools.isTopLevel(array.getClass().getName()));
+	}
+
+	public void testIsTopLevelCharArray() throws Exception {
+		assertTrue(ClassNameTools.isTopLevel(java.util.Map.class.getName().toCharArray())); // top-level
+		assertFalse(ClassNameTools.isTopLevel(java.util.Map.Entry.class.getName().toCharArray())); // member
+		assertFalse(ClassNameTools.isTopLevel(Class.forName(this.getClass().getName() + "$1LocalClass").getName().toCharArray())); // local
+		assertFalse(ClassNameTools.isTopLevel(Class.forName("java.util.Vector$1").getName().toCharArray())); // anonymous
+
+		Object[] array = new java.util.Map[0]; // top-level
+		assertFalse(ClassNameTools.isTopLevel(array.getClass().getName().toCharArray()));
+		array = new java.util.Map.Entry[0]; // member
+		assertFalse(ClassNameTools.isTopLevel(array.getClass().getName().toCharArray()));
+		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
+		array = (Object[]) Array.newInstance(localClass, 0);
+		assertFalse(ClassNameTools.isTopLevel(array.getClass().getName().toCharArray()));
+		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
+		array = (Object[]) Array.newInstance(anonClass, 0);
+		assertFalse(ClassNameTools.isTopLevel(array.getClass().getName().toCharArray()));
+	}
+
+	public void testIsMember() throws Exception {
+		assertFalse(ClassNameTools.isMember(java.util.Map.class.getName())); // top-level
+		assertTrue(ClassNameTools.isMember(java.util.Map.Entry.class.getName())); // member
+		assertFalse(ClassNameTools.isMember(Class.forName(this.getClass().getName() + "$1LocalClass").getName())); // local
+		assertFalse(ClassNameTools.isMember(Class.forName("java.util.Vector$1").getName())); // anonymous
+
+		Object[] array = new java.util.Map[0]; // top-level
+		assertFalse(ClassNameTools.isMember(array.getClass().getName()));
+		array = new java.util.Map.Entry[0]; // member
+		assertFalse(ClassNameTools.isMember(array.getClass().getName()));
+		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
+		array = (Object[]) Array.newInstance(localClass, 0);
+		assertFalse(ClassNameTools.isMember(array.getClass().getName()));
+		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
+		array = (Object[]) Array.newInstance(anonClass, 0);
+		assertFalse(ClassNameTools.isMember(array.getClass().getName()));
+
+		// test a few edge cases
+		assertTrue(ClassNameTools.isMember("java.util.Map$a1"));
+		assertTrue(ClassNameTools.isMember("java.util.Map$1aa$aaa"));  // member inside local
+		assertTrue(ClassNameTools.isMember("java.util.Map$1$aaa"));  // member inside anonymous
+		assertTrue(ClassNameTools.isMember("java.util.Map$a1$aaa$bbb"));
+		assertTrue(ClassNameTools.isMember("java.util.Map$1a1$aaa"));  // member inside local
+		assertFalse(ClassNameTools.isMember("java.util.Map$1a"));
+		assertTrue(ClassNameTools.isMember("java.util.Map$a12345$b12345"));
+		assertFalse(ClassNameTools.isMember("java.util.Map$12345a"));
+		assertFalse(ClassNameTools.isMember("java.util.Map$333"));
+		assertFalse(ClassNameTools.isMember("java.util.Map3$333"));
+	}
+
+	public void testIsMemberCharArray() throws Exception {
+		assertFalse(ClassNameTools.isMember(java.util.Map.class.getName().toCharArray())); // top-level
+		assertTrue(ClassNameTools.isMember(java.util.Map.Entry.class.getName().toCharArray())); // member
+		assertFalse(ClassNameTools.isMember(Class.forName(this.getClass().getName() + "$1LocalClass").getName().toCharArray())); // local
+		assertFalse(ClassNameTools.isMember(Class.forName("java.util.Vector$1").getName().toCharArray())); // anonymous
+
+		Object[] array = new java.util.Map[0]; // top-level
+		assertFalse(ClassNameTools.isMember(array.getClass().getName().toCharArray()));
+		array = new java.util.Map.Entry[0]; // member
+		assertFalse(ClassNameTools.isMember(array.getClass().getName().toCharArray()));
+		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
+		array = (Object[]) Array.newInstance(localClass, 0);
+		assertFalse(ClassNameTools.isMember(array.getClass().getName().toCharArray()));
+		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
+		array = (Object[]) Array.newInstance(anonClass, 0);
+		assertFalse(ClassNameTools.isMember(array.getClass().getName().toCharArray()));
+
+		// test a few edge cases
+		assertTrue(ClassNameTools.isMember("java.util.Map$a1".toCharArray()));
+		assertTrue(ClassNameTools.isMember("java.util.Map$1aa$aaa".toCharArray()));  // member inside local
+		assertTrue(ClassNameTools.isMember("java.util.Map$1$aaa".toCharArray()));  // member inside anonymous
+		assertTrue(ClassNameTools.isMember("java.util.Map$a1$aaa$bbb".toCharArray()));
+		assertTrue(ClassNameTools.isMember("java.util.Map$1a1$aaa".toCharArray()));  // member inside local
+		assertFalse(ClassNameTools.isMember("java.util.Map$1a".toCharArray()));
+		assertTrue(ClassNameTools.isMember("java.util.Map$a12345$b12345".toCharArray()));
+		assertFalse(ClassNameTools.isMember("java.util.Map$12345a".toCharArray()));
+		assertFalse(ClassNameTools.isMember("java.util.Map$333".toCharArray()));
+		assertFalse(ClassNameTools.isMember("java.util.Map3$333".toCharArray()));
+	}
+
+	public void testIsLocal() throws Exception {
+		class LocalClass {
+			void foo() {
+				System.getProperty("foo");
+			}
+		}
+		new LocalClass().foo();
+		assertFalse(ClassNameTools.isLocal(java.util.Map.class.getName())); // top-level
+		assertFalse(ClassNameTools.isLocal(java.util.Map.Entry.class.getName())); // member
+		assertTrue(ClassNameTools.isLocal(Class.forName(this.getClass().getName() + "$1LocalClass").getName())); // local
+		assertFalse(ClassNameTools.isLocal(Class.forName("java.util.Vector$1").getName())); // anonymous
+
+		Object[] array = new java.util.Map[0]; // top-level
+		assertFalse(ClassNameTools.isLocal(array.getClass().getName()));
+		array = new java.util.Map.Entry[0]; // member
+		assertFalse(ClassNameTools.isLocal(array.getClass().getName()));
+		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
+		array = (Object[]) Array.newInstance(localClass, 0);
+		assertFalse(ClassNameTools.isLocal(array.getClass().getName()));
+		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
+		array = (Object[]) Array.newInstance(anonClass, 0);
+		assertFalse(ClassNameTools.isLocal(array.getClass().getName()));
+
+		// test a few edge cases
+		assertFalse(ClassNameTools.isLocal("java.util.Map$a1"));
+		assertFalse(ClassNameTools.isLocal("java.util.Map$a1$aaa$bbb"));
+		assertFalse(ClassNameTools.isLocal("java.util.Map$11$aaa"));
+		assertTrue(ClassNameTools.isLocal("java.util.Map$1a"));
+		assertTrue(ClassNameTools.isLocal("java.util.Map$2abc"));
+		assertTrue(ClassNameTools.isLocal("java.util.Map$2abc1"));
+		assertFalse(ClassNameTools.isLocal("java.util.Map$a12345$b12345"));
+		assertTrue(ClassNameTools.isLocal("java.util.Map$12345$1234a"));
+		assertFalse(ClassNameTools.isLocal("java.util.Map$333"));
+		assertFalse(ClassNameTools.isLocal("java.util.Map3$333"));
+	}
+
+	public void testIsLocalCharArray() throws Exception {
+		class LocalClass {
+			void foo() {
+				System.getProperty("foo");
+			}
+		}
+		new LocalClass().foo();
+		assertFalse(ClassNameTools.isLocal(java.util.Map.class.getName().toCharArray())); // top-level
+		assertFalse(ClassNameTools.isLocal(java.util.Map.Entry.class.getName().toCharArray())); // member
+		assertTrue(ClassNameTools.isLocal(Class.forName(this.getClass().getName() + "$1LocalClass").getName().toCharArray())); // local
+		assertFalse(ClassNameTools.isLocal(Class.forName("java.util.Vector$1").getName().toCharArray())); // anonymous
+
+		Object[] array = new java.util.Map[0]; // top-level
+		assertFalse(ClassNameTools.isLocal(array.getClass().getName().toCharArray()));
+		array = new java.util.Map.Entry[0]; // member
+		assertFalse(ClassNameTools.isLocal(array.getClass().getName().toCharArray()));
+		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
+		array = (Object[]) Array.newInstance(localClass, 0);
+		assertFalse(ClassNameTools.isLocal(array.getClass().getName().toCharArray()));
+		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
+		array = (Object[]) Array.newInstance(anonClass, 0);
+		assertFalse(ClassNameTools.isLocal(array.getClass().getName().toCharArray()));
+
+		// test a few edge cases
+		assertFalse(ClassNameTools.isLocal("java.util.Map$a1".toCharArray()));
+		assertFalse(ClassNameTools.isLocal("java.util.Map$a1$aaa$bbb".toCharArray()));
+		assertFalse(ClassNameTools.isLocal("java.util.Map$11$aaa".toCharArray()));
+		assertTrue(ClassNameTools.isLocal("java.util.Map$1a".toCharArray()));
+		assertTrue(ClassNameTools.isLocal("java.util.Map$2abc".toCharArray()));
+		assertTrue(ClassNameTools.isLocal("java.util.Map$2abc1".toCharArray()));
+		assertFalse(ClassNameTools.isLocal("java.util.Map$a12345$b12345".toCharArray()));
+		assertTrue(ClassNameTools.isLocal("java.util.Map$12345$1234a".toCharArray()));
+		assertFalse(ClassNameTools.isLocal("java.util.Map$333".toCharArray()));
+		assertFalse(ClassNameTools.isLocal("java.util.Map3$333".toCharArray()));
+	}
+
+	public void testIsAnonymous() throws Exception {
+		assertFalse(ClassNameTools.isAnonymous(java.util.Map.class.getName())); // top-level
+		assertFalse(ClassNameTools.isAnonymous(java.util.Map.Entry.class.getName())); // member
+		assertFalse(ClassNameTools.isAnonymous(Class.forName(this.getClass().getName() + "$1LocalClass").getName())); // local
+		assertTrue(ClassNameTools.isAnonymous(Class.forName("java.util.Vector$1").getName())); // anonymous
+
+		Object[] array = new java.util.Map[0]; // top-level
+		assertFalse(ClassNameTools.isAnonymous(array.getClass().getName()));
+		array = new java.util.Map.Entry[0]; // member
+		assertFalse(ClassNameTools.isAnonymous(array.getClass().getName()));
+		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
+		array = (Object[]) Array.newInstance(localClass, 0);
+		assertFalse(ClassNameTools.isAnonymous(array.getClass().getName()));
+		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
+		array = (Object[]) Array.newInstance(anonClass, 0);
+		assertFalse(ClassNameTools.isAnonymous(array.getClass().getName()));
+
+		// test a few edge cases
+		assertFalse(ClassNameTools.isAnonymous("java.util.Map$a1"));
+		assertFalse(ClassNameTools.isAnonymous("java.util.Map$a1$aaa$bbb"));
+		assertFalse(ClassNameTools.isAnonymous("java.util.Map$1a1$aaa"));
+		assertFalse(ClassNameTools.isAnonymous("java.util.Map$1$a"));
+		assertFalse(ClassNameTools.isAnonymous("java.util.Map$1a"));
+		assertFalse(ClassNameTools.isAnonymous("java.util.Map$a12345$b12345"));
+		assertFalse(ClassNameTools.isAnonymous("java.util.Map$12345$a1234"));
+		assertTrue(ClassNameTools.isAnonymous("java.util.Map$333"));
+		assertTrue(ClassNameTools.isAnonymous("java.util.Map3$333"));
+	}
+
+	public void testIsAnonymousCharArray() throws Exception {
+		assertFalse(ClassNameTools.isAnonymous(java.util.Map.class.getName().toCharArray())); // top-level
+		assertFalse(ClassNameTools.isAnonymous(java.util.Map.Entry.class.getName().toCharArray())); // member
+		assertFalse(ClassNameTools.isAnonymous(Class.forName(this.getClass().getName() + "$1LocalClass").getName().toCharArray())); // local
+		assertTrue(ClassNameTools.isAnonymous(Class.forName("java.util.Vector$1").getName().toCharArray())); // anonymous
+
+		Object[] array = new java.util.Map[0]; // top-level
+		assertFalse(ClassNameTools.isAnonymous(array.getClass().getName().toCharArray()));
+		array = new java.util.Map.Entry[0]; // member
+		assertFalse(ClassNameTools.isAnonymous(array.getClass().getName().toCharArray()));
+		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
+		array = (Object[]) Array.newInstance(localClass, 0);
+		assertFalse(ClassNameTools.isAnonymous(array.getClass().getName().toCharArray()));
+		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
+		array = (Object[]) Array.newInstance(anonClass, 0);
+		assertFalse(ClassNameTools.isAnonymous(array.getClass().getName().toCharArray()));
+
+		// test a few edge cases
+		assertFalse(ClassNameTools.isAnonymous("java.util.Map$a1".toCharArray()));
+		assertFalse(ClassNameTools.isAnonymous("java.util.Map$a1$aaa$bbb".toCharArray()));
+		assertFalse(ClassNameTools.isAnonymous("java.util.Map$1a1$aaa".toCharArray()));
+		assertFalse(ClassNameTools.isAnonymous("java.util.Map$1$a".toCharArray()));
+		assertFalse(ClassNameTools.isAnonymous("java.util.Map$1a".toCharArray()));
+		assertFalse(ClassNameTools.isAnonymous("java.util.Map$a12345$b12345".toCharArray()));
+		assertFalse(ClassNameTools.isAnonymous("java.util.Map$12345$a1234".toCharArray()));
+		assertTrue(ClassNameTools.isAnonymous("java.util.Map$333".toCharArray()));
+		assertTrue(ClassNameTools.isAnonymous("java.util.Map3$333".toCharArray()));
+	}
+
+	public void testIsReference() throws Exception {
+		assertFalse(ClassNameTools.isReference(int.class.getName())); // top-level
+
+		assertTrue(ClassNameTools.isReference(java.util.Map.class.getName())); // top-level
+		assertTrue(ClassNameTools.isReference(java.util.Map.Entry.class.getName())); // member
+		assertTrue(ClassNameTools.isReference(Class.forName(this.getClass().getName() + "$1LocalClass").getName())); // local
+		assertTrue(ClassNameTools.isReference(Class.forName("java.util.Vector$1").getName())); // anonymous
+
+		Object[] array = new java.util.Map[0]; // top-level
+		assertTrue(ClassNameTools.isReference(array.getClass().getName()));
+		array = new java.util.Map.Entry[0]; // member
+		assertTrue(ClassNameTools.isReference(array.getClass().getName()));
+		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
+		array = (Object[]) Array.newInstance(localClass, 0);
+		assertTrue(ClassNameTools.isReference(array.getClass().getName()));
+		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
+		array = (Object[]) Array.newInstance(anonClass, 0);
+		assertTrue(ClassNameTools.isReference(array.getClass().getName()));
+	}
+
+	public void testIsReferenceCharArray() throws Exception {
+		assertFalse(ClassNameTools.isReference(int.class.getName().toCharArray())); // top-level
+
+		assertTrue(ClassNameTools.isReference(java.util.Map.class.getName().toCharArray())); // top-level
+		assertTrue(ClassNameTools.isReference(java.util.Map.Entry.class.getName().toCharArray())); // member
+		assertTrue(ClassNameTools.isReference(Class.forName(this.getClass().getName() + "$1LocalClass").getName().toCharArray())); // local
+		assertTrue(ClassNameTools.isReference(Class.forName("java.util.Vector$1").getName().toCharArray())); // anonymous
+
+		Object[] array = new java.util.Map[0]; // top-level
+		assertTrue(ClassNameTools.isReference(array.getClass().getName().toCharArray()));
+		array = new java.util.Map.Entry[0]; // member
+		assertTrue(ClassNameTools.isReference(array.getClass().getName().toCharArray()));
+		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
+		array = (Object[]) Array.newInstance(localClass, 0);
+		assertTrue(ClassNameTools.isReference(array.getClass().getName().toCharArray()));
+		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
+		array = (Object[]) Array.newInstance(anonClass, 0);
+		assertTrue(ClassNameTools.isReference(array.getClass().getName().toCharArray()));
+	}
+
+	public void testIsPrimitive() {
+		assertTrue(void.class.isPrimitive());
+
+		assertTrue(ClassNameTools.isPrimitive(void.class.getName()));
+		assertTrue(ClassNameTools.isPrimitive(int.class.getName()));
+		assertTrue(ClassNameTools.isPrimitive(float.class.getName()));
+		assertTrue(ClassNameTools.isPrimitive(boolean.class.getName()));
+
+		assertFalse(ClassNameTools.isPrimitive(java.lang.Number.class.getName()));
+		assertFalse(ClassNameTools.isPrimitive(java.lang.String.class.getName()));
+		assertFalse(ClassNameTools.isPrimitive(java.lang.Boolean.class.getName()));
+		assertFalse(ClassNameTools.isPrimitive(java.lang.Integer.class.getName()));
+	}
+
+	public void testIsPrimitiveCharArray() {
+		assertTrue(void.class.isPrimitive());
+
+		assertTrue(ClassNameTools.isPrimitive(void.class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isPrimitive(int.class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isPrimitive(float.class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isPrimitive(boolean.class.getName().toCharArray()));
+
+		assertFalse(ClassNameTools.isPrimitive(java.lang.Number.class.getName().toCharArray()));
+		assertFalse(ClassNameTools.isPrimitive(java.lang.String.class.getName().toCharArray()));
+		assertFalse(ClassNameTools.isPrimitive(java.lang.Boolean.class.getName().toCharArray()));
+		assertFalse(ClassNameTools.isPrimitive(java.lang.Integer.class.getName().toCharArray()));
+	}
+
+	public void testIsPrimitiveWrapper() {
+		assertFalse(ClassNameTools.isPrimitiveWrapper(void.class.getName()));
+		assertFalse(ClassNameTools.isPrimitiveWrapper(int.class.getName()));
+		assertFalse(ClassNameTools.isPrimitiveWrapper(float.class.getName()));
+		assertFalse(ClassNameTools.isPrimitiveWrapper(boolean.class.getName()));
+
+		assertFalse(ClassNameTools.isPrimitiveWrapper(java.lang.reflect.Field.class.getName()));
+		assertFalse(ClassNameTools.isPrimitiveWrapper(java.lang.String.class.getName()));
+		assertTrue(ClassNameTools.isPrimitiveWrapper(java.lang.Boolean.class.getName()));
+		assertTrue(ClassNameTools.isPrimitiveWrapper(java.lang.Integer.class.getName()));
+	}
+
+	public void testIsPrimitiveWrapperCharArray() {
+		assertFalse(ClassNameTools.isPrimitiveWrapper(void.class.getName().toCharArray()));
+		assertFalse(ClassNameTools.isPrimitiveWrapper(int.class.getName().toCharArray()));
+		assertFalse(ClassNameTools.isPrimitiveWrapper(float.class.getName().toCharArray()));
+		assertFalse(ClassNameTools.isPrimitiveWrapper(boolean.class.getName().toCharArray()));
+
+		assertFalse(ClassNameTools.isPrimitiveWrapper(java.lang.reflect.Field.class.getName().toCharArray()));
+		assertFalse(ClassNameTools.isPrimitiveWrapper(java.lang.String.class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isPrimitiveWrapper(java.lang.Boolean.class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isPrimitiveWrapper(java.lang.Integer.class.getName().toCharArray()));
+	}
+
+	public void testIsVariablePrimitive() {
+		assertFalse(ClassNameTools.isVariablePrimitive(void.class.getName()));
+
+		assertTrue(ClassNameTools.isVariablePrimitive(int.class.getName()));
+		assertTrue(ClassNameTools.isVariablePrimitive(float.class.getName()));
+		assertTrue(ClassNameTools.isVariablePrimitive(boolean.class.getName()));
+
+		assertFalse(ClassNameTools.isVariablePrimitive(java.lang.Number.class.getName()));
+		assertFalse(ClassNameTools.isVariablePrimitive(java.lang.String.class.getName()));
+		assertFalse(ClassNameTools.isVariablePrimitive(java.lang.Boolean.class.getName()));
+	}
+
+	public void testIsVariablePrimitiveCharArray() {
+		assertFalse(ClassNameTools.isVariablePrimitive(void.class.getName().toCharArray()));
+
+		assertTrue(ClassNameTools.isVariablePrimitive(int.class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isVariablePrimitive(float.class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isVariablePrimitive(boolean.class.getName().toCharArray()));
+
+		assertFalse(ClassNameTools.isVariablePrimitive(java.lang.Number.class.getName().toCharArray()));
+		assertFalse(ClassNameTools.isVariablePrimitive(java.lang.String.class.getName().toCharArray()));
+		assertFalse(ClassNameTools.isVariablePrimitive(java.lang.Boolean.class.getName().toCharArray()));
+	}
+
+	public void testIsVariablePrimitiveWrapper() {
+		assertFalse(ClassNameTools.isVariablePrimitiveWrapper(java.lang.Void.class.getName()));
+
+		assertTrue(ClassNameTools.isVariablePrimitiveWrapper(java.lang.Integer.class.getName()));
+		assertTrue(ClassNameTools.isVariablePrimitiveWrapper(java.lang.Float.class.getName()));
+		assertTrue(ClassNameTools.isVariablePrimitiveWrapper(java.lang.Boolean.class.getName()));
+
+		assertFalse(ClassNameTools.isVariablePrimitiveWrapper(java.lang.Number.class.getName()));
+		assertFalse(ClassNameTools.isVariablePrimitiveWrapper(java.lang.String.class.getName()));
+		assertFalse(ClassNameTools.isVariablePrimitiveWrapper(java.lang.Object.class.getName()));
+	}
+
+	public void testIsVariablePrimitiveWrapperCharArray() {
+		assertFalse(ClassNameTools.isVariablePrimitiveWrapper(java.lang.Void.class.getName().toCharArray()));
+
+		assertTrue(ClassNameTools.isVariablePrimitiveWrapper(java.lang.Integer.class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isVariablePrimitiveWrapper(java.lang.Float.class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isVariablePrimitiveWrapper(java.lang.Boolean.class.getName().toCharArray()));
+
+		assertFalse(ClassNameTools.isVariablePrimitiveWrapper(java.lang.Number.class.getName().toCharArray()));
+		assertFalse(ClassNameTools.isVariablePrimitiveWrapper(java.lang.String.class.getName().toCharArray()));
+		assertFalse(ClassNameTools.isVariablePrimitiveWrapper(java.lang.Object.class.getName().toCharArray()));
+	}
+
+	public void testWrapperClassName() {
+		assertEquals(java.lang.Void.class.getName(), ClassNameTools.primitiveWrapperClassName(void.class.getName()));
+		assertEquals(java.lang.Integer.class.getName(), ClassNameTools.primitiveWrapperClassName(int.class.getName()));
+		assertEquals(java.lang.Float.class.getName(), ClassNameTools.primitiveWrapperClassName(float.class.getName()));
+		assertEquals(java.lang.Boolean.class.getName(), ClassNameTools.primitiveWrapperClassName(boolean.class.getName()));
+
+		assertNull(ClassNameTools.primitiveWrapperClassName(java.lang.String.class.getName()));
+	}
+
+	public void testWrapperClassNameCharArray() {
+		TestTools.assertEquals(java.lang.Void.class.getName(), ClassNameTools.primitiveWrapperClassName(void.class.getName().toCharArray()));
+		TestTools.assertEquals(java.lang.Integer.class.getName(), ClassNameTools.primitiveWrapperClassName(int.class.getName().toCharArray()));
+		TestTools.assertEquals(java.lang.Float.class.getName(), ClassNameTools.primitiveWrapperClassName(float.class.getName().toCharArray()));
+		TestTools.assertEquals(java.lang.Boolean.class.getName(), ClassNameTools.primitiveWrapperClassName(boolean.class.getName().toCharArray()));
+
+		assertNull(ClassNameTools.primitiveWrapperClassName(java.lang.String.class.getName().toCharArray()));
+	}
+
+	public void testPrimitiveClassName() {
+		assertEquals(void.class.getName(), ClassNameTools.primitiveClassName(java.lang.Void.class.getName()));
+		assertEquals(int.class.getName(), ClassNameTools.primitiveClassName(java.lang.Integer.class.getName()));
+		assertEquals(float.class.getName(), ClassNameTools.primitiveClassName(java.lang.Float.class.getName()));
+		assertEquals(boolean.class.getName(), ClassNameTools.primitiveClassName(java.lang.Boolean.class.getName()));
+
+		assertNull(ClassNameTools.primitiveClassName(java.lang.String.class.getName()));
+	}
+
+	public void testPrimitiveClassNameCharArray() {
+		TestTools.assertEquals(void.class.getName(), ClassNameTools.primitiveClassName(java.lang.Void.class.getName().toCharArray()));
+		TestTools.assertEquals(int.class.getName(), ClassNameTools.primitiveClassName(java.lang.Integer.class.getName().toCharArray()));
+		TestTools.assertEquals(float.class.getName(), ClassNameTools.primitiveClassName(java.lang.Float.class.getName().toCharArray()));
+		TestTools.assertEquals(boolean.class.getName(), ClassNameTools.primitiveClassName(java.lang.Boolean.class.getName().toCharArray()));
+
+		assertNull(ClassNameTools.primitiveClassName(java.lang.String.class.getName().toCharArray()));
+	}
+
+	public void testIsAutoboxEquivalent() {
+		assertTrue(ClassNameTools.isAutoboxEquivalent(Integer.class.getName(), Integer.class.getName()));
+		assertTrue(ClassNameTools.isAutoboxEquivalent(int.class.getName(), Integer.class.getName()));
+		assertTrue(ClassNameTools.isAutoboxEquivalent(Integer.class.getName(), int.class.getName()));
+		assertFalse(ClassNameTools.isAutoboxEquivalent(int.class.getName(), Boolean.class.getName()));
+		assertTrue(ClassNameTools.isAutoboxEquivalent(String.class.getName(), String.class.getName()));
+	}
+
+	public void testIsAutoboxEquivalentCharArray() {
+		assertTrue(ClassNameTools.isAutoboxEquivalent(Integer.class.getName().toCharArray(), Integer.class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isAutoboxEquivalent(int.class.getName().toCharArray(), Integer.class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isAutoboxEquivalent(Integer.class.getName().toCharArray(), int.class.getName().toCharArray()));
+		assertFalse(ClassNameTools.isAutoboxEquivalent(int.class.getName().toCharArray(), Boolean.class.getName().toCharArray()));
+		assertTrue(ClassNameTools.isAutoboxEquivalent(String.class.getName().toCharArray(), String.class.getName().toCharArray()));
+	}
+
+	public void testForCode() {
+		assertEquals("byte", ClassNameTools.forCode('B'));
+		assertEquals("char", ClassNameTools.forCode('C'));
+		assertEquals("double", ClassNameTools.forCode('D'));
+		assertEquals("float", ClassNameTools.forCode('F'));
+		assertEquals("int", ClassNameTools.forCode('I'));
+		assertEquals("long", ClassNameTools.forCode('J'));
+		assertEquals("short", ClassNameTools.forCode('S'));
+		assertEquals("boolean", ClassNameTools.forCode('Z'));
+		assertEquals("void", ClassNameTools.forCode('V'));
+
+		assertNull(ClassNameTools.forCode('X'));
+
+		assertEquals("byte", ClassNameTools.forCode((int) 'B'));
+		assertEquals("char", ClassNameTools.forCode((int) 'C'));
+		assertEquals("double", ClassNameTools.forCode((int) 'D'));
+		assertEquals("float", ClassNameTools.forCode((int) 'F'));
+		assertEquals("int", ClassNameTools.forCode((int) 'I'));
+		assertEquals("long", ClassNameTools.forCode((int) 'J'));
+		assertEquals("short", ClassNameTools.forCode((int) 'S'));
+		assertEquals("boolean", ClassNameTools.forCode((int) 'Z'));
+		assertEquals("void", ClassNameTools.forCode((int) 'V'));
+
+		assertNull(ClassNameTools.forCode((int) 'X'));
+	}
+
+	public void testForCodeCharArray() {
+		TestTools.assertEquals("byte", ClassNameTools.forCodeCharArray('B'));
+		TestTools.assertEquals("char", ClassNameTools.forCodeCharArray('C'));
+		TestTools.assertEquals("double", ClassNameTools.forCodeCharArray('D'));
+		TestTools.assertEquals("float", ClassNameTools.forCodeCharArray('F'));
+		TestTools.assertEquals("int", ClassNameTools.forCodeCharArray('I'));
+		TestTools.assertEquals("long", ClassNameTools.forCodeCharArray('J'));
+		TestTools.assertEquals("short", ClassNameTools.forCodeCharArray('S'));
+		TestTools.assertEquals("boolean", ClassNameTools.forCodeCharArray('Z'));
+		TestTools.assertEquals("void", ClassNameTools.forCodeCharArray('V'));
+
+		assertNull(ClassNameTools.forCodeCharArray('X'));
+
+		TestTools.assertEquals("byte", ClassNameTools.forCodeCharArray((int) 'B'));
+		TestTools.assertEquals("char", ClassNameTools.forCodeCharArray((int) 'C'));
+		TestTools.assertEquals("double", ClassNameTools.forCodeCharArray((int) 'D'));
+		TestTools.assertEquals("float", ClassNameTools.forCodeCharArray((int) 'F'));
+		TestTools.assertEquals("int", ClassNameTools.forCodeCharArray((int) 'I'));
+		TestTools.assertEquals("long", ClassNameTools.forCodeCharArray((int) 'J'));
+		TestTools.assertEquals("short", ClassNameTools.forCodeCharArray((int) 'S'));
+		TestTools.assertEquals("boolean", ClassNameTools.forCodeCharArray((int) 'Z'));
+		TestTools.assertEquals("void", ClassNameTools.forCodeCharArray((int) 'V'));
+
+		assertNull(ClassNameTools.forCodeCharArray((int) 'X'));
+	}
+
+	public void testPrimitiveClassCode() {
+		assertEquals('I', ClassNameTools.primitiveClassCode(int.class.getName()));
+		assertEquals('I', ClassNameTools.primitiveClassCode("int"));
+		assertEquals('B', ClassNameTools.primitiveClassCode(byte.class.getName()));
+		assertEquals('B', ClassNameTools.primitiveClassCode("byte"));
+
+		assertEquals((char) 0, ClassNameTools.primitiveClassCode(java.lang.Object.class.getName()));
+	}
+
+	public void testPrimitiveClassCodeCharArray() {
+		assertEquals('I', ClassNameTools.primitiveClassCode(int.class.getName().toCharArray()));
+		assertEquals('I', ClassNameTools.primitiveClassCode("int".toCharArray()));
+		assertEquals('B', ClassNameTools.primitiveClassCode(byte.class.getName().toCharArray()));
+		assertEquals('B', ClassNameTools.primitiveClassCode("byte".toCharArray()));
+
+		assertEquals((char) 0, ClassNameTools.primitiveClassCode(java.lang.Object.class.getName().toCharArray()));
+	}
+
+	public void testConstructor() {
+		boolean exCaught = false;
+		try {
+			Object at = ClassTools.newInstance(ClassNameTools.class);
+			fail("bogus: " + at); //$NON-NLS-1$
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof InvocationTargetException) {
+				if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ClassToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ClassToolsTests.java
new file mode 100644
index 0000000..23752ab
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ClassToolsTests.java
@@ -0,0 +1,303 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Vector;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ClassTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.iterable.TransformationIterable;
+
+@SuppressWarnings("nls")
+public class ClassToolsTests
+	extends TestCase
+{
+	private static String testStaticField;
+
+	public ClassToolsTests(String name) {
+		super(name);
+	}
+
+// this is no longer true - it appears the JLS now defines the generated names...
+//	/**
+//	 * Return the compiler-generated class name. The Eclipse compiler generates
+//	 * "local" classes with names in the form "com.foo.Outer$1$Local"; while the
+//	 * JDK compiler generates "com.foo.Outer$1Local". There might be other
+//	 * differences.... ~bjv
+//	 */
+//	public static String compilerDependentClassNameFor(String className) {
+//		int index = className.indexOf("$1$");
+//		if (index == -1) {
+//			return className;
+//		}
+//		try {
+//			Class.forName(className);
+//		} catch (ClassNotFoundException ex) {
+//			return className.substring(0, index + 2) + className.substring(index + 3);
+//		}
+//		return className;
+//	}
+//
+//	private static String munge(String className) {
+//		return compilerDependentClassNameFor(className);
+//	}
+
+	public void testAllFields() {
+		int fieldCount = 0;
+		fieldCount += java.util.Vector.class.getDeclaredFields().length;
+		fieldCount += java.util.AbstractList.class.getDeclaredFields().length;
+		fieldCount += java.util.AbstractCollection.class.getDeclaredFields().length;
+		fieldCount += java.lang.Object.class.getDeclaredFields().length;
+		Iterable<Field> fields = ClassTools.allFields(java.util.Vector.class);
+		assertEquals(fieldCount, IterableTools.size(fields));
+		assertTrue(IterableTools.contains(this.fieldNames(fields), "modCount"));
+		assertTrue(IterableTools.contains(this.fieldNames(fields), "serialVersionUID"));
+		assertTrue(IterableTools.contains(this.fieldNames(fields), "capacityIncrement"));
+		assertTrue(IterableTools.contains(this.fieldNames(fields), "elementCount"));
+		assertTrue(IterableTools.contains(this.fieldNames(fields), "elementData"));
+		assertTrue(fields.iterator().next().isAccessible());
+	}
+
+	public void testAllMethods() {
+		int methodCount = 0;
+		methodCount += java.util.Vector.class.getDeclaredMethods().length;
+		methodCount += java.util.AbstractList.class.getDeclaredMethods().length;
+		methodCount += java.util.AbstractCollection.class.getDeclaredMethods().length;
+		methodCount += java.lang.Object.class.getDeclaredMethods().length;
+		Iterable<Method> methods = ClassTools.allMethods(java.util.Vector.class);
+		assertEquals(methodCount, IterableTools.size(methods));
+		assertTrue(IterableTools.contains(this.methodNames(methods), "wait"));
+		assertTrue(IterableTools.contains(this.methodNames(methods), "addElement"));
+		assertTrue(methods.iterator().next().isAccessible());
+	}
+
+	public void testNewInstanceClass() {
+		Vector<?> v = ClassTools.newInstance(java.util.Vector.class);
+		assertNotNull(v);
+		assertEquals(0, v.size());
+	}
+
+	public void testNewInstanceClassClassObject() {
+		int initialCapacity = 200;
+		Vector<?> v = ClassTools.newInstance(java.util.Vector.class, int.class, new Integer(initialCapacity));
+		assertNotNull(v);
+		assertEquals(0, v.size());
+		Object[] elementData = (Object[]) ObjectTools.get(v, "elementData");
+		assertEquals(initialCapacity, elementData.length);
+	}
+
+	public void testNewInstanceClassClassArrayObjectArray() {
+		int initialCapacity = 200;
+		Class<?>[] parmTypes = new Class[1];
+		parmTypes[0] = int.class;
+		Object[] parms = new Object[1];
+		parms[0] = new Integer(initialCapacity);
+		Vector<?> v = ClassTools.newInstance(java.util.Vector.class, parmTypes, parms);
+		assertNotNull(v);
+		assertEquals(0, v.size());
+		Object[] elementData = (Object[]) ObjectTools.get(v, "elementData");
+		assertEquals(initialCapacity, elementData.length);
+
+		parms[0] = new Integer(-1);
+		boolean exCaught = false;
+		try {
+			v = ClassTools.newInstance(java.util.Vector.class, parmTypes, parms);
+		} catch (RuntimeException ex) {
+			exCaught = true;
+		}
+		assertTrue("RuntimeException not thrown", exCaught);
+
+		parmTypes[0] = java.lang.String.class;
+		parms[0] = "foo";
+		exCaught = false;
+		try {
+			v = ClassTools.newInstance(java.util.Vector.class, parmTypes, parms);
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof NoSuchMethodException) {
+				exCaught = true;
+			}
+		}
+		assertTrue("NoSuchMethodException not thrown", exCaught);
+	}
+
+	public void testExecuteClassString() {
+		Double randomObject = (Double) ClassTools.execute(java.lang.Math.class, "random");
+		assertNotNull(randomObject);
+		double random = randomObject.doubleValue();
+		assertTrue(random >= 0);
+		assertTrue(random < 1);
+	}
+
+	public void testExecuteClassStringClassObject() {
+		String s = (String) ClassTools.execute(java.lang.String.class, "valueOf", boolean.class, Boolean.TRUE);
+		assertNotNull(s);
+		assertEquals("true", s);
+	}
+
+	public void testExecuteClassStringClassArrayObjectArray() {
+		Class<?>[] parmTypes = new Class[1];
+		parmTypes[0] = boolean.class;
+		Object[] parms = new Object[1];
+		parms[0] = Boolean.TRUE;
+		String s = (String) ClassTools.execute(java.lang.String.class, "valueOf", parmTypes, parms);
+		assertNotNull(s);
+		assertEquals("true", s);
+
+		boolean exCaught = false;
+		Object bogusStaticMethodReturnValue = null;
+		try {
+			bogusStaticMethodReturnValue = ClassTools.execute(java.lang.String.class, "bogusStaticMethod", parmTypes, parms);
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof NoSuchMethodException) {
+				exCaught = true;
+			}
+		}
+		assertTrue("NoSuchMethodException not thrown: " + bogusStaticMethodReturnValue, exCaught);
+
+		// test non-static method
+		exCaught = false;
+		try {
+			bogusStaticMethodReturnValue = ClassTools.execute(java.lang.String.class, "toString");
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof NoSuchMethodException) {
+				exCaught = true;
+			}
+		}
+		assertTrue("NoSuchMethodException not thrown: " + bogusStaticMethodReturnValue, exCaught);
+	}
+
+	public void testSet() {
+		ClassTools.set(this.getClass(), "testStaticField", "new value");
+		assertEquals(testStaticField, "new value");
+
+		boolean exCaught = false;
+		try {
+			ClassTools.set(this.getClass(), "bogusStaticField", "new value");
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof NoSuchFieldException) {
+				exCaught = true;
+			}
+		}
+		assertTrue("NoSuchFieldException not thrown", exCaught);
+	}
+
+	public void testSimpleName() {
+		assertEquals("Vector", java.util.Vector.class.getSimpleName());
+		assertEquals("Entry", java.util.Map.Entry.class.getSimpleName());
+		assertEquals("int", int.class.getSimpleName());
+		assertEquals("int[]", int[].class.getSimpleName());
+		assertEquals("int[][]", int[][].class.getSimpleName());
+		assertEquals("void", void.class.getSimpleName());
+	}
+
+	public void testPackageName() {
+		assertEquals("java.util", java.util.Vector.class.getPackage().getName());
+		assertEquals("java.util", java.util.Map.Entry.class.getPackage().getName());
+	}
+
+	public void testArrayDepth() {
+		assertEquals(0, ClassTools.arrayDepth(java.util.Vector.class));
+		assertEquals(0, ClassTools.arrayDepth(int.class));
+		assertEquals(0, ClassTools.arrayDepth(void.class));
+		assertEquals(1, ClassTools.arrayDepth(java.util.Vector[].class));
+		assertEquals(1, ClassTools.arrayDepth(int[].class));
+		assertEquals(3, ClassTools.arrayDepth(java.util.Vector[][][].class));
+		assertEquals(3, ClassTools.arrayDepth(int[][][].class));
+	}
+
+	public void testElementType() {
+		assertEquals(java.util.Vector.class, ClassTools.elementType(java.util.Vector.class));
+		assertEquals(int.class, ClassTools.elementType(int.class));
+		assertEquals(void.class, ClassTools.elementType(void.class));
+		assertEquals(java.util.Vector.class, ClassTools.elementType(java.util.Vector[].class));
+		assertEquals(int.class, ClassTools.elementType(int[].class));
+		assertEquals(java.util.Vector.class, ClassTools.elementType(java.util.Vector[][][].class));
+		assertEquals(int.class, ClassTools.elementType(int[][][].class));
+	}
+
+	public void testIsPrimitiveWrapper() {
+		assertTrue(ClassTools.isPrimitiveWrapper(java.lang.Void.class));
+		assertTrue(ClassTools.isPrimitiveWrapper(java.lang.Boolean.class));
+		assertTrue(ClassTools.isPrimitiveWrapper(java.lang.Integer.class));
+		assertTrue(ClassTools.isPrimitiveWrapper(java.lang.Float.class));
+
+		assertFalse(ClassTools.isPrimitiveWrapper(java.lang.String.class));
+		assertFalse(ClassTools.isPrimitiveWrapper(void.class));
+		assertFalse(ClassTools.isPrimitiveWrapper(int.class));
+	}
+
+	public void testIsVariablePrimitiveWrapper() {
+		assertFalse(ClassTools.isVariablePrimitiveWrapper(java.lang.Void.class));
+
+		assertTrue(ClassTools.isVariablePrimitiveWrapper(java.lang.Boolean.class));
+		assertTrue(ClassTools.isVariablePrimitiveWrapper(java.lang.Integer.class));
+		assertTrue(ClassTools.isVariablePrimitiveWrapper(java.lang.Float.class));
+
+		assertFalse(ClassTools.isVariablePrimitiveWrapper(java.lang.String.class));
+		assertFalse(ClassTools.isVariablePrimitiveWrapper(void.class));
+		assertFalse(ClassTools.isVariablePrimitiveWrapper(int.class));
+	}
+
+	public void testPrimitiveWrapper() {
+		assertEquals(java.lang.Void.class, ClassTools.primitiveWrapper(void.class));
+		assertEquals(java.lang.Integer.class, ClassTools.primitiveWrapper(int.class));
+		assertEquals(java.lang.Float.class, ClassTools.primitiveWrapper(float.class));
+		assertEquals(java.lang.Boolean.class, ClassTools.primitiveWrapper(boolean.class));
+
+		assertNull(ClassTools.primitiveWrapper(java.lang.String.class));
+	}
+
+	public void testForTypeDeclarationStringInt() throws Exception {
+		assertEquals(int.class, ClassTools.forTypeDeclaration("int", 0));
+		assertEquals(int[].class, ClassTools.forTypeDeclaration("int", 1));
+		assertEquals(int[][][].class, ClassTools.forTypeDeclaration("int", 3));
+
+		assertEquals(Object.class, ClassTools.forTypeDeclaration("java.lang.Object", 0));
+		assertEquals(Object[][][].class, ClassTools.forTypeDeclaration("java.lang.Object", 3));
+
+		assertEquals(void.class, ClassTools.forTypeDeclaration("void", 0));
+		try {
+			ClassTools.forTypeDeclaration(void.class.getName(), 1);
+			fail("should not get here...");
+		} catch (RuntimeException ex) {
+			// expected
+		}
+	}
+
+	public void testPrimitiveCode() {
+		assertEquals('I', ClassTools.primitiveCode(int.class));
+		assertEquals('B', ClassTools.primitiveCode(byte.class));
+	}
+
+	private Iterable<String> fieldNames(Iterable<Field> fields) {
+		return new TransformationIterable<Field, String>(fields) {
+			@Override
+			protected String transform(Field field) {
+				return field.getName();
+			}
+		};
+	}
+
+	private Iterable<String> methodNames(Iterable<Method> methods) {
+		return new TransformationIterable<Method, String>(methods) {
+			@Override
+			protected String transform(Method method) {
+				return method.getName();
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ClasspathTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ClasspathTests.java
new file mode 100644
index 0000000..da43e7d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ClasspathTests.java
@@ -0,0 +1,403 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.Classpath;
+import org.eclipse.persistence.tools.utility.SystemTools;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+
+
+@SuppressWarnings("nls")
+public class ClasspathTests extends TestCase {
+	private static final String JAVA_HOME = System.getProperty("java.home");
+
+	public ClasspathTests(String name) {
+		super(name);
+	}
+
+	public void testCompressed() {
+		String path = "";
+
+		// no changes
+		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
+		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
+
+		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
+		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
+
+		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
+		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
+
+		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar;C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
+		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
+
+		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\i18n.jar;C:\\jdk\\i18n.jar;C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
+		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
+
+		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar;C:\\jdk\\rt.jar;;;;C:\\jdk\\jaws.jar;C:\\jdk\\jaws.jar;C:\\jdk\\rt.jar;;;")).compressed().getPath();
+		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
+
+		// no changes
+		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
+		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
+
+		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
+		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
+
+		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\..\\jdk\\i18n.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
+		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
+
+		path = new Classpath(this.morph("C:\\jdk1\\jdk2\\jdk3\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk1\\jdk2\\jdk3\\..\\..\\..\\jdk1\\jdk2\\jdk3\\i18n.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
+		assertEquals(this.morph("C:\\jdk1\\jdk2\\jdk3\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
+
+	}
+
+	public void testConvertToClassName() {
+		String fileName = "java/lang/String.class";
+		File file = new File(fileName);
+		String className = Classpath.convertToClassName(file);
+		assertEquals(java.lang.String.class.getName(), className);
+	}
+
+	public void testConvertToClass() throws ClassNotFoundException {
+		String fileName = "java/lang/String.class";
+		File file = new File(fileName);
+		Class<?> javaClass = Classpath.convertToClass(file);
+		assertEquals(java.lang.String.class, javaClass);
+	}
+
+	public void testConvertToArchiveClassFileEntryName() {
+		String fileName = Classpath.convertToArchiveClassFileEntryName(java.lang.String.class);
+		assertEquals("java/lang/String.class", fileName);
+	}
+
+	public void testConvertToArchiveEntryNameBase() {
+		String fileName = Classpath.convertToArchiveEntryNameBase(java.lang.String.class);
+		assertEquals("java/lang/String", fileName);
+	}
+
+	public void testConvertToClassFileName() {
+		char sc = File.separatorChar;
+		String fileName = Classpath.convertToClassFileName(java.lang.String.class);
+		assertEquals("java" + sc + "lang" + sc + "String.class", fileName);
+	}
+
+	public void testConvertToClassFileString() {
+		char sc = File.separatorChar;
+		File file = Classpath.convertToClassFile(java.lang.String.class.getName());
+		assertEquals("java" + sc + "lang" + sc + "String.class", file.getPath());
+	}
+
+	public void testConvertToClassFileClass() {
+		char sc = File.separatorChar;
+		File file = Classpath.convertToClassFile(java.lang.String.class);
+		assertEquals("java" + sc + "lang" + sc + "String.class", file.getPath());
+	}
+
+	public void testConvertToJavaFileName() {
+		char sc = File.separatorChar;
+		String fileName = Classpath.convertToJavaFileName(java.lang.String.class);
+		assertEquals("java" + sc + "lang" + sc + "String.java", fileName);
+	}
+
+	public void testConvertToJavaFileString() {
+		char sc = File.separatorChar;
+		File file = Classpath.convertToJavaFile(java.lang.String.class.getName());
+		assertEquals("java" + sc + "lang" + sc + "String.java", file.getPath());
+	}
+
+	public void testConvertToJavaFileClass() {
+		char sc = File.separatorChar;
+		File file = Classpath.convertToJavaFile(java.lang.String.class);
+		assertEquals("java" + sc + "lang" + sc + "String.java", file.getPath());
+	}
+
+	public void testConvertToFileNameBase() {
+		char sc = File.separatorChar;
+		String fileName = Classpath.convertToFileNameBase(java.lang.String.class);
+		assertEquals("java" + sc + "lang" + sc + "String", fileName);
+	}
+
+	public void testConvertToURLs() {
+		Iterator<URL> entries = new Classpath(this.morph("C:\\jdk\\rt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar")).getURLs().iterator();
+		assertEquals(this.morphURL("/C:/jdk/rt.jar"), entries.next().getPath());
+		assertEquals(this.morphURL("/C:/jdk/i18n.jar"), entries.next().getPath());
+		assertEquals(this.morphURL("/C:/jdk/jaws.jar"), entries.next().getPath());
+		assertEquals(this.morphURL("/C:/foo/classes"), entries.next().getPath());
+		assertEquals(this.morphURL("/C:/bar/bar.jar"), entries.next().getPath());
+		assertFalse(entries.hasNext());
+	}
+
+	public void testGetEntries() {
+		Classpath cp = new Classpath(this.morph("C:\\jdk\\rt.jar;;.;C:\\jdk\\i18n.jar;;;C:\\jdk\\jaws.jar;;C:\\foo\\classes;C:\\bar\\bar.jar;C:\\bar\\bar.jar;"));
+		Iterator<Classpath.Entry> entries = cp.getEntries().iterator();
+		assertEquals(this.morph("C:\\jdk\\rt.jar"), entries.next().getFileName());
+		assertEquals(this.morph("."), entries.next().getFileName());
+		assertEquals(this.morph("C:\\jdk\\i18n.jar"), entries.next().getFileName());
+		assertEquals(this.morph("C:\\jdk\\jaws.jar"), entries.next().getFileName());
+		assertEquals(this.morph("C:\\foo\\classes"), entries.next().getFileName());
+		assertEquals(this.morph("C:\\bar\\bar.jar"), entries.next().getFileName());
+		assertEquals(this.morph("C:\\bar\\bar.jar"), entries.next().getFileName());
+		assertFalse(entries.hasNext());
+
+		cp = cp.compressed();
+		entries = cp.getEntries().iterator();
+		assertEquals(this.morph("C:\\jdk\\rt.jar"), entries.next().getFileName());
+		assertEquals(this.morph("."), entries.next().getFileName());
+		assertEquals(this.morph("C:\\jdk\\i18n.jar"), entries.next().getFileName());
+		assertEquals(this.morph("C:\\jdk\\jaws.jar"), entries.next().getFileName());
+		assertEquals(this.morph("C:\\foo\\classes"), entries.next().getFileName());
+		assertEquals(this.morph("C:\\bar\\bar.jar"), entries.next().getFileName());
+		assertFalse(entries.hasNext());
+	}
+
+	public void testGetEntryForFileNamed() {
+		Classpath.Entry entry = null;
+
+		// in the middle - qualified
+		entry = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar")).getEntryForFileNamed("rt.jar");
+		assertEquals(this.morph("C:\\jdk\\rt.jar"), entry.getFileName());
+
+		// in the middle - unqualified
+		entry = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;rt.jar;C:\\foo\\classes;C:\\bar\\bar.jar")).getEntryForFileNamed("rt.jar");
+		assertEquals("rt.jar", entry.getFileName());
+
+		// at the beginning - qualified
+		entry = new Classpath(this.morph("C:\\jdk\\rt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar")).getEntryForFileNamed("rt.jar");
+		assertEquals(this.morph("C:\\jdk\\rt.jar"), entry.getFileName());
+
+		// at the beginning - unqualified
+		entry = new Classpath(this.morph("rt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar")).getEntryForFileNamed("rt.jar");
+		assertEquals("rt.jar", entry.getFileName());
+
+		// at the end - qualified
+		entry = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar;C:\\jdk\\rt.jar")).getEntryForFileNamed("rt.jar");
+		assertEquals(this.morph("C:\\jdk\\rt.jar"), entry.getFileName());
+
+		// at the end - unqualified
+		entry = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar;rt.jar")).getEntryForFileNamed("rt.jar");
+		assertEquals("rt.jar", entry.getFileName());
+
+		// alone - qualified
+		entry = new Classpath(this.morph("C:\\jdk\\rt.jar")).getEntryForFileNamed("rt.jar");
+		assertEquals(this.morph("C:\\jdk\\rt.jar"), entry.getFileName());
+
+		// alone - unqualified
+		entry = new Classpath("rt.jar").getEntryForFileNamed("rt.jar");
+		assertEquals("rt.jar", entry.getFileName());
+
+		// trick entry at the beginning
+		entry = new Classpath(this.morph("rt.jar.new;C:\\jdk\\rt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar")).getEntryForFileNamed("rt.jar");
+		assertEquals(this.morph("C:\\jdk\\rt.jar"), entry.getFileName());
+
+		// trick entry in the middle
+		entry = new Classpath(this.morph("rt.jar.new;C:\\jdk\\rtrtrt.jar;C:\\jdk\\rt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar")).getEntryForFileNamed("rt.jar");
+		assertEquals(this.morph("C:\\jdk\\rt.jar"), entry.getFileName());
+
+		// trick entry at the end
+		entry = new Classpath(this.morph("rt.jar.new;C:\\jdk\\rtrtrt.jar;C:\\jdk\\rt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar;C:\\jdk\\rtrtrt.jar")).getEntryForFileNamed("rt.jar");
+		assertEquals(this.morph("C:\\jdk\\rt.jar"), entry.getFileName());
+
+		// missing
+		entry = new Classpath(this.morph("rt.jar.new;C:\\jdk\\rtrtrt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar;C:\\jdk\\rtrtrt.jar")).getEntryForFileNamed("rt.jar");
+		assertEquals("path entry should not be found", null, entry);
+
+	}
+
+	public void testGetEntryForClassNamed() {
+		assertNotNull(Classpath.completeClasspath().getEntryForClassNamed(java.lang.String.class.getName()));
+		assertNull(Classpath.completeClasspath().getEntryForClassNamed("foo.bar.Baz"));
+	}
+
+	public void testLocationForClass() {
+		Class<?> javaClass = Classpath.class;
+		File entry = new File(Classpath.locationFor(javaClass));
+		if (entry.isFile() || entry.isDirectory()) {
+			assertTrue(entry.exists());
+		}
+		if (entry.isDirectory()) {
+			assertTrue(new File(entry, Classpath.convertToClassFileName(javaClass)).exists());
+		}
+	}
+
+	public void testRtJarName() throws IOException {
+		File rtFile = new File(Classpath.rtJarName());
+		assertTrue("rt.jar does not exist", rtFile.exists());
+
+		JarFile rtJarFile = new JarFile(rtFile);
+		JarEntry entry = rtJarFile.getJarEntry("java/lang/Object.class");
+		rtJarFile.close();
+		assertTrue("bogus rt.jar", entry != null);
+	}
+
+	public void testJREClassNames() {
+		assertTrue("Vector is missing from JRE class names", IterableTools.contains(Classpath.bootClasspath().getClassNames(), java.util.Vector.class.getName()));
+		assertTrue("File is missing from JRE class names", IterableTools.contains(Classpath.bootClasspath().getClassNames(), java.io.File.class.getName()));
+	}
+
+	public void testJavaExtensionDirectoryNames() {
+		char sep = File.separatorChar;
+		String stdExtDirName = JAVA_HOME + sep + "lib" + sep + "ext";
+		assertTrue("standard extension dir name missing: " + stdExtDirName, ArrayTools.contains(Classpath.javaExtensionDirectoryNames(), stdExtDirName));
+	}
+
+	public void testJavaExtensionDirectories() {
+		char sep = File.separatorChar;
+		File stdExtDir = new File(JAVA_HOME + sep + "lib" + sep + "ext");
+		assertTrue("standard extension dir missing: " + stdExtDir.getParent(), ArrayTools.contains(Classpath.javaExtensionDirectories(), stdExtDir));
+	}
+
+	public void testJavaExtensionClasspathEntries() {
+		if (SystemTools.javaSpecificationVersionIsLessThan("1.4") || SystemTools.javaSpecificationVersionIsGreaterThan("1.7")) {
+			fail("we need to update this test for the current JDK: " + SystemTools.javaSpecificationVersion());
+		}
+
+		Collection<String> jarNames = new ArrayList<String>();
+		Iterable<Classpath.Entry> entries = Classpath.javaExtensionClasspath().getEntries();
+		for (Classpath.Entry entry : entries) {
+			jarNames.add(entry.getFileName());
+		}
+		char sep = File.separatorChar;
+		String stdExtJarName = JAVA_HOME + sep + "lib" + sep + "ext" + sep + "dnsns.jar";
+		String msg = "JDK standard extension jar missing: " + stdExtJarName;
+		boolean jarPresent = jarNames.contains(stdExtJarName);
+		if (SystemTools.jvmIsSun() || (SystemTools.jvmIsIBM() && SystemTools.javaSpecificationVersionIsGreaterThan("1.5"))) {
+			assertTrue(msg, jarPresent);
+		}
+	}
+
+	public void testJavaExtensionClassNames() {
+		if (SystemTools.javaSpecificationVersionIsLessThan("1.4") || SystemTools.javaSpecificationVersionIsGreaterThan("1.7")) {
+			fail("we need to update this test for the current JDK: " + SystemTools.javaSpecificationVersion());
+		}
+
+		String className = "sun.net.spi.nameservice.dns.DNSNameService";
+		String msg = "JDK standard extension class missing: " + className;
+		boolean classPresent = IteratorTools.contains(Classpath.javaExtensionClasspath().classNames(), className);
+		if (SystemTools.jvmIsSun() || (SystemTools.jvmIsIBM() && SystemTools.javaSpecificationVersionIsGreaterThan("1.5"))) {
+			assertTrue(msg, classPresent);
+		}
+	}
+
+	public void testJavaClasspathClassNames() {
+		String className = this.getClass().getName();
+		ClassLoader cl = this.getClass().getClassLoader();
+		// make sure we are running under the "normal" class loader;
+		// when the tests are executed as an ANT task, they are run under
+		// an ANT class loader and the "Java" classpath does not include this class
+		if (cl.getClass().getName().startsWith("sun.misc")) {
+			assertTrue("class missing: " + className, IterableTools.contains(Classpath.javaClasspath().getClassNames(), className));
+		}
+	}
+
+	public void testCompleteClasspathClassNames() {
+		String className = this.getClass().getName();
+		ClassLoader cl = this.getClass().getClassLoader();
+		// make sure we are running under the "normal" class loader;
+		// when the tests are executed as an ANT task, they are run under
+		// an ANT class loader and the "Java" classpath does not include this class
+		if (cl.getClass().getName().startsWith("sun.misc")) {
+			assertTrue("class missing: " + className, IterableTools.contains(Classpath.completeClasspath().getClassNames(), className));
+		}
+	}
+
+	public void testClasspathForClass() {
+		assertNotNull(Classpath.classpathFor(java.lang.String.class));
+	}
+
+	public void testAddClassNamesTo() {
+		Collection<String> classNames = new ArrayList<String>(1000);
+		Classpath.bootClasspath().addClassNamesTo(classNames);
+		assertTrue(classNames.contains(java.util.Vector.class.getName()));
+	}
+
+	public void testToString() {
+		assertNotNull(Classpath.bootClasspath().toString());
+	}
+
+	public void testEntry_getCanonicalFile() {
+		Classpath.Entry entry = Classpath.bootClasspath().getEntryForClassNamed(java.lang.String.class.getName());
+		assertTrue(entry.getCanonicalFile().getPath().endsWith(".jar"));
+	}
+
+	public void testEntry_getCanonicalFileName() {
+		Classpath.Entry entry = Classpath.bootClasspath().getEntryForClassNamed(java.lang.String.class.getName());
+		String name = entry.getCanonicalFileName();
+		if (SystemTools.jvmIsSun()) {
+			assertTrue(name.endsWith("rt.jar"));
+		} else if (SystemTools.jvmIsIBM()) {
+			assertTrue(name.endsWith("vm.jar"));
+		}
+	}
+
+	public void testEntry_equals() {
+		Classpath.Entry entry = Classpath.bootClasspath().getEntryForClassNamed(java.lang.String.class.getName());
+		assertFalse(entry.equals("foo"));
+	}
+
+	public void testEntry_containsClass() {
+		Classpath.Entry entry = Classpath.bootClasspath().getEntryForClassNamed(java.lang.String.class.getName());
+		assertTrue(entry.contains(java.lang.String.class));
+	}
+
+	public void testEntry_containsString() {
+		Classpath.Entry entry = Classpath.bootClasspath().getEntryForClassNamed(java.lang.String.class.getName());
+		assertTrue(entry.contains(java.lang.String.class.getName()));
+	}
+
+	public void testEntry_getClassNames() {
+		Classpath.Entry entry = Classpath.bootClasspath().getEntryForClassNamed(java.lang.String.class.getName());
+		assertTrue(IterableTools.contains(entry.getClassNames(), java.lang.String.class.getName()));
+	}
+
+	public void testEntry_classNames() {
+		Classpath.Entry entry = Classpath.bootClasspath().getEntryForClassNamed(java.lang.String.class.getName());
+		assertTrue(IteratorTools.contains(entry.classNames(), java.lang.String.class.getName()));
+	}
+
+	/**
+	 * morph the specified path to a platform-independent path
+	 */
+	private String morph(String path) {
+		String result = path;
+		result = result.replace('\\', File.separatorChar);
+		result = result.replace(';', File.pathSeparatorChar);
+		if (!ArrayTools.contains(File.listRoots(), new File("C:\\"))) {
+			result = result.replaceAll("C:", "");
+		}
+		return result;
+	}
+
+	/**
+	 * morph the specified URL to a platform-independent path
+	 */
+	private String morphURL(String url) {
+		String result = url;
+		if (!ArrayTools.contains(File.listRoots(), new File("C:\\"))) {
+			result = result.replaceAll("/C:", "");
+		}
+		return result;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CollectingExceptionHandlerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CollectingExceptionHandlerTests.java
new file mode 100644
index 0000000..5aa0a26
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CollectingExceptionHandlerTests.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.CollectingExceptionHandler;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+
+public class CollectingExceptionHandlerTests
+	extends TestCase
+{
+	public CollectingExceptionHandlerTests(String name) {
+		super(name);
+	}
+
+	public void testHandleException() {
+		CollectingExceptionHandler exceptionHandler = new CollectingExceptionHandler();
+		Exception npe1 = new NullPointerException();
+		exceptionHandler.handleException(npe1);
+		Exception npe2 = new NullPointerException();
+		exceptionHandler.handleException(npe2);
+
+		Iterable<Throwable> exceptions = exceptionHandler.getExceptions();
+		assertEquals(2, IterableTools.size(exceptions));
+	}
+
+	public void testGetExceptions() {
+		CollectingExceptionHandler exceptionHandler = new CollectingExceptionHandler();
+		Exception npe1 = new NullPointerException();
+		exceptionHandler.handleException(npe1);
+		Exception npe2 = new NullPointerException();
+		exceptionHandler.handleException(npe2);
+
+		Iterable<Throwable> exceptions = exceptionHandler.getExceptions();
+		assertEquals(2, IterableTools.size(exceptions));
+		assertTrue(IterableTools.contains(exceptions, npe1));
+		assertTrue(IterableTools.contains(exceptions, npe2));
+	}
+
+	public void testClearExceptions() {
+		CollectingExceptionHandler exceptionHandler = new CollectingExceptionHandler();
+		Exception npe1 = new NullPointerException();
+		exceptionHandler.handleException(npe1);
+		Exception npe2 = new NullPointerException();
+		exceptionHandler.handleException(npe2);
+
+		Iterable<Throwable> exceptions = exceptionHandler.clearExceptions();
+		assertEquals(2, IterableTools.size(exceptions));
+		assertTrue(IterableTools.contains(exceptions, npe1));
+		assertTrue(IterableTools.contains(exceptions, npe2));
+
+		exceptions = exceptionHandler.clearExceptions();
+		assertTrue(IterableTools.isEmpty(exceptions));
+
+		exceptions = exceptionHandler.getExceptions();
+		assertTrue(IterableTools.isEmpty(exceptions));
+	}
+
+	public void testToString() {
+		CollectingExceptionHandler exceptionHandler = new CollectingExceptionHandler();
+		assertNotNull(exceptionHandler.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CommonUtilityTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CommonUtilityTests.java
new file mode 100644
index 0000000..e973368
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CommonUtilityTests.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.eclipse.persistence.tools.utility.tests.collection.CommonUtilityCollectionTests;
+import org.eclipse.persistence.tools.utility.tests.command.CommonUtilityCommandTests;
+import org.eclipse.persistence.tools.utility.tests.enumeration.CommonUtilityEnumerationTests;
+import org.eclipse.persistence.tools.utility.tests.filter.CommonUtilityFilterTests;
+import org.eclipse.persistence.tools.utility.tests.io.CommonUtilityIOTests;
+import org.eclipse.persistence.tools.utility.tests.iterable.CommonUtilityIterableTests;
+import org.eclipse.persistence.tools.utility.tests.iterator.CommonUtilityIteratorTests;
+import org.eclipse.persistence.tools.utility.tests.jdbc.CommonUtilityJDBCTests;
+import org.eclipse.persistence.tools.utility.tests.model.CommonUtilityModelTests;
+import org.eclipse.persistence.tools.utility.tests.node.CommonUtilityNodeTests;
+import org.eclipse.persistence.tools.utility.tests.reference.CommonUtilityReferenceTests;
+import org.eclipse.persistence.tools.utility.tests.transformer.CommonUtilityTransformerTests;
+
+/**
+ * decentralize test creation code
+ */
+public class CommonUtilityTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CommonUtilityTests.class.getPackage().getName());
+
+		suite.addTest(CommonUtilityCollectionTests.suite());
+		suite.addTest(CommonUtilityCommandTests.suite());
+		suite.addTest(CommonUtilityEnumerationTests.suite());
+		suite.addTest(CommonUtilityFilterTests.suite());
+		suite.addTest(CommonUtilityIOTests.suite());
+		suite.addTest(CommonUtilityIterableTests.suite());
+		suite.addTest(CommonUtilityIteratorTests.suite());
+		suite.addTest(CommonUtilityJDBCTests.suite());
+		suite.addTest(CommonUtilityModelTests.suite());
+		suite.addTest(CommonUtilityNodeTests.suite());
+		suite.addTest(CommonUtilityReferenceTests.suite());
+		suite.addTest(CommonUtilityTransformerTests.suite());
+
+		suite.addTestSuite(ArrayToolsTests.class);
+		suite.addTestSuite(BitToolsTests.class);
+		suite.addTestSuite(BooleanToolsTests.class);
+		suite.addTestSuite(ByteArrayToolsTests.class);
+		suite.addTestSuite(CancelExceptionTests.class);
+		suite.addTestSuite(CharacterToolsTests.class);
+		suite.addTestSuite(CharArrayToolsTests.class);
+		suite.addTestSuite(ClassToolsTests.class);
+		suite.addTestSuite(ClassNameToolsTests.class);
+		suite.addTestSuite(ClasspathTests.class);
+		suite.addTestSuite(CollectingExceptionHandlerTests.class);
+		suite.addTestSuite(CompositeExceptionHandlerTests.class);
+		suite.addTestSuite(CompositeExceptionTests.class);
+		suite.addTestSuite(CompositeMultiThreadedExceptionHandlerTests.class);
+		suite.addTestSuite(ExceptionHandlerTests.class);
+		suite.addTestSuite(ListenerListTests.class);
+		suite.addTestSuite(NameToolsTests.class);
+		suite.addTestSuite(ObjectToolsTests.class);
+		suite.addTestSuite(PrintStreamExceptionHandlerTests.class);
+		suite.addTestSuite(PrintWriterExceptionHandlerTests.class);
+		suite.addTestSuite(RangeTests.class);
+		suite.addTestSuite(ReverseComparatorTests.class);
+		suite.addTestSuite(SimpleAssociationTests.class);
+		suite.addTestSuite(SimpleJavaTypeTests.class);
+		suite.addTestSuite(SimpleMethodSignatureTests.class);
+		suite.addTestSuite(StackTraceTests.class);
+		suite.addTestSuite(StringBufferToolsTests.class);
+		suite.addTestSuite(StringBuilderToolsTests.class);
+		suite.addTestSuite(StringToolsTests.class);
+		suite.addTestSuite(SystemToolsTests.class);
+		suite.addTestSuite(TypeDeclarationToolsTests.class);
+		suite.addTestSuite(VersionComparatorTests.class);
+		suite.addTestSuite(XMLToolsReadTests.class);
+		suite.addTestSuite(XMLToolsWriteTests.class);
+
+		return suite;
+	}
+
+	private CommonUtilityTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CompositeExceptionHandlerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CompositeExceptionHandlerTests.java
new file mode 100644
index 0000000..90c40b8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CompositeExceptionHandlerTests.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.CompositeExceptionHandler;
+import org.eclipse.persistence.tools.utility.ExceptionHandler;
+import org.eclipse.persistence.tools.utility.ExceptionHandlerAdapter;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+
+@SuppressWarnings("nls")
+public class CompositeExceptionHandlerTests
+	extends TestCase
+{
+	public CompositeExceptionHandlerTests(String name) {
+		super(name);
+	}
+
+	public void testHandleException() {
+		TestExceptionHandler handler1 = new TestExceptionHandler();
+		TestExceptionHandler handler2 = new TestExceptionHandler();
+		CompositeExceptionHandler exceptionHandler = new CompositeExceptionHandler(handler1, handler2);
+		Exception npe = new NullPointerException();
+		exceptionHandler.handleException(npe);
+
+		assertEquals(npe, handler1.throwable);
+		assertEquals(npe, handler2.throwable);
+	}
+
+	public void testGetExceptionHandlers() {
+		TestExceptionHandler handler1 = new TestExceptionHandler();
+		TestExceptionHandler handler2 = new TestExceptionHandler();
+		CompositeExceptionHandler exceptionHandler = new CompositeExceptionHandler(handler1, handler2);
+
+		Iterable<ExceptionHandler> handlers = exceptionHandler.getExceptionHandlers();
+		assertTrue(IterableTools.contains(handlers, handler1));
+		assertTrue(IterableTools.contains(handlers, handler2));
+	}
+
+	public void testAddExceptionHandler() {
+		TestExceptionHandler handler1 = new TestExceptionHandler();
+		CompositeExceptionHandler exceptionHandler = new CompositeExceptionHandler(handler1);
+		TestExceptionHandler handler2 = new TestExceptionHandler();
+		exceptionHandler.addExceptionHandler(handler2);
+		Exception npe = new NullPointerException();
+		exceptionHandler.handleException(npe);
+
+		Iterable<ExceptionHandler> handlers = exceptionHandler.getExceptionHandlers();
+		assertTrue(IterableTools.contains(handlers, handler1));
+		assertTrue(IterableTools.contains(handlers, handler2));
+
+		assertEquals(npe, handler1.throwable);
+		assertEquals(npe, handler2.throwable);
+	}
+
+	public void testAddExceptionHandler_exception() {
+		TestExceptionHandler handler1 = new TestExceptionHandler();
+		CompositeExceptionHandler exceptionHandler = new CompositeExceptionHandler(handler1);
+		try {
+			exceptionHandler.addExceptionHandler(handler1);
+			fail();
+		} catch (IllegalArgumentException ex) {
+			assertTrue(ex.getMessage().contains("duplicate handler"));
+		}
+	}
+
+	public void testRemoveExceptionHandler() {
+		TestExceptionHandler handler1 = new TestExceptionHandler();
+		CompositeExceptionHandler exceptionHandler = new CompositeExceptionHandler(handler1);
+		TestExceptionHandler handler2 = new TestExceptionHandler();
+		exceptionHandler.addExceptionHandler(handler2);
+		Exception npe = new NullPointerException();
+		exceptionHandler.handleException(npe);
+
+		Iterable<ExceptionHandler> handlers = exceptionHandler.getExceptionHandlers();
+		assertTrue(IterableTools.contains(handlers, handler1));
+		assertTrue(IterableTools.contains(handlers, handler2));
+
+		assertEquals(npe, handler1.throwable);
+		assertEquals(npe, handler2.throwable);
+
+		handler1.throwable = null;
+		handler2.throwable = null;
+		exceptionHandler.removeExceptionHandler(handler2);
+		exceptionHandler.handleException(npe);
+
+		handlers = exceptionHandler.getExceptionHandlers();
+		assertTrue(IterableTools.contains(handlers, handler1));
+		assertFalse(IterableTools.contains(handlers, handler2));
+
+		assertEquals(npe, handler1.throwable);
+		assertNull(handler2.throwable);
+	}
+
+	public void testRemoveExceptionHandler_exception() {
+		TestExceptionHandler handler1 = new TestExceptionHandler();
+		CompositeExceptionHandler exceptionHandler = new CompositeExceptionHandler(handler1);
+		TestExceptionHandler handler2 = new TestExceptionHandler();
+		try {
+			exceptionHandler.removeExceptionHandler(handler2);
+			fail();
+		} catch (IllegalArgumentException ex) {
+			assertTrue(ex.getMessage().contains("handler not registered"));
+		}
+	}
+
+	public void testToString() {
+		CompositeExceptionHandler exceptionHandler = new CompositeExceptionHandler();
+		assertNotNull(exceptionHandler.toString());
+	}
+
+
+	public static class TestExceptionHandler
+		extends ExceptionHandlerAdapter
+	{
+		public volatile Throwable throwable = null;
+		@Override
+		public void handleException(Throwable t) {
+			this.throwable = t;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CompositeExceptionTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CompositeExceptionTests.java
new file mode 100644
index 0000000..9f7d1b0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CompositeExceptionTests.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.CompositeException;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+
+@SuppressWarnings("nls")
+public class CompositeExceptionTests
+	extends TestCase
+{
+	public CompositeExceptionTests(String name) {
+		super(name);
+	}
+
+	public void testGetException() {
+		Exception npe = new NullPointerException();
+		Exception iae = new IllegalArgumentException();
+		CompositeException ex = new CompositeException(npe, iae);
+
+		Iterable<Throwable> exceptions = ex.getExceptions();
+		assertEquals(2, IterableTools.size(exceptions));
+		assertTrue(IterableTools.contains(exceptions, npe));
+		assertTrue(IterableTools.contains(exceptions, iae));
+	}
+
+	public void testGetMessage() {
+		Exception npe = new NullPointerException();
+		Exception iae = new IllegalArgumentException();
+		CompositeException ex = new CompositeException(npe, iae);
+
+		assertTrue(ex.getMessage().contains("NullPointerException"));
+		assertTrue(ex.getMessage().contains("IllegalArgumentException"));
+	}
+
+	public void testToString() {
+		CompositeException ex = new CompositeException();
+		assertNotNull(ex.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CompositeMultiThreadedExceptionHandlerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CompositeMultiThreadedExceptionHandlerTests.java
new file mode 100644
index 0000000..dc23801
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/CompositeMultiThreadedExceptionHandlerTests.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.CompositeMultiThreadedExceptionHandler;
+import org.eclipse.persistence.tools.utility.MultiThreadedExceptionHandler;
+import org.eclipse.persistence.tools.utility.tests.CompositeExceptionHandlerTests.TestExceptionHandler;
+
+public class CompositeMultiThreadedExceptionHandlerTests
+	extends TestCase
+{
+	public CompositeMultiThreadedExceptionHandlerTests(String name) {
+		super(name);
+	}
+
+	public void testHandleException() {
+		TestMultiThreadedExceptionHandler handler1 = new TestMultiThreadedExceptionHandler();
+		TestMultiThreadedExceptionHandler handler2 = new TestMultiThreadedExceptionHandler();
+		CompositeMultiThreadedExceptionHandler exceptionHandler = new CompositeMultiThreadedExceptionHandler(handler1, handler2);
+		Exception npe = new NullPointerException();
+		Thread thread = Thread.currentThread();
+		exceptionHandler.handleException(thread, npe);
+
+		assertEquals(npe, handler1.throwable);
+		assertEquals(thread, handler1.thread);
+		assertEquals(npe, handler2.throwable);
+		assertEquals(thread, handler2.thread);
+	}
+
+	public static class TestMultiThreadedExceptionHandler
+		extends TestExceptionHandler
+		implements MultiThreadedExceptionHandler
+	{
+		public volatile Thread thread = null;
+		@Override
+		public void handleException(Thread t, Throwable ex) {
+			this.thread = t;
+			this.throwable = ex;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ExceptionHandlerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ExceptionHandlerTests.java
new file mode 100644
index 0000000..2842b57
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ExceptionHandlerTests.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ExceptionHandler;
+
+public class ExceptionHandlerTests extends TestCase {
+
+	public ExceptionHandlerTests(String name) {
+		super(name);
+	}
+
+	public void testNullExceptionHandler() {
+		ExceptionHandler exceptionHandler = ExceptionHandler.Null.instance();
+		exceptionHandler.handleException(new NullPointerException());  // just make sure it doesn't blow up?
+	}
+
+	public void testNullExceptionHandlerToString() {
+		ExceptionHandler exceptionHandler = ExceptionHandler.Null.instance();
+		assertNotNull(exceptionHandler.toString());
+	}
+
+	public void testRuntimeExceptionHandler1() {
+		Exception npe = new Exception();
+		ExceptionHandler exceptionHandler = ExceptionHandler.Runtime.instance();
+		boolean exCaught = false;
+		try {
+			exceptionHandler.handleException(npe);
+			fail();
+		} catch (RuntimeException ex) {
+			assertSame(npe, ex.getCause());
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRuntimeExceptionHandler2() {
+		Exception npe = new NullPointerException();
+		ExceptionHandler exceptionHandler = ExceptionHandler.Runtime.instance();
+		boolean exCaught = false;
+		try {
+			exceptionHandler.handleException(npe);
+			fail();
+		} catch (RuntimeException ex) {
+			assertSame(npe, ex);
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRuntimeExceptionHandlerToString() {
+		ExceptionHandler exceptionHandler = ExceptionHandler.Runtime.instance();
+		assertNotNull(exceptionHandler.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/JDKTools.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/JDKTools.java
new file mode 100644
index 0000000..5ec037d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/JDKTools.java
@@ -0,0 +1,385 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests;

+

+import java.io.BufferedInputStream;

+import java.io.BufferedOutputStream;

+import java.io.ByteArrayOutputStream;

+import java.io.File;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.OutputStream;

+import java.util.ArrayList;

+import org.eclipse.persistence.tools.utility.ObjectTools;

+import org.eclipse.persistence.tools.utility.StringTools;

+import org.eclipse.persistence.tools.utility.collection.CollectionTools;

+import org.eclipse.persistence.tools.utility.filter.Filter;

+import org.eclipse.persistence.tools.utility.filter.FilterAdapter;

+import org.eclipse.persistence.tools.utility.io.NullOutputStream;

+import org.eclipse.persistence.tools.utility.iterable.FilteringIterable;

+import org.eclipse.persistence.tools.utility.iterable.TransformationIterable;

+import org.eclipse.persistence.tools.utility.transformer.Transformer;

+import org.eclipse.persistence.tools.utility.transformer.TransformerAdapter;

+

+/**

+ * Some tools for executing, compiling, JARing, etc.

+ * Possibly obviously, this stuff might not work on all platforms. It seems

+ * to work OK on Windows and Linux.

+ */

+@SuppressWarnings("nls")

+public class JDKTools {

+	private static final String CR = StringTools.CR;

+	private static final String FS = System.getProperty("file.separator");

+	private static final String JAVA_HOME = System.getProperty("java.home");

+	private static final String JAVA_CLASSPATH = System.getProperty("java.class.path");

+

+

+	/**

+	 * Compile the specified source file, using the current system classpath.

+	 */

+	public static void compile(File sourceFile) throws IOException, InterruptedException {

+		compile(sourceFile, JAVA_CLASSPATH);

+	}

+

+	/**

+	 * Compile the specified source file with the specified classpath.

+	 * The resulting class file will be put in the same directory as the

+	 * source file.

+	 * @exception RuntimeException for any non-zero exit value.

+	 */

+	public static void compile(File sourceFile, String classpath) throws IOException, InterruptedException {

+		ArrayList<String> cmd = new ArrayList<String>();

+		cmd.add(javaCompiler());

+		if ((classpath != null) && (classpath.length() != 0)) {

+			cmd.add("-classpath");

+			cmd.add(classpath);

+		}

+		cmd.add(sourceFile.getAbsolutePath());

+		exec(cmd.toArray(new String[cmd.size()]));

+	}

+

+	/**

+	 * Compile all the specified source files,

+	 * using the current system classpath.

+	 */

+	public static void compile(Iterable<File> sourceFiles) throws IOException, InterruptedException {

+		compile(sourceFiles, JAVA_CLASSPATH);

+	}

+

+	/**

+	 * Compile all the specified source files with

+	 * the specified classpath. The resulting class files will be put in

+	 * the same directories as the source files.

+	 * @exception RuntimeException for any non-zero exit value.

+	 */

+	public static void compile(Iterable<File> sourceFiles, String classpath) throws IOException, InterruptedException {

+		ArrayList<String> cmd = new ArrayList<String>();

+		cmd.add(javaCompiler());

+		if ((classpath != null) && (classpath.length() != 0)) {

+			cmd.add("-classpath");

+			cmd.add(classpath);

+		}

+		CollectionTools.addAll(cmd, javaFileNames(sourceFiles));

+		exec(cmd.toArray(new String[cmd.size()]));

+	}

+

+	/**

+	 * Return the names of the files in the collection that end with

+	 * <code>".java"</code>.

+	 */

+	private static Iterable<String> javaFileNames(Iterable<File> files) {

+		return new TransformationIterable<File, String>(filterJavaFiles(files), FILE_NAME_TRANSFORMER);

+	}

+

+	private static final Transformer<File, String> FILE_NAME_TRANSFORMER = new FileNameTransformer();

+	/* CU private */ static class FileNameTransformer

+		extends TransformerAdapter<File, String>

+	{

+		@Override

+		public String transform(File file) {

+			return file.getAbsolutePath();

+		}

+	}

+

+	/**

+	 * Return the files in the collection whose names that end with

+	 * <code>".java"</code>.

+	 */

+	private static Iterable<File> filterJavaFiles(Iterable<File> files) {

+		return new FilteringIterable<File>(files, JAVA_FILE_FILTER);

+	}

+

+	private static final Filter<File> JAVA_FILE_FILTER = new JavaFileFilter();

+	/* CU private */ static class JavaFileFilter

+		extends FilterAdapter<File>

+	{

+		@Override

+		public boolean accept(File file) {

+			return file.isFile() && file.getPath().endsWith(".java");

+		}

+	}

+

+	/**

+	 * Add to the specified archive all the files in and below

+	 * the specified directory.

+	 * Jar program options:<ul>

+	 * <li>c = create

+	 * <li>f = file

+	 * </ul>

+	 * @exception RuntimeException for any non-zero exit value.

+	 */

+	public static void jar(File jarFile, File directory) throws IOException, InterruptedException {

+		jar("cf", jarFile, directory);

+	}

+

+	/**

+	 * Add to the specified zip file all the files in and below

+	 * the specified directory.

+	 * Jar program options:<ul>

+	 * <li>c = create

+	 * <li>M = no manifest

+	 * <li>f = file

+	 * </ul>

+	 * @exception RuntimeException for any non-zero exit value.

+	 */

+	public static void zip(File zipFile, File directory) throws IOException, InterruptedException {

+		jar("cMf", zipFile, directory);

+	}

+

+	private static void jar(String jarOptions, File jarFile, File directory) throws IOException, InterruptedException {

+		exec(

+			new String[] {

+				jarUtility(),

+				jarOptions,

+				jarFile.getAbsolutePath(),

+				"-C",

+				directory.getAbsolutePath(),

+				"."

+			}

+		);

+	}

+

+	/**

+	 * Execute the specified class's main method, using the current system classpath.

+	 */

+	public static void java(String className) throws IOException, InterruptedException {

+		java(className, JAVA_CLASSPATH);

+	}

+

+	/**

+	 * Execute the specified class's main method with the specified classpath.

+	 * @exception RuntimeException for any non-zero exit value.

+	 */

+	public static void java(String className, String classpath) throws IOException, InterruptedException {

+		java(className, classpath, StringTools.EMPTY_STRING_ARRAY);

+	}

+

+	/**

+	 * Execute the specified class's main method with the specified classpath.

+	 * @exception RuntimeException for any non-zero exit value.

+	 */

+	public static void java(String className, String classpath, String[] args) throws IOException, InterruptedException {

+		java(className, classpath, StringTools.EMPTY_STRING_ARRAY, args);

+	}

+

+	/**

+	 * Execute the specified class's main method with the specified classpath.

+	 * @exception RuntimeException for any non-zero exit value.

+	 */

+	public static void java(String className, String classpath, String[] javaOptions, String[] args) throws IOException, InterruptedException {

+		ArrayList<String> cmd = new ArrayList<String>();

+		cmd.add(javaVM());

+		if ((classpath != null) && (classpath.length() != 0)) {

+			cmd.add("-classpath");

+			cmd.add(classpath);

+		}

+		CollectionTools.addAll(cmd, javaOptions);

+		cmd.add(className);

+		CollectionTools.addAll(cmd, args);

+		exec(cmd.toArray(new String[cmd.size()]));

+	}

+

+	/**

+	 * Execute the specified command line.

+	 * @exception RuntimeException for any non-zero exit value.

+	 */

+	public static void exec(String[] cmd) throws IOException, InterruptedException {

+		// dump(cmd);

+		Process process = Runtime.getRuntime().exec(cmd);

+

+		// fork a thread to consume stderr

+		ByteArrayOutputStream stderrStream = new ByteArrayOutputStream(1000);

+		Runnable stderrRunnable = new RunnableStreamReader(

+				new BufferedInputStream(process.getErrorStream()),

+				new BufferedOutputStream(stderrStream)

+			);

+		Thread stderrThread = new Thread(stderrRunnable, "stderr stream reader");

+		stderrThread.start();

+

+		// fork a thread to consume stdout

+		ByteArrayOutputStream stdoutStream = new ByteArrayOutputStream(1000);

+		Runnable stdoutRunnable = new RunnableStreamReader(

+				new BufferedInputStream(process.getInputStream()),

+				new BufferedOutputStream(stdoutStream)

+			);

+		Thread stdoutThread = new Thread(stdoutRunnable, "stdout stream reader");

+		stdoutThread.start();

+

+		// wait for all the threads to die

+		stderrThread.join();

+		stdoutThread.join();

+		int exitValue = process.waitFor();

+

+		stderrStream.close();

+		stdoutStream.close();

+

+		if (exitValue != 0) {

+			StringBuffer sb = new StringBuffer(2000);

+			sb.append(CR);

+			sb.append("**** exit value: ");

+			sb.append(exitValue);

+			sb.append(CR);

+			sb.append("**** stderr: ");

+			sb.append(CR);

+			sb.append(stderrStream.toString());

+			sb.append(CR);

+			sb.append("**** stdout: ");

+			sb.append(CR);

+			sb.append(stdoutStream.toString());

+			throw new RuntimeException(sb.toString());

+		}

+	}

+

+	/**

+	 * Return the name of the standard Java Home directory.

+	 */

+	public static String javaHomeDirectoryName() {

+		return JAVA_HOME;

+	}

+

+	/**

+	 * Return the standard Java Home directory.

+	 */

+	public static File javaHomeDirectory() {

+		return new File(javaHomeDirectoryName());

+	}

+

+	/**

+	 * Return the directory that holds the various Java tools

+	 * (e.g. java, javac, jar).

+	 */

+	public static File javaToolDirectory() {

+		return new File(javaHomeDirectory().getParentFile(), "bin");

+	}

+

+	/**

+	 * Return the name of the directory that holds the various Java tools

+	 * (e.g. java, javac, jar).

+	 */

+	public static String javaToolDirectoryName() {

+		return javaToolDirectory().getPath();

+	}

+

+	/**

+	 * Return the fully-qualified name of the Java VM.

+	 */

+	public static String javaVM() {

+		return javaToolDirectoryName() + FS + "java";

+	}

+

+	/**

+	 * Return the fully-qualified name of the Java compiler.

+	 */

+	public static String javaCompiler() {

+		return javaToolDirectoryName() + FS + "javac";

+	}

+

+	/**

+	 * Return the fully-qualified name of the JAR utility.

+	 */

+	public static String jarUtility() {

+		return javaToolDirectoryName() + FS + "jar";

+	}

+

+	/**

+	 * Print the specified "command line" to the console.

+	 */

+	static void dump(String[] cmd) {

+		for (int i = 0; i < cmd.length; i++) {

+			System.out.print(cmd[i]);

+			if (i + 1 < cmd.length) {

+				System.out.print(" ");

+			}

+		}

+		System.out.println();

+	}

+

+	/**

+	 * Suppress default constructor, ensuring non-instantiability.

+	 */

+	private JDKTools() {

+		super();

+		throw new UnsupportedOperationException();

+	}

+

+

+	// ********** stream reader **********

+

+	/**

+	 * This class allows you to fork a thread to read an input stream

+	 * asynchronously.

+	 */

+	/* CU private */ static class RunnableStreamReader

+		implements Runnable

+	{

+		private InputStream inputStream;

+		private OutputStream outputStream;

+

+

+		/**

+		 * Construct a stream reader that reads the specified stream

+		 * and discards the data.

+		 */

+		RunnableStreamReader(InputStream inputStream) {

+			this(inputStream, NullOutputStream.instance());

+		}

+

+		/**

+		 * Construct a stream reader that reads the specified input stream

+		 * and copies its data to the specified output stream.

+		 */

+		RunnableStreamReader(InputStream inputStream, OutputStream outputStream) {

+			super();

+			this.inputStream = inputStream;

+			this.outputStream = outputStream;

+		}

+

+		@Override

+		public void run() {

+			try {

+				for (int b = -1; (b = this.inputStream.read()) != -1; ) {

+					this.outputStream.write(b);

+				}

+			} catch (IOException ex) {

+				// hmmm - not sure what to do here, but this seems good enough

+				throw new RuntimeException(ex);

+			}

+		}

+

+		@Override

+		public String toString() {

+			return ObjectTools.toString(this);

+		}

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ListenerListTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ListenerListTests.java
new file mode 100644
index 0000000..e59c4ea
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ListenerListTests.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.io.Serializable;
+import java.util.EventListener;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ListenerList;
+import org.eclipse.persistence.tools.utility.SystemTools;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+
+
+@SuppressWarnings("nls")
+public class ListenerListTests extends TestCase {
+
+	public ListenerListTests(String name) {
+		super(name);
+	}
+
+	public void testGetListeners() throws Exception {
+		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
+		Listener listener1 = new LocalListener();
+		Listener listener2 = new LocalListener();
+		Iterable<Listener> listeners = listenerList.getListeners();
+		assertEquals(0, IterableTools.size(listeners));
+
+		listenerList.add(listener1);
+		listenerList.add(listener2);
+		listeners = listenerList.getListeners();
+		assertEquals(2, IterableTools.size(listeners));
+		assertTrue(IterableTools.contains(listeners, listener1));
+		assertTrue(IterableTools.contains(listeners, listener2));
+	}
+
+	public void testSize() throws Exception {
+		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
+		Listener listener1 = new LocalListener();
+		Listener listener2 = new LocalListener();
+		assertEquals(0, listenerList.size());
+
+		listenerList.add(listener1);
+		listenerList.add(listener2);
+		assertEquals(2, listenerList.size());
+	}
+
+	public void testIsEmpty() throws Exception {
+		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
+		Listener listener1 = new LocalListener();
+		Listener listener2 = new LocalListener();
+		assertTrue(listenerList.isEmpty());
+
+		listenerList.add(listener1);
+		listenerList.add(listener2);
+		assertFalse(listenerList.isEmpty());
+	}
+
+	public void testAdd_null() throws Exception {
+		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
+		boolean exCaught = false;
+		try {
+			listenerList.add(null);
+			fail("invalid listener list: " + listenerList);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAdd_duplicate() throws Exception {
+		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
+		Listener listener = new LocalListener();
+		listenerList.add(listener);
+
+		boolean exCaught = false;
+		try {
+			listenerList.add(listener);
+			fail("invalid listener list: " + listenerList);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemove() throws Exception {
+		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
+		Listener listener1 = new LocalListener();
+		Listener listener2 = new LocalListener();
+		listenerList.add(listener1);
+		listenerList.add(listener2);
+		assertTrue(IterableTools.contains(listenerList.getListeners(), listener1));
+		assertTrue(IterableTools.contains(listenerList.getListeners(), listener2));
+
+		listenerList.remove(listener1);
+		assertFalse(IterableTools.contains(listenerList.getListeners(), listener1));
+		assertTrue(IterableTools.contains(listenerList.getListeners(), listener2));
+
+		listenerList.remove(listener2);
+		assertFalse(IterableTools.contains(listenerList.getListeners(), listener2));
+	}
+
+	public void testRemove_null() throws Exception {
+		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
+		boolean exCaught = false;
+		try {
+			listenerList.remove(null);
+			fail("invalid listener list: " + listenerList);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemove_unregistered() throws Exception {
+		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
+		Listener listener = new LocalListener();
+		listenerList.add(listener);
+		listenerList.remove(listener);
+
+		boolean exCaught = false;
+		try {
+			listenerList.remove(listener);
+			fail("invalid listener list: " + listenerList);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testClear() throws Exception {
+		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
+		Listener listener1 = new LocalListener();
+		Listener listener2 = new LocalListener();
+		listenerList.add(listener1);
+		listenerList.add(listener2);
+		assertTrue(IterableTools.contains(listenerList.getListeners(), listener1));
+		assertTrue(IterableTools.contains(listenerList.getListeners(), listener2));
+
+		listenerList.clear();
+		assertFalse(IterableTools.contains(listenerList.getListeners(), listener1));
+		assertFalse(IterableTools.contains(listenerList.getListeners(), listener2));
+	}
+
+	public void testSerialization() throws Exception {
+		// This test doesn't pass in the Eclipse build environment (Linux/IBM VM) for some reason
+		if (SystemTools.jvmIsSun()) {
+			this.verifySerialization();
+		}
+	}
+
+	private void verifySerialization() throws Exception {
+		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
+		Listener listener1 = new LocalListener();
+		Listener listener2 = new LocalListener();
+		listenerList.add(listener1);
+		listenerList.add(listener2);
+
+		ListenerList<Listener> listenerList2 = TestTools.serialize(listenerList);
+		assertNotSame(listenerList, listenerList2);
+		assertEquals(2, listenerList2.size());
+
+		Listener listener3 = new NonSerializableListener();
+		listenerList.add(listener3);
+
+		listenerList2 = TestTools.serialize(listenerList);
+		assertNotSame(listenerList, listenerList2);
+		assertEquals(2, listenerList2.size());
+
+	}
+
+	interface Listener extends EventListener {
+		void somethingHappened();
+	}
+
+	static class LocalListener implements Listener, Serializable {
+		private static final long serialVersionUID = 1L;
+		@Override
+		public void somethingHappened() {
+			// do nothing
+		}
+	}
+
+	static class NonSerializableListener implements Listener {
+		@Override
+		public void somethingHappened() {
+			// do nothing
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/MultiThreadedTestCase.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/MultiThreadedTestCase.java
new file mode 100644
index 0000000..ba1965d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/MultiThreadedTestCase.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.util.ArrayList;
+import java.util.Vector;
+import java.util.concurrent.ThreadFactory;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.CompositeException;
+
+/**
+ * This test case helps simplify the testing of multi-threaded code.
+ */
+@SuppressWarnings("nls")
+public abstract class MultiThreadedTestCase
+	extends TestCase
+{
+	private final ArrayList<Thread> threads = new ArrayList<Thread>();
+	/* private */ final Vector<Throwable> exceptions = new Vector<Throwable>();
+
+	/**
+	 * The default "tick" is one second.
+	 * Specify the appropriate system property to override.
+	 */
+	public static final String TICK_SYSTEM_PROPERTY_NAME = "org.eclipse.jpt.common.utility.tests.tick";
+	public static final long TICK = Long.getLong(TICK_SYSTEM_PROPERTY_NAME, 1000).longValue();
+	public static final long TWO_TICKS = 2 * TICK;
+	public static final long THREE_TICKS = 3 * TICK;
+
+	/**
+	 * Default constructor.
+	 */
+	public MultiThreadedTestCase() {
+		super();
+	}
+
+	/**
+	 * Named constructor.
+	 */
+	public MultiThreadedTestCase(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+	}
+
+	/**
+	 * Stop all the threads constructed during the test case.
+	 * If any exceptions were thrown by the threads, re-throw them here.
+	 */
+	@Override
+	protected void tearDown() throws Exception {
+		for (Thread thread : this.threads) {
+			if (thread.isAlive()) {
+				throw new IllegalStateException("thread is still alive: " + thread);
+			}
+		}
+		if ( ! this.exceptions.isEmpty()) {
+			throw new CompositeException(this.exceptions);
+		}
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	protected Thread buildThread(Runnable runnable) {
+		return this.buildThread(runnable, null);
+	}
+
+	protected Thread buildThread(Runnable runnable, String name) {
+		Thread thread = new Thread(new RunnableWrapper(runnable));
+		if (name != null) {
+			thread.setName(name);
+		}
+		this.threads.add(thread);
+		return thread;
+	}
+
+	protected ThreadFactory buildThreadFactory() {
+		return new TestThreadFactory();
+	}
+
+	/**
+	 * Convenience method that handles {@link InterruptedException}.
+	 */
+	public void sleep(long millis) {
+		TestTools.sleep(millis);
+	}
+
+
+	/**
+	 * Wrap a runnable and log any exception it throws.
+	 */
+	public class TestThreadFactory implements ThreadFactory {
+		@Override
+		public Thread newThread(Runnable r) {
+			return MultiThreadedTestCase.this.buildThread(r);
+		}
+	}
+
+	/**
+	 * Simplify runnables that execute call that throws checked exceptions.
+	 */
+	public abstract class TestRunnable implements Runnable {
+		@Override
+		public final void run() {
+			try {
+				this.run_();
+			} catch (Throwable ex) {
+				throw new RuntimeException(ex);
+			}
+		}
+		protected abstract void run_() throws Throwable;
+	}
+
+	/**
+	 * Wrap a runnable and log any exception it throws.
+	 */
+	private class RunnableWrapper implements Runnable {
+		private final Runnable runnable;
+		RunnableWrapper(Runnable runnable) {
+			super();
+			this.runnable = runnable;
+		}
+		@Override
+		public void run() {
+			try {
+				this.runnable.run();
+			} catch (RuntimeException ex) {
+				MultiThreadedTestCase.this.exceptions.add(ex);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/NameToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/NameToolsTests.java
new file mode 100644
index 0000000..2a32370
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/NameToolsTests.java
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.NameTools;
+
+
+@SuppressWarnings("nls")
+public class NameToolsTests
+	extends TestCase
+{
+	public NameToolsTests(String name) {
+		super(name);
+	}
+
+	public void testStringAbsentIgnoreCase() {
+		List<String> colorCollection = this.buildColorCollection();
+		String returned = NameTools.uniqueNameIgnoreCase("Taupe", colorCollection);
+		assertEquals("Taupe", returned);
+	}
+
+	public void testStringPresentCaseDiffers() {
+		List<String> colorCollection = this.buildColorCollection();
+		String returned = NameTools.uniqueName("green", colorCollection);
+		assertEquals("green", returned);
+	}
+
+	public void testStringPresentIgnoreCase() {
+		List<String> colorCollection = this.buildColorCollection();
+		String returned = NameTools.uniqueNameIgnoreCase("green", colorCollection);
+		assertEquals("green2", returned);
+	}
+
+	public void testStringPresentWithAppendices() {
+		List<String> colorCollection = this.buildColorCollection();
+		colorCollection.add("Red1");
+		colorCollection.add("red2");
+		String returned = NameTools.uniqueNameIgnoreCase("red", colorCollection);
+		colorCollection.remove("Red1");
+		colorCollection.remove("red2");
+		assertEquals("red3", returned);
+	}
+
+	private List<String> buildColorCollection() {
+		List<String> colorCollection = new ArrayList<String>();
+		colorCollection.add("Red");
+		colorCollection.add("Orange");
+		colorCollection.add("Yellow");
+		colorCollection.add("Green");
+		colorCollection.add("Blue");
+		colorCollection.add("Indigo");
+		colorCollection.add("Violet");
+		return colorCollection;
+	}
+
+	public void testUniqueNameForCollection1() {
+		Collection<String> strings = new ArrayList<String>();
+		strings.add("Oracle");
+		strings.add("Oracle Corporation");
+		strings.add("Oracle2");
+		strings.add("oracle1");
+		strings.add("Oracl");
+
+		assertEquals("Oracle3", NameTools.uniqueName("Oracle", strings));
+		assertEquals("Test", NameTools.uniqueName("Test", strings));
+
+		assertEquals("Oracle3", NameTools.uniqueNameIgnoreCase("Oracle", strings));
+		assertEquals("oracle3", NameTools.uniqueNameIgnoreCase("oracle", strings));
+		assertEquals("Test", NameTools.uniqueNameIgnoreCase("Test", strings));
+	}
+
+	public void testUniqueNameForCollection2() {
+		Collection<String> strings = new ArrayList<String>();
+		strings.add("Oracle");
+		strings.add("oracle");
+		strings.add("Oracle2");
+		strings.add("Oracle1");
+
+		assertEquals("Oracle3", NameTools.uniqueName("Oracle", strings));
+		assertEquals("Test", NameTools.uniqueName("Test", strings));
+
+		strings.add("Oracle Corporation");
+		assertEquals("Oracle3", NameTools.uniqueNameIgnoreCase("Oracle", strings));
+		assertEquals("oracle3", NameTools.uniqueNameIgnoreCase("oracle", strings));
+		assertEquals("Test", NameTools.uniqueNameIgnoreCase("Test", strings));
+	}
+
+	public void testUniqueNameForCollection3() {
+		Collection<String> strings = new ArrayList<String>();
+		strings.add("Oracle");
+		strings.add("Oracle");
+		strings.add("Oracle2");
+		strings.add("Oracle1");
+
+		assertEquals("Oracle3", NameTools.uniqueName("Oracle", strings));
+	}
+
+	public void testUniqueNameForIterable1() {
+		Collection<String> strings = new ArrayList<String>();
+		strings.add("Oracle");
+		strings.add("Oracle Corporation");
+		strings.add("Oracle2");
+		strings.add("oracle1");
+		strings.add("Oracl");
+
+		assertEquals("Oracle3", NameTools.uniqueName("Oracle", (Iterable<String>) strings));
+		assertEquals("Test", NameTools.uniqueName("Test", (Iterable<String>) strings));
+
+		assertEquals("Oracle3", NameTools.uniqueNameIgnoreCase("Oracle", (Iterable<String>) strings));
+		assertEquals("oracle3", NameTools.uniqueNameIgnoreCase("oracle", (Iterable<String>) strings));
+		assertEquals("Test", NameTools.uniqueNameIgnoreCase("Test", (Iterable<String>) strings));
+	}
+
+	public void testUniqueNameForIterable2() {
+		Collection<String> strings = new ArrayList<String>();
+		strings.add("Oracle");
+		strings.add("oracle");
+		strings.add("Oracle2");
+		strings.add("Oracle1");
+
+		assertEquals("Oracle3", NameTools.uniqueName("Oracle", (Iterable<String>) strings));
+		assertEquals("Test", NameTools.uniqueName("Test", (Iterable<String>) strings));
+
+		strings.add("Oracle Corporation");
+		assertEquals("Oracle3", NameTools.uniqueNameIgnoreCase("Oracle", (Iterable<String>) strings));
+		assertEquals("oracle3", NameTools.uniqueNameIgnoreCase("oracle", (Iterable<String>) strings));
+		assertEquals("Test", NameTools.uniqueNameIgnoreCase("Test", (Iterable<String>) strings));
+	}
+
+	public void testUniqueNameForIterable3() {
+		Collection<String> strings = new ArrayList<String>();
+		strings.add("Oracle");
+		strings.add("Oracle");
+		strings.add("Oracle2");
+		strings.add("Oracle1");
+
+		assertEquals("Oracle3", NameTools.uniqueName("Oracle", (Iterable<String>) strings));
+	}
+
+	public void testBuildQualifiedDatabaseObjectName() {
+		assertEquals("catalog.schema.name", NameTools.buildQualifiedName("catalog", "schema", "name"));
+		assertEquals("catalog..name", NameTools.buildQualifiedName("catalog", null, "name"));
+		assertEquals("schema.name", NameTools.buildQualifiedName(null, "schema", "name"));
+		assertEquals("name", NameTools.buildQualifiedName(null, null, "name"));
+	}
+
+	public void testJavaReservedWords() {
+		assertTrue(NameTools.JAVA_RESERVED_WORDS.contains("class"));
+		assertFalse(NameTools.JAVA_RESERVED_WORDS.contains("Class"));
+		assertTrue(NameTools.JAVA_RESERVED_WORDS.contains("private"));
+	}
+
+	public void testconvertToJavaIdentifierString() {
+		assertEquals("foo", NameTools.convertToJavaIdentifier("foo"));
+		assertEquals("foo1", NameTools.convertToJavaIdentifier("foo1"));
+		assertEquals("private_", NameTools.convertToJavaIdentifier("private"));
+		assertEquals("throw_", NameTools.convertToJavaIdentifier("throw"));
+		assertEquals("_foo", NameTools.convertToJavaIdentifier("1foo"));
+		assertEquals("foo_", NameTools.convertToJavaIdentifier("foo%"));
+		assertEquals("foo__bar__", NameTools.convertToJavaIdentifier("foo  bar  "));
+	}
+
+	public void testconvertToJavaIdentifierStringChar() {
+		assertEquals("foo", NameTools.convertToJavaIdentifier("foo", '$'));
+		assertEquals("foo1", NameTools.convertToJavaIdentifier("foo1", '$'));
+		assertEquals("private$", NameTools.convertToJavaIdentifier("private", '$'));
+		assertEquals("throwss", NameTools.convertToJavaIdentifier("throw", 's'));
+		assertEquals("$foo", NameTools.convertToJavaIdentifier("1foo", '$'));
+		assertEquals("foo$", NameTools.convertToJavaIdentifier("foo%", '$'));
+		assertEquals("foo$$bar$$", NameTools.convertToJavaIdentifier("foo  bar  ", '$'));
+
+		boolean exCaught = false;
+		try {
+			String s = NameTools.convertToJavaIdentifier("1foo", '7');
+			fail("invalid string: \"" + s + "\"");
+		} catch (IllegalArgumentException ex) {
+			if (ex.getMessage().indexOf('7') != -1) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+
+		exCaught = false;
+		try {
+			String s = NameTools.convertToJavaIdentifier("foo%", '^');
+			fail("invalid string: \"" + s + "\"");
+		} catch (IllegalArgumentException ex) {
+			if (ex.getMessage().indexOf('^') != -1) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+
+		exCaught = false;
+		try {
+			String s = NameTools.convertToJavaIdentifier("private", '^');
+			fail("invalid string: \"" + s + "\"");
+		} catch (IllegalArgumentException ex) {
+			if (ex.getMessage().indexOf('^') != -1) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+
+	}
+
+	public void testStringIsLegalJavaIdentifier() {
+		assertFalse(NameTools.isLegalJavaIdentifier("class"));
+		assertTrue(NameTools.isLegalJavaIdentifier("clasS"));
+
+		assertFalse(NameTools.isLegalJavaIdentifier("7foo"));
+		assertFalse(NameTools.isLegalJavaIdentifier("foo@bar"));
+		assertTrue(NameTools.isLegalJavaIdentifier("_foo"));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ObjectToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ObjectToolsTests.java
new file mode 100644
index 0000000..c1068d4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ObjectToolsTests.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.util.Vector;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ClassTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+@SuppressWarnings("nls")
+public class ObjectToolsTests
+	extends TestCase
+{
+	public ObjectToolsTests(String name) {
+		super(name);
+	}
+
+	public void testEquals1() {
+		assertTrue(ObjectTools.equals(null, null));
+	}
+
+	public void testEquals2() {
+		assertFalse(ObjectTools.equals(null, "foo"));
+	}
+
+	public void testEquals3() {
+		assertFalse(ObjectTools.equals("foo", null));
+	}
+
+	public void testEquals4() {
+		assertTrue(ObjectTools.equals("foo", "foo"));
+	}
+
+	public void testEquals5() {
+		assertFalse(ObjectTools.equals("foo", "bar"));
+	}
+
+	public void testNotEquals1() {
+		assertFalse(ObjectTools.notEquals(null, null));
+	}
+
+	public void testNotEquals2() {
+		assertTrue(ObjectTools.notEquals(null, "foo"));
+	}
+
+	public void testNotEquals3() {
+		assertTrue(ObjectTools.notEquals("foo", null));
+	}
+
+	public void testNotEquals4() {
+		assertFalse(ObjectTools.notEquals("foo", "foo"));
+	}
+
+	public void testNotEquals5() {
+		assertTrue(ObjectTools.notEquals("foo", "bar"));
+	}
+
+	public void testToStringName_anonymous() {
+		Object o = new Object(){/*anonymous subclass of Object*/};
+		assertEquals("Object", ClassTools.toStringName(o.getClass()));
+	}
+
+	public void testToStringName_member() {
+		assertEquals("Map.Entry", ClassTools.toStringName(java.util.Map.Entry.class));
+	}
+
+	public void testToStringName_local() {
+		class Foo {
+			Bar bar = new Bar();
+			class Bar {
+				Bar() {
+					super();
+				}
+			}
+			Foo() {
+				super();
+			}
+		}
+		Foo foo = new Foo();
+		assertEquals("ObjectToolsTests.Foo", ClassTools.toStringName(foo.getClass()));
+		assertEquals("ObjectToolsTests.Foo.Bar", ClassTools.toStringName(foo.bar.getClass()));
+	}
+
+	public void testGet() {
+		int initialCapacity = 200;
+		Vector<?> v = new Vector<Object>(initialCapacity);
+		Object[] elementData = (Object[]) ObjectTools.get(v, "elementData");
+		assertEquals(initialCapacity, elementData.length);
+
+		// test inherited field
+		Integer modCountInteger = (Integer) ObjectTools.get(v, "modCount");
+		int modCount = modCountInteger.intValue();
+		assertEquals(0, modCount);
+
+		boolean exCaught = false;
+		Object bogusFieldValue = null;
+		try {
+			bogusFieldValue = ObjectTools.get(v, "bogusField");
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof NoSuchFieldException) {
+				exCaught = true;
+			}
+		}
+		assertTrue("NoSuchFieldException not thrown: " + bogusFieldValue, exCaught);
+	}
+
+	public void testExecuteObjectString() {
+		Vector<String> v = new Vector<String>();
+		int size = ((Integer) ObjectTools.execute(v, "size")).intValue();
+		assertEquals(0, size);
+
+		v.addElement("foo");
+		size = ((Integer) ObjectTools.execute(v, "size")).intValue();
+		assertEquals(1, size);
+	}
+
+	public void testExecuteObjectStringClassObject() {
+		Vector<String> v = new Vector<String>();
+		boolean booleanResult = ((Boolean) ObjectTools.execute(v, "add", Object.class, "foo")).booleanValue();
+		assertTrue(booleanResult);
+		assertTrue(v.contains("foo"));
+		Object voidResult = ObjectTools.execute(v, "addElement", Object.class, "bar");
+		assertNull(voidResult);
+	}
+
+	public void testExecuteObjectStringClassArrayObjectArray() {
+		Vector<String> v = new Vector<String>();
+		Class<?>[] parmTypes = new Class[1];
+		parmTypes[0] = java.lang.Object.class;
+		Object[] parms = new Object[1];
+		parms[0] = "foo";
+		boolean booleanResult = ((Boolean) ObjectTools.execute(v, "add", parmTypes, parms)).booleanValue();
+		assertTrue(booleanResult);
+		assertTrue(v.contains("foo"));
+
+		boolean exCaught = false;
+		Object bogusMethodReturnValue = null;
+		try {
+			bogusMethodReturnValue = ObjectTools.execute(v, "bogusMethod", parmTypes, parms);
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof NoSuchMethodException) {
+				exCaught = true;
+			}
+		}
+		assertTrue("NoSuchMethodException not thrown: " + bogusMethodReturnValue, exCaught);
+	}
+
+	public void testSet() {
+		Vector<String> v = new Vector<String>();
+		Object[] newElementData = new Object[5];
+		newElementData[0] = "foo";
+		ObjectTools.set(v, "elementData", newElementData);
+		ObjectTools.set(v, "elementCount", new Integer(1));
+		// test inherited field
+		ObjectTools.set(v, "modCount", new Integer(1));
+		assertTrue(v.contains("foo"));
+
+		boolean exCaught = false;
+		try {
+			ObjectTools.set(v, "bogusField", "foo");
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof NoSuchFieldException) {
+				exCaught = true;
+			}
+		}
+		assertTrue("NoSuchFieldException not thrown", exCaught);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/PrintStreamExceptionHandlerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/PrintStreamExceptionHandlerTests.java
new file mode 100644
index 0000000..1013fc7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/PrintStreamExceptionHandlerTests.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.CompositeExceptionHandler;
+import org.eclipse.persistence.tools.utility.ExceptionHandler;
+import org.eclipse.persistence.tools.utility.PrintStreamExceptionHandler;
+
+@SuppressWarnings("nls")
+public class PrintStreamExceptionHandlerTests
+	extends TestCase
+{
+	public PrintStreamExceptionHandlerTests(String name) {
+		super(name);
+	}
+
+	public void testHandleException() {
+		OutputStream out = new ByteArrayOutputStream();
+		PrintStream stream = new PrintStream(out);
+		ExceptionHandler exceptionHandler = new PrintStreamExceptionHandler(stream);
+		Exception npe = new NullPointerException();
+		exceptionHandler.handleException(npe);
+		stream.flush();
+
+		assertTrue(out.toString().contains("NullPointerException"));
+	}
+
+	public void testToString() {
+		CompositeExceptionHandler exceptionHandler = new CompositeExceptionHandler();
+		assertNotNull(exceptionHandler.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/PrintWriterExceptionHandlerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/PrintWriterExceptionHandlerTests.java
new file mode 100644
index 0000000..8ca0ef5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/PrintWriterExceptionHandlerTests.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.CompositeExceptionHandler;
+import org.eclipse.persistence.tools.utility.ExceptionHandler;
+import org.eclipse.persistence.tools.utility.PrintWriterExceptionHandler;
+
+@SuppressWarnings("nls")
+public class PrintWriterExceptionHandlerTests
+	extends TestCase
+{
+	public PrintWriterExceptionHandlerTests(String name) {
+		super(name);
+	}
+
+	public void testHandleException() {
+		OutputStream out = new ByteArrayOutputStream();
+		PrintWriter stream = new PrintWriter(out);
+		ExceptionHandler exceptionHandler = new PrintWriterExceptionHandler(stream);
+		Exception npe = new NullPointerException();
+		exceptionHandler.handleException(npe);
+		stream.flush();
+
+		assertTrue(out.toString().contains("NullPointerException"));
+	}
+
+	public void testToString() {
+		CompositeExceptionHandler exceptionHandler = new CompositeExceptionHandler();
+		assertNotNull(exceptionHandler.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/RangeTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/RangeTests.java
new file mode 100644
index 0000000..fdd1b23
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/RangeTests.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.Range;
+
+public class RangeTests extends TestCase {
+
+	public RangeTests(String name) {
+		super(name);
+	}
+
+	public void testIncludes() {
+		Range range = new Range(5, 17);
+		assertFalse(range.includes(-55));
+		assertFalse(range.includes(0));
+		assertFalse(range.includes(4));
+		assertTrue(range.includes(5));
+		assertTrue(range.includes(6));
+		assertTrue(range.includes(16));
+		assertTrue(range.includes(17));
+		assertFalse(range.includes(18));
+		assertFalse(range.includes(200));
+	}
+
+	public void testEquals() {
+		Range range1 = new Range(5, 17);
+		Range range2 = new Range(5, 17);
+		assertNotSame(range1, range2);
+		assertEquals(range1, range1);
+		assertEquals(range1, range2);
+		assertEquals(range2, range1);
+		assertEquals(range1.hashCode(), range2.hashCode());
+
+		range2 = new Range(17, 5);
+		assertFalse(range1.equals(range2));
+		assertFalse(range2.equals(range1));
+		// although they are unequal, they can have the same hash code
+		assertEquals(range1.hashCode(), range2.hashCode());
+
+		range2 = new Range(5, 15);
+		assertFalse(range1.equals(range2));
+		assertFalse(range2.equals(range1));
+	}
+
+	public void testClone() {
+		Range range1 = new Range(5, 17);
+		Range range2 = range1.clone();
+		assertNotSame(range1, range2);
+		assertEquals(range1, range1);
+		assertEquals(range1, range2);
+		assertEquals(range2, range1);
+		assertEquals(range1.hashCode(), range2.hashCode());
+	}
+
+	public void testSerialization() throws Exception {
+		Range range1 = new Range(5, 17);
+		Range range2 = TestTools.serialize(range1);
+		assertNotSame(range1, range2);
+		assertEquals(range1, range1);
+		assertEquals(range1, range2);
+		assertEquals(range2, range1);
+		assertEquals(range1.hashCode(), range2.hashCode());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ReverseComparatorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ReverseComparatorTests.java
new file mode 100644
index 0000000..38138c8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/ReverseComparatorTests.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.ReverseComparator;
+
+@SuppressWarnings("nls")
+public class ReverseComparatorTests
+	extends TestCase
+{
+	private Comparator<String> naturalReverseComparator;
+	private Comparator<String> customComparator;
+	private Comparator<String> customReverseComparator;
+
+	public ReverseComparatorTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.naturalReverseComparator = new ReverseComparator<String>();
+		this.customComparator = this.buildCustomComparator();
+		this.customReverseComparator = new ReverseComparator<String>(this.customComparator);
+	}
+
+	private Comparator<String> buildCustomComparator() {
+		return new Comparator<String>() {
+			@Override
+			public int compare(String s1, String s2) {
+				String lower1 = s1.toLowerCase();
+				String lower2 = s2.toLowerCase();
+				int result = lower1.compareTo(lower2);
+				if (result == 0) {
+					return s1.compareTo(s2); // use case to differentiate "equal" strings
+				}
+				return result;
+			}
+		};
+	}
+
+	private List<String> buildUnsortedList() {
+		List<String> result = new ArrayList<String>();
+		result.add("T");
+		result.add("Z");
+		result.add("Y");
+		result.add("M");
+		result.add("m");
+		result.add("a");
+		result.add("B");
+		result.add("b");
+		result.add("A");
+		return result;
+	}
+
+	private List<String> buildNaturallySortedList() {
+		List<String> result = new ArrayList<String>(this.buildUnsortedList());
+		Collections.sort(result);
+		return result;
+	}
+
+	private List<String> buildCustomSortedList() {
+		List<String> result = new ArrayList<String>(this.buildUnsortedList());
+		Collections.sort(result, this.customComparator);
+		return result;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testNatural() {
+		List<String> list = this.buildUnsortedList();
+		Collections.sort(list, this.naturalReverseComparator);
+		this.verifyList(this.buildNaturallySortedList(), list);
+	}
+
+	public void testCustom() {
+		List<String> list = this.buildUnsortedList();
+		Collections.sort(list, this.customReverseComparator);
+		this.verifyList(this.buildCustomSortedList(), list);
+	}
+
+	public void testCustom_nonComparable() {
+		List<Foo> list = this.buildUnsortedFooList();
+		Collections.sort(list, new ReverseComparator<Foo>(Foo.COMPARATOR));
+		this.verifyList(this.buildSortedFooList(), list);
+	}
+
+	private List<Foo> buildUnsortedFooList() {
+		List<Foo> result = new ArrayList<Foo>();
+		result.add(new Foo("T"));
+		result.add(new Foo("Z"));
+		result.add(new Foo("Y"));
+		result.add(new Foo("M"));
+		result.add(new Foo("m"));
+		result.add(new Foo("a"));
+		result.add(new Foo("B"));
+		result.add(new Foo("b"));
+		result.add(new Foo("A"));
+		return result;
+	}
+
+	private List<Foo> buildSortedFooList() {
+		List<Foo> result = new ArrayList<Foo>(this.buildUnsortedFooList());
+		Collections.sort(result, Foo.COMPARATOR);
+		return result;
+	}
+
+	private <T> void verifyList(List<T> normal, List<T> reverse) {
+		int size = normal.size();
+		int max = size - 1;
+		for (int i = 0; i < size; i++) {
+			assertEquals(normal.get(i), reverse.get(max - i));
+		}
+	}
+
+	public static class Foo {
+		public final String string;
+		public Foo(String string) {
+			super();
+			this.string = string;
+		}
+		@Override
+		public boolean equals(Object o) {
+			return (o instanceof Foo) && this.string.equals(((Foo) o).string);
+		}
+		@Override
+		public int hashCode() {
+			return this.string.hashCode();
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.toString(this, this.string);
+		}
+		public static final Comparator<Foo> COMPARATOR = new FooComparator();
+		public static class FooComparator
+			implements Comparator<Foo>
+		{
+			@Override
+			public int compare(Foo foo1, Foo foo2) {
+				String s1 = foo1.string;
+				String s2 = foo2.string;
+				String lower1 = s1.toLowerCase();
+				String lower2 = s2.toLowerCase();
+				int result = lower1.compareTo(lower2);
+				if (result == 0) {
+					return s1.compareTo(s2); // use case to differentiate "equal" strings
+				}
+				return result;
+			}
+			@Override
+			public String toString() {
+				return ObjectTools.singletonToString(this);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/SimpleAssociationTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/SimpleAssociationTests.java
new file mode 100644
index 0000000..ac09389
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/SimpleAssociationTests.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.Association;
+import org.eclipse.persistence.tools.utility.SimpleAssociation;
+
+@SuppressWarnings("nls")
+public class SimpleAssociationTests
+	extends TestCase
+{
+	private SimpleAssociation<String, String> assoc;
+
+	public SimpleAssociationTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.assoc = new SimpleAssociation<String, String>("foo", "bar");
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testGetKey() {
+		assertEquals("foo", this.assoc.getKey());
+	}
+
+	public void testGetValue() {
+		assertEquals("bar", this.assoc.getValue());
+	}
+
+	public void testSetValue() {
+		assertEquals("bar", this.assoc.getValue());
+		this.assoc.setValue("baz");
+		assertEquals("baz", this.assoc.getValue());
+	}
+
+	public void testEquals() {
+		assertFalse(this.assoc.equals("foo"));
+
+		assertEquals(this.assoc, this.copy(this.assoc));
+
+		SimpleAssociation<String, String> assoc2 = new SimpleAssociation<String, String>("foo", "baz");
+		assertFalse(this.assoc.equals(assoc2));
+
+		assoc2 = new SimpleAssociation<String, String>("fop", "bar");
+		assertFalse(this.assoc.equals(assoc2));
+
+		SimpleAssociation<String, String> assoc3 = new SimpleAssociation<String, String>(null, null);
+		SimpleAssociation<String, String> assoc4 = new SimpleAssociation<String, String>(null, null);
+		assertEquals(assoc3, assoc4);
+	}
+
+	public void testHashCode() {
+		assertEquals(this.assoc.hashCode(), this.copy(this.assoc).hashCode());
+
+		SimpleAssociation<String, String> assoc2 = new SimpleAssociation<String, String>(null, null);
+		assertEquals(assoc2.hashCode(), this.copy(assoc2).hashCode());
+	}
+
+	public void testToString() {
+		assertNotNull(this.assoc.toString());
+	}
+
+	public void testClone() {
+		this.verifyClone(this.assoc, this.assoc.clone());
+	}
+
+	private void verifyClone(Association<String, String> expected, Association<String, String> actual) {
+		assertEquals(expected, actual);
+		assertNotSame(expected, actual);
+		assertEquals(expected.getKey(), actual.getKey());
+		assertSame(expected.getKey(), actual.getKey());
+		assertEquals(expected.getValue(), actual.getValue());
+		assertSame(expected.getValue(), actual.getValue());
+	}
+
+	public void testSerialization() throws Exception {
+		@SuppressWarnings("cast")
+		Association<String, String> assoc2 = (Association<String, String>) TestTools.serialize(this.assoc);
+
+		assertEquals(this.assoc, assoc2);
+		assertNotSame(this.assoc, assoc2);
+		assertEquals(this.assoc.getKey(), assoc2.getKey());
+		assertNotSame(this.assoc.getKey(), assoc2.getKey());
+		assertEquals(this.assoc.getValue(), assoc2.getValue());
+		assertNotSame(this.assoc.getValue(), assoc2.getValue());
+	}
+
+	private SimpleAssociation<String, String> copy(SimpleAssociation<String, String> sa) {
+		return new SimpleAssociation<String, String>(sa.getKey(), sa.getValue());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/SimpleJavaTypeTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/SimpleJavaTypeTests.java
new file mode 100644
index 0000000..7dab95b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/SimpleJavaTypeTests.java
@@ -0,0 +1,255 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.JavaType;
+import org.eclipse.persistence.tools.utility.SimpleJavaType;
+
+@SuppressWarnings("nls")
+public class SimpleJavaTypeTests extends TestCase {
+
+	public SimpleJavaTypeTests(String name) {
+		super(name);
+	}
+
+	public void testInvalidElementTypeNull() throws Exception {
+		boolean exCaught = false;
+		try {
+			JavaType javaType = new SimpleJavaType(null, 0);
+			fail("invalid JavaType: " + javaType);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testInvalidElementTypeEmpty() throws Exception {
+		boolean exCaught = false;
+		try {
+			JavaType javaType = new SimpleJavaType("", 0);
+			fail("invalid JavaType: " + javaType);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testInvalidElementTypeArray() throws Exception {
+		boolean exCaught = false;
+		try {
+			JavaType javaType = new SimpleJavaType(java.lang.Object[].class.getName(), 0);
+			fail("invalid JavaType: " + javaType);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testInvalidArrayDepthNegative() throws Exception {
+		boolean exCaught = false;
+		try {
+			JavaType javaType = new SimpleJavaType(java.lang.Object.class.getName(), -2);
+			fail("invalid JavaType: " + javaType);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testInvalidVoidArray() throws Exception {
+		boolean exCaught = false;
+		try {
+			JavaType javaType = new SimpleJavaType(void.class.getName(), 2);
+			fail("invalid JavaType: " + javaType);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testElementTypeName() throws Exception {
+		JavaType javaType;
+		javaType = new SimpleJavaType(java.lang.Object.class);
+		assertEquals("java.lang.Object", javaType.getElementTypeName());
+
+		javaType = new SimpleJavaType(java.lang.Object[].class);
+		assertEquals("java.lang.Object", javaType.getElementTypeName());
+
+		javaType = new SimpleJavaType(int.class);
+		assertEquals("int", javaType.getElementTypeName());
+
+		javaType = new SimpleJavaType(int[].class);
+		assertEquals("int", javaType.getElementTypeName());
+
+		javaType = new SimpleJavaType(void.class);
+		assertEquals("void", javaType.getElementTypeName());
+
+		javaType = new SimpleJavaType(java.util.Map.Entry.class);
+		assertEquals("java.util.Map$Entry", javaType.getElementTypeName());
+
+		javaType = new SimpleJavaType(java.util.Map.Entry[][].class);
+		assertEquals("java.util.Map$Entry", javaType.getElementTypeName());
+	}
+
+	public void testArrayDepth() throws Exception {
+		JavaType javaType;
+		javaType = new SimpleJavaType(java.lang.Object.class);
+		assertEquals(0, javaType.getArrayDepth());
+
+		javaType = new SimpleJavaType(java.lang.Object[].class);
+		assertEquals(1, javaType.getArrayDepth());
+
+		javaType = new SimpleJavaType(int.class);
+		assertEquals(0, javaType.getArrayDepth());
+
+		javaType = new SimpleJavaType(int[].class);
+		assertEquals(1, javaType.getArrayDepth());
+
+		javaType = new SimpleJavaType(void.class);
+		assertEquals(0, javaType.getArrayDepth());
+
+		javaType = new SimpleJavaType(java.util.Map.Entry.class);
+		assertEquals(0, javaType.getArrayDepth());
+
+		javaType = new SimpleJavaType(java.util.Map.Entry[][].class);
+		assertEquals(2, javaType.getArrayDepth());
+	}
+
+	public void testIsArray() throws Exception {
+		JavaType javaType;
+		javaType = new SimpleJavaType(java.lang.Object.class);
+		assertFalse(javaType.isArray());
+
+		javaType = new SimpleJavaType(java.lang.Object[].class);
+		assertTrue(javaType.isArray());
+
+		javaType = new SimpleJavaType(int.class);
+		assertFalse(javaType.isArray());
+
+		javaType = new SimpleJavaType(int[].class);
+		assertTrue(javaType.isArray());
+
+		javaType = new SimpleJavaType(void.class);
+		assertFalse(javaType.isArray());
+
+		javaType = new SimpleJavaType(java.util.Map.Entry.class);
+		assertFalse(javaType.isArray());
+
+		javaType = new SimpleJavaType(java.util.Map.Entry[][].class);
+		assertTrue(javaType.isArray());
+	}
+
+	public void testJavaClass() throws Exception {
+		this.verifyJavaClass(java.lang.Object.class);
+		this.verifyJavaClass(java.lang.Object[].class);
+		this.verifyJavaClass(int.class);
+		this.verifyJavaClass(int[].class);
+		this.verifyJavaClass(void.class);
+		this.verifyJavaClass(java.util.Map.Entry.class);
+		this.verifyJavaClass(java.util.Map.Entry[][].class);
+	}
+
+	private void verifyJavaClass(Class<?> javaClass) throws Exception {
+		JavaType javaType = new SimpleJavaType(javaClass);
+		assertEquals(javaClass, javaType.getJavaClass());
+	}
+
+	public void testJavaClassName() throws Exception {
+		JavaType javaType;
+		javaType = new SimpleJavaType(java.lang.Object.class);
+		assertEquals("java.lang.Object", javaType.getJavaClassName());
+
+		javaType = new SimpleJavaType(java.lang.Object[].class);
+		assertEquals("[Ljava.lang.Object;", javaType.getJavaClassName());
+
+		javaType = new SimpleJavaType(int.class);
+		assertEquals("int", javaType.getJavaClassName());
+
+		javaType = new SimpleJavaType(int[].class);
+		assertEquals("[I", javaType.getJavaClassName());
+
+		javaType = new SimpleJavaType(void.class);
+		assertEquals("void", javaType.getJavaClassName());
+
+		javaType = new SimpleJavaType(java.util.Map.Entry.class);
+		assertEquals("java.util.Map$Entry", javaType.getJavaClassName());
+
+		javaType = new SimpleJavaType(java.util.Map.Entry[][].class);
+		assertEquals("[[Ljava.util.Map$Entry;", javaType.getJavaClassName());
+	}
+
+	public void testDescribes() throws Exception {
+		this.verifyDescribes(java.lang.Object.class);
+		this.verifyDescribes(java.lang.Object[].class);
+		this.verifyDescribes(int.class);
+		this.verifyDescribes(int[].class);
+		this.verifyDescribes(void.class);
+		this.verifyDescribes(java.util.Map.Entry.class);
+		this.verifyDescribes(java.util.Map.Entry[][].class);
+	}
+
+	private void verifyDescribes(Class<?> javaClass) throws Exception {
+		JavaType javaType = new SimpleJavaType(javaClass);
+		assertTrue(javaType.describes(javaClass));
+	}
+
+	public void testDeclaration() throws Exception {
+		JavaType javaType;
+		javaType = new SimpleJavaType(java.lang.Object.class);
+		assertEquals("java.lang.Object", javaType.declaration());
+
+		javaType = new SimpleJavaType(java.lang.Object[].class);
+		assertEquals("java.lang.Object[]", javaType.declaration());
+
+		javaType = new SimpleJavaType(int.class);
+		assertEquals("int", javaType.declaration());
+
+		javaType = new SimpleJavaType(int[].class);
+		assertEquals("int[]", javaType.declaration());
+
+		javaType = new SimpleJavaType(void.class);
+		assertEquals("void", javaType.declaration());
+
+		javaType = new SimpleJavaType(java.util.Map.Entry.class);
+		assertEquals("java.util.Map.Entry", javaType.declaration());
+
+		javaType = new SimpleJavaType(java.util.Map.Entry[][].class);
+		assertEquals("java.util.Map.Entry[][]", javaType.declaration());
+	}
+
+	public void testIsPrimitive() throws Exception {
+		JavaType javaType;
+		javaType = new SimpleJavaType(java.lang.Object.class);
+		assertFalse(javaType.isPrimitive());
+
+		javaType = new SimpleJavaType(java.lang.Object[].class);
+		assertFalse(javaType.isPrimitive());
+
+		javaType = new SimpleJavaType(int.class);
+		assertTrue(javaType.isPrimitive());
+
+		javaType = new SimpleJavaType(int[].class);
+		assertFalse(javaType.isPrimitive());
+
+		javaType = new SimpleJavaType(void.class);
+		assertTrue(javaType.isPrimitive());
+
+		javaType = new SimpleJavaType(java.util.Map.Entry.class);
+		assertFalse(javaType.isPrimitive());
+
+		javaType = new SimpleJavaType(java.util.Map.Entry[][].class);
+		assertFalse(javaType.isPrimitive());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/SimpleMethodSignatureTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/SimpleMethodSignatureTests.java
new file mode 100644
index 0000000..12916eb
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/SimpleMethodSignatureTests.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.JavaType;
+import org.eclipse.persistence.tools.utility.MethodSignature;
+import org.eclipse.persistence.tools.utility.SimpleJavaType;
+import org.eclipse.persistence.tools.utility.SimpleMethodSignature;
+
+@SuppressWarnings("nls")
+public class SimpleMethodSignatureTests extends TestCase {
+
+	public SimpleMethodSignatureTests(String name) {
+		super(name);
+	}
+
+	public void testInvalidNameNull() throws Exception {
+		boolean exCaught = false;
+		try {
+			MethodSignature methodSignature = new SimpleMethodSignature((String) null);
+			fail("invalid MethodSignature: " + methodSignature);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testInvalidNameEmpty() throws Exception {
+		boolean exCaught = false;
+		try {
+			MethodSignature methodSignature = new SimpleMethodSignature("");
+			fail("invalid MethodSignature: " + methodSignature);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testInvalidParameterTypesNull() throws Exception {
+		boolean exCaught = false;
+		try {
+			MethodSignature methodSignature = new SimpleMethodSignature("foo", (JavaType[]) null);
+			fail("invalid MethodSignature: " + methodSignature);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testInvalidParameterTypesNullItem() throws Exception {
+		boolean exCaught = false;
+		try {
+			MethodSignature methodSignature = new SimpleMethodSignature("foo", new JavaType[1]);
+			fail("invalid MethodSignature: " + methodSignature);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testInvalidParameterTypesVoidItem() throws Exception {
+		JavaType jt = new SimpleJavaType(void.class.getName());
+		boolean exCaught = false;
+		try {
+			MethodSignature methodSignature = new SimpleMethodSignature("foo", new JavaType[] {jt});
+			fail("invalid MethodSignature: " + methodSignature);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testInvalidParameterTypeNamesNull() throws Exception {
+		boolean exCaught = false;
+		try {
+			MethodSignature methodSignature = new SimpleMethodSignature("foo", (String[]) null);
+			fail("invalid MethodSignature: " + methodSignature);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testInvalidParameterTypeNamesNullItem() throws Exception {
+		boolean exCaught = false;
+		try {
+			MethodSignature methodSignature = new SimpleMethodSignature("foo", new String[1]);
+			fail("invalid MethodSignature: " + methodSignature);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testInvalidParameterJavaClassesNull() throws Exception {
+		boolean exCaught = false;
+		try {
+			MethodSignature methodSignature = new SimpleMethodSignature("foo", (Class<?>[]) null);
+			fail("invalid MethodSignature: " + methodSignature);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testInvalidParameterJavaClassesNullItem() throws Exception {
+		boolean exCaught = false;
+		try {
+			MethodSignature methodSignature = new SimpleMethodSignature("foo", new Class[1]);
+			fail("invalid MethodSignature: " + methodSignature);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testGetSignature0() throws Exception {
+		MethodSignature ms = new SimpleMethodSignature(this.getMethod("method0"));
+		assertEquals("method0()", ms.getSignature());
+	}
+
+	public void testGetSignature1() throws Exception {
+		MethodSignature ms = new SimpleMethodSignature(this.getMethod("method1"));
+		assertEquals("method1(int)", ms.getSignature());
+	}
+
+	public void testGetSignature2() throws Exception {
+		MethodSignature ms = new SimpleMethodSignature(this.getMethod("method2"));
+		assertEquals("method2(int, java.lang.String)", ms.getSignature());
+	}
+
+	public void testGetSignature3() throws Exception {
+		MethodSignature ms = new SimpleMethodSignature(this.getMethod("method3"));
+		assertEquals("method3(int, java.lang.String, java.lang.Object[][])", ms.getSignature());
+	}
+
+	public void testGetName() throws Exception {
+		MethodSignature ms = new SimpleMethodSignature(this.getMethod("method2"));
+		assertEquals("method2", ms.getName());
+	}
+
+	public void testGetParameterTypes() throws Exception {
+		MethodSignature ms = new SimpleMethodSignature(this.getMethod("method3"));
+		JavaType[] expected = new JavaType[3];
+		expected[0] = new SimpleJavaType("int");
+		expected[1] = new SimpleJavaType("java.lang.String");
+		expected[2] = new SimpleJavaType("java.lang.Object", 2);
+		assertTrue(Arrays.equals(expected, ms.getParameterTypes()));
+	}
+
+	public void testEquals() throws Exception {
+		Object ms1 = new SimpleMethodSignature(this.getMethod("method3"));
+		Object ms2 = new SimpleMethodSignature(this.getMethod("method3"));
+		assertNotSame(ms1, ms2);
+		assertEquals(ms1, ms1);
+		assertEquals(ms1, ms2);
+		assertEquals(ms1.hashCode(), ms2.hashCode());
+
+		Object ms3 = new SimpleMethodSignature(this.getMethod("method2"));
+		assertNotSame(ms1, ms3);
+		assertFalse(ms1.equals(ms3));
+	}
+
+	public void testClone() throws Exception {
+		SimpleMethodSignature ms1 = new SimpleMethodSignature(this.getMethod("method3"));
+		SimpleMethodSignature ms2 = (SimpleMethodSignature) ms1.clone();
+		assertNotSame(ms1, ms2);
+		assertEquals(ms1, ms2);
+	}
+
+	public void testSerialization() throws Exception {
+		SimpleMethodSignature ms1 = new SimpleMethodSignature(this.getMethod("method3"));
+		SimpleMethodSignature ms2 = TestTools.serialize(ms1);
+		assertNotSame(ms1, ms2);
+		assertEquals(ms1, ms2);
+	}
+
+	private Method getMethod(String methodName) {
+		for (Method method : this.getClass().getMethods()) {
+			if (method.getName().equals(methodName)) {
+				return method;
+			}
+		}
+		throw new IllegalArgumentException("method not found: " + methodName);
+	}
+
+	public void method0() { /* used by tests */ }
+	@SuppressWarnings("unused") public void method1(int foo) { /* used by tests */ }
+	@SuppressWarnings("unused") public void method2(int foo, String bar) { /* used by tests */ }
+	@SuppressWarnings("unused") public void method3(int foo, String bar, Object[][] baz) { /* used by tests */ }
+
+	@SuppressWarnings("unused") public void methodA(int foo, String bar) { /* used by tests */ }
+	@SuppressWarnings("unused") public void methodA(int foo, String bar, String baz) { /* used by tests */ }
+
+	@SuppressWarnings("unused") public void methodB(int foo, Object bar) { /* used by tests */ }
+	@SuppressWarnings("unused") public void methodB(int foo, String bar) { /* used by tests */ }
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/StackTraceTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/StackTraceTests.java
new file mode 100644
index 0000000..7cf9826
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/StackTraceTests.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.StackTrace;
+
+public class StackTraceTests
+	extends TestCase
+{
+	public StackTraceTests(String name) {
+		super(name);
+	}
+
+	public void testToString() throws Exception {
+		StackTrace st = new StackTrace();
+		assertTrue(st.toString().contains(this.getClass().getName()));
+	}
+
+	public void testToString_noTestClass() throws Exception {
+		StackTrace st = new StackTrace(this.getClass());
+		assertFalse(st.toString().contains(this.getClass().getName()));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/StringBufferToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/StringBufferToolsTests.java
new file mode 100644
index 0000000..96456cb
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/StringBufferToolsTests.java
@@ -0,0 +1,469 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.StringBufferTools;
+
+@SuppressWarnings("nls")
+public class StringBufferToolsTests
+	extends TestCase
+{
+	public StringBufferToolsTests(String name) {
+		super(name);
+	}
+
+	// ********** padding/truncating/centering **********
+
+	public void testCenter() {
+		this.verifyCenter("fred", "fred", 4);
+		this.verifyCenter(" fred ", "fred", 6);
+		this.verifyCenter(" fred  ", "fred", 7);
+		this.verifyCenter("re", "fred", 2);
+		this.verifyCenter("fre", "fred", 3);
+	}
+
+	private void verifyCenter(String expected, String s, int len) {
+		StringBuffer sb;
+		sb = new StringBuffer();
+		StringBufferTools.center(sb, s, len);
+		assertEquals(expected, sb.toString());
+
+		sb = new StringBuffer();
+		StringBufferTools.center(sb, s.toCharArray(), len);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testPad() {
+		StringBuffer sb;
+		sb = new StringBuffer();
+		StringBufferTools.pad(sb, "fred", 4);
+		assertEquals("fred", sb.toString());
+
+		sb = new StringBuffer();
+		StringBufferTools.pad(sb, "fred", 6);
+		assertEquals("fred  ", sb.toString());
+
+		sb = new StringBuffer();
+		boolean exThrown = false;
+		try {
+			StringBufferTools.pad(sb, "fred", 2);
+			fail();
+		} catch (IllegalArgumentException ex) {
+			exThrown = true;
+		}
+		assertTrue(exThrown);
+	}
+
+	public void testFit() {
+		this.verifyFit("fred", "fred", 4);
+		this.verifyFit("fred  ", "fred", 6);
+		this.verifyFit("fr", "fred", 2);
+	}
+
+	private void verifyFit(String expected, String string, int length) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.fit(sb, string, length);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testZeroPad() {
+		StringBuffer sb;
+		sb = new StringBuffer();
+		StringBufferTools.zeroPad(sb, "1234", 4);
+		assertEquals("1234", sb.toString());
+
+		sb = new StringBuffer();
+		StringBufferTools.zeroPad(sb, "1234", 6);
+		assertEquals("001234", sb.toString());
+
+		sb = new StringBuffer();
+		boolean exThrown = false;
+		try {
+			StringBufferTools.zeroPad(sb, "1234", 2);
+			fail();
+		} catch (IllegalArgumentException ex) {
+			exThrown = true;
+		}
+		assertTrue(exThrown);
+	}
+
+	public void testZeroFit() {
+		this.verifyZeroFit("1234", "1234", 4);
+		this.verifyZeroFit("001234", "1234", 6);
+		this.verifyZeroFit("34", "1234", 2);
+	}
+
+	private void verifyZeroFit(String expected, String string, int length) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.zeroFit(sb, string, length);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testSeparateOnStringCharInt() {
+		this.verifySeparate("012345", '-', 22, "012345");
+		this.verifySeparate("012345", '-',  6, "012345");
+		this.verifySeparate("012345", '-',  5, "01234-5");
+		this.verifySeparate("012345", '-',  4, "0123-45");
+		this.verifySeparate("012345", '-',  3, "012-345");
+		this.verifySeparate("012345", '-',  2, "01-23-45");
+		this.verifySeparate("012345", '-',  1, "0-1-2-3-4-5");
+	}
+
+	private void verifySeparate(String string, char separator, int segmentLength, String expected) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.separate(sb, string, separator, segmentLength);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testSeparateOnCharArrayCharInt() {
+		this.verifySeparateCharArray("012345", '-', 22, "012345");
+		this.verifySeparateCharArray("012345", '-',  6, "012345");
+		this.verifySeparateCharArray("012345", '-',  5, "01234-5");
+		this.verifySeparateCharArray("012345", '-',  4, "0123-45");
+		this.verifySeparateCharArray("012345", '-',  3, "012-345");
+		this.verifySeparateCharArray("012345", '-',  2, "01-23-45");
+		this.verifySeparateCharArray("012345", '-',  1, "0-1-2-3-4-5");
+	}
+
+	private void verifySeparateCharArray(String string, char separator, int segmentLength, String expected) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.separate(sb, string.toCharArray(), separator, segmentLength);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testDelimit() {
+		this.verifyDelimit("Employee", "123", "123Employee123");
+		this.verifyDelimit("123", "123", "123123123");
+		this.verifyDelimit("", "123", "123123");
+	}
+
+	private void verifyDelimit(String string, String delimiter, String expectedString) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.delimit(sb, string, delimiter);
+		assertEquals(expectedString, sb.toString());
+	}
+
+	public void testQuote() {
+		this.verifyQuote("Employee", "\"Employee\"");
+		this.verifyQuote("123", "\"123\"");
+		this.verifyQuote("", "\"\"");
+		this.verifyQuote("Emp\"loyee", "\"Emp\"\"loyee\"");
+	}
+
+	private void verifyQuote(String string, String expectedString) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.quote(sb, string);
+		assertEquals(expectedString, sb.toString());
+	}
+
+	public void testRemoveFirstOccurrence() {
+		this.verifyRemoveFirstOccurrence("Emplo&yee", '&', "Employee");
+		this.verifyRemoveFirstOccurrence("Emplo&yee&", '&', "Employee&");
+		this.verifyRemoveFirstOccurrence("Employee &Foo", '&', "Employee Foo");
+		this.verifyRemoveFirstOccurrence("Employee&", '&', "Employee");
+		this.verifyRemoveFirstOccurrence("&Employee", '&', "Employee");
+	}
+
+	private void verifyRemoveFirstOccurrence(String string, char charToRemove, String expectedString) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.removeFirstOccurrence(sb, string, charToRemove);
+		assertEquals(expectedString, sb.toString());
+	}
+
+	public void testRemoveAllOccurrences() {
+		this.verifyRemoveAllOccurrences("Employee Fred", ' ', "EmployeeFred");
+		this.verifyRemoveAllOccurrences(" Employee ", ' ', "Employee");
+		this.verifyRemoveAllOccurrences("Employee   Foo", ' ', "EmployeeFoo");
+		this.verifyRemoveAllOccurrences(" Emp loyee   Foo", ' ', "EmployeeFoo");
+	}
+
+	private void verifyRemoveAllOccurrences(String string, char charToRemove, String expectedString) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.removeAllOccurrences(sb, string, charToRemove);
+		assertEquals(expectedString, sb.toString());
+	}
+
+	public void testRemoveAllWhitespace() {
+		this.verifyRemoveAllWhitespace("Employee Fred\t", "EmployeeFred");
+		this.verifyRemoveAllWhitespace("\tEmployee\n", "Employee");
+		this.verifyRemoveAllWhitespace("Employee \t Foo", "EmployeeFoo");
+		this.verifyRemoveAllWhitespace(" Emp\tloyee \n Foo", "EmployeeFoo");
+	}
+
+	private void verifyRemoveAllWhitespace(String string, String expectedString) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.removeAllWhitespace(sb, string);
+		assertEquals(expectedString, sb.toString());
+	}
+
+	public void testCompressWhitespace() {
+		this.verifyCompressWhitespace("Employee      Fred\t", "Employee Fred ");
+		this.verifyCompressWhitespace("\tEmployee  \n", " Employee ");
+		this.verifyCompressWhitespace("Employee \t Foo", "Employee Foo");
+		this.verifyCompressWhitespace(" Emp\tloyee \n Foo ", " Emp loyee Foo ");
+	}
+
+	private void verifyCompressWhitespace(String string, String expectedString) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.compressWhitespace(sb, string);
+		assertEquals(expectedString, sb.toString());
+	}
+
+	public void testCapitalizeOnStringStringBuffer() {
+		this.verifyCapitalizeOnStringStringBuffer("Oracle", "Oracle");
+		this.verifyCapitalizeOnStringStringBuffer("Oracle", "oracle");
+		this.verifyCapitalizeOnStringStringBuffer("   ", "   ");
+		this.verifyCapitalizeOnStringStringBuffer("ORACLE", "ORACLE");
+		this.verifyCapitalizeOnStringStringBuffer("", "");
+		this.verifyCapitalizeOnStringStringBuffer("A", "a");
+		this.verifyCapitalizeOnStringStringBuffer("\u00C9cole", "\u00E9cole"); // e'cole -> E'cole
+	}
+
+	private void verifyCapitalizeOnStringStringBuffer(String expected, String string) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.capitalize(sb, string);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testCapitalizeOnCharArray() {
+		this.verifyCapitalizeOnCharArray("Oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyCapitalizeOnCharArray("Oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyCapitalizeOnCharArray("   ", new char[] { ' ', ' ', ' ' });
+		this.verifyCapitalizeOnCharArray("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
+		this.verifyCapitalizeOnCharArray("", new char[0]);
+		this.verifyCapitalizeOnCharArray("A", new char[] { 'a' });
+		this.verifyCapitalizeOnCharArray("\u00C9cole", new char[] { '\u00E9', 'c', 'o', 'l', 'e' });
+	}
+
+	private void verifyCapitalizeOnCharArray(String expected, char[] string) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.capitalize(sb, string);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testUncapitalizeOnString() {
+		this.verifyUncapitalizeOnString("oracle", "Oracle");
+		this.verifyUncapitalizeOnString("oracle", "oracle");
+		this.verifyUncapitalizeOnString("   ", "   ");
+		this.verifyUncapitalizeOnString("ORACLE", "ORACLE");
+		this.verifyUncapitalizeOnString("", "");
+		this.verifyUncapitalizeOnString("a", "A");
+		this.verifyUncapitalizeOnString("\u00E9cole", "\u00C9cole"); // E'cole -> e'cole
+	}
+
+	private void verifyUncapitalizeOnString(String expected, String string) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.uncapitalize(sb, string);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testUncapitalizeOnCharArray() {
+		this.verifyUncapitalizeOnCharArray("oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyUncapitalizeOnCharArray("oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyUncapitalizeOnCharArray("   ", new char[] { ' ', ' ', ' ' });
+		this.verifyUncapitalizeOnCharArray("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
+		this.verifyUncapitalizeOnCharArray("", new char[0]);
+		this.verifyUncapitalizeOnCharArray("a", new char[] { 'A' });
+		this.verifyUncapitalizeOnCharArray("\u00E9cole", new char[] { '\u00C9', 'c', 'o', 'l', 'e' });
+	}
+
+	private void verifyUncapitalizeOnCharArray(String expected, char[] string) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.uncapitalize(sb, string);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testConvertToHexString() {
+		this.verifyConvertToHexString("74657374", "test"); // UTF-8 values
+	}
+
+	public void testConvertToHexString_negative() {
+		this.verifyConvertToHexString(this.getHexCafe(), "caf\u00E9"); // UTF-8 values
+	}
+
+	private String getHexCafe() {
+		return StringToolsTests.getHexCafe();
+	}
+
+	private void verifyConvertToHexString(String expected, String string) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.convertToHexString(sb, string.getBytes());
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testConvertCamelCaseToAllCaps() {
+		this.verifyConvertCamelCaseToAllCaps("TEST", "test");
+		this.verifyConvertCamelCaseToAllCaps("TEST", "TEST");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST", "testTest");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST", "TestTest");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST_TEST", "testTESTTest");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST_TEST", "TestTESTTest");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST_TEST_T", "TestTESTTestT");
+	}
+
+	private void verifyConvertCamelCaseToAllCaps(String expected, String string) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.convertCamelCaseToAllCaps(sb, string);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testConvertCamelCaseToAllCapsMaxLength() {
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST", "test", 44);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST", "test", 4);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TES", "test", 3);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST", "TEST", 5);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TE", "TEST", 2);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TEST", "testTest", 9);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TES", "testTest", 8);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_T", "testTest", 6);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_", "testTest", 5);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST", "testTest", 4);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TEST", "TestTest", 9);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TEST", "TestTest", 1100);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TEST_", "testTESTTest", 10);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TEST_TEST", "TestTESTTest", 14);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TEST_TEST_T", "TestTESTTestT", 16);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TEST_TEST_", "TestTESTTestT", 15);
+	}
+
+	private void verifyConvertCamelCaseToAllCapsMaxLength(String expected, String string, int max) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.convertCamelCaseToAllCaps(sb, string, max);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testConvertUnderscoresToCamelCase() {
+		this.verifyConvertUnderscoresToCamelCase("test", "TEST", false);
+		this.verifyConvertUnderscoresToCamelCase("test", "TEST_", false);
+		this.verifyConvertUnderscoresToCamelCase("test", "TEST____", false);
+		this.verifyConvertUnderscoresToCamelCase("Test", "TEST", true);
+		this.verifyConvertUnderscoresToCamelCase("test", "TeST", false);
+		this.verifyConvertUnderscoresToCamelCase("testTest", "TEST_TEST", false);
+		this.verifyConvertUnderscoresToCamelCase("testTest", "TEST___TEST", false);
+		this.verifyConvertUnderscoresToCamelCase("TestTest", "TEST_TEST", true);
+		this.verifyConvertUnderscoresToCamelCase("testTestTest", "TEST_TEST_TEST", false);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTest", "TEST_TEST_TEST", true);
+		this.verifyConvertUnderscoresToCamelCase("testTestTestT", "TEST_TEST_TEST_T", false);
+		this.verifyConvertUnderscoresToCamelCase("testTestTestT", "_TEST_TEST_TEST_T", false);
+		this.verifyConvertUnderscoresToCamelCase("testTestTestT", "__TEST_TEST_TEST_T", false);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTestT", "TEST_TEST_TEST_T", true);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTestT", "_TEST_TEST_TEST_T", true);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTestT", "__TEST_TEST_TEST_T", true);
+	}
+
+	public void testConvertUnderscoresToCamelCaseLowercase() {
+		this.verifyConvertUnderscoresToCamelCase("test", "test", false);
+		this.verifyConvertUnderscoresToCamelCase("test", "test_", false);
+		this.verifyConvertUnderscoresToCamelCase("test", "test____", false);
+		this.verifyConvertUnderscoresToCamelCase("Test", "test", true);
+		this.verifyConvertUnderscoresToCamelCase("test", "test", false);
+		this.verifyConvertUnderscoresToCamelCase("testTest", "test_test", false);
+		this.verifyConvertUnderscoresToCamelCase("testTest", "test___test", false);
+		this.verifyConvertUnderscoresToCamelCase("TestTest", "test_test", true);
+		this.verifyConvertUnderscoresToCamelCase("testTestTest", "test_test_test", false);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTest", "test_test_test", true);
+		this.verifyConvertUnderscoresToCamelCase("testTestTestT", "test_test_test_t", false);
+		this.verifyConvertUnderscoresToCamelCase("testTestTestT", "_test_test_test_t", false);
+		this.verifyConvertUnderscoresToCamelCase("testTestTestT", "__test_test_test_t", false);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTestT", "test_test_test_t", true);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTestT", "_test_test_test_t", true);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTestT", "__test_test_test_t", true);
+	}
+
+	private void verifyConvertUnderscoresToCamelCase(String expected, String string, boolean capitalizeFirstLetter) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.convertAllCapsToCamelCase(sb, string, capitalizeFirstLetter);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testUndelimit() {
+		this.verifyUndelimit("\"foo\"", "foo");
+		this.verifyUndelimit("\"\"", "");
+		this.verifyUndelimit("'foo'", "foo");
+		this.verifyUndelimit("\"fo\"\"o\"", "fo\"o");
+		this.verifyUndelimit("\"foo\"\"\"", "foo\"");
+		this.verifyUndelimit("\"\"\"foo\"", "\"foo");
+		this.verifyUndelimit("[foo]", "foo");
+		this.verifyUndelimit("\"\"\"", "\"");
+		this.verifyUndelimit("\"foo\"bar\"", "foo\"");
+		this.verifyUndelimit("\"foo\"\"", "foo\"");
+	}
+
+	private void verifyUndelimit(String s, String expected) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.undelimit(sb, s);
+		assertEquals(expected, sb.toString());
+
+		sb = new StringBuffer();
+		StringBufferTools.undelimit(sb, s.toCharArray());
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testUndelimitCount() {
+		this.verifyUndelimitCount("\"foo\"", 2, "o");
+		this.verifyUndelimitCount("\"\"\"\"", 2, "");
+		this.verifyUndelimitCount("XXfooXX", 2, "foo");
+	}
+
+	private void verifyUndelimitCount(String s, int count, String expected) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.undelimit(sb, s, count);
+		assertEquals(expected, sb.toString());
+
+		sb = new StringBuffer();
+		StringBufferTools.undelimit(sb, s.toCharArray(), count);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testConvertToJavaStringLiteral() {
+		this.verifyConvertToJavaStringLiteral("", "\"\"");
+		this.verifyConvertToJavaStringLiteral("\"\"", "\"\\\"\\\"\"");
+		this.verifyConvertToJavaStringLiteral("'foo'", "\"'foo'\"");
+		this.verifyConvertToJavaStringLiteral("foo\bbar", "\"foo\\bbar\"");
+		this.verifyConvertToJavaStringLiteral("foo\n\tbar", "\"foo\\n\\tbar\"");
+		this.verifyConvertToJavaStringLiteral("foo\"bar", "\"foo\\\"bar\"");
+		this.verifyConvertToJavaStringLiteral("foo\\bar", "\"foo\\\\bar\"");
+	}
+
+	private void verifyConvertToJavaStringLiteral(String s, String expected) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.convertToJavaStringLiteral(sb, s);
+		assertEquals(expected, sb.toString());
+
+		sb = new StringBuffer();
+		StringBufferTools.convertToJavaStringLiteral(sb, s.toCharArray());
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testConvertToJavaStringLiteralContent() {
+		this.verifyConvertToJavaStringLiteralContent("", "");
+		this.verifyConvertToJavaStringLiteralContent("\"\"", "\\\"\\\"");
+		this.verifyConvertToJavaStringLiteralContent("'foo'", "'foo'");
+		this.verifyConvertToJavaStringLiteralContent("foo\bbar", "foo\\bbar");
+		this.verifyConvertToJavaStringLiteralContent("foo\n\tbar", "foo\\n\\tbar");
+		this.verifyConvertToJavaStringLiteralContent("foo\"bar", "foo\\\"bar");
+		this.verifyConvertToJavaStringLiteralContent("foo\\bar", "foo\\\\bar");
+	}
+
+	private void verifyConvertToJavaStringLiteralContent(String s, String expected) {
+		StringBuffer sb = new StringBuffer();
+		StringBufferTools.convertToJavaStringLiteralContent(sb, s);
+		assertEquals(expected, sb.toString());
+
+		sb = new StringBuffer();
+		StringBufferTools.convertToJavaStringLiteralContent(sb, s.toCharArray());
+		assertEquals(expected, sb.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/StringBuilderToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/StringBuilderToolsTests.java
new file mode 100644
index 0000000..b6d6066
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/StringBuilderToolsTests.java
@@ -0,0 +1,400 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+
+@SuppressWarnings("nls")
+public class StringBuilderToolsTests
+	extends TestCase
+{
+	public StringBuilderToolsTests(String name) {
+		super(name);
+	}
+
+	// ********** padding/truncating/centering **********
+
+	public void testCenter() {
+		this.verifyCenter("fred", "fred", 4);
+		this.verifyCenter(" fred ", "fred", 6);
+		this.verifyCenter(" fred  ", "fred", 7);
+		this.verifyCenter("re", "fred", 2);
+		this.verifyCenter("fre", "fred", 3);
+	}
+
+	private void verifyCenter(String expected, String s, int len) {
+		StringBuilder sb;
+		sb = new StringBuilder();
+		StringBuilderTools.center(sb, s, len);
+		assertEquals(expected, sb.toString());
+
+		sb = new StringBuilder();
+		StringBuilderTools.center(sb, s.toCharArray(), len);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testPad() {
+		StringBuilder sb;
+		sb = new StringBuilder();
+		StringBuilderTools.pad(sb, "fred", 4);
+		assertEquals("fred", sb.toString());
+
+		sb = new StringBuilder();
+		StringBuilderTools.pad(sb, "fred", 6);
+		assertEquals("fred  ", sb.toString());
+
+		sb = new StringBuilder();
+		boolean exThrown = false;
+		try {
+			StringBuilderTools.pad(sb, "fred", 2);
+			fail();
+		} catch (IllegalArgumentException ex) {
+			exThrown = true;
+		}
+		assertTrue(exThrown);
+	}
+
+	public void testFit() {
+		this.verifyFit("fred", "fred", 4);
+		this.verifyFit("fred  ", "fred", 6);
+		this.verifyFit("fr", "fred", 2);
+	}
+
+	private void verifyFit(String expected, String string, int length) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.fit(sb, string, length);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testZeroPad() {
+		StringBuilder sb;
+		sb = new StringBuilder();
+		StringBuilderTools.zeroPad(sb, "1234", 4);
+		assertEquals("1234", sb.toString());
+
+		sb = new StringBuilder();
+		StringBuilderTools.zeroPad(sb, "1234", 6);
+		assertEquals("001234", sb.toString());
+
+		sb = new StringBuilder();
+		boolean exThrown = false;
+		try {
+			StringBuilderTools.zeroPad(sb, "1234", 2);
+			fail();
+		} catch (IllegalArgumentException ex) {
+			exThrown = true;
+		}
+		assertTrue(exThrown);
+	}
+
+	public void testZeroFit() {
+		this.verifyZeroFit("1234", "1234", 4);
+		this.verifyZeroFit("001234", "1234", 6);
+		this.verifyZeroFit("34", "1234", 2);
+	}
+
+	private void verifyZeroFit(String expected, String string, int length) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.zeroFit(sb, string, length);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testSeparateOnStringCharInt() {
+		this.verifySeparate("012345", '-', 22, "012345");
+		this.verifySeparate("012345", '-',  6, "012345");
+		this.verifySeparate("012345", '-',  5, "01234-5");
+		this.verifySeparate("012345", '-',  4, "0123-45");
+		this.verifySeparate("012345", '-',  3, "012-345");
+		this.verifySeparate("012345", '-',  2, "01-23-45");
+		this.verifySeparate("012345", '-',  1, "0-1-2-3-4-5");
+	}
+
+	private void verifySeparate(String string, char separator, int segmentLength, String expected) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.separate(sb, string, separator, segmentLength);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testSeparateOnCharArrayCharInt() {
+		this.verifySeparateCharArray("012345", '-', 22, "012345");
+		this.verifySeparateCharArray("012345", '-',  6, "012345");
+		this.verifySeparateCharArray("012345", '-',  5, "01234-5");
+		this.verifySeparateCharArray("012345", '-',  4, "0123-45");
+		this.verifySeparateCharArray("012345", '-',  3, "012-345");
+		this.verifySeparateCharArray("012345", '-',  2, "01-23-45");
+		this.verifySeparateCharArray("012345", '-',  1, "0-1-2-3-4-5");
+	}
+
+	private void verifySeparateCharArray(String string, char separator, int segmentLength, String expected) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.separate(sb, string.toCharArray(), separator, segmentLength);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testDelimit() {
+		this.verifyDelimit("Employee", "123", "123Employee123");
+		this.verifyDelimit("123", "123", "123123123");
+		this.verifyDelimit("", "123", "123123");
+	}
+
+	private void verifyDelimit(String string, String delimiter, String expectedString) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.delimit(sb, string, delimiter);
+		assertEquals(expectedString, sb.toString());
+	}
+
+	public void testQuote() {
+		this.verifyQuote("Employee", "\"Employee\"");
+		this.verifyQuote("123", "\"123\"");
+		this.verifyQuote("", "\"\"");
+		this.verifyQuote("Emp\"loyee", "\"Emp\"\"loyee\"");
+	}
+
+	private void verifyQuote(String string, String expectedString) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.quote(sb, string);
+		assertEquals(expectedString, sb.toString());
+	}
+
+	public void testRemoveFirstOccurrence() {
+		this.verifyRemoveFirstOccurrence("Emplo&yee", '&', "Employee");
+		this.verifyRemoveFirstOccurrence("Emplo&yee&", '&', "Employee&");
+		this.verifyRemoveFirstOccurrence("Employee &Foo", '&', "Employee Foo");
+		this.verifyRemoveFirstOccurrence("Employee&", '&', "Employee");
+		this.verifyRemoveFirstOccurrence("&Employee", '&', "Employee");
+	}
+
+	private void verifyRemoveFirstOccurrence(String string, char charToRemove, String expectedString) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.removeFirstOccurrence(sb, string, charToRemove);
+		assertEquals(expectedString, sb.toString());
+	}
+
+	public void testRemoveAllOccurrences() {
+		this.verifyRemoveAllOccurrences("Employee Fred", ' ', "EmployeeFred");
+		this.verifyRemoveAllOccurrences(" Employee ", ' ', "Employee");
+		this.verifyRemoveAllOccurrences("Employee   Foo", ' ', "EmployeeFoo");
+		this.verifyRemoveAllOccurrences(" Emp loyee   Foo", ' ', "EmployeeFoo");
+	}
+
+	private void verifyRemoveAllOccurrences(String string, char charToRemove, String expectedString) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.removeAllOccurrences(sb, string, charToRemove);
+		assertEquals(expectedString, sb.toString());
+	}
+
+	public void testRemoveAllWhitespace() {
+		this.verifyRemoveAllWhitespace("Employee Fred\t", "EmployeeFred");
+		this.verifyRemoveAllWhitespace("\tEmployee\n", "Employee");
+		this.verifyRemoveAllWhitespace("Employee \t Foo", "EmployeeFoo");
+		this.verifyRemoveAllWhitespace(" Emp\tloyee \n Foo", "EmployeeFoo");
+	}
+
+	private void verifyRemoveAllWhitespace(String string, String expectedString) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.removeAllWhitespace(sb, string);
+		assertEquals(expectedString, sb.toString());
+	}
+
+	public void testCompressWhitespace() {
+		this.verifyCompressWhitespace("Employee      Fred\t", "Employee Fred ");
+		this.verifyCompressWhitespace("\tEmployee  \n", " Employee ");
+		this.verifyCompressWhitespace("Employee \t Foo", "Employee Foo");
+		this.verifyCompressWhitespace(" Emp\tloyee \n Foo ", " Emp loyee Foo ");
+	}
+
+	private void verifyCompressWhitespace(String string, String expectedString) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.compressWhitespace(sb, string);
+		assertEquals(expectedString, sb.toString());
+	}
+
+	public void testCapitalizeOnString() {
+		this.verifyCapitalizeOnString("Oracle", "Oracle");
+		this.verifyCapitalizeOnString("Oracle", "oracle");
+		this.verifyCapitalizeOnString("   ", "   ");
+		this.verifyCapitalizeOnString("ORACLE", "ORACLE");
+		this.verifyCapitalizeOnString("", "");
+		this.verifyCapitalizeOnString("A", "a");
+		this.verifyCapitalizeOnString("\u00C9cole", "\u00E9cole"); // e'cole -> E'cole
+	}
+
+	private void verifyCapitalizeOnString(String expected, String string) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.capitalize(sb, string);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testCapitalizeOnCharArray() {
+		this.verifyCapitalizeOnCharArray("Oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyCapitalizeOnCharArray("Oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyCapitalizeOnCharArray("   ", new char[] { ' ', ' ', ' ' });
+		this.verifyCapitalizeOnCharArray("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
+		this.verifyCapitalizeOnCharArray("", new char[0]);
+		this.verifyCapitalizeOnCharArray("A", new char[] { 'a' });
+		this.verifyCapitalizeOnCharArray("\u00C9cole", new char[] { '\u00E9', 'c', 'o', 'l', 'e' });
+	}
+
+	private void verifyCapitalizeOnCharArray(String expected, char[] string) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.capitalize(sb, string);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testUncapitalizeOnString() {
+		this.verifyUncapitalizeOnString("oracle", "Oracle");
+		this.verifyUncapitalizeOnString("oracle", "oracle");
+		this.verifyUncapitalizeOnString("   ", "   ");
+		this.verifyUncapitalizeOnString("ORACLE", "ORACLE");
+		this.verifyUncapitalizeOnString("", "");
+		this.verifyUncapitalizeOnString("a", "A");
+		this.verifyUncapitalizeOnString("\u00E9cole", "\u00C9cole"); // E'cole -> e'cole
+	}
+
+	private void verifyUncapitalizeOnString(String expected, String string) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.uncapitalize(sb, string);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testUncapitalizeOnCharArray() {
+		this.verifyUncapitalizeOnCharArray("oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyUncapitalizeOnCharArray("oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyUncapitalizeOnCharArray("   ", new char[] { ' ', ' ', ' ' });
+		this.verifyUncapitalizeOnCharArray("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
+		this.verifyUncapitalizeOnCharArray("", new char[0]);
+		this.verifyUncapitalizeOnCharArray("a", new char[] { 'A' });
+		this.verifyUncapitalizeOnCharArray("\u00E9cole", new char[] { '\u00C9', 'c', 'o', 'l', 'e' });
+	}
+
+	private void verifyUncapitalizeOnCharArray(String expected, char[] string) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.uncapitalize(sb, string);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testConvertToHexString() {
+		this.verifyConvertToHexString("74657374", "test"); // UTF-8 values
+	}
+
+	public void testConvertToHexString_negative() {
+		this.verifyConvertToHexString(this.getHexCafe(), "caf\u00E9"); // UTF-8 values
+	}
+
+	private String getHexCafe() {
+		return StringToolsTests.getHexCafe();
+	}
+
+	private void verifyConvertToHexString(String expected, String string) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.convertToHexString(sb, string.getBytes());
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testConvertCamelCaseToAllCaps() {
+		this.verifyConvertCamelCaseToAllCaps("TEST", "test");
+		this.verifyConvertCamelCaseToAllCaps("TEST", "TEST");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST", "testTest");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST", "TestTest");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST_TEST", "testTESTTest");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST_TEST", "TestTESTTest");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST_TEST_T", "TestTESTTestT");
+	}
+
+	private void verifyConvertCamelCaseToAllCaps(String expected, String string) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.convertCamelCaseToAllCaps(sb, string);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testUndelimit() {
+		this.verifyUndelimit("\"foo\"", "foo");
+		this.verifyUndelimit("\"\"", "");
+		this.verifyUndelimit("'foo'", "foo");
+		this.verifyUndelimit("\"fo\"\"o\"", "fo\"o");
+		this.verifyUndelimit("\"foo\"\"\"", "foo\"");
+		this.verifyUndelimit("\"\"\"foo\"", "\"foo");
+		this.verifyUndelimit("[foo]", "foo");
+		this.verifyUndelimit("\"\"\"", "\"");
+		this.verifyUndelimit("\"foo\"bar\"", "foo\"");
+		this.verifyUndelimit("\"foo\"\"", "foo\"");
+	}
+
+	private void verifyUndelimit(String s, String expected) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.undelimit(sb, s);
+		assertEquals(expected, sb.toString());
+
+		sb = new StringBuilder();
+		StringBuilderTools.undelimit(sb, s.toCharArray());
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testUndelimitCount() {
+		this.verifyUndelimitCount("\"foo\"", 2, "o");
+		this.verifyUndelimitCount("\"\"\"\"", 2, "");
+		this.verifyUndelimitCount("XXfooXX", 2, "foo");
+	}
+
+	private void verifyUndelimitCount(String s, int count, String expected) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.undelimit(sb, s, count);
+		assertEquals(expected, sb.toString());
+
+		sb = new StringBuilder();
+		StringBuilderTools.undelimit(sb, s.toCharArray(), count);
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testConvertToJavaStringLiteral() {
+		this.verifyConvertToJavaStringLiteral("", "\"\"");
+		this.verifyConvertToJavaStringLiteral("\"\"", "\"\\\"\\\"\"");
+		this.verifyConvertToJavaStringLiteral("'foo'", "\"'foo'\"");
+		this.verifyConvertToJavaStringLiteral("foo\bbar", "\"foo\\bbar\"");
+		this.verifyConvertToJavaStringLiteral("foo\n\tbar", "\"foo\\n\\tbar\"");
+		this.verifyConvertToJavaStringLiteral("foo\"bar", "\"foo\\\"bar\"");
+		this.verifyConvertToJavaStringLiteral("foo\\bar", "\"foo\\\\bar\"");
+	}
+
+	private void verifyConvertToJavaStringLiteral(String s, String expected) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.convertToJavaStringLiteral(sb, s);
+		assertEquals(expected, sb.toString());
+
+		sb = new StringBuilder();
+		StringBuilderTools.convertToJavaStringLiteral(sb, s.toCharArray());
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testConvertToJavaStringLiteralContent() {
+		this.verifyConvertToJavaStringLiteralContent("", "");
+		this.verifyConvertToJavaStringLiteralContent("\"\"", "\\\"\\\"");
+		this.verifyConvertToJavaStringLiteralContent("'foo'", "'foo'");
+		this.verifyConvertToJavaStringLiteralContent("foo\bbar", "foo\\bbar");
+		this.verifyConvertToJavaStringLiteralContent("foo\n\tbar", "foo\\n\\tbar");
+		this.verifyConvertToJavaStringLiteralContent("foo\"bar", "foo\\\"bar");
+		this.verifyConvertToJavaStringLiteralContent("foo\\bar", "foo\\\\bar");
+	}
+
+	private void verifyConvertToJavaStringLiteralContent(String s, String expected) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.convertToJavaStringLiteralContent(sb, s);
+		assertEquals(expected, sb.toString());
+
+		sb = new StringBuilder();
+		StringBuilderTools.convertToJavaStringLiteralContent(sb, s.toCharArray());
+		assertEquals(expected, sb.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/StringToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/StringToolsTests.java
new file mode 100644
index 0000000..035a2c7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/StringToolsTests.java
@@ -0,0 +1,720 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.util.Arrays;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ByteArrayTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.SystemTools;
+
+@SuppressWarnings("nls")
+public class StringToolsTests
+	extends TestCase
+{
+	public StringToolsTests(String name) {
+		super(name);
+	}
+
+	// ********** padding/truncating/centering **********
+
+	public void testCenter() {
+		assertEquals("fred", StringTools.center("fred", 4));
+		assertEquals(" fred ", StringTools.center("fred", 6));
+		assertEquals(" fred  ", StringTools.center("fred", 7));
+		assertEquals("re", StringTools.center("fred", 2));
+		assertEquals("fre", StringTools.center("fred", 3));
+	}
+
+	public void testPad() {
+		assertEquals("fred", StringTools.pad("fred", 4));
+		assertEquals("fred  ", StringTools.pad("fred", 6));
+		boolean exThrown = false;
+		try {
+			assertEquals("fr", StringTools.pad("fred", 2));
+		} catch (IllegalArgumentException ex) {
+			exThrown = true;
+		}
+		assertTrue(exThrown);
+	}
+
+	public void testFit() {
+		assertEquals("fred", StringTools.fit("fred", 4));
+		assertEquals("fred  ", StringTools.fit("fred", 6));
+		assertEquals("fr", StringTools.fit("fred", 2));
+	}
+
+	public void testZeroPad() {
+		assertEquals("1234", StringTools.zeroPad("1234", 4));
+		assertEquals("001234", StringTools.zeroPad("1234", 6));
+		boolean exThrown = false;
+		try {
+			assertEquals("12", StringTools.zeroPad("1234", 2));
+		} catch (IllegalArgumentException ex) {
+			exThrown = true;
+		}
+		assertTrue(exThrown);
+	}
+
+	public void testZeroFit() {
+		assertEquals("1234", StringTools.zeroFit("1234", 4));
+		assertEquals("001234", StringTools.zeroFit("1234", 6));
+		assertEquals("34", StringTools.zeroFit("1234", 2));
+	}
+
+	// ********** separating **********
+
+	public void testSeparateCharInt() {
+		this.verifySeparate("012345", '-', 22, "012345");
+		this.verifySeparate("012345", '-',  6, "012345");
+		this.verifySeparate("012345", '-',  5, "01234-5");
+		this.verifySeparate("012345", '-',  4, "0123-45");
+		this.verifySeparate("012345", '-',  3, "012-345");
+		this.verifySeparate("012345", '-',  2, "01-23-45");
+		this.verifySeparate("012345", '-',  1, "0-1-2-3-4-5");
+	}
+
+	private void verifySeparate(String string, char separator, int segmentLength, String expected) {
+		assertEquals(expected, StringTools.separate(string, separator, segmentLength));
+	}
+
+	// ********** delimiting **********
+
+	public void testDelimit() {
+		this.verifyDelimit("Employee", "123", "123Employee123");
+		this.verifyDelimit("123", "123", "123123123");
+		this.verifyDelimit("", "123", "123123");
+	}
+
+	private void verifyDelimit(String string, String delimiter, String expectedString) {
+		assertEquals(expectedString, StringTools.delimit(string, delimiter));
+	}
+
+	public void testQuote() {
+		this.verifyQuote("Employee", "\"Employee\"");
+		this.verifyQuote("123", "\"123\"");
+		this.verifyQuote("", "\"\"");
+		this.verifyQuote("Emp\"loyee", "\"Emp\"\"loyee\"");
+	}
+
+	private void verifyQuote(String string, String expectedString) {
+		assertEquals(expectedString, StringTools.quote(string));
+	}
+
+	// ********** removing characters **********
+
+	public void testRemoveFirstOccurrence() {
+		this.verifyRemoveFirstOccurrence("Emplo&yee", '&', "Employee");
+		this.verifyRemoveFirstOccurrence("Emplo&yee&", '&', "Employee&");
+		this.verifyRemoveFirstOccurrence("Employee &Foo", '&', "Employee Foo");
+		this.verifyRemoveFirstOccurrence("Employee&", '&', "Employee");
+		this.verifyRemoveFirstOccurrence("&Employee", '&', "Employee");
+	}
+
+	private void verifyRemoveFirstOccurrence(String string, char charToRemove, String expectedString) {
+		assertEquals(expectedString, StringTools.removeFirstOccurrence(string, charToRemove));
+	}
+
+	public void testRemoveAllOccurrences() {
+		this.verifyRemoveAllOccurrences("Employee Fred", ' ', "EmployeeFred");
+		this.verifyRemoveAllOccurrences(" Employee ", ' ', "Employee");
+		this.verifyRemoveAllOccurrences("Employee   Foo", ' ', "EmployeeFoo");
+		this.verifyRemoveAllOccurrences(" Emp loyee   Foo", ' ', "EmployeeFoo");
+	}
+
+	private void verifyRemoveAllOccurrences(String string, char charToRemove, String expectedString) {
+		assertEquals(expectedString, StringTools.removeAllOccurrences(string, charToRemove));
+	}
+
+	public void testRemoveAllWhitespace() {
+		this.verifyRemoveAllWhitespace("Employee Fred\t", "EmployeeFred");
+		this.verifyRemoveAllWhitespace("\tEmployee\n", "Employee");
+		this.verifyRemoveAllWhitespace("Employee \t Foo", "EmployeeFoo");
+		this.verifyRemoveAllWhitespace(" Emp\tloyee \n Foo", "EmployeeFoo");
+	}
+
+	private void verifyRemoveAllWhitespace(String string, String expectedString) {
+		assertEquals(expectedString, StringTools.removeAllWhitespace(string));
+	}
+
+	public void testCompressWhitespace() {
+		this.verifyCompressWhitespace("Employee      Fred\t", "Employee Fred ");
+		this.verifyCompressWhitespace("\tEmployee  \n", " Employee ");
+		this.verifyCompressWhitespace("Employee \t Foo", "Employee Foo");
+		this.verifyCompressWhitespace(" Emp\tloyee \n Foo ", " Emp loyee Foo ");
+	}
+
+	private void verifyCompressWhitespace(String string, String expectedString) {
+		assertEquals(expectedString, StringTools.compressWhitespace(string));
+	}
+
+	// ********** common prefix **********
+
+	public void testCommonPrefixLength() {
+		assertEquals(3, StringTools.commonPrefixLength("fooZZZ", "fooBBB"));
+		assertEquals(3, StringTools.commonPrefixLength("foo", "fooBBB"));
+		assertEquals(3, StringTools.commonPrefixLength("fooZZZ", "foo"));
+		assertEquals(3, StringTools.commonPrefixLength("foo", "foo"));
+	}
+
+	public void testCommonPrefixLengthMax() {
+		assertEquals(2, StringTools.commonPrefixLength("fooZZZ", "fooBBB", 2));
+		assertEquals(2, StringTools.commonPrefixLength("foo", "fooBBB", 2));
+		assertEquals(2, StringTools.commonPrefixLength("fooZZZ", "foo", 2));
+		assertEquals(2, StringTools.commonPrefixLength("foo", "foo", 2));
+	}
+
+	// ********** capitalization **********
+
+	public void testCapitalize() {
+		this.verifyCapitalize("Oracle", "Oracle");
+		this.verifyCapitalize("Oracle", "oracle");
+		this.verifyCapitalize("   ", "   ");
+		this.verifyCapitalize("ORACLE", "ORACLE");
+		this.verifyCapitalize("", "");
+		this.verifyCapitalize("A", "a");
+		this.verifyCapitalize("\u00C9cole", "\u00E9cole"); // e'cole -> E'cole
+	}
+
+	private void verifyCapitalize(String expected, String string) {
+		assertEquals(expected, StringTools.capitalize(string));
+	}
+
+	public void testUncapitalize() {
+		this.verifyUncapitalize("oracle", "Oracle");
+		this.verifyUncapitalize("oracle", "oracle");
+		this.verifyUncapitalize("   ", "   ");
+		this.verifyUncapitalize("ORACLE", "ORACLE");
+		this.verifyUncapitalize("", "");
+		this.verifyUncapitalize("a", "A");
+		this.verifyUncapitalize("\u00E9cole", "\u00C9cole"); // E'cole -> e'cole
+	}
+
+	private void verifyUncapitalize(String expected, String string) {
+		assertEquals(expected, StringTools.uncapitalize(string));
+	}
+
+	// ********** queries **********
+
+	public void testIsBlank() {
+		assertTrue(StringTools.isBlank((String) null));
+		assertTrue(StringTools.isBlank(""));
+		assertTrue(StringTools.isBlank("      "));
+		assertTrue(StringTools.isBlank("      \t\t   "));
+		assertTrue(StringTools.isBlank("      \t\t   " + StringTools.CR));
+	}
+
+	public void testEquals() {
+		assertTrue(ObjectTools.equals((String) null, (String) null));
+		assertFalse(ObjectTools.equals(null, "asdf"));
+		assertFalse(ObjectTools.equals("asdf", null));
+		assertTrue(ObjectTools.equals("asdf", "asdf"));
+		assertFalse(ObjectTools.equals("asdf", "ASDF"));
+	}
+
+	public void testEqualsIgnoreCase() {
+		assertTrue(StringTools.equalsIgnoreCase((String) null, (String) null));
+		assertFalse(StringTools.equalsIgnoreCase(null, "asdf"));
+		assertFalse(StringTools.equalsIgnoreCase("asdf", null));
+		assertTrue(StringTools.equalsIgnoreCase("asdf", "asdf"));
+		assertTrue(StringTools.equalsIgnoreCase("asdf", "ASDF"));
+	}
+
+	public void testStartsWithIgnoreCase() {
+		assertTrue(StringTools.startsWithIgnoreCase("asdf", "as"));
+		assertTrue(StringTools.startsWithIgnoreCase("asdf", "aS"));
+		assertTrue(StringTools.startsWithIgnoreCase("asdf", ""));
+		assertTrue(StringTools.startsWithIgnoreCase("asdf", "A"));
+
+		assertFalse(StringTools.startsWithIgnoreCase("asdf", "bsdf"));
+		assertFalse(StringTools.startsWithIgnoreCase("asdf", "g"));
+		assertFalse(StringTools.startsWithIgnoreCase("asdf", "asdg"));
+		assertFalse(StringTools.startsWithIgnoreCase("asdf", "asdfg"));
+		assertFalse(StringTools.startsWithIgnoreCase("asdf", "asdfgggggg"));
+	}
+
+	public void testIsUppercase() {
+		this.verifyIsUppercase("FOO");
+		this.verifyIsUppercase("FOO2");
+		this.verifyIsUppercase("F O O");
+		this.denyIsUppercase("Foo");
+		this.denyIsUppercase("");
+	}
+
+	private void verifyIsUppercase(String s) {
+		assertTrue(StringTools.isUppercase(s));
+	}
+
+	private void denyIsUppercase(String s) {
+		assertFalse(StringTools.isUppercase(s));
+	}
+
+	public void testIsLowercase() {
+		this.verifyIsLowercase("foo");
+		this.verifyIsLowercase("foo2");
+		this.verifyIsLowercase("f o o");
+		this.denyIsLowercase("Foo");
+		this.denyIsLowercase("");
+	}
+
+	private void verifyIsLowercase(String s) {
+		assertTrue(StringTools.isLowercase(s));
+	}
+
+	private void denyIsLowercase(String s) {
+		assertFalse(StringTools.isLowercase(s));
+	}
+
+	// ********** byte arrays **********
+
+	public void testConvertHexStringToByteArray_empty() throws Exception {
+		String s = StringTools.EMPTY_STRING;
+		byte[] byteArray = StringTools.convertHexStringToByteArray(s);
+		assertEquals(0, byteArray.length);
+		assertTrue(Arrays.equals(ByteArrayTools.EMPTY_BYTE_ARRAY, byteArray));
+	}
+
+	public void testConvertHexStringToByteArray_oddLength() throws Exception {
+		String s = "CAFEE";
+		boolean exCaught = false;
+		try {
+			byte[] byteArray = StringTools.convertHexStringToByteArray(s);
+			fail("bogus byte array: " + Arrays.toString(byteArray));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testConvertHexStringToByteArray_illegalCharacter1() throws Exception {
+		this.verifyConvertHexStringToByteArray_illegalCharacter("CAFEX0CAFEX0");
+	}
+
+	public void testConvertHexStringToByteArray_illegalCharacter2() throws Exception {
+		this.verifyConvertHexStringToByteArray_illegalCharacter("CAFE0XCAFE0x");
+	}
+
+	private void verifyConvertHexStringToByteArray_illegalCharacter(String s) throws Exception {
+		boolean exCaught = false;
+		try {
+			byte[] byteArray = StringTools.convertHexStringToByteArray(s);
+			fail("bogus byte array: " + Arrays.toString(byteArray));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testConvertHexStringToByteArray_ok() throws Exception {
+		String s = "74657374"; // UTF-8 values
+		assertEquals("test", new String(StringTools.convertHexStringToByteArray(s)));
+	}
+
+	public void testConvertHexStringToByteArray_negative() throws Exception {
+		String s = getHexCafe();
+		assertEquals("caf\u00E9", new String(StringTools.convertHexStringToByteArray(s)));
+	}
+
+	public void testConvertHexStringToByteArray_lowercase() throws Exception {
+		String s = getHexCafe().toLowerCase();
+		assertEquals("caf\u00E9", new String(StringTools.convertHexStringToByteArray(s)));
+	}
+
+	public static String getHexCafe() {
+		if (SystemTools.fileEncodingIsWindows()) {
+			return "636166E9";
+		}
+		if (SystemTools.fileEncodingIsUTF8()) {
+			return "636166C3A9";
+		}
+		return null;
+	}
+
+	// ********** convert camel-case to all-caps **********
+
+	public void testConvertCamelCaseToAllCaps() {
+		assertEquals("TEST", StringTools.convertCamelCaseToAllCaps("test"));
+		assertEquals("TEST", StringTools.convertCamelCaseToAllCaps("TEST"));
+		assertEquals("TEST_TEST", StringTools.convertCamelCaseToAllCaps("testTest"));
+		assertEquals("TEST_TEST", StringTools.convertCamelCaseToAllCaps("TestTest"));
+		assertEquals("TEST_TEST_TEST", StringTools.convertCamelCaseToAllCaps("testTESTTest"));
+		assertEquals("TEST_TEST_TEST", StringTools.convertCamelCaseToAllCaps("TestTESTTest"));
+		assertEquals("TEST_TEST_TEST_T", StringTools.convertCamelCaseToAllCaps("TestTESTTestT"));
+	}
+
+	public void testConvertCamelCaseToAllCapsMaxLength() {
+		assertEquals("TEST", StringTools.convertCamelCaseToAllCaps("test", 44));
+		assertEquals("TEST", StringTools.convertCamelCaseToAllCaps("test", 4));
+		assertEquals("TES", StringTools.convertCamelCaseToAllCaps("test", 3));
+		assertEquals("TEST", StringTools.convertCamelCaseToAllCaps("TEST", 5));
+		assertEquals("TE", StringTools.convertCamelCaseToAllCaps("TEST", 2));
+		assertEquals("TEST_TEST", StringTools.convertCamelCaseToAllCaps("testTest", 9));
+		assertEquals("TEST_TES", StringTools.convertCamelCaseToAllCaps("testTest", 8));
+		assertEquals("TEST_T", StringTools.convertCamelCaseToAllCaps("testTest", 6));
+		assertEquals("TEST_", StringTools.convertCamelCaseToAllCaps("testTest", 5));
+		assertEquals("TEST", StringTools.convertCamelCaseToAllCaps("testTest", 4));
+		assertEquals("TEST_TEST", StringTools.convertCamelCaseToAllCaps("TestTest", 9));
+		assertEquals("TEST_TEST", StringTools.convertCamelCaseToAllCaps("TestTest", 1100));
+		assertEquals("TEST_TEST_", StringTools.convertCamelCaseToAllCaps("testTESTTest", 10));
+		assertEquals("TEST_TEST_TEST", StringTools.convertCamelCaseToAllCaps("TestTESTTest", 14));
+		assertEquals("TEST_TEST_TEST_T", StringTools.convertCamelCaseToAllCaps("TestTESTTestT", 16));
+		assertEquals("TEST_TEST_TEST_", StringTools.convertCamelCaseToAllCaps("TestTESTTestT", 15));
+	}
+
+	// ********** convert all-caps to camel case **********
+
+	public void testConvertAllCapsToCamelCase() {
+		assertEquals("test", StringTools.convertAllCapsToCamelCase("TEST", false));
+		assertEquals("test", StringTools.convertAllCapsToCamelCase("TEST_", false));
+		assertEquals("test", StringTools.convertAllCapsToCamelCase("TEST____", false));
+		assertEquals("Test", StringTools.convertAllCapsToCamelCase("TEST", true));
+		assertEquals("test", StringTools.convertAllCapsToCamelCase("TeST", false));
+		assertEquals("testTest", StringTools.convertAllCapsToCamelCase("TEST_TEST", false));
+		assertEquals("testTest", StringTools.convertAllCapsToCamelCase("TEST___TEST", false));
+		assertEquals("TestTest", StringTools.convertAllCapsToCamelCase("TEST_TEST", true));
+		assertEquals("testTestTest", StringTools.convertAllCapsToCamelCase("TEST_TEST_TEST", false));
+		assertEquals("TestTestTest", StringTools.convertAllCapsToCamelCase("TEST_TEST_TEST", true));
+		assertEquals("testTestTestT", StringTools.convertAllCapsToCamelCase("TEST_TEST_TEST_T", false));
+		assertEquals("testTestTestT", StringTools.convertAllCapsToCamelCase("_TEST_TEST_TEST_T", false));
+		assertEquals("testTestTestT", StringTools.convertAllCapsToCamelCase("__TEST_TEST_TEST_T", false));
+		assertEquals("TestTestTestT", StringTools.convertAllCapsToCamelCase("TEST_TEST_TEST_T", true));
+		assertEquals("TestTestTestT", StringTools.convertAllCapsToCamelCase("_TEST_TEST_TEST_T", true));
+		assertEquals("TestTestTestT", StringTools.convertAllCapsToCamelCase("__TEST_TEST_TEST_T", true));
+	}
+
+	public void testConvertAllCapsToCamelCaseLowercase() {
+		assertEquals("test", StringTools.convertAllCapsToCamelCase("test", false));
+		assertEquals("test", StringTools.convertAllCapsToCamelCase("test_", false));
+		assertEquals("test", StringTools.convertAllCapsToCamelCase("test____", false));
+		assertEquals("Test", StringTools.convertAllCapsToCamelCase("test", true));
+		assertEquals("test", StringTools.convertAllCapsToCamelCase("test", false));
+		assertEquals("testTest", StringTools.convertAllCapsToCamelCase("test_test", false));
+		assertEquals("testTest", StringTools.convertAllCapsToCamelCase("test___test", false));
+		assertEquals("TestTest", StringTools.convertAllCapsToCamelCase("test_test", true));
+		assertEquals("testTestTest", StringTools.convertAllCapsToCamelCase("test_test_test", false));
+		assertEquals("TestTestTest", StringTools.convertAllCapsToCamelCase("test_test_test", true));
+		assertEquals("testTestTestT", StringTools.convertAllCapsToCamelCase("test_test_test_t", false));
+		assertEquals("testTestTestT", StringTools.convertAllCapsToCamelCase("_test_test_test_t", false));
+		assertEquals("testTestTestT", StringTools.convertAllCapsToCamelCase("__test_test_test_t", false));
+		assertEquals("TestTestTestT", StringTools.convertAllCapsToCamelCase("test_test_test_t", true));
+		assertEquals("TestTestTestT", StringTools.convertAllCapsToCamelCase("_test_test_test_t", true));
+		assertEquals("TestTestTestT", StringTools.convertAllCapsToCamelCase("__test_test_test_t", true));
+	}
+
+	// ********** delimiting **********
+
+	public void testIsQuoted() {
+		this.denyIsQuoted("foo");
+		this.verifyIsQuoted("\"foo\"");
+
+		this.denyIsQuoted("");
+		this.verifyIsQuoted("\"\"");
+
+		this.denyIsQuoted("\"");
+		this.denyIsQuoted(" ");
+		this.denyIsQuoted("''");
+		this.denyIsQuoted("'foo'");
+	}
+
+	private void verifyIsQuoted(String s) {
+		assertTrue(StringTools.isQuoted(s));
+	}
+
+	private void denyIsQuoted(String s) {
+		assertFalse(StringTools.isQuoted(s));
+	}
+
+	public void testIsParenthetical() {
+		this.denyIsParenthetical("foo");
+		this.verifyIsParenthetical("(foo)");
+
+		this.denyIsParenthetical("");
+		this.verifyIsParenthetical("()");
+
+		this.denyIsParenthetical("(");
+		this.denyIsParenthetical(" ");
+		this.denyIsParenthetical("''");
+		this.denyIsParenthetical("'foo'");
+	}
+
+	private void verifyIsParenthetical(String s) {
+		assertTrue(StringTools.isParenthetical(s));
+	}
+
+	private void denyIsParenthetical(String s) {
+		assertFalse(StringTools.isParenthetical(s));
+	}
+
+	public void testIsBracketed() {
+		this.denyIsBracketed("foo");
+		this.verifyIsBracketed("[foo]");
+
+		this.denyIsBracketed("");
+		this.verifyIsBracketed("[]");
+
+		this.denyIsBracketed("[");
+		this.denyIsBracketed(" ");
+		this.denyIsBracketed("''");
+		this.denyIsBracketed("'foo'");
+	}
+
+	private void verifyIsBracketed(String s) {
+		assertTrue(StringTools.isBracketed(s));
+	}
+
+	private void denyIsBracketed(String s) {
+		assertFalse(StringTools.isBracketed(s));
+	}
+
+	public void testIsBraced() {
+		this.denyIsBraced("foo");
+		this.verifyIsBraced("{foo}");
+
+		this.denyIsBraced("");
+		this.verifyIsBraced("{}");
+
+		this.denyIsBraced("{");
+		this.denyIsBraced(" ");
+		this.denyIsBraced("''");
+		this.denyIsBraced("'foo'");
+	}
+
+	private void verifyIsBraced(String s) {
+		assertTrue(StringTools.isBraced(s));
+	}
+
+	private void denyIsBraced(String s) {
+		assertFalse(StringTools.isBraced(s));
+	}
+
+	public void testIsChevroned() {
+		this.denyIsChevroned("foo");
+		this.verifyIsChevroned("<foo>");
+
+		this.denyIsChevroned("");
+		this.verifyIsChevroned("<>");
+
+		this.denyIsChevroned("{");
+		this.denyIsChevroned(" ");
+		this.denyIsChevroned("''");
+		this.denyIsChevroned("'foo'");
+	}
+
+	private void verifyIsChevroned(String s) {
+		assertTrue(StringTools.isChevroned(s));
+	}
+
+	private void denyIsChevroned(String s) {
+		assertFalse(StringTools.isChevroned(s));
+	}
+
+	public void testIsDelimited() {
+		this.denyIsDelimited("foo", '?');
+		this.verifyIsDelimited("?foo?", '?');
+
+		this.denyIsDelimited("", '?');
+		this.verifyIsDelimited("\"\"", '"');
+		this.verifyIsDelimited("?xx?", '?');
+		this.denyIsDelimited("?xx]", '?');
+
+		this.denyIsDelimited("\"", '"');
+		this.denyIsDelimited(" ", ' ');
+		this.denyIsDelimited("''", '"');
+		this.denyIsDelimited("'foo'", '?');
+	}
+
+	private void verifyIsDelimited(String s, char c) {
+		assertTrue(StringTools.isDelimited(s, c));
+	}
+
+	private void denyIsDelimited(String s, char c) {
+		assertFalse(StringTools.isDelimited(s, c));
+	}
+
+	public void testIsDelimited2() {
+		this.denyIsDelimited2("foo", '[', ']');
+		this.verifyIsDelimited2("{foo}", '{', '}');
+
+		this.denyIsDelimited2("", '[', ']');
+		this.verifyIsDelimited2("[]", '[', ']');
+		this.verifyIsDelimited2("[xx]", '[', ']');
+		this.denyIsDelimited2("?xx]", '[', ']');
+
+		this.denyIsDelimited2("\"", '[', ']');
+		this.denyIsDelimited2(" ", '[', ']');
+		this.denyIsDelimited2("''", '[', ']');
+		this.denyIsDelimited2("'foo'", '[', ']');
+	}
+
+	private void verifyIsDelimited2(String s, char start, char end) {
+		assertTrue(StringTools.isDelimited(s, start, end));
+	}
+
+	private void denyIsDelimited2(String s, char start, char end) {
+		assertFalse(StringTools.isDelimited(s, start, end));
+	}
+
+	// ********** undelimiting **********
+
+	public void testUndelimit() {
+		this.verifyUndelimit("\"foo\"", "foo");
+		this.verifyUndelimit("\"\"", "");
+		this.verifyUndelimit("'foo'", "foo");
+		this.verifyUndelimit("\"fo\"\"o\"", "fo\"o");
+		this.verifyUndelimit("\"foo\"\"\"", "foo\"");
+		this.verifyUndelimit("\"\"\"foo\"", "\"foo");
+		this.verifyUndelimit("[foo]", "foo");
+		this.verifyUndelimit("\"\"\"", "\"");
+		this.verifyUndelimit("\"foo\"bar\"", "foo\"");
+		this.verifyUndelimit("\"foo\"\"", "foo\"");
+	}
+
+	private void verifyUndelimit(String s, String expected) {
+		assertEquals(expected, StringTools.undelimit(s));
+	}
+
+	public void testUndelimitInt() {
+		this.verifyUndelimitInt("\"foo\"", 2, "o");
+		this.verifyUndelimitInt("\"\"foo\"\"", 2, "foo");
+		this.verifyUndelimitInt("'foo'", 2, "o");
+	}
+
+	private void verifyUndelimitInt(String s, int count, String expected) {
+		assertEquals(expected, StringTools.undelimit(s, count));
+	}
+
+	public void testUndelimitIntException() {
+		this.denyUndelimitInt("\"\"", 2);
+		this.denyUndelimitInt("'o'", 2);
+	}
+
+	private void denyUndelimitInt(String s, int count) {
+		boolean exCaught = false;
+		try {
+			String bogus = StringTools.undelimit(s, count);
+			fail("invalid string: " + bogus);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	// ********** converting to Java string literal **********
+
+	public void testConvertToJavaStringLiteral() {
+		this.verifyConvertToJavaStringLiteral("", "\"\"");
+		this.verifyConvertToJavaStringLiteral("\"\"", "\"\\\"\\\"\"");
+		this.verifyConvertToJavaStringLiteral("'foo'", "\"'foo'\"");
+		this.verifyConvertToJavaStringLiteral("foo\bbar", "\"foo\\bbar\"");
+		this.verifyConvertToJavaStringLiteral("foo\n\tbar", "\"foo\\n\\tbar\"");
+		this.verifyConvertToJavaStringLiteral("foo\"bar", "\"foo\\\"bar\"");
+		this.verifyConvertToJavaStringLiteral("foo\\bar", "\"foo\\\\bar\"");
+	}
+
+	private void verifyConvertToJavaStringLiteral(String s, String expected) {
+		assertEquals(expected, StringTools.convertToJavaStringLiteral(s));
+	}
+
+	public void testConvertToJavaStringLiteralContent() {
+		this.verifyConvertToJavaStringLiteralContent("", "");
+		this.verifyConvertToJavaStringLiteralContent("\"\"", "\\\"\\\"");
+		this.verifyConvertToJavaStringLiteralContent("'foo'", "'foo'");
+		this.verifyConvertToJavaStringLiteralContent("foo\bbar", "foo\\bbar");
+		this.verifyConvertToJavaStringLiteralContent("foo\n\tbar", "foo\\n\\tbar");
+		this.verifyConvertToJavaStringLiteralContent("foo\"bar", "foo\\\"bar");
+		this.verifyConvertToJavaStringLiteralContent("foo\\bar", "foo\\\\bar");
+	}
+
+	private void verifyConvertToJavaStringLiteralContent(String s, String expected) {
+		assertEquals(expected, StringTools.convertToJavaStringLiteralContent(s));
+	}
+
+	// ********** converting to XML **********
+
+	public void testConvertToXmlAttributeValue() {
+		this.verifyConvertToXmlAttributeValue("", "\"\"");
+		this.verifyConvertToXmlAttributeValue("\"", "'\"'");
+		this.verifyConvertToXmlAttributeValue("\"\"", "'\"\"'");
+		this.verifyConvertToXmlAttributeValue("'", "\"'\"");
+		this.verifyConvertToXmlAttributeValue("''", "\"''\"");
+		this.verifyConvertToXmlAttributeValue("\"'\"", "\"&quot;'&quot;\"");
+		this.verifyConvertToXmlAttributeValue("\"''\"", "\"&quot;''&quot;\"");
+		this.verifyConvertToXmlAttributeValue("'foo'", "\"'foo'\"");
+		this.verifyConvertToXmlAttributeValue("\"foo\"", "'\"foo\"'");
+		this.verifyConvertToXmlAttributeValue("\"foo\" 'bar'", "\"&quot;foo&quot; 'bar'\"");
+		this.verifyConvertToXmlAttributeValue("foo & bar", "\"foo &amp; bar\"");
+		this.verifyConvertToXmlAttributeValue("\"foo & bar\"", "'\"foo &amp; bar\"'");
+		this.verifyConvertToXmlAttributeValue("foo <<< bar", "\"foo &lt;&lt;&lt; bar\"");
+		this.verifyConvertToXmlAttributeValue("\"foo <<< bar\"", "'\"foo &lt;&lt;&lt; bar\"'");
+	}
+
+	private void verifyConvertToXmlAttributeValue(String s, String expected) {
+		assertEquals(expected, StringTools.convertToXmlAttributeValue(s));
+	}
+
+	public void testConvertToXmlElementText() {
+		this.verifyConvertToXmlElementText("", "");
+		this.verifyConvertToXmlElementText("\"", "\"");
+		this.verifyConvertToXmlElementText("\"\"", "\"\"");
+		this.verifyConvertToXmlElementText("'", "'");
+		this.verifyConvertToXmlElementText("''", "''");
+		this.verifyConvertToXmlElementText("\"'\"", "\"'\"");
+		this.verifyConvertToXmlElementText("\"''\"", "\"''\"");
+		this.verifyConvertToXmlElementText("'foo'", "'foo'");
+		this.verifyConvertToXmlElementText("foo & bar", "foo &amp; bar");
+		this.verifyConvertToXmlElementText("foo &", "foo &amp;");
+		this.verifyConvertToXmlElementText("& bar", "&amp; bar");
+		this.verifyConvertToXmlElementText("\"foo & bar\"", "\"foo &amp; bar\"");
+		this.verifyConvertToXmlElementText("foo <<< bar", "foo &lt;&lt;&lt; bar");
+		this.verifyConvertToXmlElementText("\"foo <<< bar\"", "\"foo &lt;&lt;&lt; bar\"");
+	}
+
+	private void verifyConvertToXmlElementText(String s, String expected) {
+		assertEquals(expected, StringTools.convertToXmlElementText(s));
+	}
+
+	public void testConvertToXmlElementCDATA() {
+		String START = "<![CDATA[";
+		String END = "]]>";
+		this.verifyConvertToXmlElementCDATA("", START + END);
+		this.verifyConvertToXmlElementCDATA("\"", START + "\"" + END);
+		this.verifyConvertToXmlElementCDATA("\"\"", START + "\"\"" + END);
+		this.verifyConvertToXmlElementCDATA("'", START + "'" + END);
+		this.verifyConvertToXmlElementCDATA("''", START + "''" + END);
+		this.verifyConvertToXmlElementCDATA("\"'\"", START + "\"'\"" + END);
+		this.verifyConvertToXmlElementCDATA("\"''\"", START + "\"''\"" + END);
+		this.verifyConvertToXmlElementCDATA("'foo'", START + "'foo'" + END);
+		this.verifyConvertToXmlElementCDATA("foo & bar", START + "foo & bar" + END);
+		this.verifyConvertToXmlElementCDATA("foo &", START + "foo &" + END);
+		this.verifyConvertToXmlElementCDATA("& bar", START + "& bar" + END);
+		this.verifyConvertToXmlElementCDATA("\"foo & bar\"", START + "\"foo & bar\"" + END);
+		this.verifyConvertToXmlElementCDATA("foo <<< bar", START + "foo <<< bar" + END);
+		this.verifyConvertToXmlElementCDATA("\"foo <<< bar\"", START + "\"foo <<< bar\"" + END);
+		this.verifyConvertToXmlElementCDATA("\"foo <&< bar\"", START + "\"foo <&< bar\"" + END);
+		this.verifyConvertToXmlElementCDATA("\"foo <]< bar\"", START + "\"foo <]< bar\"" + END);
+		this.verifyConvertToXmlElementCDATA("\"foo <]]< bar\"", START + "\"foo <]]< bar\"" + END);
+		this.verifyConvertToXmlElementCDATA("\"foo <]]>< bar\"", START + "\"foo <]]&gt;< bar\"" + END);
+		this.verifyConvertToXmlElementCDATA("foo <]", START + "foo <]" + END);
+		this.verifyConvertToXmlElementCDATA("foo <]]", START + "foo <]]" + END);
+		this.verifyConvertToXmlElementCDATA("foo <]]>", START + "foo <]]&gt;" + END);
+		this.verifyConvertToXmlElementCDATA("]foo", START + "]foo" + END);
+		this.verifyConvertToXmlElementCDATA("]]foo", START + "]]foo" + END);
+		this.verifyConvertToXmlElementCDATA("]]>foo", START + "]]&gt;foo" + END);
+	}
+
+	private void verifyConvertToXmlElementCDATA(String s, String expected) {
+		assertEquals(expected, StringTools.convertToXmlElementCDATA(s));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/SystemToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/SystemToolsTests.java
new file mode 100644
index 0000000..3c5e9b2
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/SystemToolsTests.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.SystemTools;
+
+
+@SuppressWarnings("nls")
+public class SystemToolsTests
+	extends TestCase
+{
+	public SystemToolsTests(String name) {
+		super(name);
+	}
+
+	public void testJavaSpecificationVersionIsGreaterThan() {
+		String version = SystemTools.javaSpecificationVersion();
+		if (version.equals("1.4")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsGreaterThan("1.3"));
+		} else if(version.equals("1.5")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsGreaterThan("1.4"));
+		} else if(version.equals("1.6")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsGreaterThan("1.5"));
+		} else if(version.equals("1.7")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsGreaterThan("1.6"));
+		} else {
+			fail("untested Java specification version: " + version);
+		}
+	}
+
+	public void testJavaSpecificationVersionIsLessThan() {
+		String version = SystemTools.javaSpecificationVersion();
+		if (version.equals("1.4")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsLessThan("1.5"));
+		} else if(version.equals("1.5")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsLessThan("1.6"));
+		} else if(version.equals("1.6")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsLessThan("1.7"));
+		} else if(version.equals("1.7")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsLessThan("2.0"));
+		} else {
+			fail("untested Java specification version: " + version);
+		}
+	}
+
+	public void testJavaSpecificationVersionIsGreaterThanOrEqualTo() {
+		String version = SystemTools.javaSpecificationVersion();
+		if (version.equals("1.4")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsGreaterThanOrEqualTo("1.3"));
+			assertTrue(SystemTools.javaSpecificationVersionIsGreaterThanOrEqualTo("1.4"));
+		} else if(version.equals("1.5")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsGreaterThanOrEqualTo("1.4"));
+		} else if(version.equals("1.6")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsGreaterThanOrEqualTo("1.5"));
+			assertTrue(SystemTools.javaSpecificationVersionIsGreaterThanOrEqualTo("1.6"));
+		} else if(version.equals("1.7")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsGreaterThanOrEqualTo("1.6"));
+			assertTrue(SystemTools.javaSpecificationVersionIsGreaterThanOrEqualTo("1.7"));
+		} else {
+			fail("untested Java specification version: " + version);
+		}
+	}
+
+	public void testJavaSpecificationVersionIsLessThanOrEqualTo() {
+		String version = SystemTools.javaSpecificationVersion();
+		if (version.equals("1.4")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsLessThanOrEqualTo("1.5"));
+			assertTrue(SystemTools.javaSpecificationVersionIsLessThanOrEqualTo("1.4"));
+		} else if(version.equals("1.5")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsLessThanOrEqualTo("1.5"));
+			assertTrue(SystemTools.javaSpecificationVersionIsLessThanOrEqualTo("1.6"));
+		} else if(version.equals("1.6")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsLessThanOrEqualTo("1.6"));
+			assertTrue(SystemTools.javaSpecificationVersionIsLessThanOrEqualTo("1.7"));
+		} else if(version.equals("1.7")) {
+			assertTrue(SystemTools.javaSpecificationVersionIsLessThanOrEqualTo("1.7"));
+			assertTrue(SystemTools.javaSpecificationVersionIsLessThanOrEqualTo("2.0"));
+		} else {
+			fail("untested Java specification version: " + version);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/TestCommand.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/TestCommand.java
new file mode 100644
index 0000000..f0db82d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/TestCommand.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+/**
+ * Command that can be used to execute tests; i.e. a command that allows its
+ * implementation to throw exceptions.
+ */
+public interface TestCommand {
+	void execute() throws Exception;
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/TestTools.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/TestTools.java
new file mode 100644
index 0000000..edf65cf
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/TestTools.java
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import junit.framework.TestCase;
+import junit.framework.TestFailure;
+import junit.framework.TestResult;
+import org.eclipse.persistence.tools.utility.ClassTools;
+import org.junit.Assert;
+
+/**
+ * Various tools that can be used by test cases.
+ */
+@SuppressWarnings("nls")
+public final class TestTools {
+
+	/**
+	 * Convenience method that handles {@link InterruptedException}.
+	 */
+	public static void sleep(long millis) {
+		try {
+			Thread.sleep(millis);
+		} catch (InterruptedException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+	/**
+	 * Execute the specified command. If it throws an exception, re-execute it
+	 * repeatedly until it executes without an exception.
+	 * There will be a one-second delay between each execution.
+	 * This is useful when calling third-party code that intermittently throws
+	 * exceptions but will <em>eventually</em> execute successfully (e.g. when
+	 * there are problems deleting files).
+	 */
+	public static void execute(TestCommand command) {
+		execute(command, -1);
+	}
+
+	/**
+	 * Execute the specified command. If it throws an exception, re-execute it
+	 * repeatedly until it executes without an exception. Execute the command
+	 * up to the specified number of attempts.
+	 * There will be a one-second delay between each execution.
+	 * This is useful when calling third-party code that intermittently throws
+	 * exceptions but will <em>eventually</em> execute successfully (e.g. when
+	 * there are problems deleting files).
+	 */
+	public static void execute(TestCommand command, int attempts) {
+		execute(command, attempts, 1000);
+	}
+
+	/**
+	 * Execute the specified command. If it throws an exception, re-execute it
+	 * repeatedly until it executes without an exception. Execute the command
+	 * up to the specified number of attemptsl with specified delay between
+	 * each execution.
+	 * This is useful when calling third-party code that intermittently throws
+	 * exceptions but will <em>eventually</em> execute successfully (e.g. when
+	 * there are problems deleting files).
+	 */
+	public static void execute(TestCommand command, int attempts, long delay) {
+		for (int i = 1; i <= attempts; i++) {  // NB: start with 1
+			try {
+				command.execute();
+				return;
+			} catch (Exception ex) {
+				if ((attempts != -1) && (i == attempts)) {
+					throw new RuntimeException("attempts: " + i, ex);
+				}
+				sleep(delay);
+			}
+		}
+	}
+
+	/**
+	 * Check whether the specified char array contains the same characters as
+	 * the expected string. Throw an exception if they do not.
+	 */
+	public static void assertEquals(String expected, char[] actual) {
+		Assert.assertEquals(expected, (actual == null) ? null : new String(actual));
+	}
+
+	/**
+	 * Check whether the specified byte array contains the same characters as
+	 * the expected string. Throw an exception if they do not.
+	 */
+	public static void assertEquals(String expected, byte[] actual) {
+		Assert.assertEquals(expected, (actual == null) ? null : new String(actual));
+	}
+
+	/**
+	 * Test an object's implementation of {@link java.io.Serializable} by serializing the
+	 * specified object to a byte array; then de-serializing the byte array and
+	 * returning the resultant object.
+	 */
+	public static <T> T serialize(T o) throws IOException, ClassNotFoundException {
+		ByteArrayOutputStream baOutStream = new ByteArrayOutputStream(2000);
+		ObjectOutputStream outStream = new ObjectOutputStream(baOutStream);
+		outStream.writeObject(o);
+		outStream.close();
+
+		ByteArrayInputStream baInStream = new ByteArrayInputStream(baOutStream.toByteArray());
+		ObjectInputStream inStream = new ObjectInputStream(baInStream);
+		T o2 = readObject(inStream);
+		inStream.close();
+
+		return o2;
+	}
+
+	@SuppressWarnings("unchecked")
+	private static <T> T readObject(ObjectInput objectInput) throws IOException, ClassNotFoundException {
+		return (T) objectInput.readObject();
+	}
+
+	/**
+	 * Redirect std out and std err to the specified stream.
+	 */
+	public static void redirectSystemStreamsTo(OutputStream outputStream) {
+		redirectSystemStreamsTo(new PrintStream(outputStream));
+	}
+
+	/**
+	 * Redirect std out and std err to the specified stream.
+	 */
+	public static void redirectSystemStreamsTo(PrintStream printStream) {
+		System.setOut(printStream);
+		System.setErr(printStream);
+	}
+
+	/**
+	 * Sort and print out all the current Java System properties on the
+	 * console.
+	 */
+	public static void printSystemProperties() {
+		synchronized (System.out) {
+			printSystemPropertiesOn(System.out);
+		}
+	}
+
+	/**
+	 * Sort and print out all the current Java System properties on the
+	 * specified print stream.
+	 */
+	public static void printSystemPropertiesOn(PrintStream stream) {
+		SortedSet<String> sortedKeys = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
+		for (Object key : System.getProperties().keySet()) {
+			sortedKeys.add((String) key);
+		}
+		for (String key : sortedKeys) {
+			stream.print(key);
+			stream.print(" => ");
+			stream.print(System.getProperty(key));
+			stream.println();
+		}
+	}
+
+	/**
+	 * Execute the specified test and return a text output of its results.
+	 */
+	public static String execute(TestCase testCase) {
+		long start = System.currentTimeMillis();
+		TestResult result = testCase.run();
+		long end = System.currentTimeMillis();
+
+		StringWriter stringWriter = new StringWriter();
+		PrintWriter writer = new PrintWriter(stringWriter);
+		writer.print(testCase.getName());
+		writer.print(": ");
+		if (result.wasSuccessful()) {
+			writer.println("OK");
+		} else {
+			TestFailure failure = null;
+			if (result.failures().hasMoreElements()) {
+				failure = result.failures().nextElement();
+			} else {
+				failure = result.errors().nextElement();
+			}
+			failure.thrownException().printStackTrace(writer);
+		}
+		writer.print("elapsed time: ");
+		long elapsed = end - start;
+		writer.print(elapsed / 1000L);
+		writer.println(" sec.");
+		return stringWriter.toString();
+	}
+
+	/**
+	 * Clear out all the instance variable of the specified test case, allowing
+	 * the various test fixtures to be garbage-collected. Typically this is
+	 * called in the test case's implementation of {@link TestCase#tearDown()}.
+	 */
+	public static void clear(TestCase testCase) throws IllegalAccessException {
+		for (Class<?> clazz = testCase.getClass(); clazz != TestCase_class; clazz = clazz.getSuperclass()) {
+			for (Field field : clazz.getDeclaredFields()) {
+				// leave primitives alone - they don't get garbage-collected,
+				// and we can't set them to null...
+				if (field.getType().isPrimitive()) {
+					continue;
+				}
+				// leave static fields alone (?)
+				if (Modifier.isStatic(field.getModifiers())) {
+					continue;
+				}
+				field.setAccessible(true);
+				field.set(testCase, null);
+			}
+		}
+	}
+
+	private static final Class<TestCase> TestCase_class = TestCase.class;
+
+	/**
+	 * Return the value of the specified class's <code>DEBUG</code> constant.
+	 */
+	public static boolean debug(Class<?> clazz) {
+		Boolean debug = (Boolean) ClassTools.get(clazz, "DEBUG");
+		return debug.booleanValue();
+	}
+
+	/**
+	 * Verify the specified class's <code>DEBUG</code> constant is set to
+	 * <code>false</code>.
+	 */
+	public static void assertFalseDEBUG(Class<?> clazz) {
+		Assert.assertFalse("Recompile with \"DEBUG = false\": " + clazz.getName(), debug(clazz));
+	}
+
+	/**
+	 * Workaround for a JUnit bug: JUnit does not configure the testing {@link Thread}
+	 * with a context class loader. This should probably happen in
+	 * {@link junit.textui.TestRunner#doRun(junit.framework.Test)}, just before starting the thread.
+	 */
+	public static void setUpJUnitThreadContextClassLoader() {
+		Thread.currentThread().setContextClassLoader(TestTools.class.getClassLoader());
+	}
+
+	/**
+	 * suppressed constructor
+	 */
+	private TestTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/TypeDeclarationToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/TypeDeclarationToolsTests.java
new file mode 100644
index 0000000..c229830
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/TypeDeclarationToolsTests.java
@@ -0,0 +1,339 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.SystemTools;
+import org.eclipse.persistence.tools.utility.TypeDeclarationTools;
+
+
+@SuppressWarnings("nls")
+public class TypeDeclarationToolsTests
+	extends TestCase
+{
+	public TypeDeclarationToolsTests(String name) {
+		super(name);
+	}
+
+	public void testIsArrayString() throws Exception {
+		assertFalse(TypeDeclarationTools.isArray("java.lang.Object"));
+		assertTrue(TypeDeclarationTools.isArray("java.lang.Object[]"));
+		assertTrue(TypeDeclarationTools.isArray("java.lang.Object[][][]"));
+
+		assertFalse(TypeDeclarationTools.isArray("int"));
+		assertTrue(TypeDeclarationTools.isArray("int[]"));
+		assertTrue(TypeDeclarationTools.isArray("int[][][]"));
+
+		assertFalse(TypeDeclarationTools.isArray("float"));
+		assertTrue(TypeDeclarationTools.isArray("float [ ]"));
+		assertTrue(TypeDeclarationTools.isArray("float[] [] []"));
+	}
+
+	public void testIsArrayCharArray() throws Exception {
+		assertFalse(TypeDeclarationTools.isArray("java.lang.Object".toCharArray()));
+		assertTrue(TypeDeclarationTools.isArray("java.lang.Object[]".toCharArray()));
+		assertTrue(TypeDeclarationTools.isArray("java.lang.Object[][][]".toCharArray()));
+
+		assertFalse(TypeDeclarationTools.isArray("int".toCharArray()));
+		assertTrue(TypeDeclarationTools.isArray("int[]".toCharArray()));
+		assertTrue(TypeDeclarationTools.isArray("int[][][]".toCharArray()));
+
+		assertFalse(TypeDeclarationTools.isArray("float".toCharArray()));
+		assertTrue(TypeDeclarationTools.isArray("float [ ]".toCharArray()));
+		assertTrue(TypeDeclarationTools.isArray("float[] [] []".toCharArray()));
+	}
+
+	public void testArrayDepthString() throws Exception {
+		assertEquals(0, TypeDeclarationTools.arrayDepth("java.lang.Object"));
+		assertEquals(1, TypeDeclarationTools.arrayDepth("java.lang.Object[]"));
+		assertEquals(3, TypeDeclarationTools.arrayDepth("java.lang.Object[][][]"));
+
+		assertEquals(0, TypeDeclarationTools.arrayDepth("int"));
+		assertEquals(1, TypeDeclarationTools.arrayDepth("int[]"));
+		assertEquals(3, TypeDeclarationTools.arrayDepth("int[][][]"));
+
+		assertEquals(0, TypeDeclarationTools.arrayDepth("float"));
+		assertEquals(1, TypeDeclarationTools.arrayDepth("float [ ]"));
+		assertEquals(3, TypeDeclarationTools.arrayDepth("float[] [] []"));
+	}
+
+	public void testArrayDepthCharArray() throws Exception {
+		assertEquals(0, TypeDeclarationTools.arrayDepth("java.lang.Object".toCharArray()));
+		assertEquals(1, TypeDeclarationTools.arrayDepth("java.lang.Object[]".toCharArray()));
+		assertEquals(3, TypeDeclarationTools.arrayDepth("java.lang.Object[][][]".toCharArray()));
+
+		assertEquals(0, TypeDeclarationTools.arrayDepth("int".toCharArray()));
+		assertEquals(1, TypeDeclarationTools.arrayDepth("int[]".toCharArray()));
+		assertEquals(3, TypeDeclarationTools.arrayDepth("int[][][]".toCharArray()));
+
+		assertEquals(0, TypeDeclarationTools.arrayDepth("float".toCharArray()));
+		assertEquals(1, TypeDeclarationTools.arrayDepth("float [ ]".toCharArray()));
+		assertEquals(3, TypeDeclarationTools.arrayDepth("float[] [] []".toCharArray()));
+	}
+
+	public void testElementTypeNameString() throws Exception {
+		assertEquals("java.lang.Object", TypeDeclarationTools.elementTypeName("java.lang.Object"));
+		assertEquals("java.lang.Object", TypeDeclarationTools.elementTypeName("java.lang.Object[]"));
+		assertEquals("java.lang.Object", TypeDeclarationTools.elementTypeName("java.lang.Object[][][]"));
+
+		assertEquals("int", TypeDeclarationTools.elementTypeName("int"));
+		assertEquals("int", TypeDeclarationTools.elementTypeName("int[]"));
+		assertEquals("int", TypeDeclarationTools.elementTypeName("int[][][]"));
+
+		assertEquals("float", TypeDeclarationTools.elementTypeName("float"));
+		assertEquals("float", TypeDeclarationTools.elementTypeName("float [ ]"));
+		assertEquals("float", TypeDeclarationTools.elementTypeName("float[] [] []"));
+	}
+
+	public void testElementTypeNameCharArray() throws Exception {
+		TestTools.assertEquals("java.lang.Object", TypeDeclarationTools.elementTypeName("java.lang.Object".toCharArray()));
+		TestTools.assertEquals("java.lang.Object", TypeDeclarationTools.elementTypeName("java.lang.Object[]".toCharArray()));
+		TestTools.assertEquals("java.lang.Object", TypeDeclarationTools.elementTypeName("java.lang.Object[][][]".toCharArray()));
+
+		TestTools.assertEquals("int", TypeDeclarationTools.elementTypeName("int".toCharArray()));
+		TestTools.assertEquals("int", TypeDeclarationTools.elementTypeName("int[]".toCharArray()));
+		TestTools.assertEquals("int", TypeDeclarationTools.elementTypeName("int[][][]".toCharArray()));
+
+		TestTools.assertEquals("float", TypeDeclarationTools.elementTypeName("float".toCharArray()));
+		TestTools.assertEquals("float", TypeDeclarationTools.elementTypeName("float [ ]".toCharArray()));
+		TestTools.assertEquals("float", TypeDeclarationTools.elementTypeName("float[] [] []".toCharArray()));
+	}
+
+	public void testComponentTypeDeclarationString() throws Exception {
+		assertEquals(null, TypeDeclarationTools.componentTypeDeclaration("java.lang.Object"));
+		assertEquals("java.lang.Object", TypeDeclarationTools.componentTypeDeclaration("java.lang.Object[]"));
+		assertEquals("java.lang.Object[][]", TypeDeclarationTools.componentTypeDeclaration("java.lang.Object[][][]"));
+
+		assertEquals(null, TypeDeclarationTools.componentTypeDeclaration("int"));
+		assertEquals("int", TypeDeclarationTools.componentTypeDeclaration("int[]"));
+		assertEquals("int[][]", TypeDeclarationTools.componentTypeDeclaration("int[][][]"));
+
+		assertEquals(null, TypeDeclarationTools.componentTypeDeclaration("float"));
+		assertEquals("float", TypeDeclarationTools.componentTypeDeclaration("float [ ]"));
+		assertEquals("float[][]", TypeDeclarationTools.componentTypeDeclaration("float[] [] []"));
+	}
+
+	public void testComponentTypeDeclarationCharArray() throws Exception {
+		TestTools.assertEquals(null, TypeDeclarationTools.componentTypeDeclaration("java.lang.Object".toCharArray()));
+		TestTools.assertEquals("java.lang.Object", TypeDeclarationTools.componentTypeDeclaration("java.lang.Object[]".toCharArray()));
+		TestTools.assertEquals("java.lang.Object[][]", TypeDeclarationTools.componentTypeDeclaration("java.lang.Object[][][]".toCharArray()));
+
+		TestTools.assertEquals(null, TypeDeclarationTools.componentTypeDeclaration("int".toCharArray()));
+		TestTools.assertEquals("int", TypeDeclarationTools.componentTypeDeclaration("int[]".toCharArray()));
+		TestTools.assertEquals("int[][]", TypeDeclarationTools.componentTypeDeclaration("int[][][]".toCharArray()));
+
+		TestTools.assertEquals(null, TypeDeclarationTools.componentTypeDeclaration("float".toCharArray()));
+		TestTools.assertEquals("float", TypeDeclarationTools.componentTypeDeclaration("float [ ]".toCharArray()));
+		TestTools.assertEquals("float[][]", TypeDeclarationTools.componentTypeDeclaration("float[] [] []".toCharArray()));
+	}
+
+	public void testClassNameString() throws Exception {
+		assertEquals("int", TypeDeclarationTools.className("int"));
+		assertEquals("[I", TypeDeclarationTools.className("int[]"));
+		assertEquals("[[I", TypeDeclarationTools.className("int [ ] [ ]"));
+
+		assertEquals("java.lang.Object", TypeDeclarationTools.className("java.lang.Object"));
+		assertEquals("[Ljava.lang.Object;", TypeDeclarationTools.className("java.lang.Object\t[]"));
+		assertEquals("[[Ljava.lang.Object;", TypeDeclarationTools.className("java.lang.Object\t[]\t[]"));
+	}
+
+	public void testClassNameCharArray() throws Exception {
+		TestTools.assertEquals("int", TypeDeclarationTools.className("int".toCharArray()));
+		TestTools.assertEquals("[I", TypeDeclarationTools.className("int[]".toCharArray()));
+		TestTools.assertEquals("[[I", TypeDeclarationTools.className("int [ ] [ ]".toCharArray()));
+
+		TestTools.assertEquals("java.lang.Object", TypeDeclarationTools.className("java.lang.Object".toCharArray()));
+		TestTools.assertEquals("[Ljava.lang.Object;", TypeDeclarationTools.className("java.lang.Object\t[]".toCharArray()));
+		TestTools.assertEquals("[[Ljava.lang.Object;", TypeDeclarationTools.className("java.lang.Object\t[]\t[]".toCharArray()));
+	}
+
+	public void testClassNameStringInt() throws Exception {
+		assertEquals(int.class.getName(), TypeDeclarationTools.className("int", 0));
+		assertEquals(int[].class.getName(), TypeDeclarationTools.className("int", 1));
+		assertEquals(int[][][].class.getName(), TypeDeclarationTools.className("int", 3));
+
+		assertEquals(Object.class.getName(), TypeDeclarationTools.className("java.lang.Object", 0));
+		assertEquals(Object[][][].class.getName(), TypeDeclarationTools.className("java.lang.Object", 3));
+
+		assertEquals(void.class.getName(), TypeDeclarationTools.className("void", 0));
+		try {
+			TypeDeclarationTools.className(void.class.getName(), 1);
+			fail("should not get here...");
+		} catch (IllegalArgumentException ex) {
+			// expected
+		}
+	}
+
+	public void testClassNameCharArrayInt() throws Exception {
+		TestTools.assertEquals(int.class.getName(), TypeDeclarationTools.className("int".toCharArray(), 0));
+		TestTools.assertEquals(int[].class.getName(), TypeDeclarationTools.className("int".toCharArray(), 1));
+		TestTools.assertEquals(int[][][].class.getName(), TypeDeclarationTools.className("int".toCharArray(), 3));
+
+		TestTools.assertEquals(Object.class.getName(), TypeDeclarationTools.className("java.lang.Object".toCharArray(), 0));
+		TestTools.assertEquals(Object[][][].class.getName(), TypeDeclarationTools.className("java.lang.Object".toCharArray(), 3));
+
+		TestTools.assertEquals(void.class.getName(), TypeDeclarationTools.className("void".toCharArray(), 0));
+		try {
+			TypeDeclarationTools.className(void.class.getName().toCharArray(), 1);
+			fail("should not get here...");
+		} catch (IllegalArgumentException ex) {
+			// expected
+		}
+	}
+
+	public void testSimpleNameString() throws Exception {
+		assertEquals("int", TypeDeclarationTools.simpleName("int"));
+		assertEquals("int[]", TypeDeclarationTools.simpleName("int[]"));
+		assertEquals("int[][]", TypeDeclarationTools.simpleName("int [ ] [ ]"));
+
+		assertEquals("Object", TypeDeclarationTools.simpleName("java.lang.Object"));
+		assertEquals("Object[]", TypeDeclarationTools.simpleName("java.lang.Object\t[]"));
+		assertEquals("Object[][]", TypeDeclarationTools.simpleName("java.lang.Object\t[]\t[]"));
+
+		assertEquals("Default", TypeDeclarationTools.simpleName("Default"));
+		assertEquals("Default[]", TypeDeclarationTools.simpleName("Default\t[]"));
+		assertEquals("Default[][]", TypeDeclarationTools.simpleName("Default\t[]\t[]"));
+	}
+
+	public void testSimpleNameCharArray() throws Exception {
+		TestTools.assertEquals("int", TypeDeclarationTools.simpleName("int".toCharArray()));
+		TestTools.assertEquals("int[]", TypeDeclarationTools.simpleName("int[]".toCharArray()));
+		TestTools.assertEquals("int[][]", TypeDeclarationTools.simpleName("int [ ] [ ]".toCharArray()));
+
+		TestTools.assertEquals("Object", TypeDeclarationTools.simpleName("java.lang.Object".toCharArray()));
+		TestTools.assertEquals("Object[]", TypeDeclarationTools.simpleName("java.lang.Object\t[]".toCharArray()));
+		TestTools.assertEquals("Object[][]", TypeDeclarationTools.simpleName("java.lang.Object\t[]\t[]".toCharArray()));
+
+		TestTools.assertEquals("Default", TypeDeclarationTools.simpleName("Default".toCharArray()));
+		TestTools.assertEquals("Default[]", TypeDeclarationTools.simpleName("Default\t[]".toCharArray()));
+		TestTools.assertEquals("Default[][]", TypeDeclarationTools.simpleName("Default\t[]\t[]".toCharArray()));
+	}
+
+	public void testPackageNameString() throws Exception {
+		assertEquals("", TypeDeclarationTools.packageName("int"));
+		assertEquals("", TypeDeclarationTools.packageName("int[]"));
+		assertEquals("", TypeDeclarationTools.packageName("int [ ] [ ]"));
+
+		assertEquals("java.lang", TypeDeclarationTools.packageName("java.lang.Object"));
+		assertEquals("", TypeDeclarationTools.packageName("java.lang.Object\t[]"));
+		assertEquals("", TypeDeclarationTools.packageName("java.lang.Object\t[]\t[]"));
+
+		assertEquals("", TypeDeclarationTools.packageName("Default"));
+		assertEquals("", TypeDeclarationTools.packageName("Default\t[]"));
+		assertEquals("", TypeDeclarationTools.packageName("Default\t[]\t[]"));
+	}
+
+	public void testPackageNameCharArray() throws Exception {
+		TestTools.assertEquals("", TypeDeclarationTools.packageName("int".toCharArray()));
+		TestTools.assertEquals("", TypeDeclarationTools.packageName("int[]".toCharArray()));
+		TestTools.assertEquals("", TypeDeclarationTools.packageName("int [ ] [ ]".toCharArray()));
+
+		TestTools.assertEquals("java.lang", TypeDeclarationTools.packageName("java.lang.Object".toCharArray()));
+		TestTools.assertEquals("", TypeDeclarationTools.packageName("java.lang.Object\t[]".toCharArray()));
+		TestTools.assertEquals("", TypeDeclarationTools.packageName("java.lang.Object\t[]\t[]".toCharArray()));
+
+		TestTools.assertEquals("", TypeDeclarationTools.packageName("Default".toCharArray()));
+		TestTools.assertEquals("", TypeDeclarationTools.packageName("Default\t[]".toCharArray()));
+		TestTools.assertEquals("", TypeDeclarationTools.packageName("Default\t[]\t[]".toCharArray()));
+	}
+
+	public void testLoadClassString() throws Exception {
+		assertEquals(int.class, TypeDeclarationTools.loadClass("int"));
+		assertEquals(int[].class, TypeDeclarationTools.loadClass("int[]"));
+		assertEquals(int[][].class, TypeDeclarationTools.loadClass("int [ ] [ ]"));
+
+		assertEquals(java.lang.Object.class, TypeDeclarationTools.loadClass("java.lang.Object"));
+		assertEquals(java.lang.Object[].class, TypeDeclarationTools.loadClass("java.lang.Object\t[]"));
+		assertEquals(java.lang.Object[][].class, TypeDeclarationTools.loadClass("java.lang.Object\t[]\t[]"));
+	}
+
+	public void testLoadClassCharArray() throws Exception {
+		assertEquals(int.class, TypeDeclarationTools.loadClass("int".toCharArray()));
+		assertEquals(int[].class, TypeDeclarationTools.loadClass("int[]".toCharArray()));
+		assertEquals(int[][].class, TypeDeclarationTools.loadClass("int [ ] [ ]".toCharArray()));
+
+		assertEquals(java.lang.Object.class, TypeDeclarationTools.loadClass("java.lang.Object".toCharArray()));
+		assertEquals(java.lang.Object[].class, TypeDeclarationTools.loadClass("java.lang.Object\t[]".toCharArray()));
+		assertEquals(java.lang.Object[][].class, TypeDeclarationTools.loadClass("java.lang.Object\t[]\t[]".toCharArray()));
+	}
+
+	public void testIsJavaLangClassString() {
+		assertTrue(TypeDeclarationTools.isJavaLangClass("Object"));
+		assertTrue(TypeDeclarationTools.isJavaLangClass("String"));
+		assertTrue(TypeDeclarationTools.isJavaLangClass("AutoCloseable"));
+		assertFalse(TypeDeclarationTools.isJavaLangClass(""));
+		assertFalse(TypeDeclarationTools.isJavaLangClass("Collection"));
+	}
+
+	public void testIsJavaLangClassCharArray() {
+		assertTrue(TypeDeclarationTools.isJavaLangClass("Object".toCharArray()));
+		assertTrue(TypeDeclarationTools.isJavaLangClass("String".toCharArray()));
+		assertTrue(TypeDeclarationTools.isJavaLangClass("AutoCloseable".toCharArray()));
+		assertFalse(TypeDeclarationTools.isJavaLangClass("".toCharArray()));
+		assertFalse(TypeDeclarationTools.isJavaLangClass("Collection".toCharArray()));
+	}
+
+	public void testIsJavaLangClass5String() {
+		assertTrue(TypeDeclarationTools.isJavaLangClass5("Object"));
+		assertTrue(TypeDeclarationTools.isJavaLangClass5("String"));
+		assertFalse(TypeDeclarationTools.isJavaLangClass5("AutoCloseable"));
+		assertFalse(TypeDeclarationTools.isJavaLangClass5(""));
+		assertFalse(TypeDeclarationTools.isJavaLangClass5("Collection"));
+	}
+
+	public void testIsJavaLangClass5CharArray() {
+		assertTrue(TypeDeclarationTools.isJavaLangClass5("Object".toCharArray()));
+		assertTrue(TypeDeclarationTools.isJavaLangClass5("String".toCharArray()));
+		assertFalse(TypeDeclarationTools.isJavaLangClass5("AutoCloseable".toCharArray()));
+		assertFalse(TypeDeclarationTools.isJavaLangClass5("".toCharArray()));
+		assertFalse(TypeDeclarationTools.isJavaLangClass5("Collection".toCharArray()));
+	}
+
+	public void testIsJavaLangClass6String() {
+		assertTrue(TypeDeclarationTools.isJavaLangClass6("Object"));
+		assertTrue(TypeDeclarationTools.isJavaLangClass6("String"));
+		assertFalse(TypeDeclarationTools.isJavaLangClass6("AutoCloseable"));
+		assertFalse(TypeDeclarationTools.isJavaLangClass6(""));
+		assertFalse(TypeDeclarationTools.isJavaLangClass6("Collection"));
+	}
+
+	public void testIsJavaLangClass6CharArray() {
+		assertTrue(TypeDeclarationTools.isJavaLangClass6("Object".toCharArray()));
+		assertTrue(TypeDeclarationTools.isJavaLangClass6("String".toCharArray()));
+		assertFalse(TypeDeclarationTools.isJavaLangClass6("AutoCloseable".toCharArray()));
+		assertFalse(TypeDeclarationTools.isJavaLangClass6("".toCharArray()));
+		assertFalse(TypeDeclarationTools.isJavaLangClass6("Collection".toCharArray()));
+	}
+
+	public void testIsJavaLangClass7String() {
+		assertTrue(TypeDeclarationTools.isJavaLangClass7("Object"));
+		assertTrue(TypeDeclarationTools.isJavaLangClass7("String"));
+		assertTrue(TypeDeclarationTools.isJavaLangClass7("AutoCloseable"));
+		assertFalse(TypeDeclarationTools.isJavaLangClass7(""));
+		assertFalse(TypeDeclarationTools.isJavaLangClass7("Collection"));
+	}
+
+	public void testIsJavaLangClass7CharArray() {
+		assertTrue(TypeDeclarationTools.isJavaLangClass7("Object".toCharArray()));
+		assertTrue(TypeDeclarationTools.isJavaLangClass7("String".toCharArray()));
+		assertTrue(TypeDeclarationTools.isJavaLangClass7("AutoCloseable".toCharArray()));
+		assertFalse(TypeDeclarationTools.isJavaLangClass7("".toCharArray()));
+		assertFalse(TypeDeclarationTools.isJavaLangClass7("Collection".toCharArray()));
+	}
+
+	public void testJDKVersion() {
+		assertTrue("update TypeDeclarationTools.JAVA_LANG_CLASS_NAMES for new JDK...",
+				SystemTools.javaSpecificationVersionIsLessThanOrEqualTo("1.7"));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/VersionComparatorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/VersionComparatorTests.java
new file mode 100644
index 0000000..59d0d5a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/VersionComparatorTests.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Comparator;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.VersionComparator;
+import org.eclipse.persistence.tools.utility.VersionComparator.SegmentParser;
+
+
+@SuppressWarnings("nls")
+public class VersionComparatorTests
+	extends TestCase
+{
+	public VersionComparatorTests(String name) {
+		super(name);
+	}
+
+	public void testVersionIsEqual_integer() {
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.0", "2.0.0") == 0);
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.0", "2.0.0.0") == 0);
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.0.0.0.0.0000", "2.0") == 0);
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.-1", "2.0.-1") == 0);
+	}
+
+	public void testVersionIsLess_integer() {
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.0", "2.0.1") < 0);
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.5.0", "2.14") < 0);
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.5.0", "2.5.0.0.1.0") < 0);
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.5.0.0.0.-1", "2.5") < 0);
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.-1", "2.0.0") < 0);
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.-1", "2") < 0);
+	}
+
+	public void testVersionIsGreater_integer() {
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.2", "2.0.1") > 0);
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.2", "2.0.1") > 0);
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.5.0.0.1.0", "2.5.0") > 0);
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.5", "2.5.0.0.0.-1") > 0);
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.0", "2.0.-1") > 0);
+		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2", "2.0.-1") > 0);
+	}
+
+	public void testVersionIsEqual_integer_comma() {
+		Comparator<String> versionComparator = new VersionComparator<BigDecimal>(",", DecimalSegmentParser.instance());
+		assertTrue(versionComparator.compare("2,0,0", "2,0,0") == 0);
+		assertTrue(versionComparator.compare("2,0.0,0", "2,0,0") == 0);
+		assertTrue(versionComparator.compare("2,0.0,0", "2,0,0.0") == 0);
+		assertTrue(versionComparator.compare("2.0,0.0,0", "2,0,0.0") == 0);
+	}
+
+	public void testVersionIsLess_integer_comma() {
+		Comparator<String> versionComparator = new VersionComparator<BigDecimal>(",", DecimalSegmentParser.instance());
+		assertTrue(versionComparator.compare("2,0,0", "2,0,1") < 0);
+		assertTrue(versionComparator.compare("2,0.0,0", "2,0,1") < 0);
+		assertTrue(versionComparator.compare("2,0,0", "2,0,1.0") < 0);
+		assertTrue(versionComparator.compare("2.0,0,0", "2,0,1") < 0);
+	}
+
+	public void testVersionIsGreater_integer_comma() {
+		Comparator<String> versionComparator = new VersionComparator<BigDecimal>(',', DecimalSegmentParser.instance());
+		assertTrue(versionComparator.compare("2,0,2", "2,0,1") > 0);
+		assertTrue(versionComparator.compare("2,0,2.1", "2,0,1") > 0);
+		assertTrue(versionComparator.compare("2,0,2", "2,0,1.9") > 0);
+		assertTrue(versionComparator.compare("2.000,0,2", "2,0,1") > 0);
+	}
+
+	public void testVersionIsEqual_subclass() {
+		Comparator<String> versionComparator = VersionComparator.INTEGER_VERSION_COMPARATOR;
+		assertTrue(versionComparator.compare("2.0.0", "2.0.0") == 0);
+		assertTrue(versionComparator.compare("2.0.0", "2.0.0.0") == 0);
+		assertTrue(versionComparator.compare("2.0.0.0", "2.0") == 0);
+		assertTrue(versionComparator.compare("2.0.-1", "2.0.-1") == 0);
+	}
+
+	public void testVersionIsLess_subclass() {
+		Comparator<String> versionComparator = VersionComparator.INTEGER_VERSION_COMPARATOR;
+		assertTrue(versionComparator.compare("2.0.0", "2.0.1") < 0);
+		assertTrue(versionComparator.compare("2.5.0", "2.14") < 0);
+		assertTrue(versionComparator.compare("2.5.0", "2.5.0.0.1.0") < 0);
+		assertTrue(versionComparator.compare("2.0.-1", "2.0.0") < 0);
+		assertTrue(versionComparator.compare("2.0.-1", "2") < 0);
+	}
+
+	public void testVersionIsGreater_subclass() {
+		Comparator<String> versionComparator = VersionComparator.INTEGER_VERSION_COMPARATOR;
+		assertTrue(versionComparator.compare("2.0.2", "2.0.1") > 0);
+		assertTrue(versionComparator.compare("2.0.2", "2.0.1") > 0);
+		assertTrue(versionComparator.compare("2.5.0.0.1.0", "2.5.0") > 0);
+		assertTrue(versionComparator.compare("2.0.0", "2.0.-1") > 0);
+		assertTrue(versionComparator.compare("2", "2.0.-1") > 0);
+	}
+
+	public void testBadString() {
+		boolean exCaught = false;
+		try {
+			// note the letter 'O' instead of the numeral '0'
+			assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.0", "2.O.O") == 0);
+		} catch (NumberFormatException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+
+	static final class DecimalSegmentParser
+		implements SegmentParser<BigDecimal>, Serializable
+	{
+		public static final SegmentParser<BigDecimal> INSTANCE = new DecimalSegmentParser();
+		public static SegmentParser<BigDecimal> instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private DecimalSegmentParser() {
+			super();
+		}
+		// simply parse the segment as an integer
+		@Override
+		public BigDecimal parse(int segmentIndex, String segment) {
+			return new BigDecimal(segment);
+		}
+		@Override
+		public BigDecimal getZero() {
+			return ZERO;
+		}
+		private static final BigDecimal ZERO = new BigDecimal(0);
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/XMLToolsReadTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/XMLToolsReadTests.java
new file mode 100644
index 0000000..fb6f19a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/XMLToolsReadTests.java
@@ -0,0 +1,175 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests;

+

+import java.io.StringReader;

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.XMLTools;

+import org.eclipse.persistence.tools.utility.iterable.IterableTools;

+import org.w3c.dom.Document;

+import org.w3c.dom.Node;

+

+@SuppressWarnings("nls")

+public class XMLToolsReadTests

+	extends TestCase

+{

+	private Document testDocument;

+	private Node rootNode;

+

+

+	public XMLToolsReadTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.testDocument = this.buildTestDocument();

+		this.rootNode = XMLTools.getChild(this.testDocument, "root-element");

+	}

+

+	private Document buildTestDocument() {

+		return XMLTools.parse(new StringReader(this.buildTestDocumentString()));

+	}

+

+	private String buildTestDocumentString() {

+		StringBuffer sb = new StringBuffer(2000);

+		sb.append("<?xml version = '1.0' encoding = 'UTF-8'?>");

+		sb.append("<root-element>");

+		sb.append(		"<element-0>");

+		sb.append(			"<element-0-text-1>some text</element-0-text-1>");

+		sb.append(			"<element-0-text-2></element-0-text-2>");

+		sb.append(			"<element-0-text-3/>");

+		sb.append(			"<element-0-non-text>");

+		sb.append(				"<element-0-non-text-child>");

+		sb.append(				"</element-0-non-text-child>");

+		sb.append(			"</element-0-non-text>");

+		sb.append(		"</element-0>");

+		sb.append(		"<element-1>");

+		sb.append(			"<element-1-int>42</element-1-int>");

+		sb.append(			"<element-1-boolean-true-1>true</element-1-boolean-true-1>");

+		sb.append(			"<element-1-boolean-true-2>T</element-1-boolean-true-2>");

+		sb.append(			"<element-1-boolean-true-3>1</element-1-boolean-true-3>");

+		sb.append(			"<element-1-boolean-false-1>false</element-1-boolean-false-1>");

+		sb.append(			"<element-1-boolean-false-2>F</element-1-boolean-false-2>");

+		sb.append(			"<element-1-boolean-false-3>0</element-1-boolean-false-3>");

+		sb.append(		"</element-1>");

+		sb.append(		"<element-2>");

+		sb.append(			"<element-2.0>");

+		sb.append(			"</element-2.0>");

+		sb.append(			"<element-2.0>");

+		sb.append(			"</element-2.0>");

+		sb.append(			"<element-2.0>");

+		sb.append(			"</element-2.0>");

+		sb.append(		"</element-2>");

+		sb.append(		"<element-3>element 3 contents</element-3>");

+		sb.append("</root-element>");

+		return sb.toString();

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testGetChild() {

+		assertEquals("element-1", XMLTools.getChild(this.rootNode, "element-1").getNodeName());

+		assertEquals("element-3", XMLTools.getChild(this.rootNode, "element-3").getNodeName());

+		assertEquals(null, XMLTools.getChild(this.rootNode, "element-1x"));

+	}

+

+	public void testGetChildren() {

+		Iterable<Node> children = XMLTools.getChildren(this.rootNode);

+		assertEquals(4, IterableTools.size(children));

+		for (int i = 1; i < 4; i++) {

+			assertEquals("element-" + i, IterableTools.get(children, i).getNodeName());

+		}

+	}

+

+	public void testGetChildrenNamed() {

+		Node element2Node = XMLTools.getChild(this.rootNode, "element-2");

+		Iterable<Node> children = XMLTools.getChildren(element2Node, "element-2.0");

+		assertEquals(3, IterableTools.size(children));

+		for (int i = 0; i < 3; i++) {

+			assertEquals("element-2.0", IterableTools.get(children, i).getNodeName());

+		}

+	}

+

+	public void testGetTextContent() {

+		Node node = XMLTools.getChild(this.rootNode, "element-0");

+		Node childNode = XMLTools.getChild(node, "element-0-text-1");

+		assertEquals("some text", XMLTools.getTextContent(childNode));

+

+		childNode = XMLTools.getChild(node, "element-0-text-2");

+		assertEquals("", XMLTools.getTextContent(childNode));

+

+		childNode = XMLTools.getChild(node, "element-0-text-3");

+		assertEquals("", XMLTools.getTextContent(childNode));

+

+		childNode = XMLTools.getChild(node, "element-0-non-text");

+		boolean exCaught = false;

+		try {

+			String text = XMLTools.getTextContent(childNode);

+			text = text.toString();

+		} catch (IllegalArgumentException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testGetChildTextContent() {

+		assertEquals("element 3 contents", XMLTools.getChildTextContent(this.rootNode, "element-3"));

+	}

+

+	public void testGetChildTextContentDefaultValue() {

+		assertEquals("element 3 contents", XMLTools.getChildTextContent(this.rootNode, "element-3", "default value 3"));

+		assertEquals("default value 4", XMLTools.getChildTextContent(this.rootNode, "element-4", "default value 4"));

+	}

+

+	public void testGetChildIntContent() {

+		Node node = XMLTools.getChild(this.rootNode, "element-1");

+		assertEquals(42, XMLTools.getChildIntContent(node, "element-1-int"));

+	}

+

+	public void testGetChildIntContentDefaultValue() {

+		Node node = XMLTools.getChild(this.rootNode, "element-1");

+		assertEquals(42, XMLTools.childIntContent(node, "element-1-int", 99));

+		assertEquals(99, XMLTools.childIntContent(node, "element-1-int-x", 99));

+	}

+

+	public void testGetChildBooleanContent() {

+		Node node = XMLTools.getChild(this.rootNode, "element-1");

+		assertTrue(XMLTools.getChildBooleanContent(node, "element-1-boolean-true-1"));

+		assertTrue(XMLTools.getChildBooleanContent(node, "element-1-boolean-true-2"));

+		assertTrue(XMLTools.getChildBooleanContent(node, "element-1-boolean-true-3"));

+

+		assertFalse(XMLTools.getChildBooleanContent(node, "element-1-boolean-false-1"));

+		assertFalse(XMLTools.getChildBooleanContent(node, "element-1-boolean-false-2"));

+		assertFalse(XMLTools.getChildBooleanContent(node, "element-1-boolean-false-3"));

+	}

+

+	public void testGetChildBooleanContentDefaultValue() {

+		Node node = XMLTools.getChild(this.rootNode, "element-1");

+		assertTrue(XMLTools.getChildBooleanContent(node, "element-1-boolean-true-1", false));

+		assertTrue(XMLTools.getChildBooleanContent(node, "element-1-boolean-true-2", false));

+		assertTrue(XMLTools.getChildBooleanContent(node, "element-1-boolean-true-3", false));

+		assertFalse(XMLTools.getChildBooleanContent(node, "element-1-boolean-true-bogus", false));

+

+		assertFalse(XMLTools.getChildBooleanContent(node, "element-1-boolean-false-1", true));

+		assertFalse(XMLTools.getChildBooleanContent(node, "element-1-boolean-false-2", true));

+		assertFalse(XMLTools.getChildBooleanContent(node, "element-1-boolean-false-3", true));

+		assertTrue(XMLTools.getChildBooleanContent(node, "element-1-boolean-false-bogus", true));

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/XMLToolsWriteTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/XMLToolsWriteTests.java
new file mode 100644
index 0000000..46b3a5f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/XMLToolsWriteTests.java
@@ -0,0 +1,146 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests;

+

+import java.io.ByteArrayOutputStream;

+import java.io.OutputStream;

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.StringTools;

+import org.eclipse.persistence.tools.utility.SystemTools;

+import org.eclipse.persistence.tools.utility.XMLTools;

+import org.w3c.dom.Document;

+import org.w3c.dom.Node;

+

+/**

+ * these tests assume the XML will be formatted with appropriate

+ * indentation?

+ */

+@SuppressWarnings("nls")

+public class XMLToolsWriteTests

+	extends TestCase

+{

+	private Document testDocument;

+	private Node rootNode;

+	private static final String CR = System.getProperty("line.separator");

+

+

+	public XMLToolsWriteTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.testDocument = XMLTools.newDocument();

+		this.rootNode = this.testDocument.createElement("root-element");

+		this.testDocument.appendChild(this.rootNode);

+		XMLTools.addSimpleTextNode(this.rootNode, "element-0", "foo");

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	private void verifyTestDocumentString(String string) throws Exception {

+		OutputStream stream = new ByteArrayOutputStream(2000);

+		XMLTools.print(this.testDocument, stream);

+		stream.close();

+		StringBuffer sb = new StringBuffer(2000);

+		sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"");

+		if (SystemTools.jvmIsOracle() && SystemTools.javaSpecificationVersionIsGreaterThan("1.5")) {

+			sb.append(" standalone=\"no\"");

+		}

+		sb.append("?>");

+		if (SystemTools.jvmIsOracle() || (SystemTools.jvmIsIBM() && SystemTools.javaSpecificationVersionIsLessThanOrEqualTo("1.5"))) {

+			sb.append(CR);

+		}

+		sb.append("<root-element>");

+		sb.append(CR);

+		sb.append("<element-0>");

+		sb.append("foo");

+		sb.append("</element-0>");

+		sb.append(CR);

+		sb.append(string);

+		sb.append("</root-element>");

+		if (SystemTools.jvmIsOracle() || (SystemTools.jvmIsIBM() && SystemTools.javaSpecificationVersionIsLessThanOrEqualTo("1.5"))) {

+			sb.append(CR);

+		}

+		String expected = sb.toString();

+		String actual = stream.toString();

+		assertEquals(StringTools.compressWhitespace(expected), StringTools.compressWhitespace(actual));

+	}

+

+	public void testAddSimpleTextNode() throws Exception {

+		XMLTools.addSimpleTextNode(this.rootNode, "element-1", "some text");

+		this.verifyTestDocumentString("<element-1>some text</element-1>" + CR);

+	}

+

+	public void testAddSimpleTextNodeDefaultValue1() throws Exception {

+		XMLTools.addSimpleTextNode(this.rootNode, "element-1", "some text", "some text");

+		this.verifyTestDocumentString("");

+	}

+

+	public void testAddSimpleTextNodeDefaultValue2() throws Exception {

+		XMLTools.addSimpleTextNode(this.rootNode, "element-1", "some text", "default text");

+		this.verifyTestDocumentString("<element-1>some text</element-1>" + CR);

+	}

+

+	public void testAddSimpleTextNodeInt() throws Exception {

+		XMLTools.addSimpleTextNode(this.rootNode, "element-1", 42);

+		this.verifyTestDocumentString("<element-1>42</element-1>" + CR);

+	}

+

+	public void testAddSimpleTextNodeIntDefaultValue1() throws Exception {

+		XMLTools.addSimpleTextNode(this.rootNode, "element-1", 42, 42);

+		this.verifyTestDocumentString("");

+	}

+

+	public void testAddSimpleTextNodeIntDefaultValue2() throws Exception {

+		XMLTools.addSimpleTextNode(this.rootNode, "element-1", 42, 43);

+		this.verifyTestDocumentString("<element-1>42</element-1>" + CR);

+	}

+

+	public void testAddSimpleTextNodeBoolean() throws Exception {

+		XMLTools.addSimpleTextNode(this.rootNode, "element-1", true);

+		this.verifyTestDocumentString("<element-1>true</element-1>" + CR);

+	}

+

+	public void testAddSimpleTextNodeBooleanDefaultValue1() throws Exception {

+		XMLTools.addSimpleTextNode(this.rootNode, "element-1", true, true);

+		this.verifyTestDocumentString("");

+	}

+

+	public void testAddSimpleTextNodeBooleanDefaultValue2() throws Exception {

+		XMLTools.addSimpleTextNode(this.rootNode, "element-1", false, true);

+		this.verifyTestDocumentString("<element-1>false</element-1>" + CR);

+	}

+

+	public void testAddSimpleTextNodes() throws Exception {

+		XMLTools.addSimpleTextNodes(this.rootNode, "element-1-collection", "element-1", new String[] {"text 1", "text 2", "text 3"});

+		StringBuffer sb = new StringBuffer(2000);

+		sb.append("<element-1-collection>");

+		sb.append(CR);

+		sb.append("<element-1>text 1</element-1>");

+		sb.append(CR);

+		sb.append("<element-1>text 2</element-1>");

+		sb.append(CR);

+		sb.append("<element-1>text 3</element-1>");

+		sb.append(CR);

+		sb.append("</element-1-collection>");

+		sb.append(CR);

+		this.verifyTestDocumentString(sb.toString());

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/AbstractRepeatingElementListTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/AbstractRepeatingElementListTests.java
new file mode 100644
index 0000000..08e5742
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/AbstractRepeatingElementListTests.java
@@ -0,0 +1,483 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+
+
+@SuppressWarnings("nls")
+public abstract class AbstractRepeatingElementListTests
+	extends TestCase
+{
+	public AbstractRepeatingElementListTests(String name) {
+		super(name);
+	}
+
+	public void testBogusSize() {
+		boolean exCaught = false;
+		try {
+			List<String> list = this.buildList(-3);
+			fail("bogus list: " + list);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddObject() {
+		List<String> list = this.buildList(3);
+		boolean exCaught = false;
+		try {
+			list.add("foo");
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddIntObject() {
+		List<String> list = this.buildList(3);
+		boolean exCaught = false;
+		try {
+			list.add(2, "foo");
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddAllCollection() {
+		List<String> list = this.buildList(3);
+		list.addAll(Collections.<String>emptySet());
+
+		boolean exCaught = false;
+		try {
+			list.addAll(CollectionTools.collection("foo", "bar"));
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddAllIntCollection() {
+		List<String> list = this.buildList(3);
+		list.addAll(1, Collections.<String>emptySet());
+
+		boolean exCaught = false;
+		try {
+			list.addAll(1, CollectionTools.collection("foo", "bar"));
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testClear() {
+		List<String> list = this.buildList(0);
+		list.clear();
+
+		list = this.buildList(3);
+		boolean exCaught = false;
+		try {
+			list.clear();
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testContainsObject() {
+		List<String> list = this.buildList(0);
+		assertFalse(list.contains(this.getElement()));
+		assertFalse(list.contains(new Object()));
+
+		list = this.buildList(3);
+		assertTrue(list.contains(this.getElement()));
+		assertFalse(list.contains(new Object()));
+	}
+
+	public void testContainsAllCollection() {
+		Collection<String> emptyCollection = Collections.emptySet();
+
+		Collection<String> goodCollection = new ArrayList<String>();
+		goodCollection.add(this.getElement());
+		goodCollection.add(this.getElement());
+		goodCollection.add(this.getElement());
+
+		Collection<String> badCollection = new ArrayList<String>();
+		badCollection.add(this.getElement());
+		badCollection.add("bad");
+		badCollection.add(this.getElement());
+
+		List<String> list = this.buildList(0);
+		assertTrue(list.containsAll(emptyCollection));
+		assertFalse(list.containsAll(goodCollection));
+		assertFalse(list.containsAll(badCollection));
+
+		list = this.buildList(3);
+		assertTrue(list.containsAll(emptyCollection));
+		assertTrue(list.containsAll(goodCollection));
+		assertFalse(list.containsAll(badCollection));
+	}
+
+	public void testGetInt() {
+		List<String> list = this.buildList(3);
+		assertEquals(this.getElement(), list.get(0));
+		assertEquals(this.getElement(), list.get(1));
+		assertEquals(this.getElement(), list.get(2));
+
+		boolean exCaught = false;
+		try {
+			fail("bogus element: " + list.get(-1));
+		} catch (IndexOutOfBoundsException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		exCaught = false;
+		try {
+			fail("bogus element: " + list.get(3));
+		} catch (IndexOutOfBoundsException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testIndexOfObject() {
+		List<String> list = this.buildList(3);
+		assertEquals(0, list.indexOf(this.getElement()));
+		assertEquals(-1, list.indexOf(new Object()));
+	}
+
+	public void testIsEmpty() {
+		List<String> list = this.buildList(3);
+		assertFalse(list.isEmpty());
+
+		list = this.buildList(0);
+		assertTrue(list.isEmpty());
+	}
+
+	public void testIterator() {
+		List<String> list = this.buildList(3);
+		Iterator<String> iterator = list.iterator();
+		assertTrue(iterator.hasNext());
+		assertEquals(this.getElement(), iterator.next());
+		assertTrue(iterator.hasNext());
+		assertEquals(this.getElement(), iterator.next());
+		assertTrue(iterator.hasNext());
+		assertEquals(this.getElement(), iterator.next());
+		assertFalse(iterator.hasNext());
+
+		boolean exCaught = false;
+		try {
+			iterator.remove();
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		list = this.buildList(0);
+		iterator = list.iterator();
+		assertFalse(iterator.hasNext());
+	}
+
+	public void testLastIndexOfObject() {
+		List<String> list = this.buildList(3);
+		assertEquals(2, list.lastIndexOf(this.getElement()));
+		assertEquals(-1, list.lastIndexOf(new Object()));
+	}
+
+	public void testListIterator() {
+		List<String> list = this.buildList(3);
+		ListIterator<String> iterator = list.listIterator();
+		this.verifyListIterator(list, iterator);
+
+		list = this.buildList(0);
+		iterator = list.listIterator();
+		assertFalse(iterator.hasNext());
+		assertFalse(iterator.hasPrevious());
+	}
+
+	public void testListIteratorInt() {
+		List<String> list = this.buildList(7);
+		ListIterator<String> iterator = list.listIterator(4);
+		this.verifyListIterator(list, iterator);
+
+		list = this.buildList(0);
+		iterator = list.listIterator();
+		assertFalse(iterator.hasNext());
+		assertFalse(iterator.hasPrevious());
+	}
+
+	public void verifyListIterator(List<String> list, ListIterator<String> iterator) {
+		assertTrue(iterator.hasNext());
+		assertFalse(iterator.hasPrevious());
+		assertEquals(0, iterator.nextIndex());
+		assertEquals(-1, iterator.previousIndex());
+		assertEquals(this.getElement(), iterator.next());
+
+		assertTrue(iterator.hasNext());
+		assertTrue(iterator.hasPrevious());
+		assertEquals(1, iterator.nextIndex());
+		assertEquals(0, iterator.previousIndex());
+		assertEquals(this.getElement(), iterator.next());
+
+		assertTrue(iterator.hasNext());
+		assertTrue(iterator.hasPrevious());
+		assertEquals(2, iterator.nextIndex());
+		assertEquals(1, iterator.previousIndex());
+		assertEquals(this.getElement(), iterator.next());
+
+		assertFalse(iterator.hasNext());
+		assertTrue(iterator.hasPrevious());
+		assertEquals(3, iterator.nextIndex());
+		assertEquals(2, iterator.previousIndex());
+		boolean exCaught = false;
+		try {
+			fail("bogus element: " + iterator.next());
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+		assertEquals(this.getElement(), iterator.previous());
+
+		assertTrue(iterator.hasNext());
+		assertTrue(iterator.hasPrevious());
+		assertEquals(2, iterator.nextIndex());
+		assertEquals(1, iterator.previousIndex());
+		assertEquals(this.getElement(), iterator.previous());
+
+		assertTrue(iterator.hasNext());
+		assertTrue(iterator.hasPrevious());
+		assertEquals(1, iterator.nextIndex());
+		assertEquals(0, iterator.previousIndex());
+		assertEquals(this.getElement(), iterator.previous());
+
+		assertTrue(iterator.hasNext());
+		assertFalse(iterator.hasPrevious());
+		assertEquals(0, iterator.nextIndex());
+		assertEquals(-1, iterator.previousIndex());
+		exCaught = false;
+		try {
+			fail("bogus element: " + iterator.previous());
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		exCaught = false;
+		try {
+			iterator.remove();
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+
+		exCaught = false;
+		try {
+			iterator.add("foo");
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+
+		exCaught = false;
+		try {
+			iterator.set("foo");
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		list = this.buildList(0);
+		iterator = list.listIterator();
+		assertFalse(iterator.hasNext());
+		assertFalse(iterator.hasPrevious());
+	}
+
+	public void testRemoveObject() {
+		List<String> list = this.buildList(0);
+		assertFalse(list.remove(this.getElement()));
+		assertFalse(list.remove("foo"));
+
+		list = this.buildList(3);
+		assertFalse(list.remove("foo"));
+		boolean exCaught = false;
+		try {
+			list.remove(this.getElement());
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveInt() {
+		List<String> list = this.buildList(3);
+		boolean exCaught = false;
+		try {
+			list.remove(0);
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveAllCollection() {
+		Collection<String> emptyCollection = Collections.emptySet();
+
+		Collection<String> goodCollection = new ArrayList<String>();
+		goodCollection.add("good");
+		goodCollection.add("good");
+		goodCollection.add("good");
+
+		Collection<String> badCollection = new ArrayList<String>();
+		badCollection.add("bad");
+		badCollection.add(this.getElement());
+		badCollection.add("bad");
+
+		List<String> list = this.buildList(0);
+		assertFalse(list.removeAll(emptyCollection));
+		assertFalse(list.removeAll(goodCollection));
+		assertFalse(list.removeAll(badCollection));
+
+		list = this.buildList(3);
+		assertFalse(list.removeAll(emptyCollection));
+		assertFalse(list.removeAll(goodCollection));
+		boolean exCaught = false;
+		try {
+			list.removeAll(badCollection);
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRetainAllCollection() {
+		Collection<String> emptyCollection = Collections.emptySet();
+
+		Collection<String> goodCollection = new ArrayList<String>();
+		goodCollection.add("good");
+		goodCollection.add(this.getElement());
+		goodCollection.add("good");
+
+		Collection<String> badCollection = new ArrayList<String>();
+		badCollection.add("bad");
+		badCollection.add("bad");
+		badCollection.add("bad");
+
+		List<String> list = this.buildList(0);
+		assertFalse(list.retainAll(emptyCollection));
+		assertFalse(list.retainAll(goodCollection));
+		assertFalse(list.retainAll(badCollection));
+
+		list = this.buildList(3);
+		boolean exCaught = false;
+		try {
+			list.retainAll(emptyCollection);
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+		assertFalse(list.retainAll(goodCollection));
+		exCaught = false;
+		try {
+			list.retainAll(badCollection);
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testSetIntObject() {
+		List<String> list = this.buildList(3);
+		boolean exCaught = false;
+		try {
+			list.set(0, "foo");
+			fail("bogus list: " + list);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testSize() {
+		List<String> list = this.buildList(3);
+		assertEquals(3, list.size());
+	}
+
+	public void testSubList() {
+		List<String> list = this.buildList(7);
+		List<String> subList = list.subList(2, 7);
+		assertEquals(5, subList.size());
+		assertEquals(this.getElement(), subList.get(0));
+		assertEquals(this.getElement(), subList.get(3));
+		assertEquals(this.getElement(), subList.get(4));
+	}
+
+	public void testToArray() {
+		List<String> list = this.buildList(7);
+		Object[] array = list.toArray();
+		assertEquals(7, array.length);
+		assertEquals(this.getElement(), array[0]);
+		assertEquals(this.getElement(), array[3]);
+		assertEquals(this.getElement(), array[6]);
+	}
+
+	public void testToArrayObjectArray() {
+		List<String> list = this.buildList(7);
+		String[] array = list.toArray(new String[0]);
+		assertEquals(7, array.length);
+		assertEquals(this.getElement(), array[0]);
+		assertEquals(this.getElement(), array[3]);
+		assertEquals(this.getElement(), array[6]);
+
+		String[] template = new String[21];
+		array = list.toArray(template);
+		assertSame(template, array);
+		assertEquals(21, array.length);
+		assertEquals(this.getElement(), array[0]);
+		assertEquals(this.getElement(), array[3]);
+		assertEquals(this.getElement(), array[6]);
+		assertNull(array[7]);
+		assertNull(array[20]);
+	}
+
+	public abstract List<String> buildList(int size);
+
+	public abstract String getElement();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/ArrayQueueTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/ArrayQueueTests.java
new file mode 100644
index 0000000..3499c60
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/ArrayQueueTests.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import org.eclipse.persistence.tools.utility.collection.ArrayQueue;
+import org.eclipse.persistence.tools.utility.collection.Queue;
+
+@SuppressWarnings("nls")
+public class ArrayQueueTests
+	extends QueueTests
+{
+	public ArrayQueueTests(String name) {
+		super(name);
+	}
+
+	@Override
+	Queue<String> buildQueue() {
+		return new ArrayQueue<String>();
+	}
+
+	public void testWrappedElements() {
+		Queue<String> queue = this.buildQueue();
+		assertTrue(queue.isEmpty());
+		queue.enqueue("first");
+		assertFalse(queue.isEmpty());
+		queue.enqueue("second");
+		assertFalse(queue.isEmpty());
+		queue.enqueue("third");
+		queue.enqueue("fourth");
+		queue.enqueue("fifth");
+		queue.enqueue("sixth");
+
+		// make room for 11 and 12
+		assertEquals("first", queue.dequeue());
+		assertFalse(queue.isEmpty());
+		assertEquals("second", queue.dequeue());
+		assertFalse(queue.isEmpty());
+		assertEquals("third", queue.dequeue());
+
+		queue.enqueue("seventh");
+		queue.enqueue("eighth");
+		queue.enqueue("ninth");
+		queue.enqueue("tenth");
+		queue.enqueue("eleventh");
+		queue.enqueue("twelfth");
+
+		assertEquals("fourth", queue.dequeue());
+		assertEquals("fifth", queue.dequeue());
+		assertEquals("sixth", queue.dequeue());
+		assertEquals("seventh", queue.dequeue());
+		assertEquals("eighth", queue.dequeue());
+		assertEquals("ninth", queue.dequeue());
+		assertEquals("tenth", queue.dequeue());
+		assertEquals("eleventh", queue.dequeue());
+		assertEquals("twelfth", queue.dequeue());
+		assertTrue(queue.isEmpty());
+	}
+
+	public void testArrayCapacityExceeded() {
+		Queue<String> queue = this.buildQueue();
+		assertTrue(queue.isEmpty());
+		queue.enqueue("first");
+		assertFalse(queue.isEmpty());
+		queue.enqueue("second");
+		assertFalse(queue.isEmpty());
+		queue.enqueue("third");
+		queue.enqueue("fourth");
+		queue.enqueue("fifth");
+		queue.enqueue("sixth");
+		queue.enqueue("seventh");
+		queue.enqueue("eighth");
+		queue.enqueue("ninth");
+		queue.enqueue("tenth");
+		queue.enqueue("eleventh");
+		queue.enqueue("twelfth");
+
+		assertEquals("first", queue.dequeue());
+		assertFalse(queue.isEmpty());
+		assertEquals("second", queue.dequeue());
+		assertFalse(queue.isEmpty());
+		assertEquals("third", queue.dequeue());
+		assertEquals("fourth", queue.dequeue());
+		assertEquals("fifth", queue.dequeue());
+		assertEquals("sixth", queue.dequeue());
+		assertEquals("seventh", queue.dequeue());
+		assertEquals("eighth", queue.dequeue());
+		assertEquals("ninth", queue.dequeue());
+		assertEquals("tenth", queue.dequeue());
+		assertEquals("eleventh", queue.dequeue());
+		assertEquals("twelfth", queue.dequeue());
+		assertTrue(queue.isEmpty());
+	}
+
+	public void testArrayCapacityExceededWithWrappedElements() {
+		Queue<String> queue = this.buildQueue();
+		assertTrue(queue.isEmpty());
+		queue.enqueue("first");
+		assertFalse(queue.isEmpty());
+		queue.enqueue("second");
+		assertFalse(queue.isEmpty());
+		queue.enqueue("third");
+		queue.enqueue("fourth");
+		queue.enqueue("fifth");
+		queue.enqueue("sixth");
+
+		assertEquals("first", queue.dequeue());
+		assertFalse(queue.isEmpty());
+		assertEquals("second", queue.dequeue());
+		assertFalse(queue.isEmpty());
+		assertEquals("third", queue.dequeue());
+
+		queue.enqueue("seventh");
+		queue.enqueue("eighth");
+		queue.enqueue("ninth");
+		queue.enqueue("tenth");
+		queue.enqueue("eleventh");
+		queue.enqueue("twelfth");
+		queue.enqueue("thirteenth");
+		queue.enqueue("fourteenth");
+		queue.enqueue("fifteenth");
+
+		assertEquals("fourth", queue.dequeue());
+		assertEquals("fifth", queue.dequeue());
+		assertEquals("sixth", queue.dequeue());
+		assertEquals("seventh", queue.dequeue());
+		assertEquals("eighth", queue.dequeue());
+		assertEquals("ninth", queue.dequeue());
+		assertEquals("tenth", queue.dequeue());
+		assertEquals("eleventh", queue.dequeue());
+		assertEquals("twelfth", queue.dequeue());
+		assertEquals("thirteenth", queue.dequeue());
+		assertEquals("fourteenth", queue.dequeue());
+		assertEquals("fifteenth", queue.dequeue());
+		assertTrue(queue.isEmpty());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/ArrayStackTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/ArrayStackTests.java
new file mode 100644
index 0000000..8455b33
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/ArrayStackTests.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import org.eclipse.persistence.tools.utility.collection.ArrayStack;
+import org.eclipse.persistence.tools.utility.collection.Stack;
+
+public class ArrayStackTests
+	extends StackTests
+{
+	public ArrayStackTests(String name) {
+		super(name);
+	}
+
+	@Override
+	Stack<String> buildStack() {
+		return new ArrayStack<String>();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/BagTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/BagTests.java
new file mode 100644
index 0000000..30dab6a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/BagTests.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class BagTests extends TestCase {
+
+	public BagTests(String name) {
+		super(name);
+	}
+
+	public void testEmptyBag_iterator() throws Exception {
+		assertFalse(Bag.Empty.instance().iterator().hasNext());
+	}
+
+	public void testEmptyBag_size() throws Exception {
+		assertEquals(0, Bag.Empty.instance().size());
+	}
+
+	public void testEmptyBag_uniqueIterator() throws Exception {
+		assertFalse(Bag.Empty.instance().uniqueIterator().hasNext());
+	}
+
+	public void testEmptyBag_uniqueCount() throws Exception {
+		assertEquals(0, Bag.Empty.instance().uniqueCount());
+	}
+
+	public void testEmptyBag_count() throws Exception {
+		assertEquals(0, Bag.Empty.instance().count("foo"));
+	}
+
+	public void testEmptyBag_entries() throws Exception {
+		assertFalse(Bag.Empty.instance().entries().hasNext());
+	}
+
+	public void testEmptyBag_remove() throws Exception {
+		assertFalse(Bag.Empty.instance().remove("foo", 3));
+	}
+
+	public void testEmptyBag_add() throws Exception {
+		boolean exCaught = false;
+		try {
+			Bag.Empty.instance().add("foo", 3);
+			fail();
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testEmptyBag_equals() throws Exception {
+		assertTrue(Bag.Empty.instance().equals(Bag.Empty.instance()));
+		assertFalse(Bag.Empty.instance().equals("foo"));
+
+		Bag<Object> bag = new HashBag<Object>();
+		assertTrue(Bag.Empty.instance().equals(bag));
+		bag.add("foo");
+		assertFalse(Bag.Empty.instance().equals(bag));
+	}
+
+	public void testEmptyBag_hashCode() throws Exception {
+		assertEquals(0, Bag.Empty.instance().hashCode());
+	}
+
+	public void testEmptyBag_serialization() throws Exception {
+		Bag<?> xxx = TestTools.serialize(Bag.Empty.instance());
+		assertSame(Bag.Empty.instance(), xxx);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/CollectionToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/CollectionToolsTests.java
new file mode 100644
index 0000000..79b8616
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/CollectionToolsTests.java
@@ -0,0 +1,992 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.Vector;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ClassTools;
+import org.eclipse.persistence.tools.utility.ReverseComparator;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.iterable.EmptyIterable;
+import org.eclipse.persistence.tools.utility.iterator.ArrayIterator;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+import org.eclipse.persistence.tools.utility.tests.ArrayToolsTests;
+
+@SuppressWarnings("nls")
+public class CollectionToolsTests
+	extends TestCase
+{
+	public CollectionToolsTests(String name) {
+		super(name);
+	}
+
+
+	// ********** add all **********
+
+	public void testAddAllCollectionIterable_StringModified() {
+		List<String> list1 = this.buildStringList1();
+		Iterable<String> iterable2 = this.buildStringList2();
+		assertTrue(CollectionTools.addAll(list1, iterable2.iterator()));
+		assertEquals(6, list1.size());
+		assertTrue(list1.containsAll(this.buildStringList2()));
+	}
+
+	public void testAddAllCollectionIterable_StringUnmodified() {
+		Set<String> set1 = this.buildStringSet1();
+		Iterable<String> iterable3 = this.buildStringList1(); // same elements as set1
+		assertFalse(CollectionTools.addAll(set1, iterable3.iterator()));
+		assertEquals(3, set1.size());
+		assertTrue(set1.containsAll(this.buildStringList1()));
+	}
+
+	public void testAddAllCollectionIterable_ObjectModified() {
+		List<Object> list1 = this.buildObjectList1();
+		Iterable<String> iterable2 = this.buildStringList2();
+		assertTrue(CollectionTools.addAll(list1, iterable2));
+		assertEquals(6, list1.size());
+		assertTrue(list1.containsAll((List<String>) iterable2));
+	}
+
+	public void testAddAllCollectionIterable_ObjectUnmodified() {
+		Set<Object> set1 = this.buildObjectSet1();
+		Iterable<String> iterable3 = this.buildStringList1(); // same elements as set1
+		assertFalse(CollectionTools.addAll(set1, iterable3));
+		assertEquals(3, set1.size());
+		assertTrue(set1.containsAll((List<String>) iterable3));
+	}
+
+	public void testAddAllCollectionIterable_EmptyIterable() {
+		Set<Object> set1 = this.buildObjectSet1();
+		assertFalse(CollectionTools.addAll(set1, EmptyIterable.instance()));
+		assertEquals(3, set1.size());
+	}
+
+	public void testAddAllCollectionIterableInt_Modified() {
+		List<String> list1 = this.buildStringList1();
+		List<String> list2 = this.buildStringList2();
+		Iterable<String> iterable2 = list2;
+		assertTrue(CollectionTools.addAll(list1, iterable2, list2.size()));
+		assertEquals(6, list1.size());
+		assertTrue(list1.containsAll(this.buildStringList2()));
+	}
+
+	public void testAddAllCollectionIterableInt_Unmodified() {
+		Set<String> set1 = this.buildStringSet1();
+		List<String> list1 = this.buildStringList1(); // same elements as set1
+		Iterable<String> iterable3 = list1;
+		assertFalse(CollectionTools.addAll(set1, iterable3, list1.size()));
+		assertEquals(3, set1.size());
+		assertTrue(set1.containsAll(this.buildStringList1()));
+	}
+
+	public void testAddAllCollectionIterator_StringModified() {
+		List<String> list1 = this.buildStringList1();
+		List<String> list2 = this.buildStringList2();
+		assertTrue(CollectionTools.addAll(list1, list2.iterator()));
+		assertEquals(6, list1.size());
+		assertTrue(list1.containsAll(list2));
+	}
+
+	public void testAddAllCollectionIterator_StringUnmodified() {
+		Set<String> set1 = this.buildStringSet1();
+		List<String> list3 = this.buildStringList1(); // same elements as s1
+		assertFalse(CollectionTools.addAll(set1, list3.iterator()));
+		assertEquals(3, set1.size());
+		assertTrue(set1.containsAll(list3));
+	}
+
+	public void testAddAllCollectionIterator_ObjectModified() {
+		List<Object> list1 = this.buildObjectList1();
+		List<String> list2 = this.buildStringList2();
+		assertTrue(CollectionTools.addAll(list1, list2.iterator()));
+		assertEquals(6, list1.size());
+		assertTrue(list1.containsAll(list2));
+	}
+
+	public void testAddAllCollectionIterator_ObjectUnmodified() {
+		Set<Object> set1 = this.buildObjectSet1();
+		List<String> list3 = this.buildStringList1(); // same elements as s1
+		assertFalse(CollectionTools.addAll(set1, list3.iterator()));
+		assertEquals(3, set1.size());
+		assertTrue(set1.containsAll(list3));
+	}
+
+	public void testAddAllCollectionIterator_EmptyIterator() {
+		List<String> list1 = this.buildStringList1();
+		assertFalse(CollectionTools.addAll(list1, EmptyIterator.<String>instance()));
+		assertEquals(3, list1.size());
+	}
+
+	public void testAddAllCollectionIteratorInt_Modified() {
+		List<String> list1 = this.buildStringList1();
+		List<String> list2 = this.buildStringList2();
+		assertTrue(CollectionTools.addAll(list1, list2.iterator(), 3));
+		assertEquals(6, list1.size());
+		assertTrue(list1.containsAll(list2));
+	}
+
+	public void testAddAllCollectionIteratorInt_Unmodified() {
+		Set<String> set1 = this.buildStringSet1();
+		List<String> list3 = this.buildStringList1(); // same elements as s1
+		assertFalse(CollectionTools.addAll(set1, list3.iterator(), 3));
+		assertEquals(3, set1.size());
+		assertTrue(set1.containsAll(list3));
+	}
+
+	public void testAddAllCollectionIteratorInt_EmptyIterator() {
+		List<String> list1 = this.buildStringList1();
+		assertFalse(CollectionTools.addAll(list1, EmptyIterator.<String>instance(), 0));
+		assertEquals(3, list1.size());
+	}
+
+	public void testAddAllCollectionObjectArray_StringModified() {
+		List<String> list = this.buildStringList1();
+		String[] a = this.buildStringArray1();
+		assertTrue(CollectionTools.addAll(list, a));
+		assertEquals(6, list.size());
+		assertTrue(list.containsAll(CollectionTools.collection(a)));
+	}
+
+	public void testAddAllCollectionObjectArray_StringListEmptyArray() {
+		List<String> list = this.buildStringList1();
+		assertFalse(CollectionTools.addAll(list, new String[0]));
+	}
+
+	public void testAddAllCollectionObjectArray_StringUnmodified() {
+		Set<String> set = this.buildStringSet1();
+		String[] a = this.buildStringArray1();
+		assertFalse(CollectionTools.addAll(set, a));
+		assertEquals(3, set.size());
+		assertTrue(set.containsAll(CollectionTools.collection(a)));
+
+		assertFalse(CollectionTools.addAll(set, new String[0]));
+	}
+
+	public void testAddAllCollectionObjectArray_StringSetEmptyArray() {
+		Set<String> set = this.buildStringSet1();
+		assertFalse(CollectionTools.addAll(set, new String[0]));
+	}
+
+	public void testAddAllCollectionObjectArray_ObjectModified() {
+		List<Object> list = this.buildObjectList1();
+		String[] a = this.buildStringArray1();
+
+		assertTrue(CollectionTools.addAll(list, a));
+		assertEquals(6, list.size());
+		assertTrue(list.containsAll(CollectionTools.collection(a)));
+	}
+
+	public void testAddAllCollectionObjectArray_ObjectUnmodified() {
+		String[] a = this.buildStringArray1();
+		Set<Object> set = this.buildObjectSet1();
+		assertFalse(CollectionTools.addAll(set, a));
+		assertEquals(3, set.size());
+		assertTrue(set.containsAll(CollectionTools.collection(a)));
+	}
+
+
+	// ********** bag **********
+
+	public void testBagIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		Bag<String> b = CollectionTools.bag(iterable);
+		assertEquals(3, b.size());
+		assertTrue(b.containsAll(this.buildStringList1()));
+	}
+
+	public void testBagIterableInt() {
+		Iterable<String> iterable = this.buildStringList1();
+		Bag<String> b = CollectionTools.bag(iterable, 3);
+		assertEquals(3, b.size());
+		assertTrue(b.containsAll(this.buildStringList1()));
+	}
+
+	public void testBagIterator_String() {
+		Bag<String> b = CollectionTools.bag(this.buildStringList1().iterator());
+		assertEquals(3, b.size());
+		assertTrue(b.containsAll(this.buildStringList1()));
+	}
+
+	public void testBagIterator_StringObject() {
+		Collection<String> c = new ArrayList<String>();
+		c.add("zero");
+		c.add("one");
+		c.add("two");
+		c.add("three");
+		Bag<Object> b = CollectionTools.<Object>bag(c.iterator());
+		assertEquals(4, b.size());
+		assertTrue(b.containsAll(c));
+	}
+
+	public void testBagIterator_Empty() {
+		Bag<String> b = CollectionTools.bag(EmptyIterator.<String>instance());
+		assertEquals(0, b.size());
+	}
+
+	public void testBagIteratorInt() {
+		Bag<String> b = CollectionTools.bag(this.buildStringList1().iterator(), 3);
+		assertEquals(3, b.size());
+		assertTrue(b.containsAll(this.buildStringList1()));
+	}
+
+	public void testBagIteratorInt_Empty() {
+		Bag<String> b = CollectionTools.bag(EmptyIterator.<String>instance(), 3);
+		assertEquals(0, b.size());
+	}
+
+	public void testBagObjectArray() {
+		Bag<String> b = CollectionTools.bag(this.buildStringArray1());
+		assertEquals(3, b.size());
+		assertTrue(CollectionTools.containsAll(b, (Object[]) this.buildStringArray1()));
+	}
+
+	public void testBagObjectArray_Vararg() {
+		Bag<String> b = CollectionTools.bag("foo", "bar", "baz");
+		assertEquals(3, b.size());
+		assertTrue(CollectionTools.containsAll(b, new Object[]{"foo", "bar", "baz"}));
+	}
+
+	public void testBagObjectArray_Empty() {
+		Bag<String> b = CollectionTools.bag(Bag.Empty.<String>instance());
+		assertEquals(0, b.size());
+	}
+
+
+	// ********** collection **********
+
+	public void testCollectionIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		Collection<String> c = CollectionTools.collection(iterable);
+		assertEquals(3, c.size());
+		assertTrue(c.containsAll(this.buildStringList1()));
+	}
+
+	public void testCollectionIterableInt() {
+		Iterable<String> iterable = this.buildStringList1();
+		Collection<String> c = CollectionTools.collection(iterable, 3);
+		assertEquals(3, c.size());
+		assertTrue(c.containsAll(this.buildStringList1()));
+	}
+
+	public void testCollectionIterator() {
+		Collection<String> c = CollectionTools.collection(this.buildStringList1().iterator());
+		assertEquals(3, c.size());
+		assertTrue(c.containsAll(this.buildStringList1()));
+	}
+
+	public void testCollectionIterator_ObjectString() {
+		Collection<Object> c = CollectionTools.<Object>collection(this.buildStringList1().iterator());
+		assertEquals(3, c.size());
+		assertTrue(c.containsAll(this.buildStringList1()));
+	}
+
+	public void testCollectionIteratorInt() {
+		Collection<String> c = CollectionTools.collection(this.buildStringList1().iterator(), 3);
+		assertEquals(3, c.size());
+		assertTrue(c.containsAll(this.buildStringList1()));
+	}
+
+	public void testCollectionObjectArray() {
+		Collection<String> c = CollectionTools.collection(this.buildStringArray1());
+		assertEquals(3, c.size());
+		assertTrue(CollectionTools.containsAll(c, (Object[]) this.buildStringArray1()));
+	}
+
+
+	// ********** contains all **********
+
+	public void testContainsAllCollectionIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(CollectionTools.containsAll(this.buildStringList1(), iterable));
+	}
+
+	public void testContainsAllCollectionIterator_String() {
+		assertTrue(CollectionTools.containsAll(this.buildStringList1(), this.buildStringList1().iterator()));
+	}
+
+	public void testContainsAllCollectionIterator_Object() {
+		Collection<Object> c1 = new ArrayList<Object>();
+		c1.add("zero");
+		c1.add("one");
+		c1.add("two");
+		Collection<String> c2 = new ArrayList<String>();
+		c2.add("two");
+		c2.add("zero");
+		c2.add("one");
+		assertTrue(CollectionTools.containsAll(c1, c2.iterator()));
+	}
+
+	public void testContainsAllCollectionObjectArray_StringObject() {
+		assertTrue(CollectionTools.containsAll(this.buildStringList1(), this.buildObjectArray1()));
+	}
+
+	public void testContainsAllCollectionObjectArray() {
+		Object[] a = new Object[] { "zero", "one", "two" };
+		assertTrue(CollectionTools.containsAll(this.buildStringList1(), a));
+	}
+
+	// ********** filter **********
+
+	public void testFilterCollectionFilter() {
+		Collection<String> c = CollectionTools.collection(new String[] { "zero", "one", "two", "three", "four" });
+		Collection<String> actual = CollectionTools.filter(c, new ArrayToolsTests.StringLengthFilter(3));
+		Collection<String> expected = CollectionTools.collection(new String[] { "one", "two" });
+		assertEquals(expected, actual);
+	}
+
+	public void testFilterCollectionFilterTransparent() {
+		Collection<String> c = CollectionTools.collection(new String[] { "zero", "one", "two", "three", "four" });
+		Collection<String> actual = CollectionTools.filter(c, Filter.Transparent.<String>instance());
+		Collection<String> expected = CollectionTools.collection(new String[] { "zero", "one", "two", "three", "four" });
+		assertEquals(expected, actual);
+		assertNotSame(expected, actual);
+	}
+
+	// ********** remove all **********
+
+	public void testRemoveAllCollectionIterable() {
+		Collection<String> c = this.buildStringList1();
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(CollectionTools.removeAll(c, iterable));
+		assertEquals(0, c.size());
+		assertFalse(c.contains("one"));
+		assertFalse(c.contains("two"));
+		assertFalse(c.contains("three"));
+
+		c = this.buildStringList1();
+		iterable = this.buildStringList2();
+		assertFalse(CollectionTools.removeAll(c, iterable));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+	}
+
+	public void testRemoveAllCollectionIterableInt() {
+		Collection<String> c = this.buildStringList1();
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(CollectionTools.removeAll(c, iterable, 4));
+		assertEquals(0, c.size());
+		assertFalse(c.contains("one"));
+		assertFalse(c.contains("two"));
+		assertFalse(c.contains("three"));
+
+		c = this.buildStringList1();
+		iterable = this.buildStringList2();
+		assertFalse(CollectionTools.removeAll(c, iterable, 55));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+	}
+
+	public void testRemoveAllCollectionIterator_Empty() {
+		Collection<String> c = this.buildStringList1();
+		assertTrue(CollectionTools.removeAll(c, this.buildStringList1().iterator()));
+		assertEquals(0, c.size());
+		assertFalse(c.contains("one"));
+		assertFalse(c.contains("two"));
+		assertFalse(c.contains("three"));
+
+		c = this.buildStringList1();
+		assertFalse(CollectionTools.removeAll(c, this.buildStringList2().iterator()));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+
+		c = this.buildStringList1();
+		assertFalse(CollectionTools.removeAll(c, EmptyIterator.instance()));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+	}
+
+	public void testRemoveAllCollectionIteratorInt_Empty() {
+		Collection<String> c = this.buildStringList1();
+		assertTrue(CollectionTools.removeAll(c, this.buildStringList1().iterator(), 5));
+		assertEquals(0, c.size());
+		assertFalse(c.contains("one"));
+		assertFalse(c.contains("two"));
+		assertFalse(c.contains("three"));
+
+		c = this.buildStringList1();
+		assertFalse(CollectionTools.removeAll(c, this.buildStringList2().iterator(), 5));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+
+		c = this.buildStringList1();
+		assertFalse(CollectionTools.removeAll(c, EmptyIterator.instance(), 0));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+	}
+
+	public void testRemoveAllCollectionIterator_Duplicates() {
+		Collection<String> c = new ArrayList<String>();
+		c.add("a");
+		c.add("a");
+		c.add("b");
+		c.add("c");
+		c.add("d");
+		c.add("d");
+		String[] a = new String[] { "a", "d" };
+		Iterator<String> iterator = new ArrayIterator<String>(a);
+		assertTrue(CollectionTools.removeAll(c, iterator));
+		assertEquals(2, c.size());
+		assertFalse(c.contains("a"));
+		assertTrue(c.contains("b"));
+		assertTrue(c.contains("c"));
+		assertFalse(c.contains("d"));
+
+		iterator = new ArrayIterator<String>(a);
+		assertFalse(CollectionTools.removeAll(c, iterator));
+	}
+
+	public void testRemoveAllCollectionIterator_ObjectString() {
+		Collection<Object> c = new ArrayList<Object>();
+		c.add("a");
+		c.add("a");
+		c.add("b");
+		c.add("c");
+		c.add("d");
+		c.add("d");
+		String[] a = new String[] { "a", "d" };
+		Iterator<String> iterator = new ArrayIterator<String>(a);
+		assertTrue(CollectionTools.removeAll(c, iterator));
+		assertEquals(2, c.size());
+		assertFalse(c.contains("a"));
+		assertTrue(c.contains("b"));
+		assertTrue(c.contains("c"));
+		assertFalse(c.contains("d"));
+
+		iterator = new ArrayIterator<String>(a);
+		assertFalse(CollectionTools.removeAll(c, iterator));
+	}
+
+	public void testRemoveAllCollectionObjectArray_Empty() {
+		Collection<String> c = this.buildStringList1();
+		assertTrue(CollectionTools.removeAll(c, this.buildObjectArray1()));
+		assertEquals(0, c.size());
+		assertFalse(c.contains("one"));
+		assertFalse(c.contains("two"));
+		assertFalse(c.contains("three"));
+
+		c = this.buildStringList1();
+		assertFalse(CollectionTools.removeAll(c, this.buildObjectArray2()));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+
+		c = this.buildStringList1();
+		assertFalse(CollectionTools.removeAll(c, new Object[0]));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+	}
+
+	public void testRemoveAllCollectionObjectArray_Duplicates() {
+		Collection<String> c = new ArrayList<String>();
+		c.add("a");
+		c.add("a");
+		c.add("b");
+		c.add("c");
+		c.add("d");
+		c.add("d");
+		String[] a = new String[] { "a", "d" };
+		assertTrue(CollectionTools.removeAll(c, (Object[]) a));
+		assertEquals(2, c.size());
+		assertFalse(c.contains("a"));
+		assertTrue(c.contains("b"));
+		assertTrue(c.contains("c"));
+		assertFalse(c.contains("d"));
+
+		assertFalse(CollectionTools.removeAll(c,(Object[])  a));
+	}
+
+	public void testRemoveAllCollectionObjectArray_MoreDuplicates() {
+		Collection<String> c = new ArrayList<String>();
+		c.add("a");
+		c.add("b");
+		c.add("c");
+		c.add("d");
+		c.add("a");
+		c.add("d");
+		c.add("d");
+		c.add("a");
+		c.add("c");
+		String[] a = new String[] { "a", "d" };
+		assertTrue(CollectionTools.removeAll(c, (Object[]) a));
+		assertEquals(3, c.size());
+		assertFalse(c.contains("a"));
+		assertTrue(c.contains("b"));
+		assertTrue(c.contains("c"));
+		assertFalse(c.contains("d"));
+
+		assertFalse(CollectionTools.removeAll(c, (Object[]) a));
+	}
+
+
+	// ********** remove all occurrences **********
+
+	public void testRemoveAllOccurrencesCollectionObject() {
+		Collection<String> c = this.buildStringList1();
+		assertEquals(3, c.size());
+		assertFalse(CollectionTools.removeAllOccurrences(c, "three"));
+		assertTrue(CollectionTools.removeAllOccurrences(c, "two"));
+		assertFalse(CollectionTools.removeAllOccurrences(c, "two"));
+		assertEquals(2, c.size());
+
+		c.add("five");
+		c.add("five");
+		c.add("five");
+		assertEquals(5, c.size());
+		assertTrue(CollectionTools.removeAllOccurrences(c, "five"));
+		assertFalse(CollectionTools.removeAllOccurrences(c, "five"));
+		assertEquals(2, c.size());
+
+		c.add(null);
+		c.add(null);
+		c.add(null);
+		assertEquals(5, c.size());
+		assertTrue(CollectionTools.removeAllOccurrences(c, null));
+		assertFalse(CollectionTools.removeAllOccurrences(c, null));
+		assertEquals(2, c.size());
+	}
+
+
+	// ********** retain all **********
+
+	public void testRetainAllCollectionIterable() {
+		Collection<String> c = this.buildStringList1();
+		Iterable<String> iterable = this.buildStringList1();
+		assertFalse(CollectionTools.retainAll(c, iterable));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+
+		iterable = this.buildStringList2();
+		assertTrue(CollectionTools.retainAll(c, iterable));
+		assertEquals(0, c.size());
+		assertFalse(c.contains("one"));
+		assertFalse(c.contains("two"));
+		assertFalse(c.contains("three"));
+	}
+
+	public void testRetainAllCollectionIterableInt() {
+		Collection<String> c = this.buildStringList1();
+		Iterable<String> iterable = this.buildStringList1();
+		assertFalse(CollectionTools.retainAll(c, iterable));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+
+		iterable = this.buildStringList2();
+		assertTrue(CollectionTools.retainAll(c, iterable, 7));
+		assertEquals(0, c.size());
+		assertFalse(c.contains("one"));
+		assertFalse(c.contains("two"));
+		assertFalse(c.contains("three"));
+	}
+
+	public void testRetainAllCollectionIterator() {
+		Collection<String> c = this.buildStringList1();
+		assertFalse(CollectionTools.retainAll(c, this.buildStringList1().iterator()));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+
+		assertTrue(CollectionTools.retainAll(c, this.buildStringList2().iterator()));
+		assertEquals(0, c.size());
+		assertFalse(c.contains("one"));
+		assertFalse(c.contains("two"));
+		assertFalse(c.contains("three"));
+	}
+
+	public void testRetainAllCollectionIterator_ObjectString() {
+		Collection<Object> c1 = new ArrayList<Object>();
+		c1.add("zero");
+		c1.add("one");
+		c1.add("two");
+
+		Collection<String> c2 = new ArrayList<String>();
+		c2.add("zero");
+		c2.add("one");
+		c2.add("two");
+
+		assertFalse(CollectionTools.retainAll(c1, c2.iterator()));
+		assertEquals(c2.size(), c1.size());
+		assertEquals(c2, c1);
+
+		Collection<String> c3 = new ArrayList<String>();
+		c3.add("three");
+		c3.add("four");
+		c3.add("five");
+	}
+
+	public void testRetainAllCollectionIterator_EmptyIterator() {
+		Collection<String> c = this.buildStringList1();
+		assertTrue(CollectionTools.retainAll(c, EmptyIterator.instance()));
+		assertEquals(0, c.size());
+	}
+
+	public void testRetainAllCollectionIterator_EmptyCollection() {
+		Collection<String> c = new ArrayList<String>();
+		assertFalse(CollectionTools.retainAll(c, this.buildStringList1().iterator()));
+		assertEquals(0, c.size());
+	}
+
+	public void testRetainAllCollectionIterator_EmptyCollectionEmptyIterator() {
+		Collection<String> c = new ArrayList<String>();
+		assertFalse(CollectionTools.retainAll(c, EmptyIterator.instance()));
+		assertEquals(0, c.size());
+	}
+
+	public void testRetainAllCollectionIteratorInt() {
+		Collection<String> c = this.buildStringList1();
+		assertFalse(CollectionTools.retainAll(c, this.buildStringList1().iterator(), 8));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+
+		assertTrue(CollectionTools.retainAll(c, this.buildStringList2().iterator(), 9));
+		assertEquals(0, c.size());
+		assertFalse(c.contains("one"));
+		assertFalse(c.contains("two"));
+		assertFalse(c.contains("three"));
+	}
+
+	public void testRetainAllCollectionIteratorInt_EmptyIterator() {
+		Collection<String> c = this.buildStringList1();
+		assertTrue(CollectionTools.retainAll(c, EmptyIterator.instance(), 0));
+		assertEquals(0, c.size());
+	}
+
+	public void testRetainAllCollectionIteratorInt_EmptyCollection() {
+		Collection<String> c = new ArrayList<String>();
+		assertFalse(CollectionTools.retainAll(c, this.buildStringList1().iterator(), 3));
+		assertEquals(0, c.size());
+	}
+
+	public void testRetainAllCollectionIteratorInt_EmptyCollectionEmptyIterator() {
+		Collection<String> c = new ArrayList<String>();
+		assertFalse(CollectionTools.retainAll(c, EmptyIterator.instance(), 0));
+		assertEquals(0, c.size());
+	}
+
+	public void testRetainAllCollectionObjectArray() {
+		Collection<String> c = this.buildStringList1();
+		assertFalse(CollectionTools.retainAll(c, this.buildObjectArray1()));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+
+		assertTrue(CollectionTools.retainAll(c, this.buildObjectArray2()));
+		assertEquals(0, c.size());
+		assertFalse(c.contains("one"));
+		assertFalse(c.contains("two"));
+		assertFalse(c.contains("three"));
+	}
+
+	public void testRetainAllCollectionObjectArray_EmptyObjectArray() {
+		Collection<String> c = this.buildStringList1();
+		assertTrue(CollectionTools.retainAll(c, new Object[0]));
+		assertEquals(0, c.size());
+	}
+
+	public void testRetainAllCollectionObjectArray_EmptyCollection() {
+		Collection<String> c = new ArrayList<String>();
+		assertFalse(CollectionTools.retainAll(c, (Object[]) new String[] { "foo" }));
+		assertEquals(0, c.size());
+	}
+
+	public void testRetainAllCollectionObjectArray_EmptyCollectionEmptyObjectArray() {
+		Collection<String> c = new ArrayList<String>();
+		assertFalse(CollectionTools.retainAll(c, (Object[]) new String[0]));
+		assertEquals(0, c.size());
+	}
+
+
+	// ********** transform **********
+
+	public void testTransformCollectionTransformer() {
+		List<String> list = Arrays.asList(new String[] { "zero", "one", "two" });
+		Collection<String> actual = CollectionTools.transform(list, ArrayToolsTests.UPPER_CASE_TRANSFORMER);
+		assertEquals(3, actual.size());
+		assertTrue(actual.contains("ZERO"));
+		assertTrue(actual.contains("ONE"));
+		assertTrue(actual.contains("TWO"));
+	}
+
+
+	// ********** set **********
+
+	public void testSetIterable() {
+		Iterable<String> iterable = this.buildStringSet1();
+		assertEquals(this.buildStringSet1(), CollectionTools.set(iterable));
+	}
+
+	public void testSetIterableInt() {
+		Iterable<String> iterable = this.buildStringSet1();
+		assertEquals(this.buildStringSet1(), CollectionTools.set(iterable, 22));
+	}
+
+	public void testSetIterator_String() {
+		assertEquals(this.buildStringSet1(), CollectionTools.set(this.buildStringSet1().iterator()));
+	}
+
+	public void testSetIterator_Object() {
+		List<String> list = new ArrayList<String>();
+		list.add("0");
+		list.add("1");
+		list.add("2");
+		list.add("3");
+		list.add("0");
+		list.add("1");
+		list.add("2");
+		list.add("3");
+		Set<String> set = new HashSet<String>();
+		set.addAll(list);
+
+		assertEquals(set, CollectionTools.<Object>set(list.iterator()));
+	}
+
+	public void testSetIteratorInt() {
+		assertEquals(this.buildStringSet1(), CollectionTools.set(this.buildStringSet1().iterator(), 3));
+	}
+
+	public void testSetObjectArray() {
+		assertEquals(this.buildStringSet1(), CollectionTools.set(this.buildStringSet1().toArray()));
+	}
+
+
+	// ********** sorted set **********
+
+	public void testSortedSetIterable() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("0");
+		list.add("2");
+		list.add("3");
+		list.add("1");
+
+		SortedSet<String> ss1 = new TreeSet<String>();
+		ss1.addAll(list);
+
+		Iterable<String> iterable = list;
+		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(iterable);
+		assertEquals(ss1, ss2);
+	}
+
+	public void testSortedSetIterableInt() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("0");
+		list.add("2");
+		list.add("3");
+		list.add("1");
+
+		SortedSet<String> ss1 = new TreeSet<String>();
+		ss1.addAll(list);
+
+		Iterable<String> iterable = list;
+		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(iterable, 5);
+		assertEquals(ss1, ss2);
+	}
+
+	public void testSortedSetIterableComparator() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("0");
+		list.add("2");
+		list.add("3");
+		list.add("1");
+
+		SortedSet<String> ss1 = new TreeSet<String>(new ReverseComparator<String>());
+		ss1.addAll(list);
+
+		Iterable<String> iterable = list;
+		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(iterable, new ReverseComparator<String>());
+		assertEquals(ss1, ss2);
+	}
+
+	public void testSortedSetIterableComparatorInt() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("0");
+		list.add("2");
+		list.add("3");
+		list.add("1");
+
+		SortedSet<String> ss1 = new TreeSet<String>(new ReverseComparator<String>());
+		ss1.addAll(list);
+
+		Iterable<String> iterable = list;
+		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(iterable, new ReverseComparator<String>(), 5);
+		assertEquals(ss1, ss2);
+	}
+
+	public void testSortedSetIterator() {
+		assertEquals(this.buildSortedStringSet1(), CollectionTools.sortedSet(this.buildSortedStringSet1().iterator()));
+	}
+
+	public void testSortedSetIterator_TreeSet() {
+		SortedSet<String> ss1 = new TreeSet<String>();
+		ss1.add("0");
+		ss1.add("2");
+		ss1.add("3");
+		ss1.add("1");
+
+		SortedSet<String> set2 = CollectionTools.<String>sortedSet(ss1.iterator());
+		assertEquals(ss1, set2);
+	}
+
+	public void testSortedSetIteratorInt() {
+		assertEquals(this.buildSortedStringSet1(), CollectionTools.sortedSet(this.buildSortedStringSet1().iterator(), 8));
+	}
+
+	public void testSortedSetObjectArray() {
+		assertEquals(this.buildSortedStringSet1(), CollectionTools.sortedSet(this.buildStringSet1().toArray(new String[0])));
+	}
+
+	public void testSortedSetObjectArrayComparator() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("0");
+		list.add("2");
+		list.add("3");
+		list.add("1");
+
+		SortedSet<String> ss1 = new TreeSet<String>(new ReverseComparator<String>());
+		ss1.addAll(list);
+
+		String[] array = list.toArray(new String[list.size()]);
+		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(array, new ReverseComparator<String>());
+		assertEquals(ss1, ss2);
+	}
+
+
+	// ********** Old School Vector **********
+
+	public void testVectorIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		Vector<String> v = CollectionTools.vector(iterable);
+		assertEquals(3, v.size());
+		assertTrue(v.containsAll(this.buildStringList1()));
+	}
+
+	public void testVectorIterableInt() {
+		Iterable<String> iterable = this.buildStringList1();
+		Vector<String> v = CollectionTools.vector(iterable, 8);
+		assertEquals(3, v.size());
+		assertTrue(v.containsAll(this.buildStringList1()));
+	}
+
+	public void testVectorIterator_String() {
+		Vector<String> v = CollectionTools.vector(this.buildStringList1().iterator());
+		assertEquals(3, v.size());
+		assertTrue(v.containsAll(this.buildStringList1()));
+	}
+
+	public void testVectorIterator_Object() {
+		Vector<Object> v = CollectionTools.<Object>vector(this.buildStringList1().iterator());
+		assertEquals(3, v.size());
+		assertTrue(v.containsAll(this.buildStringList1()));
+	}
+
+	public void testVectorIteratorInt() {
+		Vector<String> v = CollectionTools.vector(this.buildStringList1().iterator(), 7);
+		assertEquals(3, v.size());
+		assertTrue(v.containsAll(this.buildStringList1()));
+	}
+
+	public void testVectorObjectArray() {
+		Vector<String> v = CollectionTools.vector(this.buildStringArray1());
+		assertEquals(3, v.size());
+		assertTrue(v.containsAll(this.buildStringList1()));
+	}
+
+
+	// ********** constructor **********
+
+	public void testConstructor() {
+		boolean exCaught = false;
+		try {
+			Object at = ClassTools.newInstance(CollectionTools.class);
+			fail("bogus: " + at); //$NON-NLS-1$
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof InvocationTargetException) {
+				if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+
+	// ********** test harness **********
+
+	private Object[] buildObjectArray1() {
+		return new Object[] { "zero", "one", "two" };
+	}
+
+	private String[] buildStringArray1() {
+		return new String[] { "zero", "one", "two" };
+	}
+
+	private Object[] buildObjectArray2() {
+		return new Object[] { "three", "four", "five" };
+	}
+
+	private List<String> buildStringList1() {
+		List<String> l = new ArrayList<String>();
+		this.addToCollection1(l);
+		return l;
+	}
+
+	private List<Object> buildObjectList1() {
+		List<Object> l = new ArrayList<Object>();
+		this.addToCollection1(l);
+		return l;
+	}
+
+	private void addToCollection1(Collection<? super String> c) {
+		c.add("zero");
+		c.add("one");
+		c.add("two");
+	}
+
+	private List<String> buildStringList2() {
+		List<String> l = new ArrayList<String>();
+		this.addToCollection2(l);
+		return l;
+	}
+
+	private void addToCollection2(Collection<? super String> c) {
+		c.add("three");
+		c.add("four");
+		c.add("five");
+	}
+
+	private Set<String> buildStringSet1() {
+		Set<String> s = new HashSet<String>();
+		this.addToCollection1(s);
+		return s;
+	}
+
+	private Set<Object> buildObjectSet1() {
+		Set<Object> s = new HashSet<Object>();
+		this.addToCollection1(s);
+		return s;
+	}
+
+	private SortedSet<String> buildSortedStringSet1() {
+		SortedSet<String> s = new TreeSet<String>();
+		this.addToCollection1(s);
+		return s;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/CommonUtilityCollectionTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/CommonUtilityCollectionTests.java
new file mode 100644
index 0000000..d2d11ef
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/CommonUtilityCollectionTests.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * decentralize test creation code
+ */
+public class CommonUtilityCollectionTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CommonUtilityCollectionTests.class.getPackage().getName());
+
+		suite.addTestSuite(ArrayQueueTests.class);
+		suite.addTestSuite(ArrayStackTests.class);
+		suite.addTestSuite(BagTests.class);
+		suite.addTestSuite(CollectionToolsTests.class);
+		suite.addTestSuite(HashBagTests.class);
+		suite.addTestSuite(IdentityHashBagTests.class);
+		suite.addTestSuite(LinkedQueueTests.class);
+		suite.addTestSuite(LinkedStackTests.class);
+		suite.addTestSuite(ListToolsTests.class);
+		suite.addTestSuite(NullElementListTests.class);
+		suite.addTestSuite(RepeatingElementListTests.class);
+		suite.addTestSuite(SynchronizedQueueTests.class);
+		suite.addTestSuite(SynchronizedStackTests.class);
+
+		return suite;
+	}
+
+	private CommonUtilityCollectionTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/HashBagTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/HashBagTests.java
new file mode 100644
index 0000000..b1c443c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/HashBagTests.java
@@ -0,0 +1,557 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.SystemTools;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class HashBagTests extends TestCase {
+	private HashBag<String> bag;
+
+	public HashBagTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.bag = this.buildBag();
+	}
+
+	private HashBag<String> buildBag() {
+		HashBag<String> b = new HashBag<String>();
+		b.add(null);
+		b.add(new String("one"));
+		b.add(new String("two"));
+		b.add(new String("two"));
+		b.add(new String("three"));
+		b.add(new String("three"));
+		b.add(new String("three"));
+		b.add(new String("four"));
+		b.add(new String("four"));
+		b.add(new String("four"));
+		b.add(new String("four"));
+		return b;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	private Collection<String> buildCollection() {
+		Collection<String> c = new ArrayList<String>();
+		c.add(new String("foo"));
+		c.add(new String("foo"));
+		c.add(new String("bar"));
+		c.add(new String("bar"));
+		c.add(new String("bar"));
+		return c;
+	}
+
+	public void testCtorCollection() {
+		Collection<String> c = this.buildCollection();
+		Bag<String> b = new HashBag<String>(c);
+		for (String s : c) {
+			assertTrue(b.contains(s));
+		}
+	}
+
+	public void testCtorIntFloat() {
+		boolean exCaught;
+
+		exCaught = false;
+		try {
+			this.bag = new HashBag<String>(-20, 0.66f);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		exCaught = false;
+		try {
+			this.bag = new HashBag<String>(20, -0.66f);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAdd() {
+		// the other adds took place in setUp
+		assertTrue(this.bag.add("five"));
+
+		assertTrue(this.bag.contains("one"));
+		assertTrue(this.bag.contains("two"));
+		assertTrue(this.bag.contains("three"));
+		assertTrue(this.bag.contains("four"));
+		assertTrue(this.bag.contains("five"));
+	}
+
+	public void testAddCount() {
+		// the other adds took place in setUp
+		this.bag.add("minus3", -3);
+		this.bag.add("zero", 0);
+		this.bag.add("five", 5);
+
+		assertFalse(this.bag.contains("minus3"));
+		assertFalse(this.bag.contains("zero"));
+		assertEquals(1, this.bag.count("one"));
+		assertEquals(2, this.bag.count("two"));
+		assertEquals(3, this.bag.count("three"));
+		assertEquals(4, this.bag.count("four"));
+		assertEquals(5, this.bag.count("five"));
+
+		this.bag.add("three", 2);
+		assertEquals(5, this.bag.count("three"));
+	}
+
+	public void testAddAll() {
+		Collection<String> c = this.buildCollection();
+		assertTrue(this.bag.addAll(c));
+		for (String s : c) {
+			assertTrue(this.bag.contains(s));
+		}
+	}
+
+	public void testClear() {
+		assertTrue(this.bag.contains("one"));
+		assertTrue(this.bag.contains("two"));
+		assertTrue(this.bag.contains("three"));
+		assertTrue(this.bag.contains("four"));
+		assertTrue(this.bag.contains(null));
+		assertEquals(11, this.bag.size());
+		this.bag.clear();
+		assertFalse(this.bag.contains("one"));
+		assertFalse(this.bag.contains("two"));
+		assertFalse(this.bag.contains("three"));
+		assertFalse(this.bag.contains("four"));
+		assertFalse(this.bag.contains(null));
+		assertEquals(0, this.bag.size());
+	}
+
+	public void testClone() {
+		Bag<String> bag2 = this.bag.clone();
+		assertTrue(this.bag != bag2);
+		assertEquals(this.bag, bag2);
+		assertTrue(this.bag.hashCode() == bag2.hashCode());
+	}
+
+	public void testContains() {
+		assertTrue(this.bag.contains(null));
+		assertTrue(this.bag.contains("one"));
+		assertTrue(this.bag.contains("two"));
+		assertTrue(this.bag.contains("three"));
+		assertTrue(this.bag.contains("four"));
+		assertTrue(this.bag.contains(new String("four")));
+		assertTrue(this.bag.contains("fo" + "ur"));
+		assertFalse(this.bag.contains("five"));
+	}
+
+	public void testContainsAll() {
+		Collection<String> c = new ArrayList<String>();
+		c.add(null);
+		c.add(new String("one"));
+		c.add(new String("two"));
+		c.add(new String("three"));
+		c.add(new String("four"));
+		assertTrue(this.bag.containsAll(c));
+	}
+
+	public void testCount() {
+		assertEquals(0, this.bag.count("zero"));
+		assertEquals(1, this.bag.count("one"));
+		assertEquals(2, this.bag.count("two"));
+		assertEquals(3, this.bag.count("three"));
+		assertEquals(4, this.bag.count("four"));
+		assertEquals(0, this.bag.count("five"));
+	}
+
+	public void testEquals() {
+		Bag<String> bag2 = this.buildBag();
+		assertEquals(this.bag, bag2);
+		bag2.add("five");
+		assertFalse(this.bag.equals(bag2));
+		Collection<String> c = new ArrayList<String>(this.bag);
+		assertFalse(this.bag.equals(c));
+	}
+
+	public void testHashCode() {
+		Bag<String> bag2 = this.buildBag();
+		assertEquals(this.bag.hashCode(), bag2.hashCode());
+	}
+
+	public void testIsEmpty() {
+		assertFalse(this.bag.isEmpty());
+		this.bag.clear();
+		assertTrue(this.bag.isEmpty());
+		this.bag.add("foo");
+		assertFalse(this.bag.isEmpty());
+	}
+
+	public void testEmptyIterator() {
+		this.bag.clear();
+		Iterator<String> iterator = this.bag.iterator();
+		assertFalse(iterator.hasNext());
+
+		boolean exCaught = false;
+		Object element = null;
+		try {
+			element = iterator.next();
+			fail(element.toString());
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		exCaught = false;
+		try {
+			iterator.remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testIterator() {
+		int i = 0;
+		Iterator<String> iterator = this.bag.iterator();
+		assertTrue(iterator.hasNext());
+		while (iterator.hasNext()) {
+			iterator.next();
+			i++;
+		}
+		assertEquals(11, i);
+		assertFalse(iterator.hasNext());
+
+		boolean exCaught = false;
+		Object element = null;
+		try {
+			element = iterator.next();
+			fail(element.toString());
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		iterator.remove();
+		assertEquals(10, this.bag.size());
+
+		exCaught = false;
+		try {
+			iterator.remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		// start over
+		iterator = this.bag.iterator();
+		this.bag.add("five");
+		exCaught = false;
+		try {
+			iterator.next();
+		} catch (ConcurrentModificationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testUniqueIterator() {
+		int i = 0;
+		Iterator<String> iterator = this.bag.uniqueIterator();
+		assertTrue(iterator.hasNext());
+		while (iterator.hasNext()) {
+			iterator.next();
+			i++;
+		}
+		assertEquals(5, i);
+		assertFalse(iterator.hasNext());
+
+		boolean exCaught = false;
+		Object element = null;
+		try {
+			element = iterator.next();
+			fail(element.toString());
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		// start over
+		iterator = this.bag.uniqueIterator();
+		Object next = null;
+		while (iterator.hasNext() && !"four".equals(next)) {
+			next = iterator.next();
+		}
+		iterator.remove();
+		assertEquals(7, this.bag.size());
+
+		exCaught = false;
+		try {
+			iterator.remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		// start over
+		iterator = this.bag.uniqueIterator();
+		this.bag.add("five");
+		exCaught = false;
+		try {
+			iterator.next();
+		} catch (ConcurrentModificationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testEntries() {
+		int i = 0;
+		Iterator<Bag.Entry<String>> iterator = this.bag.entries();
+		assertTrue(iterator.hasNext());
+		while (iterator.hasNext()) {
+			iterator.next();
+			i++;
+		}
+		assertEquals(5, i);
+		assertFalse(iterator.hasNext());
+
+		boolean exCaught = false;
+		Object element = null;
+		try {
+			element = iterator.next();
+			fail(element.toString());
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		// start over
+		iterator = this.bag.entries();
+		Bag.Entry<String> next = null;
+		while (iterator.hasNext()) {
+			next = iterator.next();
+			if (next.getElement().equals("four")) {
+				iterator.remove();
+				break;
+			}
+		}
+		assertEquals(7, this.bag.size());
+
+		exCaught = false;
+		try {
+			iterator.remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		// start over
+		iterator = this.bag.entries();
+		this.bag.add("five");
+		exCaught = false;
+		try {
+			iterator.next();
+		} catch (ConcurrentModificationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testHashingDistribution() throws Exception {
+		Bag<String> bigBag = new HashBag<String>();
+		for (int i = 0; i < 10000; i++) {
+			bigBag.add("object" + i);
+		}
+
+		java.lang.reflect.Field field = bigBag.getClass().getDeclaredField("table");
+		field.setAccessible(true);
+		Object[] table = (Object[]) field.get(bigBag);
+		int bucketCount = table.length;
+		int filledBucketCount = 0;
+		for (Object o : table) {
+			if (o != null) {
+				filledBucketCount++;
+			}
+		}
+		float loadFactor = ((float) filledBucketCount) / ((float) bucketCount);
+		if ((loadFactor < 0.20) || (loadFactor > 0.80)) {
+			String msg = "poor load factor: " + loadFactor;
+			if (SystemTools.jvmIsSun()) {
+				fail(msg);
+			} else {
+				// poor load factor is seen in the Eclipse build environment for some reason...
+				System.out.println(this.getClass().getName() + '.' + this.getName() + " - " + msg);
+				TestTools.printSystemProperties();
+			}
+		}
+	}
+
+	public void testRemove() {
+		assertTrue(this.bag.remove("one"));
+		assertFalse(this.bag.contains("one"));
+		assertFalse(this.bag.remove("one"));
+
+		assertTrue(this.bag.remove("two"));
+		assertTrue(this.bag.remove("two"));
+		assertFalse(this.bag.contains("two"));
+		assertFalse(this.bag.remove("two"));
+	}
+
+	public void testRemoveCount() {
+		assertFalse(this.bag.remove("one", 0));
+		assertTrue(this.bag.contains("one"));
+
+		assertTrue(this.bag.remove("one", 1));
+		assertFalse(this.bag.contains("one"));
+		assertFalse(this.bag.remove("one"));
+
+		assertFalse(this.bag.remove("two", -3));
+		assertTrue(this.bag.remove("two", 1));
+		assertTrue(this.bag.contains("two"));
+
+		assertTrue(this.bag.remove("two", 1));
+		assertFalse(this.bag.contains("two"));
+		assertFalse(this.bag.remove("two"));
+
+		assertTrue(this.bag.remove("three", 3));
+		assertFalse(this.bag.contains("three"));
+		assertFalse(this.bag.remove("three"));
+	}
+
+	public void testRemoveAll() {
+		Collection<String> c = new ArrayList<String>();
+		c.add("one");
+		c.add("three");
+		assertTrue(this.bag.removeAll(c));
+		assertFalse(this.bag.contains("one"));
+		assertFalse(this.bag.contains("three"));
+		assertFalse(this.bag.remove("one"));
+		assertFalse(this.bag.remove("three"));
+		assertFalse(this.bag.removeAll(c));
+	}
+
+	public void testRetainAll() {
+		Collection<String> c = new ArrayList<String>();
+		c.add("one");
+		c.add("three");
+		assertTrue(this.bag.retainAll(c));
+		assertTrue(this.bag.contains("one"));
+		assertTrue(this.bag.contains("three"));
+		assertFalse(this.bag.contains("two"));
+		assertFalse(this.bag.contains("four"));
+		assertFalse(this.bag.remove("two"));
+		assertFalse(this.bag.remove("four"));
+		assertFalse(this.bag.retainAll(c));
+	}
+
+	public void testSize() {
+		assertTrue(this.bag.size() == 11);
+		this.bag.add("five");
+		this.bag.add("five");
+		this.bag.add("five");
+		this.bag.add("five");
+		this.bag.add("five");
+		assertEquals(16, this.bag.size());
+	}
+
+	public void testSerialization() throws Exception {
+		Bag<String> bag2 = TestTools.serialize(this.bag);
+
+		assertTrue("same object?", this.bag != bag2);
+		assertEquals(11, bag2.size());
+		assertEquals(this.bag, bag2);
+		// look for similar elements
+		assertTrue(bag2.contains(null));
+		assertTrue(bag2.contains("one"));
+		assertTrue(bag2.contains("two"));
+		assertTrue(bag2.contains("three"));
+		assertTrue(bag2.contains("four"));
+
+		int nullCount = 0, oneCount = 0, twoCount = 0, threeCount = 0, fourCount = 0;
+		for (String s : bag2) {
+			if (s == null) {
+				nullCount++;
+			} else if (s.equals("one")) {
+				oneCount++;
+			} else if (s.equals("two")) {
+				twoCount++;
+			} else if (s.equals("three")) {
+				threeCount++;
+			} else if (s.equals("four")) {
+				fourCount++;
+			}
+		}
+		assertEquals(1, nullCount);
+		assertEquals(1, oneCount);
+		assertEquals(2, twoCount);
+		assertEquals(3, threeCount);
+		assertEquals(4, fourCount);
+	}
+
+	public void testToArray() {
+		Object[] a = this.bag.toArray();
+		assertEquals(11, a.length);
+		assertTrue(ArrayTools.contains(a, null));
+		assertTrue(ArrayTools.contains(a, "one"));
+		assertTrue(ArrayTools.contains(a, "two"));
+		assertTrue(ArrayTools.contains(a, "three"));
+		assertTrue(ArrayTools.contains(a, "four"));
+	}
+
+	public void testToArrayObjectArray() {
+		String[] a = new String[12];
+		a[11] = "not null";
+		String[] b = this.bag.toArray(a);
+		assertEquals(a, b);
+		assertEquals(12, a.length);
+		assertTrue(ArrayTools.contains(a, null));
+		assertTrue(ArrayTools.contains(a, "one"));
+		assertTrue(ArrayTools.contains(a, "two"));
+		assertTrue(ArrayTools.contains(a, "three"));
+		assertTrue(ArrayTools.contains(a, "four"));
+		assertTrue(a[11] == null);
+	}
+
+	public void testToString() {
+		String s = this.bag.toString();
+		assertTrue(s.startsWith("["));
+		assertTrue(s.endsWith("]"));
+		int commaCount = 0;
+		for (int i = 0; i < s.length(); i++) {
+			if (s.charAt(i) == ',') {
+				commaCount++;
+			}
+		}
+		assertEquals(10, commaCount);
+		assertTrue(s.indexOf("one") != -1);
+		assertTrue(s.indexOf("two") != -1);
+		assertTrue(s.indexOf("three") != -1);
+		assertTrue(s.indexOf("four") != -1);
+		assertTrue(s.indexOf("null") != -1);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/IdentityHashBagTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/IdentityHashBagTests.java
new file mode 100644
index 0000000..0c779ac
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/IdentityHashBagTests.java
@@ -0,0 +1,576 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.SystemTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.IdentityHashBag;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+
+@SuppressWarnings("nls")
+public class IdentityHashBagTests extends TestCase {
+	private IdentityHashBag<String> bag;
+	private String one = "one";
+	private String two = "two";
+	private String three = "three";
+	private String four = "four";
+	private String foo = "foo";
+	private String bar = "bar";
+
+	public IdentityHashBagTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.bag = this.buildBag();
+	}
+
+	protected IdentityHashBag<String> buildBag() {
+		IdentityHashBag<String> result = new IdentityHashBag<String>();
+		result.add(null);
+		result.add(this.one);
+		result.add(this.two);
+		result.add(this.two);
+		result.add(this.three);
+		result.add(this.three);
+		result.add(this.three);
+		result.add(this.four);
+		result.add(this.four);
+		result.add(this.four);
+		result.add(this.four);
+		return result;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	private Collection<String> buildCollection() {
+		Collection<String> c = new ArrayList<String>();
+		c.add(this.foo);
+		c.add(this.foo);
+		c.add(this.bar);
+		c.add(this.bar);
+		c.add(this.bar);
+		return c;
+	}
+
+	public void testCtorCollection() {
+		Collection<String> c = this.buildCollection();
+		IdentityHashBag<String> localBag = new IdentityHashBag<String>(c);
+		for (String s : c) {
+			assertTrue(localBag.contains(s));
+		}
+	}
+
+	public void testCtorIntFloat() {
+		boolean exCaught;
+
+		exCaught = false;
+		try {
+			this.bag = new IdentityHashBag<String>(-20, 0.66f);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue("IllegalArgumentException not thrown", exCaught);
+
+		exCaught = false;
+		try {
+			this.bag = new IdentityHashBag<String>(20, -0.66f);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue("IllegalArgumentException not thrown", exCaught);
+	}
+
+	public void testAdd() {
+		// the other adds took place in setUp
+		String five = "five";
+		assertTrue(this.bag.add(five));
+
+		assertTrue(this.bag.contains(this.one));
+		assertTrue(this.bag.contains(this.two));
+		assertTrue(this.bag.contains(this.three));
+		assertTrue(this.bag.contains(this.four));
+		assertTrue(this.bag.contains(five));
+	}
+
+	public void testAddCount() {
+		String minus3 = "minus3";
+		String zero = "zero";
+		String five = "five";
+		// the other adds took place in setUp
+		this.bag.add(minus3, -3);
+		this.bag.add(zero, 0);
+		this.bag.add(five, 5);
+
+		assertFalse(this.bag.contains(minus3));
+		assertFalse(this.bag.contains(zero));
+		assertEquals(1, this.bag.count(this.one));
+		assertEquals(2, this.bag.count(this.two));
+		assertEquals(3, this.bag.count(this.three));
+		assertEquals(4, this.bag.count(this.four));
+		assertEquals(5, this.bag.count(five));
+
+		this.bag.add(this.three, 2);
+		assertEquals(5, this.bag.count(this.three));
+	}
+
+	public void testAddAll() {
+		Collection<String> c = this.buildCollection();
+		assertTrue(this.bag.addAll(c));
+		for (String s : c) {
+			assertTrue(this.bag.contains(s));
+		}
+	}
+
+	public void testClear() {
+		assertTrue(this.bag.contains(this.one));
+		assertTrue(this.bag.contains(this.two));
+		assertTrue(this.bag.contains(this.three));
+		assertTrue(this.bag.contains(this.four));
+		assertTrue(this.bag.contains(null));
+		assertEquals(11, this.bag.size());
+		this.bag.clear();
+		assertFalse(this.bag.contains(this.one));
+		assertFalse(this.bag.contains(this.two));
+		assertFalse(this.bag.contains(this.three));
+		assertFalse(this.bag.contains(this.four));
+		assertFalse(this.bag.contains(null));
+		assertEquals(0, this.bag.size());
+	}
+
+	public void testClone() {
+		IdentityHashBag<String> bag2 = this.bag.clone();
+		assertTrue("bad clone", this.bag != bag2);
+		assertEquals("bad clone", this.bag, bag2);
+		assertTrue("bad clone", this.bag.hashCode() == bag2.hashCode());
+	}
+
+	public void testContains() {
+		assertTrue(this.bag.contains(null));
+		assertTrue(this.bag.contains(this.one));
+		assertTrue(this.bag.contains(this.two));
+		assertTrue(this.bag.contains(this.three));
+		assertTrue(this.bag.contains(this.four));
+
+		assertFalse(this.bag.contains(new String("four")));
+		assertFalse(this.bag.contains("five"));
+	}
+
+	public void testContainsAll() {
+		Collection<String> c = new ArrayList<String>();
+		c.add(null);
+		c.add(this.one);
+		c.add(this.two);
+		c.add(this.three);
+		c.add(this.four);
+		assertTrue(this.bag.containsAll(c));
+		c.add(new String(this.four));
+		assertFalse(this.bag.containsAll(c));
+	}
+
+	public void testCount() {
+		assertEquals(0, this.bag.count("zero"));
+		assertEquals(1, this.bag.count("one"));
+		assertEquals(2, this.bag.count("two"));
+		assertEquals(3, this.bag.count("three"));
+		assertEquals(4, this.bag.count("four"));
+		assertEquals(0, this.bag.count("five"));
+	}
+
+	public void testEquals() {
+		IdentityHashBag<String> bag2 = this.buildBag();
+		assertEquals(this.bag, bag2);
+		bag2.add("five");
+		assertFalse(this.bag.equals(bag2));
+		Collection<String> c = new ArrayList<String>(this.bag);
+		assertFalse(this.bag.equals(c));
+	}
+
+	public void testHashCode() {
+		IdentityHashBag<String> bag2 = this.buildBag();
+		assertEquals(this.bag.hashCode(), bag2.hashCode());
+	}
+
+	public void testIsEmpty() {
+		assertFalse(this.bag.isEmpty());
+		this.bag.clear();
+		assertTrue(this.bag.isEmpty());
+		this.bag.add("foo");
+		assertFalse(this.bag.isEmpty());
+	}
+
+	public void testEmptyIterator() {
+		this.bag.clear();
+		Iterator<String> iterator = this.bag.iterator();
+		assertFalse(iterator.hasNext());
+
+		boolean exCaught = false;
+		Object element = null;
+		try {
+			element = iterator.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + element, exCaught);
+
+		exCaught = false;
+		try {
+			iterator.remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue("IllegalStateException not thrown", exCaught);
+	}
+
+	public void testIterator() {
+		int i = 0;
+		Iterator<String> iterator = this.bag.iterator();
+		assertTrue(iterator.hasNext());
+		while (iterator.hasNext()) {
+			iterator.next();
+			i++;
+		}
+		assertEquals(11, i);
+		assertFalse(iterator.hasNext());
+
+		boolean exCaught = false;
+		Object element = null;
+		try {
+			element = iterator.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + element, exCaught);
+
+		iterator.remove();
+		assertEquals(10, this.bag.size());
+
+		exCaught = false;
+		try {
+			iterator.remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue("IllegalStateException not thrown", exCaught);
+
+		// start over
+		iterator = this.bag.iterator();
+		this.bag.add("five");
+		exCaught = false;
+		try {
+			iterator.next();
+		} catch (ConcurrentModificationException ex) {
+			exCaught = true;
+		}
+		assertTrue("ConcurrentModificationException not thrown", exCaught);
+	}
+
+	public void testUniqueIterator() {
+		int i = 0;
+		Iterator<String> iterator = this.bag.uniqueIterator();
+		assertTrue(iterator.hasNext());
+		while (iterator.hasNext()) {
+			iterator.next();
+			i++;
+		}
+		assertEquals(5, i);
+		assertFalse(iterator.hasNext());
+
+		boolean exCaught = false;
+		Object element = null;
+		try {
+			element = iterator.next();
+			fail(element.toString());
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		// start over
+		iterator = this.bag.uniqueIterator();
+		Object next = null;
+		while (iterator.hasNext() && !this.four.equals(next)) {
+			next = iterator.next();
+		}
+		iterator.remove();
+		assertEquals(7, this.bag.size());
+
+		exCaught = false;
+		try {
+			iterator.remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		// start over
+		iterator = this.bag.uniqueIterator();
+		String five = "five";
+		this.bag.add(five);
+		exCaught = false;
+		try {
+			iterator.next();
+		} catch (ConcurrentModificationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testEntries() {
+		int i = 0;
+		Iterator<org.eclipse.persistence.tools.utility.collection.Bag.Entry<String>> iterator = this.bag.entries();
+		assertTrue(iterator.hasNext());
+		while (iterator.hasNext()) {
+			iterator.next();
+			i++;
+		}
+		assertEquals(5, i);
+		assertFalse(iterator.hasNext());
+
+		boolean exCaught = false;
+		Object element = null;
+		try {
+			element = iterator.next();
+			fail(element.toString());
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		// start over
+		iterator = this.bag.entries();
+		org.eclipse.persistence.tools.utility.collection.Bag.Entry<String> next = null;
+		while (iterator.hasNext()) {
+			next = iterator.next();
+			if (next.getElement().equals(this.four)) {
+				iterator.remove();
+				break;
+			}
+		}
+		assertEquals(7, this.bag.size());
+
+		exCaught = false;
+		try {
+			iterator.remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		// start over
+		iterator = this.bag.entries();
+		String five = "five";
+		this.bag.add(five);
+		exCaught = false;
+		try {
+			iterator.next();
+		} catch (ConcurrentModificationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testHashingDistribution() throws Exception {
+		IdentityHashBag<String> bigBag = new IdentityHashBag<String>();
+		for (int i = 0; i < 10000; i++) {
+			bigBag.add("object" + i);
+		}
+
+		java.lang.reflect.Field field = bigBag.getClass().getDeclaredField("table");
+		field.setAccessible(true);
+		Object[] table = (Object[]) field.get(bigBag);
+		int bucketCount = table.length;
+		int filledBucketCount = 0;
+		for (int i = 0; i < bucketCount; i++) {
+			if (table[i] != null) {
+				filledBucketCount++;
+			}
+		}
+		float loadFactor = ((float) filledBucketCount) / ((float) bucketCount);
+		if ((loadFactor < 0.20) || (loadFactor > 0.80)) {
+			String msg = "poor load factor: " + loadFactor;
+			if (SystemTools.jvmIsSun()) {
+				fail(msg);
+			} else {
+				// poor load factor is seen in the Eclipse build environment for some reason...
+				System.out.println(this.getClass().getName() + '.' + this.getName() + " - " + msg);
+				TestTools.printSystemProperties();
+			}
+		}
+	}
+
+	public void testRemove() {
+		assertTrue(this.bag.remove(this.one));
+		assertFalse(this.bag.contains(this.one));
+		assertFalse(this.bag.remove(this.one));
+
+		assertTrue(this.bag.remove(this.two));
+		assertTrue(this.bag.remove(this.two));
+		assertFalse(this.bag.contains(this.two));
+		assertFalse(this.bag.remove(this.two));
+
+		assertFalse(this.bag.remove(new String(this.three)));
+	}
+
+	public void testRemoveCount() {
+		assertFalse(this.bag.remove(this.one, 0));
+		assertTrue(this.bag.contains(this.one));
+
+		assertTrue(this.bag.remove(this.one, 1));
+		assertFalse(this.bag.contains(this.one));
+		assertFalse(this.bag.remove(this.one));
+
+		assertFalse(this.bag.remove(this.two, -3));
+		assertTrue(this.bag.remove(this.two, 1));
+		assertTrue(this.bag.contains(this.two));
+
+		assertTrue(this.bag.remove(this.two, 1));
+		assertFalse(this.bag.contains(this.two));
+		assertFalse(this.bag.remove(this.two));
+
+		assertTrue(this.bag.remove(this.three, 3));
+		assertFalse(this.bag.contains(this.three));
+		assertFalse(this.bag.remove(this.three));
+	}
+
+	public void testRemoveAll() {
+		Collection<String> c = new ArrayList<String>();
+		c.add(this.one);
+		c.add(new String(this.two));
+		c.add(this.three);
+		assertTrue(this.bag.removeAll(c));
+		assertFalse(this.bag.contains(this.one));
+		assertTrue(this.bag.contains(this.two));
+		assertFalse(this.bag.contains(this.three));
+		assertFalse(this.bag.remove(this.one));
+		assertTrue(this.bag.remove(this.two));
+		assertFalse(this.bag.remove(this.three));
+		assertFalse(this.bag.removeAll(c));
+	}
+
+	public void testRetainAll() {
+		Collection<String> c = new ArrayList<String>();
+		c.add(this.one);
+		c.add(new String(this.two));
+		c.add(this.three);
+		assertTrue(this.bag.retainAll(c));
+		assertTrue(this.bag.contains(this.one));
+		assertFalse(this.bag.contains(this.two));
+		assertTrue(this.bag.contains(this.three));
+		assertFalse(this.bag.contains(this.four));
+		assertFalse(this.bag.remove(this.two));
+		assertFalse(this.bag.remove(this.four));
+		assertFalse(this.bag.retainAll(c));
+	}
+
+	public void testSize() {
+		assertTrue(this.bag.size() == 11);
+		String five = "five";
+		this.bag.add(five);
+		this.bag.add(five);
+		this.bag.add(five);
+		this.bag.add(five);
+		this.bag.add(new String(five));
+		assertEquals(16, this.bag.size());
+	}
+
+	public void testSerialization() throws Exception {
+		IdentityHashBag<String> bag2 = TestTools.serialize(this.bag);
+
+		assertTrue("same object?", this.bag != bag2);
+		assertEquals(11, bag2.size());
+		assertEquals(CollectionTools.bag(this.bag.iterator()), CollectionTools.bag(bag2.iterator()));
+		// look for similar elements
+		assertTrue(CollectionTools.bag(bag2.iterator()).contains(null));
+		assertTrue(CollectionTools.bag(bag2.iterator()).contains("one"));
+		assertTrue(CollectionTools.bag(bag2.iterator()).contains("two"));
+		assertTrue(CollectionTools.bag(bag2.iterator()).contains("three"));
+		assertTrue(CollectionTools.bag(bag2.iterator()).contains("four"));
+
+		int nullCount = 0, oneCount = 0, twoCount = 0, threeCount = 0, fourCount = 0;
+		for (String next : bag2) {
+			if (next == null)
+				nullCount++;
+			else if (next.equals("one"))
+				oneCount++;
+			else if (next.equals("two"))
+				twoCount++;
+			else if (next.equals("three"))
+				threeCount++;
+			else if (next.equals("four"))
+				fourCount++;
+		}
+		assertEquals(1, nullCount);
+		assertEquals(1, oneCount);
+		assertEquals(2, twoCount);
+		assertEquals(3, threeCount);
+		assertEquals(4, fourCount);
+	}
+
+	public void testToArray() {
+		Object[] a = this.bag.toArray();
+		assertEquals(11, a.length);
+		assertTrue(ArrayTools.contains(a, null));
+		assertTrue(ArrayTools.contains(a, this.one));
+		assertTrue(ArrayTools.contains(a, this.two));
+		assertTrue(ArrayTools.contains(a, this.three));
+		assertTrue(ArrayTools.contains(a, this.four));
+	}
+
+	public void testToArrayObjectArray() {
+		String[] a = new String[12];
+		a[11] = "not null";
+		String[] b = this.bag.toArray(a);
+		assertEquals(a, b);
+		assertEquals(12, a.length);
+		assertTrue(ArrayTools.contains(a, null));
+		assertTrue(ArrayTools.contains(a, this.one));
+		assertTrue(ArrayTools.contains(a, this.two));
+		assertTrue(ArrayTools.contains(a, this.three));
+		assertTrue(ArrayTools.contains(a, this.four));
+		assertTrue(a[11] == null);
+	}
+
+	public void testToString() {
+		String s = this.bag.toString();
+		assertTrue(s.startsWith("["));
+		assertTrue(s.endsWith("]"));
+		int commaCount = 0;
+		for (int i = 0; i < s.length(); i++) {
+			if (s.charAt(i) == ',') {
+				commaCount++;
+			}
+		}
+		assertEquals("invalid number of commas", 10, commaCount);
+		assertTrue(s.indexOf("one") != -1);
+		assertTrue(s.indexOf("two") != -1);
+		assertTrue(s.indexOf("three") != -1);
+		assertTrue(s.indexOf("four") != -1);
+		assertTrue(s.indexOf("null") != -1);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/LinkedQueueTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/LinkedQueueTests.java
new file mode 100644
index 0000000..d704276
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/LinkedQueueTests.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import org.eclipse.persistence.tools.utility.collection.LinkedQueue;
+import org.eclipse.persistence.tools.utility.collection.Queue;
+
+public class LinkedQueueTests
+	extends QueueTests
+{
+	public LinkedQueueTests(String name) {
+		super(name);
+	}
+
+	@Override
+	Queue<String> buildQueue() {
+		return new LinkedQueue<String>();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/LinkedStackTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/LinkedStackTests.java
new file mode 100644
index 0000000..113ba80
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/LinkedStackTests.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import org.eclipse.persistence.tools.utility.collection.LinkedStack;
+import org.eclipse.persistence.tools.utility.collection.Stack;
+
+public class LinkedStackTests
+	extends StackTests
+{
+	public LinkedStackTests(String name) {
+		super(name);
+	}
+
+	@Override
+	Stack<String> buildStack() {
+		return new LinkedStack<String>();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/ListToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/ListToolsTests.java
new file mode 100644
index 0000000..82b3131
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/ListToolsTests.java
@@ -0,0 +1,694 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.Vector;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ClassTools;
+import org.eclipse.persistence.tools.utility.Range;
+import org.eclipse.persistence.tools.utility.ReverseComparator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.iterable.EmptyIterable;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+import org.eclipse.persistence.tools.utility.tests.ArrayToolsTests;
+
+@SuppressWarnings("nls")
+public class ListToolsTests
+	extends TestCase
+{
+	public ListToolsTests(String name) {
+		super(name);
+	}
+	public void testAddAllListIntObjectArray() {
+		List<String> list = this.buildStringList1();
+		ListTools.addAll(list, 2, new String[] { "X", "X", "X" });
+		assertEquals(6, list.size());
+		assertTrue(list.contains("X"));
+		assertTrue(Arrays.equals(new Object[] { "zero", "one", "X", "X", "X", "two" }, list.toArray()));
+	}
+
+	public void testAddAllListIntObjectArray_Zero() {
+		List<String> list = new ArrayList<String>();
+		ListTools.addAll(list, 0, new String[] { "X", "X", "X" });
+		assertEquals(3, list.size());
+		assertTrue(list.contains("X"));
+		assertTrue(Arrays.equals(new Object[] { "X", "X", "X" }, list.toArray()));
+	}
+
+	public void testAddAllListIntObjectArray_EmptyArray() {
+		List<String> list = this.buildStringList1();
+		ListTools.addAll(list, 2, new String[0]);
+		assertEquals(3, list.size());
+		assertTrue(Arrays.equals(new Object[] { "zero", "one", "two" }, list.toArray()));
+	}
+
+	public void testAddAllListIntIterable() {
+		List<String> list = this.buildStringList1();
+		Iterable<String> iterable = Arrays.asList(new String[] { "X", "X", "X" });
+		ListTools.addAll(list, 2, iterable);
+		assertEquals(6, list.size());
+		assertTrue(list.contains("X"));
+		assertTrue(Arrays.equals(new Object[] { "zero", "one", "X", "X", "X", "two" }, list.toArray()));
+	}
+
+	public void testAddAllListIntIterable_Zero() {
+		List<String> list = new ArrayList<String>();
+		Iterable<String> iterable = Arrays.asList(new String[] { "X", "X", "X" });
+		ListTools.addAll(list, 0, iterable);
+		assertEquals(3, list.size());
+		assertTrue(list.contains("X"));
+		assertTrue(Arrays.equals(new Object[] { "X", "X", "X" }, list.toArray()));
+	}
+
+	public void testAddAllListIntIterable_EmptyIterable() {
+		List<String> list = this.buildStringList1();
+		Iterable<String> iterable = EmptyIterable.instance();
+		ListTools.addAll(list, 2, iterable);
+		assertEquals(3, list.size());
+		assertTrue(Arrays.equals(new Object[] { "zero", "one", "two" }, list.toArray()));
+	}
+
+	public void testAddAllListIntIterableInt() {
+		List<String> list = this.buildStringList1();
+		Iterable<String> iterable = Arrays.asList(new String[] { "X", "X", "X" });
+		ListTools.addAll(list, 2, iterable, 3);
+		assertEquals(6, list.size());
+		assertTrue(list.contains("X"));
+		assertTrue(Arrays.equals(new Object[] { "zero", "one", "X", "X", "X", "two" }, list.toArray()));
+	}
+
+	public void testAddAllListIntIterableInt_Zero() {
+		List<String> list = new ArrayList<String>();
+		Iterable<String> iterable = Arrays.asList(new String[] { "X", "X", "X" });
+		ListTools.addAll(list, 0, iterable, 3);
+		assertEquals(3, list.size());
+		assertTrue(list.contains("X"));
+		assertTrue(Arrays.equals(new Object[] { "X", "X", "X" }, list.toArray()));
+	}
+
+	public void testAddAllListIntIterableInt_EmptyIterable() {
+		List<String> list = this.buildStringList1();
+		Iterable<String> iterable = EmptyIterable.instance();
+		ListTools.addAll(list, 2, iterable, 0);
+		assertEquals(3, list.size());
+		assertTrue(Arrays.equals(new Object[] { "zero", "one", "two" }, list.toArray()));
+	}
+
+	public void testAddAllListIntIterator() {
+		List<String> list = this.buildStringList1();
+		Iterator<String> iterator = Arrays.asList(new String[] { "X", "X", "X" }).iterator();
+		ListTools.addAll(list, 2, iterator);
+		assertEquals(6, list.size());
+		assertTrue(list.contains("X"));
+		assertTrue(Arrays.equals(new Object[] { "zero", "one", "X", "X", "X", "two" }, list.toArray()));
+	}
+
+	public void testAddAllListIntIterator_Zero() {
+		List<String> list = new ArrayList<String>();
+		Iterator<String> iterator = Arrays.asList(new String[] { "X", "X", "X" }).iterator();
+		ListTools.addAll(list, 0, iterator);
+		assertEquals(3, list.size());
+		assertTrue(list.contains("X"));
+		assertTrue(Arrays.equals(new Object[] { "X", "X", "X" }, list.toArray()));
+	}
+
+	public void testAddAllListIntIterator_EmptyIterator() {
+		List<String> list = this.buildStringList1();
+		Iterator<String> iterator = EmptyIterator.instance();
+		ListTools.addAll(list, 2, iterator);
+		assertEquals(3, list.size());
+		assertTrue(Arrays.equals(new Object[] { "zero", "one", "two" }, list.toArray()));
+	}
+
+	public void testAddAllListIntIteratorInt() {
+		List<String> list = this.buildStringList1();
+		Iterator<String> iterator = Arrays.asList(new String[] { "X", "X", "X" }).iterator();
+		ListTools.addAll(list, 2, iterator, 3);
+		assertEquals(6, list.size());
+		assertTrue(list.contains("X"));
+		assertTrue(Arrays.equals(new Object[] { "zero", "one", "X", "X", "X", "two" }, list.toArray()));
+	}
+
+	public void testAddAllListIntIteratorInt_Zero() {
+		List<String> list = new ArrayList<String>();
+		Iterator<String> iterator = Arrays.asList(new String[] { "X", "X", "X" }).iterator();
+		ListTools.addAll(list, 0, iterator, 3);
+		assertEquals(3, list.size());
+		assertTrue(list.contains("X"));
+		assertTrue(Arrays.equals(new Object[] { "X", "X", "X" }, list.toArray()));
+	}
+
+	public void testAddAllListIntIteratorInt_EmptyIterator() {
+		List<String> list = this.buildStringList1();
+		Iterator<String> iterator = EmptyIterator.instance();
+		ListTools.addAll(list, 2, iterator, 0);
+		assertEquals(3, list.size());
+		assertTrue(Arrays.equals(new Object[] { "zero", "one", "two" }, list.toArray()));
+	}
+
+
+
+	// ********** diff **********
+
+	public void testIndexOfDifference() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("a");
+		list1.add("b");
+		list1.add("c");
+		List<String> list2 = new ArrayList<String>();
+		list2.add(new String("a"));
+		list2.add(new String("b"));
+		list2.add(new String("c"));
+		assertEquals(3, ListTools.indexOfDifference(list1, list2));
+	}
+
+	public void testLastIndexOfDifference() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("a");
+		list1.add("b");
+		list1.add("c");
+		List<String> list2 = new ArrayList<String>();
+		list2.add(new String("a"));
+		list2.add(new String("b"));
+		list2.add(new String("c"));
+		assertEquals(-1, ListTools.lastIndexOfDifference(list1, list2));
+	}
+
+	public void testDifferenceRange() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("a");
+		list1.add("b");
+		list1.add("c");
+		List<String> list2 = new ArrayList<String>();
+		list2.add(new String("a"));
+		list2.add(new String("b"));
+		list2.add(new String("c"));
+		assertEquals(new Range(3, -1), ListTools.differenceRange(list1, list2));
+	}
+
+
+	// ********** filter **********
+
+	public void testFilterListFilter() {
+		List<String> list = Arrays.asList(new String[] { "zero", "one", "two", "three", "four" });
+		List<String> actual = ListTools.filter(list, new ArrayToolsTests.StringLengthFilter(3));
+		List<String> expected = Arrays.asList(new String[] { "one", "two" });
+		assertEquals(expected, actual);
+	}
+
+	public void testFilterListFilterTransparent() {
+		List<String> list = Arrays.asList(new String[] { "zero", "one", "two", "three", "four" });
+		List<String> actual = ListTools.filter(list, Filter.Transparent.<String>instance());
+		List<String> expected = Arrays.asList(new String[] { "zero", "one", "two", "three", "four" });
+		assertEquals(expected, actual);
+		assertNotSame(expected, actual);
+	}
+
+
+	// ********** identity diff **********
+
+	public void testIndexOfIdentityDifference() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("a");
+		list1.add("b");
+		list1.add("c");
+		List<String> list2 = new ArrayList<String>();
+		list2.add("a");
+		list2.add("b");
+		list2.add("c");
+		assertEquals(3, ListTools.indexOfIdentityDifference(list1, list2));
+	}
+
+	public void testLastIndexOfIdentityDifference() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("a");
+		list1.add("b");
+		list1.add("c");
+		List<String> list2 = new ArrayList<String>();
+		list2.add("a");
+		list2.add("b");
+		list2.add("c");
+		assertEquals(-1, ListTools.lastIndexOfIdentityDifference(list1, list2));
+	}
+
+	public void testIdentityDifferenceRange() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("a");
+		list1.add("b");
+		list1.add("c");
+		List<String> list2 = new ArrayList<String>();
+		list2.add("a");
+		list2.add("b");
+		list2.add("c");
+		assertEquals(new Range(3, -1), ListTools.identityDifferenceRange(list1, list2));
+	}
+
+
+	// ********** insertion index of **********
+
+	public void testInsertionIndexOfListComparableRandomAccess() {
+		List<String> list = Arrays.asList(new String[] { "A", "C", "D" });
+		assertEquals(1, ListTools.insertionIndexOf(list, "B"));
+
+		list = Arrays.asList(new String[] { "A", "B", "C", "D" });
+		assertEquals(2, ListTools.insertionIndexOf(list, "B"));
+
+		list = Arrays.asList(new String[] { "A", "B", "B", "B", "C", "D" });
+		assertEquals(4, ListTools.insertionIndexOf(list, "B"));
+
+		list = Arrays.asList(new String[] { "A", "B", "B", "B", "C", "D" });
+		assertEquals(6, ListTools.insertionIndexOf(list, "E"));
+
+		list = Arrays.asList(new String[] { "B", "B", "B", "C", "D" });
+		assertEquals(0, ListTools.insertionIndexOf(list, "A"));
+
+		list = Arrays.asList(new String[] { "A", "A", "B", "B", "C", "D" });
+		assertEquals(2, ListTools.insertionIndexOf(list, "A"));
+	}
+
+	public void testInsertionIndexOfListComparableNonRandomAccess() {
+		List<String> list = new LinkedList<String>(Arrays.asList(new String[] { "A", "C", "D" }));
+		assertEquals(1, ListTools.insertionIndexOf(list, "B"));
+
+		list = new LinkedList<String>(Arrays.asList(new String[] { "A", "B", "C", "D" }));
+		assertEquals(1, ListTools.insertionIndexOf(list, "B"));
+
+		list = new LinkedList<String>(Arrays.asList(new String[] { "A", "B", "B", "B", "C", "D" }));
+		assertEquals(1, ListTools.insertionIndexOf(list, "B"));
+
+		list = new LinkedList<String>(Arrays.asList(new String[] { "A", "B", "B", "B", "C", "D" }));
+		assertEquals(6, ListTools.insertionIndexOf(list, "E"));
+
+		list = new LinkedList<String>(Arrays.asList(new String[] { "B", "B", "B", "C", "D" }));
+		assertEquals(0, ListTools.insertionIndexOf(list, "A"));
+
+		list = new LinkedList<String>(Arrays.asList(new String[] { "A", "A", "B", "B", "C", "D" }));
+		assertEquals(0, ListTools.insertionIndexOf(list, "A"));
+	}
+
+	public void testInsertionIndexOfListObjectComparatorRandomAccess() {
+		Comparator<String> c = new ReverseComparator<String>();
+		List<String> list = Arrays.asList(new String[] { "D", "C", "A" });
+		assertEquals(2, ListTools.insertionIndexOf(list, "B", c));
+
+		list = Arrays.asList(new String[] { "D", "C", "B", "A" });
+		assertEquals(3, ListTools.insertionIndexOf(list, "B", c));
+
+		list = Arrays.asList(new String[] { "D", "C", "B", "B", "B", "A" });
+		assertEquals(5, ListTools.insertionIndexOf(list, "B", c));
+
+		list = Arrays.asList(new String[] { "D", "C", "B", "B", "B", "A" });
+		assertEquals(0, ListTools.insertionIndexOf(list, "E", c));
+
+		list = Arrays.asList(new String[] { "D", "C", "B", "B", "B" });
+		assertEquals(5, ListTools.insertionIndexOf(list, "A", c));
+
+		list = Arrays.asList(new String[] { "D", "C", "B", "B", "A", "A" });
+		assertEquals(6, ListTools.insertionIndexOf(list, "A", c));
+	}
+
+	public void testInsertionIndexOfListObjectComparatorNonRandomAccess() {
+		Comparator<String> c = new ReverseComparator<String>();
+		List<String> list = new LinkedList<String>(Arrays.asList(new String[] { "D", "C", "A" }));
+		assertEquals(2, ListTools.insertionIndexOf(list, "B", c));
+
+		list = new LinkedList<String>(Arrays.asList(new String[] { "D", "C", "B", "A" }));
+		assertEquals(2, ListTools.insertionIndexOf(list, "B", c));
+
+		list = new LinkedList<String>(Arrays.asList(new String[] { "D", "C", "B", "B", "B", "A" }));
+		assertEquals(2, ListTools.insertionIndexOf(list, "B", c));
+
+		list = new LinkedList<String>(Arrays.asList(new String[] { "D", "C", "B", "B", "B", "A" }));
+		assertEquals(0, ListTools.insertionIndexOf(list, "E", c));
+
+		list = new LinkedList<String>(Arrays.asList(new String[] { "D", "C", "B", "B", "B" }));
+		assertEquals(5, ListTools.insertionIndexOf(list, "A", c));
+
+		list = new LinkedList<String>(Arrays.asList(new String[] { "D", "C", "B", "B", "A", "A" }));
+		assertEquals(4, ListTools.insertionIndexOf(list, "A", c));
+	}
+
+
+	// ********** list **********
+
+	public void testListIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertEquals(this.buildStringList1(), ListTools.list(iterable));
+	}
+
+	public void testListIterableInt() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertEquals(this.buildStringList1(), ListTools.list(iterable, 3));
+	}
+
+	public void testListIterator_String() {
+		List<String> list = ListTools.list(this.buildStringList1().iterator());
+		assertEquals(this.buildStringList1(), list);
+	}
+
+	public void testListIterator_StringObject() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("0");
+		list1.add("1");
+		list1.add("2");
+		list1.add("3");
+
+		List<Object> list2 = ListTools.<Object>list(list1.iterator());
+		assertEquals(list1, list2);
+	}
+
+	public void testListIterator_Empty() {
+		assertEquals(0, ListTools.list(EmptyIterator.instance()).size());
+	}
+
+	public void testListIteratorInt() {
+		List<String> list = ListTools.list(this.buildStringList1().iterator(), 3);
+		assertEquals(this.buildStringList1(), list);
+	}
+
+	public void testListIteratorInt_Empty() {
+		assertEquals(0, ListTools.list(EmptyIterator.instance(), 5).size());
+	}
+
+	public void testListObjectArray() {
+		List<String> list = ListTools.list(this.buildStringArray1());
+		assertEquals(this.buildStringList1(), list);
+	}
+
+
+	// ********** move **********
+
+	public void testMoveListIntIntRandomAccess() {
+		List<String> list = new ArrayList<String>();
+		CollectionTools.addAll(list, new String[] { "0", "1", "2", "3", "4", "5" });
+
+		List<String> result = ListTools.move(list, 4, 2);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result.toArray()));
+
+		result = ListTools.move(list, 0, 5);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result.toArray()));
+
+		result = ListTools.move(list, 2, 4);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result.toArray()));
+
+		result = ListTools.move(list, 2, 2);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result.toArray()));
+	}
+
+	public void testMoveListIntIntSequentialAccess() {
+		List<String> list = new LinkedList<String>();
+		CollectionTools.addAll(list, new String[] { "0", "1", "2", "3", "4", "5" });
+
+		List<String> result = ListTools.move(list, 4, 2);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result.toArray()));
+
+		result = ListTools.move(list, 0, 5);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result.toArray()));
+
+		result = ListTools.move(list, 2, 4);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result.toArray()));
+
+		result = ListTools.move(list, 2, 2);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result.toArray()));
+	}
+
+	public void testMoveListIntIntIntRandomAccess() {
+		List<String> list = new ArrayList<String>(Arrays.asList(new String[] { "0", "1", "2", "3", "4", "5" }));
+
+		List<String> result = ListTools.move(list, 4, 2, 1);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result.toArray()));
+
+		result = ListTools.move(list, 0, 5, 1);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result.toArray()));
+
+		result = ListTools.move(list, 2, 4, 1);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result.toArray()));
+
+		result = ListTools.move(list, 2, 4, 2);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
+
+		result = ListTools.move(list, 0, 1, 4);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "3", "2", "4", "5", "1" }, result.toArray()));
+
+		result = ListTools.move(list, 1, 0, 4);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
+
+		result = ListTools.move(list, 1, 1, 4);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
+
+		result = ListTools.move(list, 1, 0, 0);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
+	}
+
+	public void testMoveListIntIntIntSequentialAccess() {
+		List<String> list = new LinkedList<String>(Arrays.asList(new String[] { "0", "1", "2", "3", "4", "5" }));
+
+		List<String> result = ListTools.move(list, 4, 2, 1);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result.toArray()));
+
+		result = ListTools.move(list, 0, 5, 1);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result.toArray()));
+
+		result = ListTools.move(list, 2, 4, 1);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result.toArray()));
+
+		result = ListTools.move(list, 2, 4, 2);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
+
+		result = ListTools.move(list, 0, 1, 4);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "3", "2", "4", "5", "1" }, result.toArray()));
+
+		result = ListTools.move(list, 1, 0, 4);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
+
+		result = ListTools.move(list, 1, 1, 4);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
+
+		result = ListTools.move(list, 1, 0, 0);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
+	}
+
+
+	// ********** remove elements at index **********
+
+	public void testRemoveElementsAtIndexListIntInt() {
+		List<String> list = new ArrayList<String>(Arrays.asList(new String[] { "A", "B", "A", "C", "A", "D" }));
+		List<String> removed = ListTools.removeElementsAtIndex(list, 3, 2);
+		assertTrue(Arrays.equals(new String[] { "A", "B", "A", "D" }, list.toArray()));
+		assertTrue(Arrays.equals(new String[] { "C", "A" }, removed.toArray()));
+
+		list = new ArrayList<String>(Arrays.asList(new String[] { "A", "B", "C", "D", "E", "F" }));
+		removed = ListTools.removeElementsAtIndex(list, 3, 3);
+		assertTrue(Arrays.equals(new String[] { "A", "B", "C" }, list.toArray()));
+		assertTrue(Arrays.equals(new String[] { "D", "E", "F" }, removed.toArray()));
+
+		list = new ArrayList<String>(Arrays.asList(new String[] { "A", "B", "C", "D", "E", "F" }));
+		removed = ListTools.removeElementsAtIndex(list, 0, 3);
+		assertTrue(Arrays.equals(new String[] { "D", "E", "F" }, list.toArray()));
+		assertTrue(Arrays.equals(new String[] { "A", "B", "C" }, removed.toArray()));
+	}
+
+
+	// ********** remove duplicate elements **********
+
+	public void testRemoveDuplicateElementsList1() {
+		List<String> list = this.buildStringVector1();
+		list.add("zero");
+		list.add("zero");
+		list.add("two");
+		list.add("zero");
+		assertTrue(ListTools.removeDuplicateElements(list));
+		int i = 0;
+		assertEquals("zero", list.get(i++));
+		assertEquals("one", list.get(i++));
+		assertEquals("two", list.get(i++));
+		assertEquals(i, list.size());
+	}
+
+	public void testRemoveDuplicateElementsList2() {
+		List<String> list = this.buildStringVector1();
+		assertFalse(ListTools.removeDuplicateElements(list));
+		int i = 0;
+		assertEquals("zero", list.get(i++));
+		assertEquals("one", list.get(i++));
+		assertEquals("two", list.get(i++));
+		assertEquals(i, list.size());
+	}
+
+	public void testRemoveDuplicateElementsList_Empty() {
+		List<String> list = new ArrayList<String>();
+		assertFalse(ListTools.removeDuplicateElements(list));
+		assertEquals(0, list.size());
+	}
+
+	public void testRemoveDuplicateElementsList_SingleElement() {
+		List<String> list = new ArrayList<String>();
+		list.add("zero");
+		assertFalse(ListTools.removeDuplicateElements(list));
+		assertEquals(1, list.size());
+	}
+
+
+	// ********** rotate **********
+
+	public void testRotateList() {
+		List<String> actual = ListTools.rotate(this.buildStringList1());
+		List<String> expected = this.buildStringList1();
+		Collections.rotate(expected, 1);
+		assertEquals(expected, actual);
+	}
+
+
+	// ********** transform **********
+
+	public void testTransformListTransformer() {
+		List<String> list = Arrays.asList(new String[] { "zero", "one", "two" });
+		List<String> actual = ListTools.transform(list, ArrayToolsTests.UPPER_CASE_TRANSFORMER);
+		List<Object> expected = Arrays.asList(new Object[] { "ZERO", "ONE", "TWO" });
+		assertEquals(expected, actual);
+	}
+
+
+	// ********** java.util.Collections enhancements **********
+
+	public void testCopyListList() {
+		List<String> src = this.buildStringList1();
+		List<String> dest = new ArrayList<String>();
+		for (String s : src) {
+			dest.add(s.toUpperCase());
+		}
+		List<String> result = ListTools.copy(dest, src);
+		assertSame(dest, result);
+	}
+
+	public void testFillListObject() {
+		List<String> list = this.buildStringList1();
+		List<String> result = ListTools.fill(list, "foo");
+		assertSame(list, result);
+		for (String string : result) {
+			assertEquals("foo", string);
+		}
+	}
+
+	public void testShuffleList() {
+		List<String> list = this.buildStringList1();
+		List<String> result = ListTools.shuffle(list);
+		assertSame(list, result);
+	}
+
+	public void testShuffleListRandom() {
+		List<String> list = this.buildStringList1();
+		List<String> result = ListTools.shuffle(list, new Random());
+		assertSame(list, result);
+	}
+
+	public void testSortList() {
+		List<String> list = this.buildStringList1();
+		SortedSet<String> ss = new TreeSet<String>();
+		ss.addAll(list);
+		List<String> result = ListTools.sort(list);
+		assertSame(list, result);
+	}
+
+	public void testSwapListIntInt() {
+		List<String> list = this.buildStringList1();
+		List<String> result = ListTools.swap(list, 0, 1);
+		assertSame(list, result);
+		List<String> original = this.buildStringList1();
+		assertEquals(original.get(0), result.get(1));
+		assertEquals(original.get(1), result.get(0));
+		assertEquals(original.get(2), result.get(2));
+	}
+
+
+	// ********** constructor **********
+
+	public void testConstructor() {
+		boolean exCaught = false;
+		try {
+			Object at = ClassTools.newInstance(ListTools.class);
+			fail("bogus: " + at); //$NON-NLS-1$
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof InvocationTargetException) {
+				if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+
+	// ********** test harness **********
+
+	private String[] buildStringArray1() {
+		return new String[] { "zero", "one", "two" };
+	}
+
+	private Vector<String> buildStringVector1() {
+		Vector<String> v = new Vector<String>();
+		this.addToCollection1(v);
+		return v;
+	}
+
+	private List<String> buildStringList1() {
+		List<String> l = new ArrayList<String>();
+		this.addToCollection1(l);
+		return l;
+	}
+
+	private void addToCollection1(Collection<? super String> c) {
+		c.add("zero");
+		c.add("one");
+		c.add("two");
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/NullElementListTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/NullElementListTests.java
new file mode 100644
index 0000000..2f73a91
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/NullElementListTests.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import java.util.List;
+import org.eclipse.persistence.tools.utility.collection.NullElementList;
+
+public class NullElementListTests
+	extends AbstractRepeatingElementListTests
+{
+	public NullElementListTests(String name) {
+		super(name);
+	}
+
+	@Override
+	public List<String> buildList(int size) {
+		return new NullElementList<String>(size);
+	}
+
+	@Override
+	public String getElement() {
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/QueueTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/QueueTests.java
new file mode 100644
index 0000000..d14f7ce
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/QueueTests.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.Queue;
+import org.eclipse.persistence.tools.utility.tests.MultiThreadedTestCase;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+// subclass MultiThreadedTestCase for subclasses of this class
+@SuppressWarnings("nls")
+public abstract class QueueTests
+	extends MultiThreadedTestCase
+{
+	public QueueTests(String name) {
+		super(name);
+	}
+
+	abstract Queue<String> buildQueue();
+
+	public void testIsEmpty() {
+		Queue<String> queue = this.buildQueue();
+		assertTrue(queue.isEmpty());
+		queue.enqueue("first");
+		assertFalse(queue.isEmpty());
+		queue.enqueue("second");
+		assertFalse(queue.isEmpty());
+		queue.dequeue();
+		assertFalse(queue.isEmpty());
+		queue.dequeue();
+		assertTrue(queue.isEmpty());
+	}
+
+	public void testEnqueueAndDequeue() {
+		Queue<String> queue = this.buildQueue();
+		String first = "first";
+		String second = "second";
+
+		queue.enqueue(first);
+		queue.enqueue(second);
+		assertEquals(first, queue.dequeue());
+		assertEquals(second, queue.dequeue());
+	}
+
+	public void testEnqueueAndPeek() {
+		Queue<String> queue = this.buildQueue();
+		String first = "first";
+		String second = "second";
+
+		queue.enqueue(first);
+		queue.enqueue(second);
+		assertEquals(first, queue.peek());
+		assertEquals(first, queue.peek());
+		assertEquals(first, queue.dequeue());
+		assertEquals(second, queue.peek());
+		assertEquals(second, queue.peek());
+		assertEquals(second, queue.dequeue());
+	}
+
+	public void testEmptyQueueExceptionPeek() {
+		Queue<String> queue = this.buildQueue();
+		String first = "first";
+		String second = "second";
+
+		queue.enqueue(first);
+		queue.enqueue(second);
+		assertEquals(first, queue.peek());
+		assertEquals(first, queue.dequeue());
+		assertEquals(second, queue.peek());
+		assertEquals(second, queue.dequeue());
+
+		boolean exCaught = false;
+		try {
+			queue.peek();
+			fail();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testEmptyQueueExceptionDequeue() {
+		Queue<String> queue = this.buildQueue();
+		String first = "first";
+		String second = "second";
+
+		queue.enqueue(first);
+		queue.enqueue(second);
+		assertEquals(first, queue.peek());
+		assertEquals(first, queue.dequeue());
+		assertEquals(second, queue.peek());
+		assertEquals(second, queue.dequeue());
+
+		boolean exCaught = false;
+		try {
+			queue.dequeue();
+			fail();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testClone() {
+		Queue<String> queue = this.buildQueue();
+		queue.enqueue("first");
+		queue.enqueue("second");
+		queue.enqueue("third");
+
+		@SuppressWarnings("unchecked")
+		Queue<String> clone = (Queue<String>) ObjectTools.execute(queue, "clone");
+		this.verifyClone(queue, clone);
+	}
+
+	public void testSerialization() throws Exception {
+		Queue<String> queue = this.buildQueue();
+		queue.enqueue("first");
+		queue.enqueue("second");
+		queue.enqueue("third");
+
+		this.verifyClone(queue, TestTools.serialize(queue));
+	}
+
+	private void verifyClone(Queue<String> original, Queue<String> clone) {
+		assertNotSame(original, clone);
+		assertEquals(original.peek(), clone.peek());
+		assertEquals(original.dequeue(), clone.dequeue());
+		assertEquals(original.peek(), clone.peek());
+		assertEquals(original.dequeue(), clone.dequeue());
+		assertEquals(original.isEmpty(), clone.isEmpty());
+		assertEquals(original.peek(), clone.peek());
+		assertEquals(original.dequeue(), clone.dequeue());
+		assertTrue(original.isEmpty());
+		assertEquals(original.isEmpty(), clone.isEmpty());
+
+		original.enqueue("fourth");
+		assertFalse(original.isEmpty());
+		// clone should still be empty
+		assertTrue(clone.isEmpty());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/RepeatingElementListTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/RepeatingElementListTests.java
new file mode 100644
index 0000000..07d0c5c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/RepeatingElementListTests.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import java.util.List;
+import org.eclipse.persistence.tools.utility.collection.RepeatingElementList;
+
+
+@SuppressWarnings("nls")
+public class RepeatingElementListTests
+	extends AbstractRepeatingElementListTests
+{
+	public RepeatingElementListTests(String name) {
+		super(name);
+	}
+
+	@Override
+	public List<String> buildList(int size) {
+		return new RepeatingElementList<String>(this.getElement(), size);
+	}
+
+	@Override
+	public String getElement() {
+		return "repeating element";
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/StackTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/StackTests.java
new file mode 100644
index 0000000..a9976a3
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/StackTests.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import java.util.EmptyStackException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.Stack;
+import org.eclipse.persistence.tools.utility.tests.MultiThreadedTestCase;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+//subclass MultiThreadedTestCase for subclasses of this class
+@SuppressWarnings("nls")
+public abstract class StackTests
+	extends MultiThreadedTestCase
+{
+	public StackTests(String name) {
+		super(name);
+	}
+
+	abstract Stack<String> buildStack();
+
+	public void testIsEmpty() {
+		Stack<String> stack = this.buildStack();
+		assertTrue(stack.isEmpty());
+		stack.push("first");
+		assertFalse(stack.isEmpty());
+		stack.push("second");
+		assertFalse(stack.isEmpty());
+		stack.pop();
+		assertFalse(stack.isEmpty());
+		stack.pop();
+		assertTrue(stack.isEmpty());
+	}
+
+	public void testPushAndPop() {
+		Stack<String> stack = this.buildStack();
+		String first = "first";
+		String second = "second";
+
+		stack.push(first);
+		stack.push(second);
+		assertEquals(second, stack.pop());
+		assertEquals(first, stack.pop());
+	}
+
+	public void testPushAndPeek() {
+		Stack<String> stack = this.buildStack();
+		String first = "first";
+		String second = "second";
+
+		stack.push(first);
+		stack.push(second);
+		assertEquals(second, stack.peek());
+		assertEquals(second, stack.peek());
+		assertEquals(second, stack.pop());
+		assertEquals(first, stack.peek());
+		assertEquals(first, stack.peek());
+		assertEquals(first, stack.pop());
+	}
+
+	public void testEmptyStackExceptionPeek() {
+		Stack<String> stack = this.buildStack();
+		String first = "first";
+		String second = "second";
+
+		stack.push(first);
+		stack.push(second);
+		assertEquals(second, stack.peek());
+		assertEquals(second, stack.pop());
+		assertEquals(first, stack.peek());
+		assertEquals(first, stack.pop());
+
+		boolean exCaught = false;
+		try {
+			stack.peek();
+			fail();
+		} catch (EmptyStackException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testEmptyStackExceptionPop() {
+		Stack<String> stack = this.buildStack();
+		String first = "first";
+		String second = "second";
+
+		stack.push(first);
+		stack.push(second);
+		assertEquals(second, stack.peek());
+		assertEquals(second, stack.pop());
+		assertEquals(first, stack.peek());
+		assertEquals(first, stack.pop());
+
+		boolean exCaught = false;
+		try {
+			stack.pop();
+			fail();
+		} catch (EmptyStackException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testClone() {
+		Stack<String> stack = this.buildStack();
+		stack.push("first");
+		stack.push("second");
+		stack.push("third");
+
+		@SuppressWarnings("unchecked")
+		Stack<String> clone = (Stack<String>) ObjectTools.execute(stack, "clone");
+		this.verifyClone(stack, clone);
+	}
+
+	public void testSerialization() throws Exception {
+		Stack<String> stack = this.buildStack();
+		stack.push("first");
+		stack.push("second");
+		stack.push("third");
+
+		this.verifyClone(stack, TestTools.serialize(stack));
+	}
+
+	private void verifyClone(Stack<String> original, Stack<String> clone) {
+		assertNotSame(original, clone);
+		assertEquals(original.peek(), clone.peek());
+		assertEquals(original.pop(), clone.pop());
+		assertEquals(original.peek(), clone.peek());
+		assertEquals(original.pop(), clone.pop());
+		assertEquals(original.isEmpty(), clone.isEmpty());
+		assertEquals(original.peek(), clone.peek());
+		assertEquals(original.pop(), clone.pop());
+		assertTrue(original.isEmpty());
+		assertEquals(original.isEmpty(), clone.isEmpty());
+
+		original.push("fourth");
+		assertFalse(original.isEmpty());
+		// clone should still be empty
+		assertTrue(clone.isEmpty());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/SynchronizedQueueTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/SynchronizedQueueTests.java
new file mode 100644
index 0000000..6cf8ce9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/SynchronizedQueueTests.java
@@ -0,0 +1,269 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.collection.LinkedQueue;
+import org.eclipse.persistence.tools.utility.collection.Queue;
+import org.eclipse.persistence.tools.utility.collection.SynchronizedQueue;
+
+@SuppressWarnings("nls")
+public class SynchronizedQueueTests
+	extends QueueTests
+{
+	private volatile SynchronizedQueue<String> sq;
+	volatile boolean timeoutOccurred;
+	volatile long startTime;
+	volatile long endTime;
+	volatile Object dequeuedObject;
+
+	static final String ITEM_1 = new String();
+	static final String ITEM_2 = new String();
+
+	public SynchronizedQueueTests(String name) {
+		super(name);
+	}
+
+	@Override
+	Queue<String> buildQueue() {
+		return new SynchronizedQueue<String>();
+	}
+
+	@Override
+	public void testClone() {
+		// synchronized queue is not cloneable
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.sq = new SynchronizedQueue<String>();
+		this.timeoutOccurred = false;
+		this.startTime = 0;
+		this.endTime = 0;
+		this.dequeuedObject = null;
+	}
+
+	/**
+	 * test first with an unsynchronized queue,
+	 * then with a synchronized queue
+	 */
+	public void testConcurrentAccess() throws Exception {
+		this.verifyConcurrentAccess(new SlowLinkedQueue<String>(), "first");
+		this.verifyConcurrentAccess(new SlowSynchronizedQueue<String>(), "second");
+	}
+
+	private void verifyConcurrentAccess(SlowQueue<String> slowQueue, String expected) throws Exception {
+		slowQueue.enqueue("first");
+		slowQueue.enqueue("second");
+
+		Thread thread = this.buildThread(this.buildRunnable(slowQueue));
+		thread.start();
+		Thread.sleep(TWO_TICKS);
+
+		assertEquals(expected, slowQueue.dequeue());
+		thread.join();
+		assertTrue(slowQueue.isEmpty());
+	}
+
+	private Runnable buildRunnable(final SlowQueue<String> slowQueue) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				slowQueue.slowDequeue();
+			}
+		};
+	}
+
+
+	private interface SlowQueue<E> extends Queue<E> {
+		Object slowDequeue();
+	}
+
+	private class SlowLinkedQueue<E> extends LinkedQueue<E> implements SlowQueue<E> {
+		private static final long serialVersionUID = 1L;
+		SlowLinkedQueue() {
+			super();
+		}
+		@Override
+		public Object slowDequeue() {
+			try {
+				Thread.sleep(5 * TICK);
+			} catch (InterruptedException ex) {
+				throw new RuntimeException(ex);
+			}
+			return this.dequeue();
+		}
+
+	}
+
+	private class SlowSynchronizedQueue<E> extends SynchronizedQueue<E> implements SlowQueue<E> {
+		private static final long serialVersionUID = 1L;
+		SlowSynchronizedQueue() {
+			super();
+		}
+		@Override
+		public synchronized Object slowDequeue() {
+			try {
+				Thread.sleep(5 * TICK);
+			} catch (InterruptedException ex) {
+				throw new RuntimeException(ex);
+			}
+			return this.dequeue();
+		}
+
+	}
+
+
+	// ********** waits **********
+
+	public void testWaitToDequeue() throws Exception {
+		this.verifyWaitToDequeue(0);
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and an item should have been dequeued by t2...
+		assertSame(ITEM_1, this.dequeuedObject);
+		// ...and the queue should be empty
+		assertTrue(this.sq.isEmpty());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.calculateElapsedTime() > TICK);
+	}
+
+	public void testWaitToDequeueTimeout() throws Exception {
+		this.verifyWaitToDequeue(TICK);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the queue was never dequeued...
+		assertNull(this.dequeuedObject);
+		// ...and it still holds the item
+		assertSame(ITEM_1, this.sq.peek());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.calculateElapsedTime() < THREE_TICKS);
+	}
+
+	private void verifyWaitToDequeue(long timeout) throws Exception {
+		Runnable r1 = this.buildRunnable(this.buildEnqueueCommand(), this.sq, TWO_TICKS);
+		Runnable r2 = this.buildRunnable(this.buildWaitToDequeueCommand(timeout), this.sq, 0);
+		Thread t1 = this.buildThread(r1);
+		Thread t2 = this.buildThread(r2);
+		t1.start();
+		t2.start();
+		t1.join();
+		t2.join();
+	}
+
+	public void testWaitToEnqueue() throws Exception {
+		this.verifyWaitToEnqueue(0);
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and the queue gets dequeued by t1...
+		assertSame(ITEM_1, this.dequeuedObject);
+		// ...and an item is enqueued on to the queue by t2
+		assertFalse(this.sq.isEmpty());
+		assertSame(ITEM_2, this.sq.peek());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.calculateElapsedTime() > TICK);
+	}
+
+	public void testWaitToEnqueueTimeout() throws Exception {
+		this.verifyWaitToEnqueue(TICK);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the queue is eventually dequeued by t1...
+		assertSame(ITEM_1, this.dequeuedObject);
+		// ...but nothing is enqueued on to the queue by t2
+		assertTrue(this.sq.isEmpty());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.calculateElapsedTime() < THREE_TICKS);
+	}
+
+	private void verifyWaitToEnqueue(long timeout) throws Exception {
+		this.sq.enqueue(ITEM_1);
+		Runnable r1 = this.buildRunnable(this.buildDequeueCommand(), this.sq, TWO_TICKS);
+		Runnable r2 = this.buildRunnable(this.buildWaitToEnqueueCommand(timeout), this.sq, 0);
+		Thread t1 = this.buildThread(r1);
+		Thread t2 = this.buildThread(r2);
+		t1.start();
+		t2.start();
+		t1.join();
+		t2.join();
+	}
+
+	private Command buildEnqueueCommand() {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedQueue<String> synchronizedQueue) {
+				synchronizedQueue.enqueue(ITEM_1);
+			}
+		};
+	}
+
+	private Command buildWaitToDequeueCommand(final long timeout) {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedQueue<String> synchronizedQueue) throws InterruptedException {
+				SynchronizedQueueTests.this.startTime = System.currentTimeMillis();
+				try {
+					SynchronizedQueueTests.this.dequeuedObject = synchronizedQueue.waitToDequeue(timeout);
+				} catch (NoSuchElementException ex) {
+					SynchronizedQueueTests.this.timeoutOccurred = true;
+				}
+				SynchronizedQueueTests.this.endTime = System.currentTimeMillis();
+			}
+		};
+	}
+
+	private Command buildDequeueCommand() {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedQueue<String> synchronizedQueue) {
+				SynchronizedQueueTests.this.dequeuedObject = synchronizedQueue.dequeue();
+			}
+		};
+	}
+
+	private Command buildWaitToEnqueueCommand(final long timeout) {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedQueue<String> synchronizedQueue) throws InterruptedException {
+				SynchronizedQueueTests.this.startTime = System.currentTimeMillis();
+				SynchronizedQueueTests.this.timeoutOccurred = ! synchronizedQueue.waitToEnqueue(ITEM_2, timeout);
+				SynchronizedQueueTests.this.endTime = System.currentTimeMillis();
+			}
+		};
+	}
+
+	private Runnable buildRunnable(final Command command, final SynchronizedQueue<String> synchronizedQueue, final long sleep) {
+		return new TestRunnable() {
+			@Override
+			protected void run_() throws Throwable {
+				if (sleep != 0) {
+					Thread.sleep(sleep);
+				}
+				command.execute(synchronizedQueue);
+			}
+		};
+	}
+
+	long calculateElapsedTime() {
+		return this.endTime - this.startTime;
+	}
+
+
+	// ********** Command interface **********
+
+	private interface Command {
+		void execute(SynchronizedQueue<String> synchronizedQueue) throws InterruptedException;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/SynchronizedStackTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/SynchronizedStackTests.java
new file mode 100644
index 0000000..4521c0d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/collection/SynchronizedStackTests.java
@@ -0,0 +1,269 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.collection;
+
+import java.util.EmptyStackException;
+import org.eclipse.persistence.tools.utility.collection.LinkedStack;
+import org.eclipse.persistence.tools.utility.collection.Stack;
+import org.eclipse.persistence.tools.utility.collection.SynchronizedStack;
+
+@SuppressWarnings("nls")
+public class SynchronizedStackTests
+	extends StackTests
+{
+	private volatile SynchronizedStack<String> ss;
+	volatile boolean timeoutOccurred;
+	volatile long startTime;
+	volatile long endTime;
+	volatile Object poppedObject;
+
+	static final String ITEM_1 = new String();
+	static final String ITEM_2 = new String();
+
+	public SynchronizedStackTests(String name) {
+		super(name);
+	}
+
+	@Override
+	Stack<String> buildStack() {
+		return new SynchronizedStack<String>();
+	}
+
+	@Override
+	public void testClone() {
+		// synchronized stack is not cloneable
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.ss = new SynchronizedStack<String>();
+		this.timeoutOccurred = false;
+		this.startTime = 0;
+		this.endTime = 0;
+		this.poppedObject = null;
+	}
+
+	/**
+	 * test first with an unsynchronized stack,
+	 * then with a synchronized stack
+	 */
+	public void testConcurrentAccess() throws Exception {
+		this.verifyConcurrentAccess(new SlowLinkedStack<String>(), "second");
+		this.verifyConcurrentAccess(new SlowSynchronizedStack<String>(), "first");
+	}
+
+	private void verifyConcurrentAccess(SlowStack<String> slowStack, String expected) throws Exception {
+		slowStack.push("first");
+		slowStack.push("second");
+
+		Thread thread = this.buildThread(this.buildRunnable(slowStack));
+		thread.start();
+		Thread.sleep(TWO_TICKS);
+
+		assertEquals(expected, slowStack.pop());
+		thread.join();
+		assertTrue(slowStack.isEmpty());
+	}
+
+	private Runnable buildRunnable(final SlowStack<String> slowStack) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				slowStack.slowPop();
+			}
+		};
+	}
+
+
+	private interface SlowStack<E> extends Stack<E> {
+		Object slowPop();
+	}
+
+	private class SlowLinkedStack<E> extends LinkedStack<E> implements SlowStack<E> {
+		private static final long serialVersionUID = 1L;
+		SlowLinkedStack() {
+			super();
+		}
+		@Override
+		public Object slowPop() {
+			try {
+				Thread.sleep(5 * TICK);
+			} catch (InterruptedException ex) {
+				throw new RuntimeException(ex);
+			}
+			return this.pop();
+		}
+
+	}
+
+	private class SlowSynchronizedStack<E> extends SynchronizedStack<E> implements SlowStack<E> {
+		private static final long serialVersionUID = 1L;
+		SlowSynchronizedStack() {
+			super();
+		}
+		@Override
+		public synchronized Object slowPop() {
+			try {
+				Thread.sleep(5 * TICK);
+			} catch (InterruptedException ex) {
+				throw new RuntimeException(ex);
+			}
+			return this.pop();
+		}
+
+	}
+
+
+	// ********** waits **********
+
+	public void testWaitToPop() throws Exception {
+		this.verifyWaitToPop(0);
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and an item should have been popped by t2...
+		assertSame(ITEM_1, this.poppedObject);
+		// ...and the stack should be empty
+		assertTrue(this.ss.isEmpty());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.calculateElapsedTime() > TICK);
+	}
+
+	public void testWaitToPopTimeout() throws Exception {
+		this.verifyWaitToPop(TICK);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the stack was never popped...
+		assertNull(this.poppedObject);
+		// ...and it still holds the item
+		assertSame(ITEM_1, this.ss.peek());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.calculateElapsedTime() < THREE_TICKS);
+	}
+
+	private void verifyWaitToPop(long timeout) throws Exception {
+		Runnable r1 = this.buildRunnable(this.buildPushCommand(), this.ss, TWO_TICKS);
+		Runnable r2 = this.buildRunnable(this.buildWaitToPopCommand(timeout), this.ss, 0);
+		Thread t1 = this.buildThread(r1);
+		Thread t2 = this.buildThread(r2);
+		t1.start();
+		t2.start();
+		t1.join();
+		t2.join();
+	}
+
+	public void testWaitToPush() throws Exception {
+		this.verifyWaitToPush(0);
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and the stack gets popped by t1...
+		assertSame(ITEM_1, this.poppedObject);
+		// ...and an item is pushed on to the stack by t2
+		assertFalse(this.ss.isEmpty());
+		assertSame(ITEM_2, this.ss.peek());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.calculateElapsedTime() > TICK);
+	}
+
+	public void testWaitToPushTimeout() throws Exception {
+		this.verifyWaitToPush(TICK);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the stack is eventually popped by t1...
+		assertSame(ITEM_1, this.poppedObject);
+		// ...but nothing is pushed on to the stack by t2
+		assertTrue(this.ss.isEmpty());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.calculateElapsedTime() < THREE_TICKS);
+	}
+
+	private void verifyWaitToPush(long timeout) throws Exception {
+		this.ss.push(ITEM_1);
+		Runnable r1 = this.buildRunnable(this.buildPopCommand(), this.ss, TWO_TICKS);
+		Runnable r2 = this.buildRunnable(this.buildWaitToPushCommand(timeout), this.ss, 0);
+		Thread t1 = this.buildThread(r1);
+		Thread t2 = this.buildThread(r2);
+		t1.start();
+		t2.start();
+		t1.join();
+		t2.join();
+	}
+
+	private Command buildPushCommand() {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedStack<String> synchronizedStack) {
+				synchronizedStack.push(ITEM_1);
+			}
+		};
+	}
+
+	private Command buildWaitToPopCommand(final long timeout) {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedStack<String> synchronizedStack) throws InterruptedException {
+				SynchronizedStackTests.this.startTime = System.currentTimeMillis();
+				try {
+					SynchronizedStackTests.this.poppedObject = synchronizedStack.waitToPop(timeout);
+				} catch (EmptyStackException ex) {
+					SynchronizedStackTests.this.timeoutOccurred = true;
+				}
+				SynchronizedStackTests.this.endTime = System.currentTimeMillis();
+			}
+		};
+	}
+
+	private Command buildPopCommand() {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedStack<String> synchronizedStack) {
+				SynchronizedStackTests.this.poppedObject = synchronizedStack.pop();
+			}
+		};
+	}
+
+	private Command buildWaitToPushCommand(final long timeout) {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedStack<String> synchronizedStack) throws InterruptedException {
+				SynchronizedStackTests.this.startTime = System.currentTimeMillis();
+				SynchronizedStackTests.this.timeoutOccurred = ! synchronizedStack.waitToPush(ITEM_2, timeout);
+				SynchronizedStackTests.this.endTime = System.currentTimeMillis();
+			}
+		};
+	}
+
+	private Runnable buildRunnable(final Command command, final SynchronizedStack<String> synchronizedStack, final long sleep) {
+		return new TestRunnable() {
+			@Override
+			protected void run_() throws Throwable {
+				if (sleep != 0) {
+					Thread.sleep(sleep);
+				}
+				command.execute(synchronizedStack);
+			}
+		};
+	}
+
+	long calculateElapsedTime() {
+		return this.endTime - this.startTime;
+	}
+
+
+	// ********** Command interface **********
+
+	private interface Command {
+		void execute(SynchronizedStack<String> synchronizedStack) throws InterruptedException;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/AsynchronousCommandExecutorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/AsynchronousCommandExecutorTests.java
new file mode 100644
index 0000000..86ebb48
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/AsynchronousCommandExecutorTests.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.command;
+
+import org.eclipse.persistence.tools.utility.ExceptionHandler;
+import org.eclipse.persistence.tools.utility.command.AsynchronousExtendedCommandExecutor;
+import org.eclipse.persistence.tools.utility.command.Command;
+import org.eclipse.persistence.tools.utility.command.StatefulCommandExecutor;
+import org.eclipse.persistence.tools.utility.tests.MultiThreadedTestCase;
+
+public class AsynchronousCommandExecutorTests
+	extends MultiThreadedTestCase
+{
+	public AsynchronousCommandExecutorTests(String name) {
+		super(name);
+	}
+
+	public void testExecution() throws Exception {
+		TestCommand command = new TestCommand();
+		AsynchronousExtendedCommandExecutor.SimpleConfig config = new AsynchronousExtendedCommandExecutor.SimpleConfig();
+		config.setThreadFactory(this.buildThreadFactory());
+		config.setExceptionHandler(ExceptionHandler.Runtime.instance());
+		StatefulCommandExecutor commandExecutor = new AsynchronousExtendedCommandExecutor(config);
+		commandExecutor.start();
+		commandExecutor.execute(command);
+		commandExecutor.execute(command);
+		commandExecutor.execute(command);
+		Thread.sleep(TWO_TICKS);  // wait for the command to execute
+		commandExecutor.stop();
+		assertEquals(3, command.count);
+	}
+
+	static class TestCommand implements Command {
+		int count = 0;
+		@Override
+		public void execute() {
+			this.count++;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/AsynchronousRepeatingCommandWrapperTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/AsynchronousRepeatingCommandWrapperTests.java
new file mode 100644
index 0000000..9b9c943
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/AsynchronousRepeatingCommandWrapperTests.java
@@ -0,0 +1,462 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.command;
+
+import org.eclipse.persistence.tools.utility.CollectingExceptionHandler;
+import org.eclipse.persistence.tools.utility.ConsumerThreadCoordinator;
+import org.eclipse.persistence.tools.utility.ExceptionHandler;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.command.AsynchronousRepeatingCommandWrapper;
+import org.eclipse.persistence.tools.utility.command.Command;
+import org.eclipse.persistence.tools.utility.command.RepeatingCommand;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.tests.MultiThreadedTestCase;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+
+@SuppressWarnings("nls")
+public class AsynchronousRepeatingCommandWrapperTests
+	extends MultiThreadedTestCase
+{
+	PrimaryModel1 primaryModel1;
+	SecondaryModel1 secondaryModel1;
+	Command command1;
+	RepeatingCommand repeatingCommand1;
+
+	PrimaryModel2 primaryModel2;
+	SecondaryModel2 secondaryModel2;
+	Command command2;
+	RepeatingCommand repeatingCommand2;
+
+	public AsynchronousRepeatingCommandWrapperTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.primaryModel1 = new PrimaryModel1();
+		this.secondaryModel1 = new SecondaryModel1(this.primaryModel1);
+		this.command1 = new SynchronizeSecondaryModelCommand1(this.secondaryModel1);
+		this.repeatingCommand1 = new AsynchronousRepeatingCommandWrapper(this.command1, this.buildThreadFactory(), null, ExceptionHandler.Runtime.instance());
+		this.primaryModel1.setSynchronizer(this.repeatingCommand1);
+
+		this.primaryModel2 = new PrimaryModel2();
+		this.secondaryModel2 = new SecondaryModel2(this.primaryModel2);
+		this.command2 = new SynchronizeSecondaryModelCommand2(this.primaryModel2, this.secondaryModel2);
+		this.repeatingCommand2 = new AsynchronousRepeatingCommandWrapper(this.command2, this.buildThreadFactory(), null, ExceptionHandler.Runtime.instance());
+		this.primaryModel2.setSynchronizer(this.repeatingCommand2);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		this.repeatingCommand1.stop();
+		this.repeatingCommand2.stop();
+		super.tearDown();
+	}
+
+	public void testInitialization() {
+		assertEquals(4, this.secondaryModel1.getDoubleCount());
+	}
+
+	public void testToString() {
+		assertNotNull(this.repeatingCommand1.toString());
+	}
+
+	public void testChange() throws Exception {
+		assertEquals(4, this.secondaryModel1.getDoubleCount());
+		this.primaryModel1.setCount(7);
+
+		this.sleep(TICK);
+		this.repeatingCommand1.stop();
+		this.sleep(TICK);
+
+		assertEquals(14, this.secondaryModel1.getDoubleCount());
+
+		// re-start so tear-down works
+		this.repeatingCommand1.start();
+	}
+
+	public void testStart() throws Exception {
+		assertEquals(4, this.secondaryModel1.getDoubleCount());
+		this.primaryModel1.setSynchronizer(RepeatingCommand.Null.instance());
+		this.primaryModel1.setCount(7);
+		assertEquals(4, this.secondaryModel1.getDoubleCount());
+		this.primaryModel1.setSynchronizer(this.repeatingCommand1);
+		// the async synchronizer does not synchronize at start-up
+		assertEquals(4, this.secondaryModel1.getDoubleCount());
+
+		this.primaryModel1.setCount(8);
+
+		this.sleep(TICK);
+		this.repeatingCommand1.stop();
+		this.sleep(TICK);
+
+		assertEquals(16, this.secondaryModel1.getDoubleCount());
+
+		// re-start so tear-down works
+		this.repeatingCommand1.start();
+	}
+
+	public void testStop() throws Exception {
+		assertEquals(4, this.secondaryModel1.getDoubleCount());
+		this.primaryModel1.dispose();
+		this.primaryModel1.setCount(7);
+		assertEquals(4, this.secondaryModel1.getDoubleCount());
+
+		// re-start so tear-down works
+		this.repeatingCommand1.start();
+	}
+
+	public void testDoubleStart() throws Exception {
+		assertEquals(4, this.secondaryModel1.getDoubleCount());
+		boolean exCaught = false;
+		try {
+			this.primaryModel1.startSynchronizer();
+			fail();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+		this.primaryModel1.setCount(7);
+
+		this.sleep(TICK);
+		this.repeatingCommand1.stop();
+		this.sleep(TICK);
+
+		assertEquals(14, this.secondaryModel1.getDoubleCount());
+
+		// re-start so tear-down works
+		this.repeatingCommand1.start();
+	}
+
+	public void testDoubleStop() throws Exception {
+		assertEquals(4, this.secondaryModel1.getDoubleCount());
+		this.primaryModel1.dispose();
+		boolean exCaught = false;
+		try {
+			this.primaryModel1.dispose();
+			fail();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+		this.primaryModel1.setCount(7);
+		assertEquals(4, this.secondaryModel1.getDoubleCount());
+
+		// re-start so tear-down works
+		this.repeatingCommand1.start();
+	}
+
+	public void testRecursiveChange() throws Exception {
+		assertEquals(4, this.secondaryModel2.getDoubleCount());
+		this.primaryModel2.setCount(7);
+
+		this.sleep(TICK);
+		assertEquals(10, this.primaryModel2.getCountPlus3());
+		assertEquals(14, this.secondaryModel2.getDoubleCount());
+
+		this.sleep(TICK);
+		assertEquals(20, this.secondaryModel2.getDoubleCountPlus3());
+	}
+
+	public void testNullCommand() {
+		boolean exCaught = false;
+		try {
+			RepeatingCommand s = new AsynchronousRepeatingCommandWrapper(null, this.buildThreadFactory(), null, ExceptionHandler.Runtime.instance());
+			fail("bogus: " + s);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testThreadName() throws Exception {
+		RepeatingCommand s = new AsynchronousRepeatingCommandWrapper(this.command1, this.buildThreadFactory(), "sync", ExceptionHandler.Runtime.instance());
+		s.start();
+		ConsumerThreadCoordinator ctc = (ConsumerThreadCoordinator) ObjectTools.get(s, "consumerThreadCoordinator");
+		Thread t = (Thread) ObjectTools.get(ctc, "thread");
+		assertEquals("sync", t.getName());
+		s.stop();
+	}
+
+	public void testExecuteCalledBeforeStart() throws Exception {
+		SimpleCommand command = new SimpleCommand();
+		RepeatingCommand synchronizer = new AsynchronousRepeatingCommandWrapper(command, this.buildThreadFactory(), null, ExceptionHandler.Runtime.instance());
+
+		synchronizer.execute();
+		synchronizer.start();
+		this.sleep(TICK);
+		synchronizer.stop();
+		assertEquals(1, command.count);
+	}
+
+	public class SimpleCommand implements Command {
+		int count = 0;
+		@Override
+		public void execute() {
+			this.count++;
+		}
+	}
+
+	public void testException() throws Exception {
+		BogusCommand command = new BogusCommand();
+		CollectingExceptionHandler exHandler = new CollectingExceptionHandler();
+		RepeatingCommand synchronizer = new AsynchronousRepeatingCommandWrapper(command, this.buildThreadFactory(), null, exHandler);
+		synchronizer.start();
+
+		synchronizer.execute();
+		this.sleep(TICK);
+
+		synchronizer.execute();
+		this.sleep(TICK);
+
+		synchronizer.stop();
+		assertEquals(2, IterableTools.size(exHandler.getExceptions()));
+		assertEquals(2, command.count);
+	}
+
+	public class BogusCommand implements Command {
+		int count = 0;
+		@Override
+		public void execute() {
+			this.count++;
+			throw new NullPointerException();
+		}
+	}
+
+	/**
+	 * Make sure the <code>DEBUG</code> constant is <code>false</code>
+	 * before checking in the code.
+	 */
+	public void testDEBUG() {
+		TestTools.assertFalseDEBUG(AsynchronousRepeatingCommandWrapper.class);
+	}
+
+
+	// ********** synchronize commands **********
+
+	public static class SynchronizeSecondaryModelCommand1
+		implements Command
+	{
+		private final SecondaryModel1 secondaryModel;
+
+		public SynchronizeSecondaryModelCommand1(SecondaryModel1 secondaryModel) {
+			super();
+			this.secondaryModel = secondaryModel;
+		}
+
+		@Override
+		public void execute() {
+			this.secondaryModel.synchronize();
+		}
+	}
+
+	/**
+	 * the primary model (subclass) has to synchronize with itself (superclass)
+	 */
+	public static class SynchronizeSecondaryModelCommand2
+		extends SynchronizeSecondaryModelCommand1
+	{
+		private final PrimaryModel2 primaryModel;
+
+		public SynchronizeSecondaryModelCommand2(PrimaryModel2 primaryModel, SecondaryModel2 secondaryModel) {
+			super(secondaryModel);
+			this.primaryModel = primaryModel;
+		}
+
+		@Override
+		public void execute() {
+			super.execute();
+			this.primaryModel.synchronize();
+		}
+	}
+
+
+	// ********** primary models **********
+
+	/**
+	 * this object will call the synchronizer whenever its count changes,
+	 * allowing interested parties to synchronize with the change
+	 */
+	public static class PrimaryModel1 {
+		protected RepeatingCommand synchronizer;
+		protected int count = 2;
+
+		public PrimaryModel1() {
+			super();
+			this.setSynchronizer_(RepeatingCommand.Null.instance());
+		}
+
+		public int getCount() {
+			return this.count;
+		}
+		public void setCount(int count) {
+			if (count != this.count) {
+				this.count = count;
+				this.stateChanged();
+			}
+		}
+
+		protected void stateChanged() {
+			this.synchronizer.execute();
+		}
+
+		public void setSynchronizer(RepeatingCommand synchronizer) throws InterruptedException {
+			if (synchronizer == null) {
+				throw new NullPointerException();
+			}
+			this.synchronizer.stop();
+			this.setSynchronizer_(synchronizer);
+		}
+
+		protected void setSynchronizer_(RepeatingCommand synchronizer) {
+			this.synchronizer = synchronizer;
+			this.synchronizer.start();
+		}
+
+		public void startSynchronizer() {
+			this.synchronizer.start();  // this should cause an exception
+		}
+		public void dispose() throws InterruptedException {
+			this.synchronizer.stop();
+		}
+
+		@Override
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			sb.append(this.getClass().getSimpleName());
+			sb.append('(');
+			this.toString(sb);
+			sb.append(')');
+			return sb.toString();
+		}
+		public void toString(StringBuilder sb) {
+			sb.append("count=");
+			sb.append(this.count);
+		}
+	}
+
+	/**
+	 * This model synchronizes with itself, triggering a recursive synchronization
+	 * with the change. Whenever the [inherited] 'count' changes, 'countPlus3'
+	 * is updated appropriately and another synchronize is initiated if appropriate.
+	 */
+	public static class PrimaryModel2
+		extends PrimaryModel1
+	{
+		private int countPlus3 = 0;
+
+		public PrimaryModel2() {
+			super();
+			this.countPlus3 = this.count + 3;
+		}
+
+		public int getCountPlus3() {
+			return this.countPlus3;
+		}
+		protected void setCountPlus3(int countPlus3) {
+			if (countPlus3 != this.countPlus3) {
+				this.countPlus3 = countPlus3;
+				this.stateChanged();
+			}
+		}
+
+		// synchronize with itself, so to speak
+		public void synchronize() {
+			this.setCountPlus3(this.count + 3);
+		}
+
+		@Override
+		public void toString(StringBuilder sb) {
+			super.toString(sb);
+			sb.append(", countPlus3=");
+			sb.append(this.countPlus3);
+		}
+	}
+
+
+	// ********** secondary models **********
+
+	/**
+	 * This dependent object updates its 'doubleCount' whenever the
+	 * PrimaryModel1's 'count' changes, via the 'synchronizer'.
+	 */
+	public static class SecondaryModel1 {
+		protected final PrimaryModel1 primaryModel;
+		protected int doubleCount = 0;
+
+		public SecondaryModel1(PrimaryModel1 primaryModel) {
+			super();
+			this.primaryModel = primaryModel;
+			this.synchronize();
+		}
+
+		public void synchronize() {
+			this.doubleCount = this.primaryModel.getCount() * 2;
+		}
+
+		public int getDoubleCount() {
+			return this.doubleCount;
+		}
+
+		@Override
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			sb.append(this.getClass().getSimpleName());
+			sb.append('(');
+			this.toString(sb);
+			sb.append(')');
+			return sb.toString();
+		}
+		public void toString(StringBuilder sb) {
+			sb.append("doubleCount=");
+			sb.append(this.doubleCount);
+		}
+	}
+
+	public static class SecondaryModel2
+		extends SecondaryModel1
+	{
+		private int doubleCountPlus3 = 0;
+
+		public SecondaryModel2(PrimaryModel2 extendedPrimaryModel) {
+			super(extendedPrimaryModel);
+		}
+
+		protected PrimaryModel2 getExtendedPrimaryModel() {
+			return (PrimaryModel2) this.primaryModel;
+		}
+
+		@Override
+		public void synchronize() {
+			super.synchronize();
+			int temp = this.getExtendedPrimaryModel().getCountPlus3() * 2;
+			if (this.doubleCountPlus3 != temp) {
+				this.doubleCountPlus3 = temp;
+			}
+		}
+
+		public int getDoubleCountPlus3() {
+			return this.doubleCountPlus3;
+		}
+
+		@Override
+		public void toString(StringBuilder sb) {
+			super.toString(sb);
+			sb.append(", doubleCountPlus3=");
+			sb.append(this.doubleCountPlus3);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CommandExecutorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CommandExecutorTests.java
new file mode 100644
index 0000000..57cefb2
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CommandExecutorTests.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.command;
+
+import org.eclipse.persistence.tools.utility.command.Command;
+import org.eclipse.persistence.tools.utility.command.CommandExecutor;
+import org.eclipse.persistence.tools.utility.command.ExtendedCommandExecutor;
+import org.eclipse.persistence.tools.utility.command.ThreadLocalExtendedCommandExecutor;
+import org.eclipse.persistence.tools.utility.tests.MultiThreadedTestCase;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+public class CommandExecutorTests
+	extends MultiThreadedTestCase
+{
+
+	public CommandExecutorTests(String name) {
+		super(name);
+	}
+
+	public void testDefaultCommandExecutor_toString() throws Exception {
+		CommandExecutor commandExecutor = CommandExecutor.Default.instance();
+		assertNotNull(commandExecutor.toString());
+	}
+
+	public void testDefaultCommandExecutor_serialization() throws Exception {
+		CommandExecutor commandExecutor1 = CommandExecutor.Default.instance();
+		CommandExecutor commandExecutor2 = TestTools.serialize(commandExecutor1);
+		assertSame(commandExecutor1, commandExecutor2);
+	}
+
+	public void testDefaultCommandExecutor() {
+		TestCommand testCommand = new TestCommand();
+		assertEquals(0, testCommand.count);
+		CommandExecutor commandExecutor = CommandExecutor.Default.instance();
+		commandExecutor.execute(testCommand);
+		assertEquals(1, testCommand.count);
+	}
+
+	static class TestCommand implements Command {
+		int count = 0;
+		@Override
+		public void execute() {
+			this.count++;
+		}
+	}
+
+	public void testThreadLocalCommandExecutor_toString() throws Exception {
+		CommandExecutor commandExecutor = new ThreadLocalExtendedCommandExecutor();
+		assertNotNull(commandExecutor.toString());
+	}
+
+	public void testThreadLocalCommandExecutor() throws Exception {
+		ThreadLocalExtendedCommandExecutor threadLocalCommandExecutor = new ThreadLocalExtendedCommandExecutor();
+		TestRunnable testRunnable1 = new TestRunnable(threadLocalCommandExecutor, 1);
+		Thread thread1 = this.buildThread(testRunnable1);
+		thread1.run();
+
+		TestRunnable testRunnable2 = new TestRunnable(threadLocalCommandExecutor, 2);
+		Thread thread2 = this.buildThread(testRunnable2);
+		thread2.run();
+
+		TestRunnable testRunnable3 = new TestRunnable(threadLocalCommandExecutor, 3, null);
+		Thread thread3 = this.buildThread(testRunnable3);
+		thread3.run();
+
+		thread1.join();
+		thread2.join();
+		thread3.join();
+
+		assertEquals(1, testRunnable1.testCommand.count);
+		assertEquals(1, testRunnable1.testCommandExecutor.count);
+
+		assertEquals(2, testRunnable2.testCommand.count);
+		assertEquals(2, testRunnable2.testCommandExecutor.count);
+
+		assertEquals(3, testRunnable3.testCommand.count);
+		assertNull(testRunnable3.testCommandExecutor);
+	}
+
+	static class TestCommandExecutor implements ExtendedCommandExecutor {
+		int count = 0;
+		@Override
+		public void execute(Command command) {
+			this.count++;
+			command.execute();
+		}
+		@Override
+		public void waitToExecute(Command command) {
+			this.execute(command);
+		}
+		@Override
+		public boolean waitToExecute(Command command, long timeout) {
+			this.execute(command);
+			return true;
+		}
+	}
+
+	static class TestRunnable implements Runnable {
+		final ThreadLocalExtendedCommandExecutor threadLocalCommandExecutor;
+		final int executionCount;
+		final TestCommand testCommand = new TestCommand();
+		final TestCommandExecutor testCommandExecutor;
+		TestRunnable(ThreadLocalExtendedCommandExecutor threadLocalCommandExecutor, int executionCount) {
+			this(threadLocalCommandExecutor, executionCount, new TestCommandExecutor());
+		}
+		TestRunnable(ThreadLocalExtendedCommandExecutor threadLocalCommandExecutor, int executionCount, TestCommandExecutor testCommandExecutor) {
+			super();
+			this.threadLocalCommandExecutor = threadLocalCommandExecutor;
+			this.executionCount = executionCount;
+			this.testCommandExecutor = testCommandExecutor;
+		}
+		@Override
+		public void run() {
+			this.threadLocalCommandExecutor.set(this.testCommandExecutor);
+			for (int i = 0; i < this.executionCount; i++) {
+				this.threadLocalCommandExecutor.execute(this.testCommand);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CommandRunnableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CommandRunnableTests.java
new file mode 100644
index 0000000..8d75a34
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CommandRunnableTests.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.command;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.command.Command;
+import org.eclipse.persistence.tools.utility.command.CommandRunnable;
+
+@SuppressWarnings("nls")
+public class CommandRunnableTests extends TestCase {
+	boolean commandExecuted = false;
+
+	public CommandRunnableTests(String name) {
+		super(name);
+	}
+
+	public void testNullCommand() {
+		boolean exCaught = false;
+		try {
+			Runnable runnable = new CommandRunnable(null);
+			fail("bogus: " + runnable);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRun() {
+		Runnable runnable = new CommandRunnable(this.buildCommand());
+		runnable.run();
+		assertTrue(this.commandExecuted);
+	}
+
+	public void testToString() {
+		Runnable runnable = new CommandRunnable(this.buildCommand());
+		assertNotNull(runnable.toString());
+	}
+
+	private Command buildCommand() {
+		return new Command() {
+			@Override
+			public void execute() {
+				CommandRunnableTests.this.commandExecuted = true;
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CommandTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CommandTests.java
new file mode 100644
index 0000000..37b7837
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CommandTests.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.command;
+
+import org.eclipse.persistence.tools.utility.command.Command;
+import org.eclipse.persistence.tools.utility.command.CommandExecutor;
+import org.eclipse.persistence.tools.utility.command.CommandRunnable;
+import org.eclipse.persistence.tools.utility.command.RunnableCommand;
+import org.eclipse.persistence.tools.utility.command.ThreadLocalCommand;
+import org.eclipse.persistence.tools.utility.tests.MultiThreadedTestCase;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+
+public class CommandTests
+	extends MultiThreadedTestCase
+{
+	public CommandTests(String name) {
+		super(name);
+	}
+
+	public void testNullCommand() {
+		Command command = Command.Null.instance();
+		command.execute();  // just make sure it doesn't blow up?
+	}
+
+	public void testNullCommand_toString() {
+		Command command = Command.Null.instance();
+		assertNotNull(command.toString());
+	}
+
+	public void testNullCommand_serialization() throws Exception {
+		Command command1 = Command.Null.instance();
+		Command command2 = TestTools.serialize(command1);
+		assertSame(command1, command2);
+	}
+
+	public void testDisabledCommand() {
+		Command command = Command.Disabled.instance();
+		boolean exCaught = false;
+		try {
+			command.execute();
+			fail();
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testDisabledCommand_toString() {
+		Command command = Command.Disabled.instance();
+		assertNotNull(command.toString());
+	}
+
+	public void testDisabledCommand_serialization() throws Exception {
+		Command command1 = Command.Disabled.instance();
+		Command command2 = TestTools.serialize(command1);
+		assertSame(command1, command2);
+	}
+
+	public void testRunnableCommand() {
+		SimpleTestRunnable testRunnable = new SimpleTestRunnable();
+		assertFalse(testRunnable.ran);
+		Command command = new RunnableCommand(testRunnable);
+		command.execute();
+		assertTrue(testRunnable.ran);
+	}
+
+	static class SimpleTestRunnable implements Runnable {
+		boolean ran = false;
+		@Override
+		public void run() {
+			this.ran = true;
+		}
+	}
+
+	public void testCommandRunnable() {
+		TestCommand testCommand = new TestCommand();
+		assertEquals(0, testCommand.count);
+		Runnable runnable = new CommandRunnable(testCommand);
+		runnable.run();
+		assertEquals(1, testCommand.count);
+	}
+
+	static class TestCommand implements Command {
+		int count = 0;
+		@Override
+		public void execute() {
+			this.count++;
+		}
+	}
+
+	public void testThreadLocalCommand() throws Exception {
+		ThreadLocalCommand threadLocalCommand = new ThreadLocalCommand();
+		TestRunnable testRunnable1 = new TestRunnable(threadLocalCommand, 1);
+		Thread thread1 = this.buildThread(testRunnable1);
+		thread1.run();
+
+		TestRunnable testRunnable2 = new TestRunnable(threadLocalCommand, 2);
+		Thread thread2 = this.buildThread(testRunnable2);
+		thread2.run();
+
+		thread1.join();
+		thread2.join();
+
+		assertEquals(1, testRunnable1.testCommand.count);
+
+		assertEquals(2, testRunnable2.testCommand.count);
+	}
+
+	static class TestCommandExecutor implements CommandExecutor {
+		int count = 0;
+		@Override
+		public void execute(Command command) {
+			this.count++;
+			command.execute();
+		}
+	}
+
+	static class TestRunnable implements Runnable {
+		final ThreadLocalCommand threadLocalCommand;
+		final int executionCount;
+		final TestCommand testCommand = new TestCommand();
+		TestRunnable(ThreadLocalCommand threadLocalCommand, int executionCount) {
+			super();
+			this.threadLocalCommand = threadLocalCommand;
+			this.executionCount = executionCount;
+		}
+		@Override
+		public void run() {
+			this.threadLocalCommand.set(this.testCommand);
+			for (int i = 0; i < this.executionCount; i++) {
+				this.threadLocalCommand.execute();
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CommonUtilityCommandTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CommonUtilityCommandTests.java
new file mode 100644
index 0000000..d46b3b1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CommonUtilityCommandTests.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.command;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * decentralize test creation code
+ */
+public class CommonUtilityCommandTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CommonUtilityCommandTests.class.getPackage().getName());
+
+		suite.addTestSuite(AsynchronousCommandExecutorTests.class);
+		suite.addTestSuite(AsynchronousRepeatingCommandWrapperTests.class);
+		suite.addTestSuite(CommandExecutorTests.class);
+		suite.addTestSuite(CommandRunnableTests.class);
+		suite.addTestSuite(CommandTests.class);
+		suite.addTestSuite(CompositeCommandTests.class);
+
+		return suite;
+	}
+
+	private CommonUtilityCommandTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CompositeCommandTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CompositeCommandTests.java
new file mode 100644
index 0000000..4d93c48
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/command/CompositeCommandTests.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.command;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.command.Command;
+import org.eclipse.persistence.tools.utility.command.CommandRunnable;
+import org.eclipse.persistence.tools.utility.command.CompositeCommand;
+
+public class CompositeCommandTests extends TestCase {
+	boolean command1Executed = false;
+	boolean command2Executed = false;
+
+	public CompositeCommandTests(String name) {
+		super(name);
+	}
+
+	public void testRun() {
+		Runnable runnable = new CommandRunnable(this.buildCompositeCommand());
+		runnable.run();
+		assertTrue(this.command1Executed);
+		assertTrue(this.command2Executed);
+	}
+
+	public void testToString() {
+		Runnable runnable = new CommandRunnable(this.buildCompositeCommand());
+		assertNotNull(runnable.toString());
+	}
+
+	private Command buildCompositeCommand() {
+		return new CompositeCommand(
+					this.buildCommand1(),
+					this.buildCommand2()
+				);
+	}
+
+	private Command buildCommand1() {
+		return new Command() {
+			@Override
+			public void execute() {
+				CompositeCommandTests.this.command1Executed = true;
+			}
+		};
+	}
+
+	private Command buildCommand2() {
+		return new Command() {
+			@Override
+			public void execute() {
+				CompositeCommandTests.this.command2Executed = true;
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/enumeration/CommonUtilityEnumerationTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/enumeration/CommonUtilityEnumerationTests.java
new file mode 100644
index 0000000..16420d1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/enumeration/CommonUtilityEnumerationTests.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.enumeration;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * decentralize test creation code
+ */
+public class CommonUtilityEnumerationTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CommonUtilityEnumerationTests.class.getPackage().getName());
+
+		suite.addTestSuite(EmptyEnumerationTests.class);
+		suite.addTestSuite(EnumerationToolsTests.class);
+		suite.addTestSuite(IteratorEnumerationTests.class);
+
+		return suite;
+	}
+
+	private CommonUtilityEnumerationTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/enumeration/EmptyEnumerationTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/enumeration/EmptyEnumerationTests.java
new file mode 100644
index 0000000..b1b7a50
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/enumeration/EmptyEnumerationTests.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.enumeration;
+
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.enumeration.EmptyEnumeration;
+
+
+@SuppressWarnings("nls")
+public class EmptyEnumerationTests extends TestCase {
+
+	public EmptyEnumerationTests(String name) {
+		super(name);
+	}
+
+	public void testHasMoreElements() {
+		int i = 0;
+		for (Enumeration<Object> stream = EmptyEnumeration.instance(); stream.hasMoreElements();) {
+			stream.nextElement();
+			i++;
+		}
+		assertEquals(0, i);
+	}
+
+	public void testNextElement() {
+		for (Enumeration<Object> stream = EmptyEnumeration.instance(); stream.hasMoreElements();) {
+			fail("bogus element: " + stream.nextElement());
+		}
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		Enumeration<Object> stream = EmptyEnumeration.instance();
+		Object element = null;
+		while (stream.hasMoreElements()) {
+			element = stream.nextElement();
+		}
+		try {
+			element = stream.nextElement();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + element, exCaught);
+	}
+
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/enumeration/EnumerationToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/enumeration/EnumerationToolsTests.java
new file mode 100644
index 0000000..c9e5177
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/enumeration/EnumerationToolsTests.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.enumeration;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.Vector;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ClassTools;
+import org.eclipse.persistence.tools.utility.enumeration.EnumerationTools;
+
+@SuppressWarnings("nls")
+public class EnumerationToolsTests
+	extends TestCase
+{
+	public EnumerationToolsTests(String name) {
+		super(name);
+	}
+
+	public void testContainsEnumerationObject_String() {
+		Vector<String> v = this.buildStringVector1();
+		assertTrue(EnumerationTools.contains(v.elements(), "one"));
+		assertFalse(EnumerationTools.contains(v.elements(), null));
+		v.add(null);
+		assertTrue(EnumerationTools.contains(v.elements(), null));
+	}
+
+	public void testContainsEnumerationObject_Object() {
+		Vector<Object> c = new Vector<Object>();
+		c.add("zero");
+		c.add("one");
+		c.add("two");
+		c.add("three");
+		String one = "one";
+		assertTrue(EnumerationTools.contains(c.elements(), one));
+		assertFalse(EnumerationTools.contains(c.elements(), null));
+		c.add(null);
+		assertTrue(EnumerationTools.contains(c.elements(), null));
+	}
+
+	public void testConstructor() {
+		boolean exCaught = false;
+		try {
+			Object at = ClassTools.newInstance(EnumerationTools.class);
+			fail("bogus: " + at); //$NON-NLS-1$
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof InvocationTargetException) {
+				if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	private Vector<String> buildStringVector1() {
+		Vector<String> v = new Vector<String>();
+		this.addToCollection1(v);
+		return v;
+	}
+
+	private void addToCollection1(Collection<? super String> c) {
+		c.add("zero");
+		c.add("one");
+		c.add("two");
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/enumeration/IteratorEnumerationTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/enumeration/IteratorEnumerationTests.java
new file mode 100644
index 0000000..5ad8f48
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/enumeration/IteratorEnumerationTests.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.enumeration;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.enumeration.IteratorEnumeration;
+
+
+@SuppressWarnings("nls")
+public class IteratorEnumerationTests extends TestCase {
+
+	public IteratorEnumerationTests(String name) {
+		super(name);
+	}
+
+	public void testHasMoreElements() {
+		int i = 0;
+		for (Enumeration<String> stream = this.buildEnumeration(); stream.hasMoreElements();) {
+			stream.nextElement();
+			i++;
+		}
+		assertEquals(this.buildVector().size(), i);
+	}
+
+	public void testHasMoreElementsUpcast() {
+		int i = 0;
+		for (Enumeration<Object> stream = this.buildEnumerationUpcast(); stream.hasMoreElements();) {
+			stream.nextElement();
+			i++;
+		}
+		assertEquals(this.buildVector().size(), i);
+	}
+
+	public void testNextElement() {
+		Iterator<String> iterator = this.buildIterator();
+		for (Enumeration<String> stream = this.buildEnumeration(); stream.hasMoreElements();) {
+			assertEquals("bogus element", iterator.next(), stream.nextElement());
+		}
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		Enumeration<String> stream = this.buildEnumeration();
+		String string = null;
+		while (stream.hasMoreElements()) {
+			string = stream.nextElement();
+		}
+		try {
+			string = stream.nextElement();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
+	}
+
+	private Enumeration<String> buildEnumeration() {
+		return this.buildEnumeration(this.buildIterator());
+	}
+
+	private Enumeration<Object> buildEnumerationUpcast() {
+		return this.buildEnumerationUpcast(this.buildIterator());
+	}
+
+	private Enumeration<String> buildEnumeration(Iterator<String> iterator) {
+		return new IteratorEnumeration<String>(iterator);
+	}
+
+	private Enumeration<Object> buildEnumerationUpcast(Iterator<String> iterator) {
+		return new IteratorEnumeration<Object>(iterator);
+	}
+
+	private Iterator<String> buildIterator() {
+		return this.buildVector().iterator();
+	}
+
+	private Vector<String> buildVector() {
+		Vector<String> v = new Vector<String>();
+		v.addElement("one");
+		v.addElement("two");
+		v.addElement("three");
+		v.addElement("four");
+		v.addElement("five");
+		v.addElement("six");
+		v.addElement("seven");
+		v.addElement("eight");
+		return v;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/ANDFilterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/ANDFilterTests.java
new file mode 100644
index 0000000..6e6d35a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/ANDFilterTests.java
@@ -0,0 +1,153 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.filter;

+

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.BitTools;

+import org.eclipse.persistence.tools.utility.filter.ANDFilter;

+import org.eclipse.persistence.tools.utility.filter.Filter;

+import org.eclipse.persistence.tools.utility.filter.FilterAdapter;

+import org.eclipse.persistence.tools.utility.filter.SimpleFilter;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+public class ANDFilterTests

+	extends TestCase

+{

+	private ANDFilter<Number> andFilter;

+

+

+	public ANDFilterTests(String name) {

+		super(name);

+	}

+

+	@Override

+	@SuppressWarnings("unchecked")

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.andFilter = new ANDFilter<Number>(this.buildMinFilter(1), this.buildMaxFilter(10));

+	}

+

+	private Filter<Number> buildMinFilter(double min) {

+		return new MinFilter(min);

+	}

+

+	static class MinFilter

+		extends SimpleFilter<Number, Number>

+	{

+		private static final long serialVersionUID = 1L;

+		MinFilter(double min) {

+			super(new Double(min));

+		}

+		@Override

+		public boolean accept(Number number) {

+			return number.doubleValue() >= this.criterion.doubleValue();

+		}

+	}

+

+	private Filter<Number> buildMaxFilter(double max) {

+		return new MaxFilter(max);

+	}

+

+	static class MaxFilter

+		extends SimpleFilter<Number, Number>

+	{

+		private static final long serialVersionUID = 1L;

+		MaxFilter(double min) {

+			super(new Double(min));

+		}

+		@Override

+		public boolean accept(Number number) {

+			return number.doubleValue() <= this.criterion.doubleValue();

+		}

+	}

+

+	private Filter<Number> buildEvenFilter() {

+		return new EvenFilter();

+	}

+

+	static class EvenFilter

+		extends FilterAdapter<Number>

+	{

+		EvenFilter() {

+			super();

+		}

+		@Override

+		public boolean accept(Number number) {

+			return BitTools.isEven(number.intValue());

+		}

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testFiltering2() {

+		assertTrue(this.andFilter.accept(new Integer(7)));

+		assertTrue(this.andFilter.accept(new Integer(2)));

+		assertTrue(this.andFilter.accept(new Double(6.666)));

+		assertFalse(this.andFilter.accept(new Double(-99)));

+		assertFalse(this.andFilter.accept(new Double(-1)));

+		assertFalse(this.andFilter.accept(new Double(11)));

+		assertFalse(this.andFilter.accept(new Double(111)));

+	}

+

+	public void testFiltering3() {

+		@SuppressWarnings("unchecked")

+		ANDFilter<Number> andFilter2 = new ANDFilter<Number>(this.andFilter, this.buildEvenFilter());

+		assertFalse(andFilter2.accept(new Integer(7)));

+		assertTrue(andFilter2.accept(new Integer(2)));

+		assertTrue(andFilter2.accept(new Double(6.1)));

+		assertFalse(andFilter2.accept(new Double(-99)));

+		assertFalse(andFilter2.accept(new Double(-1)));

+		assertFalse(andFilter2.accept(new Double(11)));

+		assertFalse(andFilter2.accept(new Double(111)));

+	}

+

+	public void testFilteringComposite() {

+		@SuppressWarnings("unchecked")

+		Filter<Number> andFilter2 = new ANDFilter<Number>(this.buildMinFilter(1), this.buildMaxFilter(10), this.buildEvenFilter());

+		assertFalse(andFilter2.accept(new Integer(7)));

+		assertTrue(andFilter2.accept(new Integer(2)));

+		assertTrue(andFilter2.accept(new Double(6.1)));

+		assertFalse(andFilter2.accept(new Double(-99)));

+		assertFalse(andFilter2.accept(new Double(-1)));

+		assertFalse(andFilter2.accept(new Double(11)));

+		assertFalse(andFilter2.accept(new Double(111)));

+	}

+

+	public void testClone() {

+		@SuppressWarnings("unchecked")

+		ANDFilter<Number> andFilter2 = (ANDFilter<Number>) this.andFilter.clone();

+		assertEquals(this.andFilter.getFilters()[0], andFilter2.getFilters()[0]);

+		assertEquals(this.andFilter.getFilters()[1], andFilter2.getFilters()[1]);

+		assertNotSame(this.andFilter, andFilter2);

+	}

+

+	public void testEquals() {

+		@SuppressWarnings("unchecked")

+		ANDFilter<Number> andFilter2 = new ANDFilter<Number>(this.buildMinFilter(1), this.buildMaxFilter(10));

+		assertEquals(this.andFilter, andFilter2);

+		assertEquals(this.andFilter.hashCode(), andFilter2.hashCode());

+	}

+

+	public void testSerialization() throws Exception {

+		@SuppressWarnings("cast")

+		ANDFilter<Number> andFilter2 = (ANDFilter<Number>) TestTools.serialize(this.andFilter);

+		assertEquals(this.andFilter.getFilters()[0], andFilter2.getFilters()[0]);

+		assertEquals(this.andFilter.getFilters()[1], andFilter2.getFilters()[1]);

+		assertNotSame(this.andFilter, andFilter2);

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/CommonUtilityFilterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/CommonUtilityFilterTests.java
new file mode 100644
index 0000000..88f39f9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/CommonUtilityFilterTests.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.filter;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CommonUtilityFilterTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CommonUtilityFilterTests.class.getPackage().getName());
+
+		suite.addTestSuite(ANDFilterTests.class);
+		suite.addTestSuite(FilterTests.class);
+		suite.addTestSuite(NOTFilterTests.class);
+		suite.addTestSuite(NotNullFilterTests.class);
+		suite.addTestSuite(ORFilterTests.class);
+		suite.addTestSuite(XORFilterTests.class);
+
+		return suite;
+	}
+
+	private CommonUtilityFilterTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/FilterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/FilterTests.java
new file mode 100644
index 0000000..fbd15a1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/FilterTests.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.filter;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class FilterTests extends TestCase {
+
+	public FilterTests(String name) {
+		super(name);
+	}
+
+	public void testNullFilter() {
+		Filter<String> filter = Filter.Transparent.instance();
+		assertTrue(filter.accept(""));
+		assertTrue(filter.accept("foo"));
+		assertTrue(filter.accept("bar"));
+	}
+
+	public void testNullFilter_toString() {
+		Filter<String> filter = Filter.Transparent.instance();
+		assertNotNull(filter.toString());
+	}
+
+	public void testNullFilter_serialization() throws Exception {
+		Filter<String> filter = Filter.Transparent.instance();
+		assertSame(filter, TestTools.serialize(filter));
+	}
+
+	public void testOpaqueFilter() {
+		Filter<String> filter = Filter.Opaque.instance();
+		assertFalse(filter.accept(""));
+		assertFalse(filter.accept("foo"));
+		assertFalse(filter.accept("bar"));
+	}
+
+	public void testOpaqueFilter_toString() {
+		Filter<String> filter = Filter.Opaque.instance();
+		assertNotNull(filter.toString());
+	}
+
+	public void testOpaqueFilter_serialization() throws Exception {
+		Filter<String> filter = Filter.Opaque.instance();
+		assertSame(filter, TestTools.serialize(filter));
+	}
+
+	public void testDisabledFilter() {
+		Filter<String> filter = Filter.Disabled.instance();
+		boolean exCaught = false;
+		try {
+			assertFalse(filter.accept("foo"));
+			fail();
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testDisabledFilter_toString() {
+		Filter<String> filter = Filter.Disabled.instance();
+		assertNotNull(filter.toString());
+	}
+
+	public void testDisabledFilter_serialization() throws Exception {
+		Filter<String> filter = Filter.Disabled.instance();
+		assertSame(filter, TestTools.serialize(filter));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/NOTFilterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/NOTFilterTests.java
new file mode 100644
index 0000000..e701655
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/NOTFilterTests.java
@@ -0,0 +1,95 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.filter;

+

+import java.io.Serializable;

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.filter.Filter;

+import org.eclipse.persistence.tools.utility.filter.FilterAdapter;

+import org.eclipse.persistence.tools.utility.filter.NOTFilter;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+public class NOTFilterTests

+	extends TestCase

+{

+	private NOTFilter<Number> notFilter;

+

+

+	public NOTFilterTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.notFilter = new NOTFilter<Number>(this.buildPositiveFilter());

+	}

+

+	private Filter<Number> buildPositiveFilter() {

+		return new PositiveFilter();

+	}

+

+	static class PositiveFilter

+		extends FilterAdapter<Number>

+		implements Serializable

+	{

+		private static final long serialVersionUID = 1L;

+		@Override

+		public boolean accept(Number number) {

+			return number.doubleValue() > 0;

+		}

+		@Override

+		public boolean equals(Object obj) {

+			return this.getClass() == obj.getClass();

+		}

+		@Override

+		public int hashCode() {

+			return 789;

+		}

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testFiltering() {

+		assertTrue(this.notFilter.accept(new Integer(0)));

+		assertTrue(this.notFilter.accept(new Integer(-1)));

+		assertTrue(this.notFilter.accept(new Double(-0.001)));

+		assertFalse(this.notFilter.accept(new Double(1)));

+		assertFalse(this.notFilter.accept(new Double(11)));

+		assertFalse(this.notFilter.accept(new Double(111)));

+	}

+

+	public void testClone() {

+		@SuppressWarnings("unchecked")

+		NOTFilter<Number> notFilter2 = (NOTFilter<Number>) this.notFilter.clone();

+		assertEquals(this.notFilter.getFilter(), notFilter2.getFilter());

+		assertNotSame(this.notFilter, notFilter2);

+	}

+

+	public void testEquals() {

+		NOTFilter<Number> notFilter2 = new NOTFilter<Number>(this.buildPositiveFilter());

+		assertEquals(this.notFilter, notFilter2);

+		assertEquals(this.notFilter.hashCode(), notFilter2.hashCode());

+	}

+

+	public void testSerialization() throws Exception {

+		NOTFilter<Number> notFilter2 = TestTools.serialize(this.notFilter);

+		assertEquals(this.notFilter.getFilter(), notFilter2.getFilter());

+		assertNotSame(this.notFilter, notFilter2);

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/NotNullFilterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/NotNullFilterTests.java
new file mode 100644
index 0000000..3b60f85
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/NotNullFilterTests.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.filter;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.filter.NotNullFilter;
+
+@SuppressWarnings("nls")
+public class NotNullFilterTests extends TestCase {
+
+	public NotNullFilterTests(String name) {
+		super(name);
+	}
+
+	public void testNotNullFilter() {
+		Filter<String> filter = NotNullFilter.instance();
+		assertTrue(filter.accept(""));
+		assertFalse(filter.accept(null));
+		assertTrue(filter.accept("foo"));
+		assertTrue(filter.accept("bar"));
+	}
+
+	public void testToString() {
+		Filter<String> filter = NotNullFilter.instance();
+		assertNotNull(filter.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/ORFilterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/ORFilterTests.java
new file mode 100644
index 0000000..e64ddc6
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/ORFilterTests.java
@@ -0,0 +1,166 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.filter;

+

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.BitTools;

+import org.eclipse.persistence.tools.utility.filter.Filter;

+import org.eclipse.persistence.tools.utility.filter.FilterAdapter;

+import org.eclipse.persistence.tools.utility.filter.ORFilter;

+import org.eclipse.persistence.tools.utility.filter.SimpleFilter;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+public class ORFilterTests

+	extends TestCase

+{

+	private ORFilter<Number> orFilter;

+

+

+	public ORFilterTests(String name) {

+		super(name);

+	}

+

+	@Override

+	@SuppressWarnings("unchecked")

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.orFilter = new ORFilter<Number>(this.buildMinFilter(1), this.buildMaxFilter(10));

+	}

+

+	private Filter<Number> buildMinFilter(double min) {

+		return new MinFilter(min);

+	}

+

+	static class MinFilter

+		extends SimpleFilter<Number, Number>

+	{

+		private static final long serialVersionUID = 1L;

+		MinFilter(double min) {

+			super(new Double(min));

+		}

+		@Override

+		public boolean accept(Number number) {

+			return number.doubleValue() <= this.criterion.doubleValue();

+		}

+	}

+

+	private Filter<Number> buildMaxFilter(double max) {

+		return new MaxFilter(max);

+	}

+

+	static class MaxFilter

+		extends SimpleFilter<Number, Number>

+	{

+		private static final long serialVersionUID = 1L;

+		MaxFilter(double min) {

+			super(new Double(min));

+		}

+		@Override

+		public boolean accept(Number number) {

+			return number.doubleValue() >= this.criterion.doubleValue();

+		}

+	}

+

+	private Filter<Number> buildEvenFilter() {

+		return new EvenFilter();

+	}

+

+	static class EvenFilter

+		extends FilterAdapter<Number>

+	{

+		EvenFilter() {

+			super();

+		}

+		@Override

+		public boolean accept(Number number) {

+			return BitTools.isEven(number.intValue());

+		}

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testFiltering2() {

+		assertFalse(this.orFilter.accept(new Integer(7)));

+		assertFalse(this.orFilter.accept(new Integer(2)));

+		assertFalse(this.orFilter.accept(new Double(6.666)));

+		assertTrue(this.orFilter.accept(new Double(-99)));

+		assertTrue(this.orFilter.accept(new Double(-1)));

+		assertTrue(this.orFilter.accept(new Double(11)));

+		assertTrue(this.orFilter.accept(new Double(111)));

+	}

+

+	public void testFiltering3() {

+		@SuppressWarnings("unchecked")

+		ORFilter<Number> orFilter2 = new ORFilter<Number>(this.orFilter, this.buildEvenFilter());

+		assertFalse(orFilter2.accept(new Integer(7)));

+		assertFalse(orFilter2.accept(new Integer(3)));

+		assertFalse(orFilter2.accept(new Integer(9)));

+		assertTrue(orFilter2.accept(new Integer(2)));

+		assertTrue(orFilter2.accept(new Double(6.1)));

+		assertTrue(orFilter2.accept(new Double(-99)));

+		assertTrue(orFilter2.accept(new Double(-1)));

+		assertTrue(orFilter2.accept(new Double(11)));

+		assertTrue(orFilter2.accept(new Double(111)));

+		assertTrue(orFilter2.accept(new Double(-98)));

+		assertTrue(orFilter2.accept(new Double(0)));

+		assertTrue(orFilter2.accept(new Double(-2)));

+		assertTrue(orFilter2.accept(new Double(12)));

+		assertTrue(orFilter2.accept(new Double(222)));

+	}

+

+	public void testFilteringComposite() {

+		@SuppressWarnings("unchecked")

+		Filter<Number> orFilter2 = new ORFilter<Number>(this.buildMinFilter(1), this.buildMaxFilter(10), this.buildEvenFilter());

+		assertFalse(orFilter2.accept(new Integer(7)));

+		assertFalse(orFilter2.accept(new Integer(3)));

+		assertFalse(orFilter2.accept(new Integer(9)));

+		assertTrue(orFilter2.accept(new Integer(2)));

+		assertTrue(orFilter2.accept(new Double(6.1)));

+		assertTrue(orFilter2.accept(new Double(-99)));

+		assertTrue(orFilter2.accept(new Double(-1)));

+		assertTrue(orFilter2.accept(new Double(11)));

+		assertTrue(orFilter2.accept(new Double(111)));

+		assertTrue(orFilter2.accept(new Double(-98)));

+		assertTrue(orFilter2.accept(new Double(0)));

+		assertTrue(orFilter2.accept(new Double(-2)));

+		assertTrue(orFilter2.accept(new Double(12)));

+		assertTrue(orFilter2.accept(new Double(222)));

+	}

+

+	public void testClone() {

+		@SuppressWarnings("unchecked")

+		ORFilter<Number> orFilter2 = (ORFilter<Number>) this.orFilter.clone();

+		assertEquals(this.orFilter.getFilters()[0], orFilter2.getFilters()[0]);

+		assertEquals(this.orFilter.getFilters()[1], orFilter2.getFilters()[1]);

+		assertNotSame(this.orFilter, orFilter2);

+	}

+

+	public void testEquals() {

+		@SuppressWarnings("unchecked")

+		ORFilter<Number> orFilter2 = new ORFilter<Number>(this.buildMinFilter(1), this.buildMaxFilter(10));

+		assertEquals(this.orFilter, orFilter2);

+		assertEquals(this.orFilter.hashCode(), orFilter2.hashCode());

+	}

+

+	public void testSerialization() throws Exception {

+		ORFilter<Number> orFilter2 = TestTools.serialize(this.orFilter);

+		assertEquals(this.orFilter.getFilters()[0], orFilter2.getFilters()[0]);

+		assertEquals(this.orFilter.getFilters()[1], orFilter2.getFilters()[1]);

+		assertNotSame(this.orFilter, orFilter2);

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/XORFilterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/XORFilterTests.java
new file mode 100644
index 0000000..87c3423
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/filter/XORFilterTests.java
@@ -0,0 +1,144 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.filter;

+

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.BitTools;

+import org.eclipse.persistence.tools.utility.filter.Filter;

+import org.eclipse.persistence.tools.utility.filter.FilterAdapter;

+import org.eclipse.persistence.tools.utility.filter.SimpleFilter;

+import org.eclipse.persistence.tools.utility.filter.XORFilter;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+public class XORFilterTests

+	extends TestCase

+{

+	private XORFilter<Number> xorFilter;

+

+

+	public XORFilterTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.xorFilter = new XORFilter<Number>(this.buildMinFilter(1), this.buildMaxFilter(10));

+	}

+

+	private Filter<Number> buildMinFilter(double min) {

+		return new MinFilter(min);

+	}

+

+	static class MinFilter

+		extends SimpleFilter<Number, Number>

+	{

+		private static final long serialVersionUID = 1L;

+		MinFilter(double min) {

+			super(new Double(min));

+		}

+		@Override

+		public boolean accept(Number number) {

+			return number.doubleValue() <= this.criterion.doubleValue();

+		}

+	}

+

+	private Filter<Number> buildMaxFilter(double max) {

+		return new MaxFilter(max);

+	}

+

+	static class MaxFilter

+		extends SimpleFilter<Number, Number>

+	{

+		private static final long serialVersionUID = 1L;

+		MaxFilter(double min) {

+			super(new Double(min));

+		}

+		@Override

+		public boolean accept(Number number) {

+			return number.doubleValue() >= this.criterion.doubleValue();

+		}

+	}

+

+	private Filter<Number> buildEvenFilter() {

+		return new EvenFilter();

+	}

+

+	static class EvenFilter

+		extends FilterAdapter<Number>

+	{

+		EvenFilter() {

+			super();

+		}

+		@Override

+		public boolean accept(Number number) {

+			return BitTools.isEven(number.intValue());

+		}

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testFiltering2() {

+		assertFalse(this.xorFilter.accept(new Integer(7)));

+		assertFalse(this.xorFilter.accept(new Integer(2)));

+		assertFalse(this.xorFilter.accept(new Double(6.666)));

+		assertTrue(this.xorFilter.accept(new Double(-99)));

+		assertTrue(this.xorFilter.accept(new Double(-1)));

+		assertTrue(this.xorFilter.accept(new Double(11)));

+		assertTrue(this.xorFilter.accept(new Double(111)));

+	}

+

+	public void testFiltering3() {

+		XORFilter<Number> xorFilter2 = new XORFilter<Number>(this.xorFilter, this.buildEvenFilter());

+		assertFalse(xorFilter2.accept(new Integer(7)));

+		assertFalse(xorFilter2.accept(new Integer(3)));

+		assertFalse(xorFilter2.accept(new Integer(9)));

+		assertTrue(xorFilter2.accept(new Integer(2)));

+		assertTrue(xorFilter2.accept(new Double(6.1)));

+		assertTrue(xorFilter2.accept(new Double(-99)));

+		assertTrue(xorFilter2.accept(new Double(-1)));

+		assertTrue(xorFilter2.accept(new Double(11)));

+		assertTrue(xorFilter2.accept(new Double(111)));

+		assertFalse(xorFilter2.accept(new Double(-98)));

+		assertFalse(xorFilter2.accept(new Double(0)));

+		assertFalse(xorFilter2.accept(new Double(-2)));

+		assertFalse(xorFilter2.accept(new Double(12)));

+		assertFalse(xorFilter2.accept(new Double(222)));

+	}

+

+	public void testClone() {

+		@SuppressWarnings("unchecked")

+		XORFilter<Number> xorFilter2 = (XORFilter<Number>) this.xorFilter.clone();

+		assertEquals(this.xorFilter.getFilters()[0], xorFilter2.getFilters()[0]);

+		assertEquals(this.xorFilter.getFilters()[1], xorFilter2.getFilters()[1]);

+		assertNotSame(this.xorFilter, xorFilter2);

+	}

+

+	public void testEquals() {

+		XORFilter<Number> xorFilter2 = new XORFilter<Number>(this.buildMinFilter(1), this.buildMaxFilter(10));

+		assertEquals(this.xorFilter, xorFilter2);

+		assertEquals(this.xorFilter.hashCode(), xorFilter2.hashCode());

+	}

+

+	public void testSerialization() throws Exception {

+		XORFilter<Number> xorFilter2 = TestTools.serialize(this.xorFilter);

+		assertEquals(this.xorFilter.getFilters()[0], xorFilter2.getFilters()[0]);

+		assertEquals(this.xorFilter.getFilters()[1], xorFilter2.getFilters()[1]);

+		assertNotSame(this.xorFilter, xorFilter2);

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ArrayToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ArrayToolsTests.java
deleted file mode 100644
index 5362ea6..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ArrayToolsTests.java
+++ /dev/null
@@ -1,3525 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Vector;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.ArrayTools;
-import org.eclipse.persistence.tools.utility.Range;
-import org.eclipse.persistence.tools.utility.ReflectionTools;
-import org.eclipse.persistence.tools.utility.ReverseComparator;
-import org.eclipse.persistence.tools.utility.iterators.EmptyIterator;
-
-@SuppressWarnings("nls")
-public class ArrayToolsTests extends TestCase {
-
-	public ArrayToolsTests(String name) {
-		super(name);
-	}
-
-
-	// ********** instantiation **********
-
-	public void testNewArrayObjectArray() {
-		String[] array1 = new String[2];
-		String[] array2 = ArrayTools.newArray(array1);
-		array2[0] = "foo";
-		array2[1] = "bar";
-		assertEquals(String.class, array2.getClass().getComponentType());
-		assertEquals(2, array2.length);
-	}
-
-	public void testNewArrayObjectArrayInt() {
-		String[] array1 = new String[2];
-		String[] array2 = ArrayTools.newArray(array1, 5);
-		array2[0] = "foo";
-		array2[4] = "bar";
-		assertEquals(String.class, array2.getClass().getComponentType());
-		assertEquals(5, array2.length);
-	}
-
-	public void testNewArrayObjectArrayInt_Exception() {
-		String[] array1 = new String[2];
-		Object[] array2 = ArrayTools.newArray(array1, 5);
-		boolean exCaught = false;
-		try {
-			array2[1] = Integer.valueOf(7);
-			fail("bogus array: " + Arrays.toString(array2));
-		} catch (ArrayStoreException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testComponentType() {
-		String[] array = new String[2];
-		Class<? extends String> javaClass = ArrayTools.componentType(array);
-		assertEquals(String.class, javaClass);
-	}
-
-	public void testNewArrayClassInt() {
-		String[] array = ArrayTools.newArray(String.class, 5);
-		array[0] = "foo";
-		array[4] = "bar";
-		assertEquals(String.class, array.getClass().getComponentType());
-		assertEquals(5, array.length);
-	}
-
-	public void testNewArrayClassInt_Exception() {
-		Object[] array = ArrayTools.newArray(String.class, 5);
-		boolean exCaught = false;
-		try {
-			array[1] = Integer.valueOf(7);
-			fail("bogus array: " + Arrays.toString(array));
-		} catch (ArrayStoreException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testNewArrayClassInt_Primitive() {
-		boolean exCaught = false;
-		try {
-			Object[] array = ArrayTools.newArray(int.class, 5);
-			fail("bogus array: " + Arrays.toString(array));
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-
-	// ********** conversion **********
-
-	public void testArrayIterable() {
-		Iterable<String> iterable = this.buildStringList1();
-		Object[] a = ArrayTools.array(iterable);
-		assertEquals(3, a.length);
-		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
-	}
-
-	public void testArrayIterableInt() {
-		Iterable<String> iterable = this.buildStringList1();
-		Object[] a = ArrayTools.array(iterable, 3);
-		assertEquals(3, a.length);
-		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
-	}
-
-	public void testArrayIterableObjectArray_String() {
-		Iterable<String> iterable = this.buildStringList1();
-		String[] a = ArrayTools.array(iterable, new String[0]);
-		assertEquals(3, a.length);
-		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
-	}
-
-	public void testArrayIterableObjectArray_Object() {
-		Iterable<String> iterable = this.buildStringList1();
-		Object[] a = ArrayTools.array(iterable, new Object[0]);
-		assertEquals(3, a.length);
-		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
-	}
-
-	public void testArrayIterableIntObjectArray() {
-		Iterable<String> iterable = this.buildStringList1();
-		String[] a = ArrayTools.array(iterable, 3, new String[0]);
-		assertEquals(3, a.length);
-		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
-	}
-
-	public void testArrayIterator() {
-		Object[] a = ArrayTools.array(this.buildStringList1().iterator());
-		assertEquals(3, a.length);
-		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
-	}
-
-	public void testArrayIterator_Empty() {
-		Object[] a = ArrayTools.array(EmptyIterator.instance());
-		assertEquals(0, a.length);
-	}
-
-	public void testArrayIteratorInt() {
-		Object[] a = ArrayTools.array(this.buildStringList1().iterator(), 3);
-		assertEquals(3, a.length);
-		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
-	}
-
-	public void testArrayIteratorInt_Empty() {
-		Object[] a = ArrayTools.array(EmptyIterator.instance(), 3);
-		assertEquals(0, a.length);
-	}
-
-	public void testArrayIteratorObjectArray_String() {
-		String[] a = ArrayTools.array(this.buildStringList1().iterator(), new String[0]);
-		assertEquals(3, a.length);
-		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
-	}
-
-	public void testArrayIteratorObjectArray_Empty() {
-		String[] a = ArrayTools.array(EmptyIterator.<String>instance(), new String[0]);
-		assertEquals(0, a.length);
-	}
-
-	public void testArrayIteratorObjectArray_Empty_ClearArray() {
-		String[] a = ArrayTools.array(EmptyIterator.<String>instance(), new String[5]);
-		assertEquals(5, a.length);
-		assertNull(a[0]);
-	}
-
-	public void testArrayIteratorObjectArray_Object() {
-		Object[] a = ArrayTools.array(this.buildStringList1().iterator(), new Object[0]);
-		assertEquals(3, a.length);
-		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
-	}
-
-	public void testArrayIteratorIntObjectArray() {
-		String[] a = ArrayTools.array(this.buildStringList1().iterator(), 3, new String[0]);
-		assertEquals(3, a.length);
-		assertTrue(ArrayTools.containsAll(a, this.buildStringList1().iterator()));
-	}
-
-	public void testArrayIteratorIntObjectArray_Empty() {
-		String[] a = ArrayTools.array(EmptyIterator.<String>instance(), 3, new String[0]);
-		assertEquals(0, a.length);
-	}
-
-
-	// ********** add **********
-
-	public void testAddObjectArrayObject_Object() {
-		Object[] a = ArrayTools.add(this.buildObjectArray1(), "twenty");
-		assertEquals(4, a.length);
-		assertTrue(ArrayTools.contains(a, "twenty"));
-		assertEquals("twenty", a[a.length-1]);
-	}
-
-	public void testAddObjectArrayObject_String() {
-		String[] a = ArrayTools.add(this.buildStringArray1(), "twenty");
-		assertEquals(4, a.length);
-		assertTrue(ArrayTools.contains(a, "twenty"));
-		assertEquals("twenty", a[a.length-1]);
-	}
-
-	public void testAddObjectArrayObject_EmptyArray() {
-		String[] a = new String[0];
-		a = ArrayTools.add(a, "twenty");
-		assertEquals(1, a.length);
-		assertTrue(ArrayTools.contains(a, "twenty"));
-		assertEquals("twenty", a[0]);
-	}
-
-	public void testAddObjectArrayIntObject_Object() {
-		Object[] a = new Object[] { "a", "b", "c", "d" };
-		a = ArrayTools.add(a, 2, "X");
-		assertEquals(5, a.length);
-		assertTrue(ArrayTools.contains(a, "X"));
-		assertTrue(Arrays.equals(new Object[] { "a", "b", "X", "c", "d" }, a));
-	}
-
-	public void testAddObjectArrayIntObject_String() {
-		String[] a = new String[] { "a", "b", "c", "d" };
-		a = ArrayTools.add(a, 2, "X");
-		assertEquals(5, a.length);
-		assertTrue(ArrayTools.contains(a, "X"));
-		assertTrue(Arrays.equals(new String[] { "a", "b", "X", "c", "d" }, a));
-	}
-
-	public void testAddObjectArrayIntObject_End() {
-		String[] a = new String[] { "a", "b", "c", "d" };
-		a = ArrayTools.add(a, 4, "X");
-		assertEquals(5, a.length);
-		assertTrue(ArrayTools.contains(a, "X"));
-		assertTrue(Arrays.equals(new String[] { "a", "b", "c", "d", "X" }, a));
-	}
-
-	public void testAddObjectArrayIntObject_Zero() {
-		String[] a = new String[] { "a", "b", "c", "d" };
-		a = ArrayTools.add(a, 0, "X");
-		assertEquals(5, a.length);
-		assertTrue(ArrayTools.contains(a, "X"));
-		assertTrue(Arrays.equals(new String[] { "X", "a", "b", "c", "d" }, a));
-	}
-
-	public void testAddObjectArrayIntObject_Exception() {
-		Object[] a = new Object[] { "a", "b", "c", "d" };
-		boolean exCaught = false;
-		try {
-			a = ArrayTools.add(a, 33, "X");
-		} catch (IndexOutOfBoundsException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testAddCharArrayChar() {
-		char[] a = ArrayTools.add(this.buildCharArray(), 'd');
-		assertEquals(4, a.length);
-		assertTrue(ArrayTools.contains(a, 'd'));
-	}
-
-	public void testAddCharArrayChar_Empty() {
-		char[] a = new char[0];
-		a = ArrayTools.add(a, 'd');
-		assertEquals(1, a.length);
-		assertTrue(ArrayTools.contains(a, 'd'));
-		assertTrue(Arrays.equals(new char[] { 'd' }, a));
-	}
-
-	public void testAddCharArrayIntChar() {
-		char[] a = new char[] { 'a', 'b', 'c', 'd' };
-		a = ArrayTools.add(a, 2, 'X');
-		assertEquals(5, a.length);
-		assertTrue(ArrayTools.contains(a, 'X'));
-		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'X', 'c', 'd' }, a));
-	}
-
-	public void testAddCharArrayIntChar_Zero() {
-		char[] a = new char[] { 'a', 'b', 'c', 'd' };
-		a = ArrayTools.add(a, 0, 'X');
-		assertEquals(5, a.length);
-		assertTrue(ArrayTools.contains(a, 'X'));
-		assertTrue(Arrays.equals(new char[] { 'X', 'a', 'b', 'c', 'd' }, a));
-	}
-
-	public void testAddCharArrayIntChar_End() {
-		char[] a = new char[] { 'a', 'b', 'c', 'd' };
-		a = ArrayTools.add(a, 4, 'X');
-		assertEquals(5, a.length);
-		assertTrue(ArrayTools.contains(a, 'X'));
-		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'c', 'd', 'X' }, a));
-	}
-
-	public void testAddIntArrayInt() {
-		int[] a = ArrayTools.add(this.buildIntArray(), 30);
-		assertEquals(4, a.length);
-		assertTrue(ArrayTools.contains(a, 30));
-	}
-
-	public void testAddIntArrayInt_Empty() {
-		int[] a = new int[0];
-		a = ArrayTools.add(a, 30);
-		assertEquals(1, a.length);
-		assertTrue(ArrayTools.contains(a, 30));
-		assertTrue(Arrays.equals(new int[] { 30 }, a));
-	}
-
-	public void testAddIntArrayIntInt() {
-		int[] a = new int[] { 1, 2, 3, 4 };
-		a = ArrayTools.add(a, 2, 99);
-		assertEquals(5, a.length);
-		assertTrue(ArrayTools.contains(a, 99));
-		assertTrue(Arrays.equals(new int[] { 1, 2, 99, 3, 4 }, a));
-	}
-
-	public void testAddIntArrayIntInt_Zero() {
-		int[] a = new int[] { 1, 2, 3, 4 };
-		a = ArrayTools.add(a, 0, 99);
-		assertEquals(5, a.length);
-		assertTrue(ArrayTools.contains(a, 99));
-		assertTrue(Arrays.equals(new int[] { 99, 1, 2, 3, 4 }, a));
-	}
-
-	public void testAddIntArrayIntInt_End() {
-		int[] a = new int[] { 1, 2, 3, 4 };
-		a = ArrayTools.add(a, 4, 99);
-		assertEquals(5, a.length);
-		assertTrue(ArrayTools.contains(a, 99));
-		assertTrue(Arrays.equals(new int[] { 1, 2, 3, 4, 99 }, a));
-	}
-
-
-	// ********** add all **********
-
-	public void testAddAllObjectArrayCollection_String() {
-		String[] a = this.buildStringArray1();
-		Collection<String> c = this.buildStringList2();
-		String[] newArray = ArrayTools.addAll(a, c);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, c));
-	}
-
-	public void testAddAllObjectArrayCollection_Object() {
-		Object[] a = this.buildObjectArray1();
-		Collection<String> c = this.buildStringList2();
-		Object[] newArray = ArrayTools.addAll(a, c);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, c));
-	}
-
-	public void testAddAllObjectArrayCollection_EmptyArray() {
-		String[] a = new String[0];
-		Collection<String> c = this.buildStringList2();
-		String[] newArray = ArrayTools.addAll(a, c);
-
-		assertEquals(3, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, c));
-	}
-
-	public void testAddAllObjectArrayCollection_EmptyCollection() {
-		String[] a = this.buildStringArray1();
-		Collection<String> c = new ArrayList<String>();
-		String[] newArray = ArrayTools.addAll(a, c);
-
-		assertEquals(3, newArray.length);
-	}
-
-	public void testAddAllObjectArrayIntCollection_String() {
-		String[] a = this.buildStringArray1();
-		Collection<String> c = this.buildStringList2();
-		String[] newArray = ArrayTools.addAll(a, 1, c);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, c));
-	}
-
-	public void testAddAllObjectArrayIntCollection_String_End() {
-		String[] a = this.buildStringArray1();
-		Collection<String> c = this.buildStringList2();
-		String[] newArray = ArrayTools.addAll(a, 3, c);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, c));
-	}
-
-	public void testAddAllObjectArrayIntCollection_EmptyArray() {
-		String[] a = new String[0];
-		Collection<String> c = this.buildStringList2();
-		String[] newArray = ArrayTools.addAll(a, 0, c);
-
-		assertEquals(3, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, c));
-	}
-
-	public void testAddAllObjectArrayIntCollection_EmptyArray_Exception() {
-		String[] a = new String[0];
-		Collection<String> c = this.buildStringList2();
-		boolean exCaught = false;
-		try {
-			String[] newArray = ArrayTools.addAll(a, 3, c);
-			fail("bogus array: " + Arrays.toString(newArray));
-		} catch (IndexOutOfBoundsException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testAddAllObjectArrayIntCollection_EmptyCollection() {
-		String[] a = this.buildStringArray1();
-		Collection<String> c = new ArrayList<String>();
-		String[] newArray = ArrayTools.addAll(a, 1, c);
-
-		assertEquals(3, newArray.length);
-	}
-
-	public void testAddAllObjectArrayIntIterable_String() {
-		String[] a = this.buildStringArray1();
-		Iterable<String> iterable = this.buildStringList2();
-		String[] newArray = ArrayTools.addAll(a, 1, iterable);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, iterable));
-	}
-
-	public void testAddAllObjectArrayIntIterable_EmptyArray() {
-		String[] a = new String[0];
-		Iterable<String> iterable = this.buildStringList2();
-		String[] newArray = ArrayTools.addAll(a, 0, iterable);
-
-		assertEquals(3, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, iterable));
-	}
-
-	public void testAddAllObjectArrayIntIterable_EmptyIterable() {
-		String[] a = this.buildStringArray1();
-		Iterable<String> iterable = new ArrayList<String>();
-		String[] newArray = ArrayTools.addAll(a, 1, iterable);
-
-		assertEquals(3, newArray.length);
-	}
-
-	public void testAddAllObjectArrayIntIterableInt_String() {
-		String[] a = this.buildStringArray1();
-		Iterable<String> iterable = this.buildStringList2();
-		String[] newArray = ArrayTools.addAll(a, 1, iterable, 3);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, iterable));
-	}
-
-	public void testAddAllObjectArrayIntIterableInt_EmptyArray() {
-		String[] a = new String[0];
-		Iterable<String> iterable = this.buildStringList2();
-		String[] newArray = ArrayTools.addAll(a, 0, iterable, 3);
-
-		assertEquals(3, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, iterable));
-	}
-
-	public void testAddAllObjectArrayIntIterableInt_EmptyIterable() {
-		String[] a = this.buildStringArray1();
-		Iterable<String> iterable = new ArrayList<String>();
-		String[] newArray = ArrayTools.addAll(a, 1, iterable, 0);
-
-		assertEquals(3, newArray.length);
-	}
-
-	public void testAddAllObjectArrayIntIterator_String() {
-		String[] a = this.buildStringArray1();
-		Iterator<String> iterator = this.buildStringList2().iterator();
-		String[] newArray = ArrayTools.addAll(a, 1, iterator);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList2()));
-	}
-
-	public void testAddAllObjectArrayIntIterator_EmptyArray() {
-		String[] a = new String[0];
-		Iterator<String> iterator = this.buildStringList2().iterator();
-		String[] newArray = ArrayTools.addAll(a, 0, iterator);
-
-		assertEquals(3, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList2()));
-	}
-
-	public void testAddAllObjectArrayIntIterator_EmptyIterable() {
-		String[] a = this.buildStringArray1();
-		Iterator<String> iterator = EmptyIterator.instance();
-		String[] newArray = ArrayTools.addAll(a, 1, iterator);
-
-		assertEquals(3, newArray.length);
-	}
-
-	public void testAddAllObjectArrayIntIteratorInt_String() {
-		String[] a = this.buildStringArray1();
-		Iterator<String> iterator = this.buildStringList2().iterator();
-		String[] newArray = ArrayTools.addAll(a, 1, iterator, 3);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList2()));
-	}
-
-	public void testAddAllObjectArrayIntIteratorInt_EmptyArray() {
-		String[] a = new String[0];
-		Iterator<String> iterator = this.buildStringList2().iterator();
-		String[] newArray = ArrayTools.addAll(a, 0, iterator, 3);
-
-		assertEquals(3, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList2()));
-	}
-
-	public void testAddAllObjectArrayIntIteratorInt_EmptyIterator() {
-		String[] a = this.buildStringArray1();
-		Iterator<String> iterator = EmptyIterator.instance();
-		String[] newArray = ArrayTools.addAll(a, 1, iterator, 0);
-
-		assertEquals(3, newArray.length);
-	}
-
-	public void testAddAllObjectArrayIterable() {
-		String[] a = this.buildStringArray1();
-		Iterable<String> iterable = this.buildStringList1();
-		String[] newArray = ArrayTools.addAll(a, iterable);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList1()));
-	}
-
-	public void testAddAllObjectArrayIterableInt() {
-		String[] a = this.buildStringArray1();
-		Iterable<String> iterable = this.buildStringList1();
-		String[] newArray = ArrayTools.addAll(a, iterable, 33);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList1()));
-	}
-
-	public void testAddAllObjectArrayIterator_String() {
-		String[] a = this.buildStringArray1();
-		Iterator<String> iterator = this.buildStringList1().iterator();
-		String[] newArray = ArrayTools.addAll(a, iterator);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList1()));
-	}
-
-	public void testAddAllObjectArrayIterator_Object() {
-		String[] a = this.buildStringArray1();
-		Iterator<Object> iterator = this.buildObjectList1().iterator();
-		Object[] newArray = ArrayTools.addAll(a, iterator);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, this.buildObjectList1()));
-	}
-
-	public void testAddAllObjectArrayIterator_EmptyIterator() {
-		String[] a = this.buildStringArray1();
-		Iterator<String> iterator = EmptyIterator.instance();
-		String[] newArray = ArrayTools.addAll(a, iterator);
-
-		assertEquals(3, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList1()));
-	}
-
-	public void testAddAllObjectArrayIteratorInt() {
-		String[] a = this.buildStringArray1();
-		Iterator<Object> iterator = this.buildObjectList1().iterator();
-		Object[] newArray = ArrayTools.addAll(a, iterator, 3);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, this.buildObjectList1()));
-	}
-
-	public void testAddAllObjectArrayIteratorInt_EmptyIterator() {
-		String[] a = this.buildStringArray1();
-		Iterator<String> iterator = EmptyIterator.instance();
-		String[] newArray = ArrayTools.addAll(a, iterator, 0);
-
-		assertEquals(3, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, this.buildStringList1()));
-	}
-
-	public void testAddAllObjectArrayObjectArray_Object() {
-		Object[] a1 = this.buildObjectArray1();
-		Object[] a2 = this.buildObjectArray2();
-		Object[] newArray = ArrayTools.addAll(a1, a2);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, a1));
-		assertTrue(ArrayTools.containsAll(newArray, a2));
-	}
-
-	public void testAddAllObjectArrayObjectArray_String() {
-		String[] a1 = this.buildStringArray1();
-		String[] a2 = this.buildStringArray2();
-		String[] newArray = ArrayTools.addAll(a1, a2);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, (Object[]) a1));
-		assertTrue(ArrayTools.containsAll(newArray, (Object[]) a2));
-	}
-
-	public void testAddAllObjectArrayObjectArray_ObjectString() {
-		Object[] a1 = this.buildObjectArray1();
-		String[] a2 = this.buildStringArray2();
-		Object[] newArray = ArrayTools.addAll(a1, (Object[]) a2);
-
-		assertEquals(6, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, a1));
-		assertTrue(ArrayTools.containsAll(newArray, (Object[]) a2));
-	}
-
-	public void testAddAllObjectArrayObjectArray_EmptyArray1() {
-		Object[] a1 = new Object[0];
-		Object[] a2 = this.buildObjectArray2();
-		Object[] newArray = ArrayTools.addAll(a1, a2);
-
-		assertEquals(3, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, a2));
-	}
-
-	public void testAddAllObjectArrayObjectArray_EmptyArray2() {
-		Object[] a1 = this.buildObjectArray1();
-		Object[] a2 = new Object[0];
-		Object[] newArray = ArrayTools.addAll(a1, a2);
-
-		assertEquals(3, newArray.length);
-		assertTrue(ArrayTools.containsAll(newArray, a1));
-	}
-
-	public void testAddAllObjectArrayIntObjectArray_Object() {
-		Object[] a = new Object[] { "a", "b", "c", "d" };
-		a = ArrayTools.addAll(a, 2, new Object[] { "X", "X", "X" });
-		assertEquals(7, a.length);
-		assertTrue(ArrayTools.contains(a, "X"));
-		assertTrue(Arrays.equals(new Object[] { "a", "b", "X", "X", "X", "c", "d" }, a));
-	}
-
-	public void testAddAllObjectArrayIntObjectArray_String() {
-		String[] a = new String[] { "a", "b", "c", "d" };
-		a = ArrayTools.addAll(a, 2, new String[] { "X", "X", "X" });
-		assertEquals(7, a.length);
-		assertTrue(ArrayTools.contains(a, "X"));
-		assertTrue(Arrays.equals(new String[] { "a", "b", "X", "X", "X", "c", "d" }, a));
-	}
-
-	public void testAddAllObjectArrayIntObjectArray_ObjectString() {
-		Object[] a = new Object[] { "a", "b", "c", "d" };
-		a = ArrayTools.addAll(a, 2, (Object[]) new String[] { "X", "X", "X" });
-		assertEquals(7, a.length);
-		assertTrue(ArrayTools.contains(a, "X"));
-		assertTrue(Arrays.equals(new Object[] { "a", "b", "X", "X", "X", "c", "d" }, a));
-	}
-
-	public void testAddAllObjectArrayIntObjectArray_End() {
-		Object[] a = new Object[] { "a", "b", "c", "d" };
-		a = ArrayTools.addAll(a, 4, (Object[]) new String[] { "X", "X", "X" });
-		assertEquals(7, a.length);
-		assertTrue(ArrayTools.contains(a, "X"));
-		assertTrue(Arrays.equals(new Object[] { "a", "b", "c", "d", "X", "X", "X" }, a));
-	}
-
-	public void testAddAllObjectArrayIntObjectArray_Zero() {
-		Object[] a = new Object[0];
-		a = ArrayTools.addAll(a, 0, (Object[]) new String[] { "X", "X", "X" });
-		assertEquals(3, a.length);
-		assertTrue(ArrayTools.contains(a, "X"));
-		assertTrue(Arrays.equals(new Object[] { "X", "X", "X" }, a));
-	}
-
-	public void testAddAllObjectArrayIntObjectArray_EmptyArray2() {
-		Object[] a = new Object[] { "a", "b", "c", "d" };
-		a = ArrayTools.addAll(a, 4, (Object[]) new String[0]);
-		assertEquals(4, a.length);
-		assertTrue(Arrays.equals(new Object[] { "a", "b", "c", "d" }, a));
-	}
-
-	public void testAddAllObjectArrayIntObjectArray_EmptyArray1() {
-		Object[] a = new String[0];
-		a = ArrayTools.addAll(a, 0, new Object[] { "a", "b", "c", "d" });
-		assertEquals(4, a.length);
-		assertTrue(Arrays.equals(new Object[] { "a", "b", "c", "d" }, a));
-	}
-
-	public void testAddAllCharArrayCharArray() {
-		char[] a = ArrayTools.addAll(this.buildCharArray(), new char[] { 'd', 'e' });
-		assertEquals(5, a.length);
-		assertTrue(ArrayTools.contains(a, 'd'));
-		assertTrue(ArrayTools.contains(a, 'e'));
-	}
-
-	public void testAddAllCharArrayCharArray_EmptyArray2() {
-		char[] a = ArrayTools.addAll(this.buildCharArray(), new char[0]);
-		assertEquals(3, a.length);
-	}
-
-	public void testAddAllCharArrayCharArrayEmptyArray1() {
-		char[] a = ArrayTools.addAll(new char[0], new char[] { 'd', 'e' });
-		assertEquals(2, a.length);
-		assertTrue(ArrayTools.contains(a, 'd'));
-		assertTrue(ArrayTools.contains(a, 'e'));
-	}
-
-	public void testAddAllCharArrayIntCharArray() {
-		char[] a = new char[] { 'a', 'b', 'c', 'd' };
-		a = ArrayTools.addAll(a, 2, new char[] { 'X', 'X', 'X' });
-		assertEquals(7, a.length);
-		assertTrue(ArrayTools.contains(a, 'X'));
-		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'X', 'X', 'X', 'c', 'd' }, a));
-	}
-
-	public void testAddAllCharArrayIntCharArray_End() {
-		char[] a = new char[] { 'a', 'b', 'c', 'd' };
-		a = ArrayTools.addAll(a, 4, new char[] { 'X', 'X', 'X' });
-		assertEquals(7, a.length);
-		assertTrue(ArrayTools.contains(a, 'X'));
-		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'c', 'd', 'X', 'X', 'X' }, a));
-	}
-
-	public void testAddAllCharArrayIntCharArray_EmptyArray1() {
-		char[] a = new char[0];
-		a = ArrayTools.addAll(a, 0, new char[] { 'X', 'X', 'X' });
-		assertEquals(3, a.length);
-		assertTrue(ArrayTools.contains(a, 'X'));
-		assertTrue(Arrays.equals(new char[] { 'X', 'X', 'X' }, a));
-	}
-
-	public void testAddAllCharArrayIntCharArray_EmptyArray2() {
-		char[] a = new char[] { 'a', 'b', 'c', 'd' };
-		a = ArrayTools.addAll(a, 2, new char[0]);
-		assertEquals(4, a.length);
-		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'c', 'd' }, a));
-	}
-
-	public void testAddAllIntArrayIntArray() {
-		int[] a = ArrayTools.addAll(this.buildIntArray(), new int[] { 30, 40 });
-		assertEquals(5, a.length);
-		assertTrue(ArrayTools.contains(a, 30));
-		assertTrue(ArrayTools.contains(a, 40));
-	}
-
-	public void testAddAllIntArrayIntArray_EmptyArray2() {
-		int[] a = ArrayTools.addAll(this.buildIntArray(), new int[0]);
-		assertEquals(3, a.length);
-	}
-
-	public void testAddAllIntArrayIntArray_EmptyArray1() {
-		int[] a = ArrayTools.addAll(new int[0], new int[] { 30, 40 });
-		assertEquals(2, a.length);
-		assertTrue(ArrayTools.contains(a, 30));
-		assertTrue(ArrayTools.contains(a, 40));
-	}
-
-	public void testAddAllIntArrayIntIntArray() {
-		int[] a = new int[] { 1, 2, 3, 4 };
-		a = ArrayTools.addAll(a, 2, new int[] { 99, 99, 99 });
-		assertEquals(7, a.length);
-		assertTrue(ArrayTools.contains(a, 99));
-		assertTrue(Arrays.equals(new int[] { 1, 2, 99, 99, 99, 3, 4 }, a));
-	}
-
-	public void testAddAllIntArrayIntIntArray_End() {
-		int[] a = new int[] { 1, 2, 3, 4 };
-		a = ArrayTools.addAll(a, 4, new int[] { 99, 99, 99 });
-		assertEquals(7, a.length);
-		assertTrue(ArrayTools.contains(a, 99));
-		assertTrue(Arrays.equals(new int[] { 1, 2, 3, 4, 99, 99, 99 }, a));
-	}
-
-	public void testAddAllIntArrayIntIntArray_EmptyArray2() {
-		int[] a = new int[] { 1, 2, 3, 4 };
-		a = ArrayTools.addAll(a, 2, new int[0]);
-		assertEquals(4, a.length);
-		assertTrue(Arrays.equals(new int[] { 1, 2, 3, 4 }, a));
-	}
-
-	public void testAddAllIntArrayIntIntArray_EmptyArray1() {
-		int[] a = new int[0];
-		a = ArrayTools.addAll(a, 0, new int[] { 99, 99, 99 });
-		assertEquals(3, a.length);
-		assertTrue(ArrayTools.contains(a, 99));
-		assertTrue(Arrays.equals(new int[] { 99, 99, 99 }, a));
-	}
-
-
-	// ********** clear **********
-
-	public void testClearObjectArray() {
-		String[] a = this.buildStringArray1();
-		assertEquals(3, a.length);
-		a = ArrayTools.clear(a);
-		assertEquals(0, a.length);
-	}
-
-	public void testClearObjectArray_Empty() {
-		String[] a = new String[0];
-		assertEquals(0, a.length);
-		a = ArrayTools.clear(a);
-		assertEquals(0, a.length);
-	}
-
-
-	// ********** concatenate **********
-
-	public void testConcatenateObjectArrayArray() {
-		String[] aArray = new String[] { "a", "b", "c", "d" };
-		String[] eArray = new String[] { "e", "f", "g", "h" };
-		String[] iArray = new String[] { "i", "j", "k", "l" };
-
-		String[] expected = new String[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l" };
-		String[] actual = ArrayTools.concatenate(aArray, eArray, iArray);
-		assertTrue(Arrays.equals(expected, actual));
-	}
-
-	public void testConcatenateObjectArrayArray_Empty() {
-		String[] aArray = new String[] {  };
-		String[] eArray = new String[0];
-		String[] iArray = new String[0];
-
-		String[] expected = new String[0];
-		String[] actual = ArrayTools.concatenate(aArray, eArray, iArray);
-		assertEquals(0, actual.length);
-		assertTrue(Arrays.equals(expected, actual));
-	}
-
-	public void testConcatenateCharArrayArray() {
-		char[] aArray = new char[] { 'a', 'b', 'c', 'd' };
-		char[] eArray = new char[] { 'e', 'f', 'g', 'h' };
-		char[] iArray = new char[] { 'i', 'j', 'k', 'l' };
-
-		char[] expected = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l' };
-		char[] actual = ArrayTools.concatenate(aArray, eArray, iArray);
-		assertTrue(Arrays.equals(expected, actual));
-	}
-
-	public void testConcatenateCharArrayArray_Empty() {
-		char[] aArray = new char[] {  };
-		char[] eArray = new char[0];
-		char[] iArray = new char[0];
-
-		char[] expected = new char[0];
-		char[] actual = ArrayTools.concatenate(aArray, eArray, iArray);
-		assertEquals(0, actual.length);
-		assertTrue(Arrays.equals(expected, actual));
-	}
-
-	public void testConcatenateIntArrayArray() {
-		int[] aArray = new int[] { 'a', 'b', 'c', 'd' };
-		int[] eArray = new int[] { 'e', 'f', 'g', 'h' };
-		int[] iArray = new int[] { 'i', 'j', 'k', 'l' };
-
-		int[] expected = new int[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l' };
-		int[] actual = ArrayTools.concatenate(aArray, eArray, iArray);
-		assertTrue(Arrays.equals(expected, actual));
-	}
-
-	public void testConcatenateIntArrayArray_Empty() {
-		int[] aArray = new int[] {  };
-		int[] eArray = new int[0];
-		int[] iArray = new int[0];
-
-		int[] expected = new int[0];
-		int[] actual = ArrayTools.concatenate(aArray, eArray, iArray);
-		assertEquals(0, actual.length);
-		assertTrue(Arrays.equals(expected, actual));
-	}
-
-
-	// ********** contains **********
-
-	public void testContainsObjectArrayObject() {
-		Object[] a = this.buildObjectArray1();
-		assertTrue(ArrayTools.contains(a, "one"));
-		assertFalse(ArrayTools.contains(a, null));
-		Object[] a2 = ArrayTools.add(a, null);
-		assertTrue(ArrayTools.contains(a2, null));
-	}
-
-	public void testContainsObjectArrayObject_EmptyArray() {
-		Object[] a = new Object[0];
-		assertFalse(ArrayTools.contains(a, "one"));
-		assertFalse(ArrayTools.contains(a, null));
-	}
-
-	public void testContainsCharArrayChar() {
-		char[] a = this.buildCharArray();
-		assertTrue(ArrayTools.contains(a, 'a'));
-		assertFalse(ArrayTools.contains(a, 'z'));
-		char[] a2 = ArrayTools.add(a, 'z');
-		assertTrue(ArrayTools.contains(a2, 'z'));
-	}
-
-	public void testContainsCharArrayObject_EmptyArray() {
-		char[] a = new char[0];
-		assertFalse(ArrayTools.contains(a, 'a'));
-	}
-
-	public void testContainsIntArrayInt() {
-		int[] a = this.buildIntArray();
-		assertTrue(ArrayTools.contains(a, 10));
-		assertFalse(ArrayTools.contains(a, 55));
-		int[] a2 = ArrayTools.add(a, 55);
-		assertTrue(ArrayTools.contains(a2, 55));
-	}
-
-	public void testContainsIntArrayObject_EmptyArray() {
-		int[] a = new int[0];
-		assertFalse(ArrayTools.contains(a, 'a'));
-	}
-
-
-	// ********** contains all **********
-
-	public void testContainsAllObjectArrayCollection() {
-		assertTrue(ArrayTools.containsAll(this.buildObjectArray1(), this.buildStringList1()));
-		assertFalse(ArrayTools.containsAll(this.buildObjectArray1(), this.buildStringList2()));
-	}
-
-	public void testContainsAllObjectArrayIterable() {
-		Iterable<String> iterable = this.buildStringList1();
-		assertTrue(ArrayTools.containsAll(this.buildObjectArray1(), iterable));
-		iterable = this.buildStringList2();
-		assertFalse(ArrayTools.containsAll(this.buildObjectArray1(), iterable));
-	}
-
-	public void testContainsAllObjectArrayIterator() {
-		assertTrue(ArrayTools.containsAll(this.buildObjectArray1(), this.buildStringList1().iterator()));
-		assertFalse(ArrayTools.containsAll(this.buildObjectArray1(), this.buildStringList2().iterator()));
-	}
-
-	public void testContainsAllObjectArrayIterator_Empty() {
-		assertTrue(ArrayTools.containsAll(this.buildObjectArray1(), EmptyIterator.instance()));
-	}
-
-	public void testContainsAllObjectArrayObjectArray() {
-		assertTrue(ArrayTools.containsAll(this.buildObjectArray1(), this.buildObjectArray1()));
-		assertFalse(ArrayTools.containsAll(this.buildObjectArray1(), this.buildObjectArray2()));
-	}
-
-	public void testContainsAllCharArrayCharArray() {
-		assertTrue(ArrayTools.containsAll(this.buildCharArray(), this.buildCharArray()));
-		assertFalse(ArrayTools.containsAll(this.buildCharArray(), new char[] { 'x', 'y' }));
-	}
-
-	public void testContainsAllIntArrayIntArray() {
-		assertTrue(ArrayTools.containsAll(this.buildIntArray(), this.buildIntArray()));
-		assertFalse(ArrayTools.containsAll(this.buildIntArray(), new int[] { 444, 888 }));
-	}
-
-
-	// ********** diff **********
-
-	public void testDiffEnd() {
-		String a = "a";
-		String b = "b";
-		String c = "c";
-		String d = "d";
-		String e = "e";
-		String a_ = new String("a");
-		String b_ = new String("b");
-		String c_ = new String("c");
-		String d_ = new String("d");
-		String e_ = new String("e");
-		assertTrue((a != a_) && a.equals(a_));
-		assertTrue((b != b_) && b.equals(b_));
-		assertTrue((c != c_) && c.equals(c_));
-		assertTrue((d != d_) && d.equals(d_));
-		assertTrue((e != e_) && e.equals(e_));
-		String[] array1;
-		String[] array2;
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(-1, ArrayTools.diffEnd(array1, array2));
-
-		array1 = new String[] { a };
-		array2 = new String[] { a_ };
-		assertEquals(-1, ArrayTools.diffEnd(array1, array2));
-
-		array1 = new String[] { b, c, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(4, ArrayTools.diffEnd(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { b_, c_, d_, e_ };
-		assertEquals(4, ArrayTools.diffEnd(array1, array2));
-
-		array1 = new String[0];
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(4, ArrayTools.diffEnd(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[0];
-		assertEquals(4, ArrayTools.diffEnd(array1, array2));
-
-		array1 = new String[0];
-		array2 = new String[0];
-		assertEquals(-1, ArrayTools.diffEnd(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { b_, c_, a_, d_, e_ };
-		assertEquals(2, ArrayTools.diffEnd(array1, array2));
-
-		array1 = new String[] { b, c, d, e };
-		array2 = new String[] { a_, c_, d_, e_ };
-		assertEquals(0, ArrayTools.diffEnd(array1, array2));
-
-		array1 = new String[] { a, b, c, e };
-		array2 = new String[] { a_, b_, c_, d_ };
-		assertEquals(3, ArrayTools.diffEnd(array1, array2));
-
-		String c__ = new String(c);
-		assertTrue((c != c__) && c.equals(c_));
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, c__, d_, e_ };
-		assertEquals(-1, ArrayTools.diffEnd(array1, array2));
-
-		array1 = new String[] { a, b, null, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(2, ArrayTools.diffEnd(array1, array2));
-
-		array1 = new String[] { a, b, null, d, e };
-		array2 = new String[] { a_, b_, null, d_, e_ };
-		assertEquals(-1, ArrayTools.diffEnd(array1, array2));
-	}
-
-	public void testDiffRange() {
-		String a = "a";
-		String b = "b";
-		String c = "c";
-		String d = "d";
-		String e = "e";
-		String a_ = a;
-		String b_ = b;
-		String c_ = c;
-		String d_ = d;
-		String e_ = e;
-		assertTrue((a == a_) && a.equals(a_));
-		assertTrue((b == b_) && b.equals(b_));
-		assertTrue((c == c_) && c.equals(c_));
-		assertTrue((d == d_) && d.equals(d_));
-		assertTrue((e == e_) && e.equals(e_));
-		String[] array1;
-		String[] array2;
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(new Range(5, -1), ArrayTools.diffRange(array1, array2));
-
-		array1 = new String[] { a };
-		array2 = new String[] { a_ };
-		assertEquals(new Range(1, -1), ArrayTools.diffRange(array1, array2));
-
-		array1 = new String[] { b, c, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(new Range(0, 4), ArrayTools.diffRange(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { b_, c_, d_, e_ };
-		assertEquals(new Range(0, 4), ArrayTools.diffRange(array1, array2));
-
-		array1 = new String[0];
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(new Range(0, 4), ArrayTools.diffRange(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[0];
-		assertEquals(new Range(0, 4), ArrayTools.diffRange(array1, array2));
-
-		array1 = new String[0];
-		array2 = new String[0];
-		assertEquals(new Range(0, -1), ArrayTools.diffRange(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { b_, c_, a_, d_, e_ };
-		assertEquals(new Range(0, 2), ArrayTools.diffRange(array1, array2));
-
-		array1 = new String[] { b, c, d, e };
-		array2 = new String[] { a_, c_, d_, e_ };
-		assertEquals(new Range(0, 0), ArrayTools.diffRange(array1, array2));
-
-		array1 = new String[] { a, b, c, e };
-		array2 = new String[] { a_, b_, c_, d_ };
-		assertEquals(new Range(3, 3), ArrayTools.diffRange(array1, array2));
-
-		String c__ = new String(c);
-		assertTrue((c != c__) && c.equals(c_));
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, c__, d_, e_ };
-		assertEquals(new Range(5, -1), ArrayTools.diffRange(array1, array2));
-
-		array1 = new String[] { a, b, null, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(new Range(2, 2), ArrayTools.diffRange(array1, array2));
-
-		array1 = new String[] { a, b, null, d, e };
-		array2 = new String[] { a_, b_, null, d_, e_ };
-		assertEquals(new Range(5, -1), ArrayTools.diffRange(array1, array2));
-	}
-
-	public void testDiffStart() {
-		String a = "a";
-		String b = "b";
-		String c = "c";
-		String d = "d";
-		String e = "e";
-		String a_ = new String("a");
-		String b_ = new String("b");
-		String c_ = new String("c");
-		String d_ = new String("d");
-		String e_ = new String("e");
-		assertTrue((a != a_) && a.equals(a_));
-		assertTrue((b != b_) && b.equals(b_));
-		assertTrue((c != c_) && c.equals(c_));
-		assertTrue((d != d_) && d.equals(d_));
-		assertTrue((e != e_) && e.equals(e_));
-		String[] array1;
-		String[] array2;
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(5, ArrayTools.diffStart(array1, array2));
-
-		array1 = new String[] { a };
-		array2 = new String[] { a_ };
-		assertEquals(1, ArrayTools.diffStart(array1, array2));
-
-		array1 = new String[] { a, b, c, d };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(4, ArrayTools.diffStart(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, c_, d_ };
-		assertEquals(4, ArrayTools.diffStart(array1, array2));
-
-		array1 = new String[0];
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(0, ArrayTools.diffStart(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[0];
-		assertEquals(0, ArrayTools.diffStart(array1, array2));
-
-		array1 = new String[0];
-		array2 = new String[0];
-		assertEquals(0, ArrayTools.diffStart(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, e_, c_, d_ };
-		assertEquals(2, ArrayTools.diffStart(array1, array2));
-
-		array1 = new String[] { a, b, c, e };
-		array2 = new String[] { a_, b_, c_, d_ };
-		assertEquals(3, ArrayTools.diffStart(array1, array2));
-
-		array1 = new String[] { b, c, d, e };
-		array2 = new String[] { a_, c_, d_, e_ };
-		assertEquals(0, ArrayTools.diffStart(array1, array2));
-
-		String c__ = new String(c);
-		assertTrue((c != c__) && c.equals(c__));
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, c__, d_, e_ };
-		assertEquals(5, ArrayTools.diffStart(array1, array2));
-
-		array1 = new String[] { a, b, null, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(2, ArrayTools.diffStart(array1, array2));
-
-		array1 = new String[] { a, b, null, d, e };
-		array2 = new String[] { a_, b_, null, d_, e_ };
-		assertEquals(5, ArrayTools.diffStart(array1, array2));
-	}
-
-
-	// ********** identity diff **********
-
-	public void testIdentityDiffEnd() {
-		String a = "a";
-		String b = "b";
-		String c = "c";
-		String d = "d";
-		String e = "e";
-		String a_ = a;
-		String b_ = b;
-		String c_ = c;
-		String d_ = d;
-		String e_ = e;
-		assertTrue((a == a_) && a.equals(a_));
-		assertTrue((b == b_) && b.equals(b_));
-		assertTrue((c == c_) && c.equals(c_));
-		assertTrue((d == d_) && d.equals(d_));
-		assertTrue((e == e_) && e.equals(e_));
-		String[] array1;
-		String[] array2;
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(-1, ArrayTools.identityDiffEnd(array1, array2));
-
-		array1 = new String[] { a };
-		array2 = new String[] { a_ };
-		assertEquals(-1, ArrayTools.identityDiffEnd(array1, array2));
-
-		array1 = new String[] { b, c, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(4, ArrayTools.identityDiffEnd(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { b_, c_, d_, e_ };
-		assertEquals(4, ArrayTools.identityDiffEnd(array1, array2));
-
-		array1 = new String[0];
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(4, ArrayTools.identityDiffEnd(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[0];
-		assertEquals(4, ArrayTools.identityDiffEnd(array1, array2));
-
-		array1 = new String[0];
-		array2 = new String[0];
-		assertEquals(-1, ArrayTools.identityDiffEnd(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { b_, c_, a_, d_, e_ };
-		assertEquals(2, ArrayTools.identityDiffEnd(array1, array2));
-
-		array1 = new String[] { b, c, d, e };
-		array2 = new String[] { a_, c_, d_, e_ };
-		assertEquals(0, ArrayTools.identityDiffEnd(array1, array2));
-
-		array1 = new String[] { a, b, c, e };
-		array2 = new String[] { a_, b_, c_, d_ };
-		assertEquals(3, ArrayTools.identityDiffEnd(array1, array2));
-
-		String c__ = new String(c);
-		assertTrue((c != c__) && c.equals(c_));
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, c__, d_, e_ };
-		assertEquals(2, ArrayTools.identityDiffEnd(array1, array2));
-
-		array1 = new String[] { a, b, null, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(2, ArrayTools.identityDiffEnd(array1, array2));
-
-		array1 = new String[] { a, b, null, d, e };
-		array2 = new String[] { a_, b_, null, d_, e_ };
-		assertEquals(-1, ArrayTools.identityDiffEnd(array1, array2));
-	}
-
-	public void testIdentityDiffRange() {
-		String a = "a";
-		String b = "b";
-		String c = "c";
-		String d = "d";
-		String e = "e";
-		String a_ = a;
-		String b_ = b;
-		String c_ = c;
-		String d_ = d;
-		String e_ = e;
-		assertTrue((a == a_) && a.equals(a_));
-		assertTrue((b == b_) && b.equals(b_));
-		assertTrue((c == c_) && c.equals(c_));
-		assertTrue((d == d_) && d.equals(d_));
-		assertTrue((e == e_) && e.equals(e_));
-		String[] array1;
-		String[] array2;
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(new Range(5, -1), ArrayTools.identityDiffRange(array1, array2));
-
-		array1 = new String[] { a };
-		array2 = new String[] { a_ };
-		assertEquals(new Range(1, -1), ArrayTools.identityDiffRange(array1, array2));
-
-		array1 = new String[] { b, c, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(new Range(0, 4), ArrayTools.identityDiffRange(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { b_, c_, d_, e_ };
-		assertEquals(new Range(0, 4), ArrayTools.identityDiffRange(array1, array2));
-
-		array1 = new String[0];
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(new Range(0, 4), ArrayTools.identityDiffRange(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[0];
-		assertEquals(new Range(0, 4), ArrayTools.identityDiffRange(array1, array2));
-
-		array1 = new String[0];
-		array2 = new String[0];
-		assertEquals(new Range(0, -1), ArrayTools.identityDiffRange(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { b_, c_, a_, d_, e_ };
-		assertEquals(new Range(0, 2), ArrayTools.identityDiffRange(array1, array2));
-
-		array1 = new String[] { b, c, d, e };
-		array2 = new String[] { a_, c_, d_, e_ };
-		assertEquals(new Range(0, 0), ArrayTools.identityDiffRange(array1, array2));
-
-		array1 = new String[] { a, b, c, e };
-		array2 = new String[] { a_, b_, c_, d_ };
-		assertEquals(new Range(3, 3), ArrayTools.identityDiffRange(array1, array2));
-
-		String c__ = new String(c);
-		assertTrue((c != c__) && c.equals(c_));
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, c__, d_, e_ };
-		assertEquals(new Range(2, 2), ArrayTools.identityDiffRange(array1, array2));
-
-		array1 = new String[] { a, b, null, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(new Range(2, 2), ArrayTools.identityDiffRange(array1, array2));
-
-		array1 = new String[] { a, b, null, d, e };
-		array2 = new String[] { a_, b_, null, d_, e_ };
-		assertEquals(new Range(5, -1), ArrayTools.identityDiffRange(array1, array2));
-	}
-
-	public void testIdentityDiffStart() {
-		String a = "a";
-		String b = "b";
-		String c = "c";
-		String d = "d";
-		String e = "e";
-		String a_ = a;
-		String b_ = b;
-		String c_ = c;
-		String d_ = d;
-		String e_ = e;
-		assertTrue((a == a_) && a.equals(a_));
-		assertTrue((b == b_) && b.equals(b_));
-		assertTrue((c == c_) && c.equals(c_));
-		assertTrue((d == d_) && d.equals(d_));
-		assertTrue((e == e_) && e.equals(e_));
-		String[] array1;
-		String[] array2;
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(5, ArrayTools.identityDiffStart(array1, array2));
-
-		array1 = new String[] { a };
-		array2 = new String[] { a_ };
-		assertEquals(1, ArrayTools.identityDiffStart(array1, array2));
-
-		array1 = new String[] { a, b, c, d };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(4, ArrayTools.identityDiffStart(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, c_, d_ };
-		assertEquals(4, ArrayTools.identityDiffStart(array1, array2));
-
-		array1 = new String[0];
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(0, ArrayTools.identityDiffStart(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[0];
-		assertEquals(0, ArrayTools.identityDiffStart(array1, array2));
-
-		array1 = new String[0];
-		array2 = new String[0];
-		assertEquals(0, ArrayTools.identityDiffStart(array1, array2));
-
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, e_, c_, d_ };
-		assertEquals(2, ArrayTools.identityDiffStart(array1, array2));
-
-		array1 = new String[] { a, b, c, e };
-		array2 = new String[] { a_, b_, c_, d_ };
-		assertEquals(3, ArrayTools.identityDiffStart(array1, array2));
-
-		array1 = new String[] { b, c, d, e };
-		array2 = new String[] { a_, c_, d_, e_ };
-		assertEquals(0, ArrayTools.identityDiffStart(array1, array2));
-
-		String c__ = new String(c);
-		assertTrue((c != c__) && c.equals(c_));
-		array1 = new String[] { a, b, c, d, e };
-		array2 = new String[] { a_, b_, c__, d_, e_ };
-		assertEquals(2, ArrayTools.identityDiffStart(array1, array2));
-
-		array1 = new String[] { a, b, null, d, e };
-		array2 = new String[] { a_, b_, c_, d_, e_ };
-		assertEquals(2, ArrayTools.identityDiffStart(array1, array2));
-
-		array1 = new String[] { a, b, null, d, e };
-		array2 = new String[] { a_, b_, null, d_, e_ };
-		assertEquals(5, ArrayTools.identityDiffStart(array1, array2));
-	}
-
-
-	// ********** elements are identical **********
-
-	public void testElementsAreIdenticalObjectArrayObjectArray() {
-		Object[] a1 = new Object[4];
-		for (int i = 0; i < a1.length; i++) {
-			a1[i] = String.valueOf(i * 1000);
-		}
-
-		Object[] a2 = new Object[a1.length];
-		for (int i = 0; i < a2.length; i++) {
-			a2[i] = a1[i];
-		}
-
-		assertTrue(ArrayTools.elementsAreIdentical(a1, a2));
-		a2[2] = "2000";
-		assertFalse(ArrayTools.elementsAreIdentical(a1, a2));
-		assertTrue(Arrays.equals(a1, a2));
-	}
-
-	public void testElementsAreIdenticalObjectArrayObjectArray_BothNull() {
-		Object[] a1 = null;
-		Object[] a2 = null;
-		assertTrue(ArrayTools.elementsAreIdentical(a1, a2));
-	}
-
-	public void testElementsAreIdenticalObjectArrayObjectArray_OneNull() {
-		Object[] a1 = null;
-		Object[] a2 = new Object[0];
-		assertFalse(ArrayTools.elementsAreIdentical(a1, a2));
-	}
-
-	public void testElementsAreIdenticalObjectArrayObjectArray_DifferentLengths() {
-		Object[] a1 = new String[] {"foo", "bar"};
-		Object[] a2 = new String[] {"foo", "bar", "baz"};
-		assertFalse(ArrayTools.elementsAreIdentical(a1, a2));
-	}
-
-
-	// ********** index of **********
-
-	public void testIndexOfObjectArrayObject() {
-		Object[] a = this.buildObjectArray1();
-		assertEquals(1, ArrayTools.indexOf(a, "one"));
-	}
-
-	public void testIndexOfObjectArrayObject_NotFound() {
-		Object[] a = this.buildObjectArray1();
-		assertEquals(-1, ArrayTools.indexOf(a, "twenty"));
-	}
-
-	public void testIndexOfObjectArrayObject_Null() {
-		Object[] a = this.buildObjectArray1();
-		a = ArrayTools.add(a, null);
-		assertEquals(a.length - 1, ArrayTools.indexOf(a, null));
-	}
-
-	public void testIndexOfObjectArrayObject_Null_NotFound() {
-		Object[] a = this.buildObjectArray1();
-		assertEquals(-1, ArrayTools.indexOf(a, null));
-	}
-
-	public void testIdentityIndexOfObjectArrayObject() {
-		String foo = "foo";
-		String bar = "bar";
-		String baz = "baz";
-		Object[] a = new Object[3];
-		a[0] = foo;
-		a[1] = bar;
-		a[2] = baz;
-		assertEquals(1, ArrayTools.identityIndexOf(a, bar));
-	}
-
-	public void testIdentityIndexOfObjectArrayObject_NotFound() {
-		String foo = "foo";
-		String bar = "bar";
-		String baz = "baz";
-		Object[] a = new Object[3];
-		a[0] = foo;
-		a[1] = bar;
-		a[2] = baz;
-		assertEquals(-1, ArrayTools.identityIndexOf(a, new String("bar")));
-	}
-
-	public void testIndexOfCharArrayChar() {
-		char[] a = this.buildCharArray();
-		assertEquals(1, ArrayTools.indexOf(a, 'b'));
-		a = ArrayTools.add(a, 'd');
-		assertEquals(a.length - 1, ArrayTools.indexOf(a, 'd'));
-	}
-
-	public void testIndexOfCharArrayChar_NotFound() {
-		char[] a = this.buildCharArray();
-		assertEquals(-1, ArrayTools.indexOf(a, 'z'));
-	}
-
-	public void testIndexOfIntArrayInt() {
-		int[] a = this.buildIntArray();
-		assertEquals(1, ArrayTools.indexOf(a, 10));
-		a = ArrayTools.add(a, 30);
-		assertEquals(a.length - 1, ArrayTools.indexOf(a, 30));
-	}
-
-	public void testIndexOfIntArrayInt_NotFound() {
-		int[] a = this.buildIntArray();
-		assertEquals(-1, ArrayTools.indexOf(a, 1000));
-	}
-
-
-	// ********** insertion index of **********
-
-	public void testInsertionIndexOfObjectArrayComparable() {
-		String[] a = new String[] { "A", "C", "D" };
-		assertEquals(1, ArrayTools.insertionIndexOf(a, "B"));
-
-		a = new String[] { "A", "B", "C", "D" };
-		assertEquals(2, ArrayTools.insertionIndexOf(a, "B"));
-
-		a = new String[] { "A", "B", "B", "B", "C", "D" };
-		assertEquals(4, ArrayTools.insertionIndexOf(a, "B"));
-
-		a = new String[] { "A", "B", "B", "B", "C", "D" };
-		assertEquals(6, ArrayTools.insertionIndexOf(a, "E"));
-
-		a = new String[] { "B", "B", "B", "C", "D" };
-		assertEquals(0, ArrayTools.insertionIndexOf(a, "A"));
-
-		a = new String[] { "A", "A", "B", "B", "C", "D" };
-		assertEquals(2, ArrayTools.insertionIndexOf(a, "A"));
-	}
-
-	public void testInsertionIndexOfObjectArrayObjectComparator() {
-		Comparator<String> c = new ReverseComparator<String>();
-		String[] a = new String[] { "D", "C", "A" };
-		assertEquals(2, ArrayTools.insertionIndexOf(a, "B", c));
-
-		a = new String[] { "D", "C", "B", "A" };
-		assertEquals(3, ArrayTools.insertionIndexOf(a, "B", c));
-
-		a = new String[] { "D", "C", "B", "B", "B", "A" };
-		assertEquals(5, ArrayTools.insertionIndexOf(a, "B", c));
-
-		a = new String[] { "D", "C", "B", "B", "B", "A" };
-		assertEquals(0, ArrayTools.insertionIndexOf(a, "E", c));
-
-		a = new String[] { "D", "C", "B", "B", "B" };
-		assertEquals(5, ArrayTools.insertionIndexOf(a, "A", c));
-
-		a = new String[] { "D", "C", "B", "B", "A", "A" };
-		assertEquals(6, ArrayTools.insertionIndexOf(a, "A", c));
-	}
-
-
-	// ********** last index of **********
-
-	public void testLastIndexOfObjectArrayObject() {
-		Object[] a = this.buildObjectArray1();
-		assertEquals(1, ArrayTools.lastIndexOf(a, "one"));
-	}
-
-	public void testLastIndexOfObjectArrayObject_NotFound() {
-		Object[] a = this.buildObjectArray1();
-		assertEquals(-1, ArrayTools.lastIndexOf(a, "twenty"));
-	}
-
-	public void testLastIndexOfObjectArrayObject_Null() {
-		Object[] a = this.buildObjectArray1();
-		a = ArrayTools.add(a, null);
-		assertEquals(a.length - 1, ArrayTools.lastIndexOf(a, null));
-	}
-
-	public void testLastIndexOfObjectArrayObject_Null_NotFound() {
-		Object[] a = this.buildObjectArray1();
-		assertEquals(-1, ArrayTools.lastIndexOf(a, null));
-	}
-
-	public void testLastIndexOfCharArrayChar() {
-		char[] a = this.buildCharArray();
-		assertEquals(1, ArrayTools.lastIndexOf(a, 'b'));
-		a = ArrayTools.add(a, 'd');
-		assertEquals(a.length - 1, ArrayTools.lastIndexOf(a, 'd'));
-	}
-
-	public void testLastIndexOfCharArrayChar_NotFound() {
-		char[] a = this.buildCharArray();
-		assertEquals(-1, ArrayTools.lastIndexOf(a, 'z'));
-	}
-
-	public void testLastIndexOfIntArrayInt() {
-		int[] a = this.buildIntArray();
-		assertEquals(1, ArrayTools.lastIndexOf(a, 10));
-		a = ArrayTools.add(a, 30);
-		assertEquals(a.length - 1, ArrayTools.lastIndexOf(a, 30));
-	}
-
-	public void testLastIndexOfIntArrayInt_NotFound() {
-		int[] a = this.buildIntArray();
-		assertEquals(-1, ArrayTools.lastIndexOf(a, 1000));
-	}
-
-
-	// ********** min/max **********
-
-	public void testMinCharArray() {
-		assertEquals('a', ArrayTools.min(this.buildCharArray()));
-	}
-
-	public void testMinCharArray_Exception() {
-		char[] array = new char[0];
-		boolean exCaught = false;
-		try {
-			char c = ArrayTools.min(array);
-			fail("bogus char: " + c);
-		} catch (IndexOutOfBoundsException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testMinIntArray() {
-		assertEquals(0, ArrayTools.min(this.buildIntArray()));
-	}
-
-	public void testMinIntArray_Exception() {
-		int[] array = new int[0];
-		boolean exCaught = false;
-		try {
-			int i = ArrayTools.min(array);
-			fail("bogus int: " + i);
-		} catch (IndexOutOfBoundsException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testMaxCharArray1() {
-		assertEquals('c', ArrayTools.max(this.buildCharArray()));
-	}
-
-	public void testMaxCharArray2() {
-		char[] array = new char[] { 'x', 'a', 'b', 'c' };
-		assertEquals('x', ArrayTools.max(array));
-	}
-
-	public void testMaxCharArray_Exception() {
-		char[] array = new char[0];
-		boolean exCaught = false;
-		try {
-			char c = ArrayTools.max(array);
-			fail("bogus char: " + c);
-		} catch (IndexOutOfBoundsException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testMaxIntArray1() {
-		assertEquals(20, ArrayTools.max(this.buildIntArray()));
-	}
-
-	public void testMaxIntArray2() {
-		int[] array = new int[] { 77, 3, 1, -3 };
-		assertEquals(77, ArrayTools.max(array));
-	}
-
-	public void testMaxIntArray_Exception() {
-		int[] array = new int[0];
-		boolean exCaught = false;
-		try {
-			int i = ArrayTools.max(array);
-			fail("bogus int: " + i);
-		} catch (IndexOutOfBoundsException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-
-	// ********** move **********
-
-	public void testMoveObjectArrayIntInt() {
-		String[] array = new String[] { "0", "1", "2", "3", "4", "5" };
-
-		String[] result = ArrayTools.move(array, 4, 2);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result));
-
-		result = ArrayTools.move(array, 0, 5);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result));
-
-		result = ArrayTools.move(array, 2, 4);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result));
-
-		result = ArrayTools.move(array, 4, 4);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result));
-	}
-
-	public void testMoveObjectArrayIntIntInt() {
-		String[] array = new String[] { "0", "1", "2", "3", "4", "5" };
-
-		String[] result = ArrayTools.move(array, 4, 2, 1);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result));
-
-		result = ArrayTools.move(array, 0, 5, 1);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result));
-
-		result = ArrayTools.move(array, 2, 4, 1);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result));
-
-		result = ArrayTools.move(array, 2, 4, 2);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result));
-
-		result = ArrayTools.move(array, 0, 1, 4);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "0", "3", "2", "4", "5", "1" }, result));
-
-		result = ArrayTools.move(array, 1, 0, 4);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result));
-
-		result = ArrayTools.move(array, 1, 1, 4);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result));
-
-		result = ArrayTools.move(array, 1, 0, 0);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result));
-	}
-
-	public void testMoveIntArrayIntInt() {
-		int[] array = new int[] { 0, 1, 2, 3, 4, 5 };
-
-		int[] result = ArrayTools.move(array, 4, 2);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new int[] { 0, 1, 3, 4, 2, 5 }, result));
-
-		result = ArrayTools.move(array, 0, 5);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new int[] { 5, 0, 1, 3, 4, 2 }, result));
-
-		result = ArrayTools.move(array, 2, 4);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new int[] { 5, 0, 4, 1, 3, 2 }, result));
-
-		result = ArrayTools.move(array, 2, 2);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new int[] { 5, 0, 4, 1, 3, 2 }, result));
-	}
-
-	public void testMoveIntArrayIntIntInt() {
-		int[] array = new int[] { 0, 1, 2, 3, 4, 5 };
-
-		int[] result = ArrayTools.move(array, 4, 2, 1);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new int[] { 0, 1, 3, 4, 2, 5 }, result));
-
-		result = ArrayTools.move(array, 0, 5, 1);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new int[] { 5, 0, 1, 3, 4, 2 }, result));
-
-		result = ArrayTools.move(array, 2, 4, 1);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new int[] { 5, 0, 4, 1, 3, 2 }, result));
-
-		result = ArrayTools.move(array, 2, 4, 2);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new int[] { 5, 0, 3, 2, 4, 1 }, result));
-
-		result = ArrayTools.move(array, 0, 1, 4);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new int[] { 0, 3, 2, 4, 5, 1 }, result));
-
-		result = ArrayTools.move(array, 1, 0, 4);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new int[] { 5, 0, 3, 2, 4, 1 }, result));
-
-		result = ArrayTools.move(array, 1, 1, 4);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new int[] { 5, 0, 3, 2, 4, 1 }, result));
-
-		result = ArrayTools.move(array, 1, 0, 0);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new int[] { 5, 0, 3, 2, 4, 1 }, result));
-	}
-
-	public void testMoveCharArrayIntInt() {
-		char[] array = new char[] { 'a', 'b', 'c', 'd', 'e', 'f' };
-
-		char[] result = ArrayTools.move(array, 4, 2);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'd', 'e', 'c', 'f' }, result));
-
-		result = ArrayTools.move(array, 0, 5);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new char[] { 'f', 'a', 'b', 'd', 'e', 'c' }, result));
-
-		result = ArrayTools.move(array, 2, 4);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new char[] { 'f', 'a', 'e', 'b', 'd', 'c' }, result));
-
-		result = ArrayTools.move(array, 2, 2);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new char[] { 'f', 'a', 'e', 'b', 'd', 'c' }, result));
-	}
-
-	public void testMoveCharArrayIntIntInt() {
-		char[] array = new char[] { 'a', 'b', 'b', 'c', 'd', 'e' };
-
-		char[] result = ArrayTools.move(array, 4, 2, 1);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'c', 'd', 'b', 'e' }, result));
-
-		result = ArrayTools.move(array, 0, 5, 1);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'b', 'c', 'd', 'b' }, result));
-
-		result = ArrayTools.move(array, 2, 4, 1);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'd', 'b', 'c', 'b' }, result));
-
-		result = ArrayTools.move(array, 2, 4, 2);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'c', 'b', 'd', 'b' }, result));
-
-		result = ArrayTools.move(array, 0, 1, 4);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new char[] { 'a', 'c', 'b', 'd', 'e', 'b' }, result));
-
-		result = ArrayTools.move(array, 1, 0, 4);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'c', 'b', 'd', 'b' }, result));
-
-		result = ArrayTools.move(array, 1, 1, 4);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'c', 'b', 'd', 'b' }, result));
-
-		result = ArrayTools.move(array, 1, 0, 0);
-		assertSame(array, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'c', 'b', 'd', 'b' }, result));
-	}
-
-
-	// ********** remove **********
-
-	public void testRemoveObjectArrayObject_Object() {
-		Object[] a = this.buildObjectArray1();
-		a = ArrayTools.add(a, "three");
-		a = ArrayTools.add(a, "four");
-		a = ArrayTools.add(a, "five");
-
-		assertEquals(6, a.length);
-		assertTrue(ArrayTools.contains(a, "three"));
-		a = ArrayTools.remove(a, "three");
-		assertEquals(5, a.length);
-		assertFalse(ArrayTools.contains(a, "three"));
-		assertTrue(ArrayTools.contains(a, "four"));
-		assertTrue(ArrayTools.contains(a, "five"));
-	}
-
-	public void testRemoveObjectArrayObject_String() {
-		String[] a = this.buildStringArray1();
-		a = ArrayTools.add(a, "three");
-		a = ArrayTools.add(a, "four");
-		a = ArrayTools.add(a, "five");
-
-		assertEquals(6, a.length);
-		assertTrue(ArrayTools.contains(a, "three"));
-		a = ArrayTools.remove(a, "three");
-		assertEquals(5, a.length);
-		assertFalse(ArrayTools.contains(a, "three"));
-		assertTrue(ArrayTools.contains(a, "four"));
-		assertTrue(ArrayTools.contains(a, "five"));
-	}
-
-	public void testRemoveCharArrayChar() {
-		char[] a = this.buildCharArray();
-		a = ArrayTools.add(a, 'd');
-		a = ArrayTools.add(a, 'e');
-		a = ArrayTools.add(a, 'f');
-
-		assertEquals(6, a.length);
-		assertTrue(ArrayTools.contains(a, 'd'));
-		a = ArrayTools.remove(a, 'd');
-		assertEquals(5, a.length);
-		assertFalse(ArrayTools.contains(a, 'd'));
-		assertTrue(ArrayTools.contains(a, 'e'));
-		assertTrue(ArrayTools.contains(a, 'f'));
-	}
-
-	public void testRemoveIntArrayInt() {
-		int[] a = this.buildIntArray();
-		a = ArrayTools.add(a, 30);
-		a = ArrayTools.add(a, 40);
-		a = ArrayTools.add(a, 50);
-
-		assertEquals(6, a.length);
-		assertTrue(ArrayTools.contains(a, 30));
-		a = ArrayTools.remove(a, 30);
-		assertEquals(5, a.length);
-		assertFalse(ArrayTools.contains(a, 30));
-		assertTrue(ArrayTools.contains(a, 40));
-		assertTrue(ArrayTools.contains(a, 50));
-	}
-
-
-	// ********** remove all **********
-
-	public void testRemoveAllObjectArrayObjectArray() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		String[] a2 = new String[] { "E", "B" };
-		String[] a3 = ArrayTools.removeAll(a1, (Object[]) a2);
-		assertTrue(Arrays.equals(new String[] { "A", "A", "C", "C", "D", "D", "F", "F" }, a3));
-	}
-
-	public void testRemoveAllObjectArrayObjectArray_Empty() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		String[] a2 = new String[0];
-		String[] a3 = ArrayTools.removeAll(a1, (Object[]) a2);
-		assertTrue(Arrays.equals(a1, a3));
-	}
-
-	public void testRemoveAllObjectArrayObjectArray_NoMatches() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		String[] a2 = new String[] { "X", "Y", "Z" };
-		String[] a3 = ArrayTools.removeAll(a1, (Object[]) a2);
-		assertTrue(Arrays.equals(a1, a3));
-	}
-
-	public void testRemoveAllObjectArrayIterable() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Iterable<?> iterable = Arrays.asList(new String[] { "E", "B" });
-		String[] a3 = ArrayTools.removeAll(a1, iterable);
-		assertTrue(Arrays.equals(new String[] { "A", "A", "C", "C", "D", "D", "F", "F" }, a3));
-	}
-
-	public void testRemoveAllObjectArrayIterableInt() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Iterable<?> iterable = Arrays.asList(new String[] { "E", "B" });
-		String[] a3 = ArrayTools.removeAll(a1, iterable, 7);
-		assertTrue(Arrays.equals(new String[] { "A", "A", "C", "C", "D", "D", "F", "F" }, a3));
-	}
-
-	public void testRemoveAllObjectArrayIterator() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Iterable<?> iterable = Arrays.asList(new String[] { "E", "B" });
-		String[] a3 = ArrayTools.removeAll(a1, iterable.iterator());
-		assertTrue(Arrays.equals(new String[] { "A", "A", "C", "C", "D", "D", "F", "F" }, a3));
-	}
-
-	public void testRemoveAllObjectArrayIterator_Empty() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		String[] a3 = ArrayTools.removeAll(a1, EmptyIterator.instance());
-		assertTrue(Arrays.equals(a1, a3));
-	}
-
-	public void testRemoveAllObjectArrayIteratorInt() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Iterable<?> iterable = Arrays.asList(new String[] { "E", "B" });
-		String[] a3 = ArrayTools.removeAll(a1, iterable.iterator(), 7);
-		assertTrue(Arrays.equals(new String[] { "A", "A", "C", "C", "D", "D", "F", "F" }, a3));
-	}
-
-	public void testRemoveAllObjectArrayIteratorInt_Empty() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		String[] a3 = ArrayTools.removeAll(a1, EmptyIterator.instance(), 7);
-		assertTrue(Arrays.equals(a1, a3));
-	}
-
-	public void testRemoveAllObjectArrayCollection() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Collection<String> collection = Arrays.asList(new String[] { "E", "B" });
-		String[] a3 = ArrayTools.removeAll(a1, collection);
-		assertTrue(Arrays.equals(new String[] { "A", "A", "C", "C", "D", "D", "F", "F" }, a3));
-	}
-
-	public void testRemoveAllObjectArrayCollection_Empty() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Collection<String> collection = new ArrayList<String>();
-		String[] a3 = ArrayTools.removeAll(a1, collection);
-		assertTrue(Arrays.equals(a1, a3));
-	}
-
-	public void testRemoveAllObjectArrayCollection_EmptyArray() {
-		String[] a1 = new String[0];
-		Collection<String> collection = Arrays.asList(new String[] { "E", "B" });
-		String[] a3 = ArrayTools.removeAll(a1, collection);
-		assertTrue(Arrays.equals(a1, a3));
-		assertEquals(0, a3.length);
-	}
-
-	public void testRemoveAllObjectArrayCollection_NoMatches() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Collection<String> collection = Arrays.asList(new String[] { "X", "Y", "Z" });
-		String[] a3 = ArrayTools.removeAll(a1, collection);
-		assertTrue(Arrays.equals(a1, a3));
-	}
-
-	public void testRemoveAllCharArrayCharArray() {
-		char[] a1 = new char[] { 'A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'E', 'E', 'F', 'F' };
-		char[] a2 = new char[] { 'E', 'B' };
-		assertTrue(Arrays.equals(new char[] { 'A', 'A', 'C', 'C', 'D', 'D', 'F', 'F' }, ArrayTools.removeAll(a1, a2)));
-	}
-
-	public void testRemoveAllCharArrayCharArray_Empty1() {
-		char[] a1 = new char[0];
-		char[] a2 = new char[] { 'E', 'B' };
-		assertTrue(Arrays.equals(a1, ArrayTools.removeAll(a1, a2)));
-	}
-
-	public void testRemoveAllCharArrayCharArray_Empty2() {
-		char[] a1 = new char[] { 'A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'E', 'E', 'F', 'F' };
-		char[] a2 = new char[0];
-		assertTrue(Arrays.equals(a1, ArrayTools.removeAll(a1, a2)));
-	}
-
-	public void testRemoveAllCharArrayCharArray_NoMatches() {
-		char[] a1 = new char[] { 'A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'E', 'E', 'F', 'F' };
-		char[] a2 = new char[] { 'X', 'Z' };
-		assertTrue(Arrays.equals(a1, ArrayTools.removeAll(a1, a2)));
-	}
-
-	public void testRemoveAllIntArrayIntArray() {
-		int[] a1 = new int[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6 };
-		int[] a2 = new int[] { 5, 2 };
-		assertTrue(Arrays.equals(new int[] { 1, 1, 3, 3, 4, 4, 6, 6 }, ArrayTools.removeAll(a1, a2)));
-	}
-
-	public void testRemoveAllIntArrayIntArray_Empty1() {
-		int[] a1 = new int[0];
-		int[] a2 = new int[] { 5, 2 };
-		assertTrue(Arrays.equals(a1, ArrayTools.removeAll(a1, a2)));
-	}
-
-	public void testRemoveAllIntArrayIntArray_Empty2() {
-		int[] a1 = new int[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6 };
-		int[] a2 = new int[0];
-		assertTrue(Arrays.equals(a1, ArrayTools.removeAll(a1, a2)));
-	}
-
-	public void testRemoveAllIntArrayIntArray_NoMatches() {
-		int[] a1 = new int[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6 };
-		int[] a2 = new int[] { 52, 67 };
-		assertTrue(Arrays.equals(a1, ArrayTools.removeAll(a1, a2)));
-	}
-
-
-	// ********** remove all occurrences **********
-
-	public void testRemoveAllOccurrencesObjectArrayObject() {
-		String[] a = this.buildStringArray1();
-		assertEquals(3, a.length);
-		a = ArrayTools.removeAllOccurrences(a, "three");
-		assertEquals(3, a.length);
-		a = ArrayTools.removeAllOccurrences(a, "two");
-		assertEquals(2, a.length);
-		a = ArrayTools.removeAllOccurrences(a, "two");
-		assertEquals(2, a.length);
-
-		a = ArrayTools.add(a, "five");
-		a = ArrayTools.add(a, "five");
-		a = ArrayTools.add(a, "five");
-		assertEquals(5, a.length);
-		a = ArrayTools.removeAllOccurrences(a, "five");
-		assertEquals(2, a.length);
-		a = ArrayTools.removeAllOccurrences(a, "five");
-		assertEquals(2, a.length);
-
-		a = ArrayTools.add(a, null);
-		a = ArrayTools.add(a, null);
-		a = ArrayTools.add(a, null);
-		assertEquals(5, a.length);
-		a = ArrayTools.removeAllOccurrences(a, null);
-		assertEquals(2, a.length);
-		a = ArrayTools.removeAllOccurrences(a, null);
-		assertEquals(2, a.length);
-	}
-
-	public void testRemoveAllOccurrencesObjectArrayObject_Empty() {
-		String[] a = new String[0];
-		a = ArrayTools.removeAllOccurrences(a, "three");
-		assertEquals(0, a.length);
-	}
-
-	public void testRemoveAllOccurrencesCharArrayChar() {
-		char[] a = this.buildCharArray();
-		assertEquals(3, a.length);
-		a = ArrayTools.removeAllOccurrences(a, 'd');
-		assertEquals(3, a.length);
-		a = ArrayTools.removeAllOccurrences(a, 'b');
-		assertEquals(2, a.length);
-		a = ArrayTools.removeAllOccurrences(a, 'b');
-		assertEquals(2, a.length);
-
-		a = ArrayTools.add(a, 'g');
-		a = ArrayTools.add(a, 'g');
-		a = ArrayTools.add(a, 'g');
-		assertEquals(5, a.length);
-		a = ArrayTools.removeAllOccurrences(a, 'g');
-		assertEquals(2, a.length);
-		a = ArrayTools.removeAllOccurrences(a, 'g');
-		assertEquals(2, a.length);
-	}
-
-	public void testRemoveAllOccurrencesCharArrayChar_Empty() {
-		char[] a = new char[0];
-		a = ArrayTools.removeAllOccurrences(a, 'a');
-		assertEquals(0, a.length);
-	}
-
-	public void testRemoveAllOccurrencesIntArrayInt() {
-		int[] a = this.buildIntArray();
-		assertEquals(3, a.length);
-		a = ArrayTools.removeAllOccurrences(a, 55);
-		assertEquals(3, a.length);
-		a = ArrayTools.removeAllOccurrences(a, 10);
-		assertEquals(2, a.length);
-		a = ArrayTools.removeAllOccurrences(a, 10);
-		assertEquals(2, a.length);
-
-		a = ArrayTools.add(a, 77);
-		a = ArrayTools.add(a, 77);
-		a = ArrayTools.add(a, 77);
-		assertEquals(5, a.length);
-		a = ArrayTools.removeAllOccurrences(a, 77);
-		assertEquals(2, a.length);
-		a = ArrayTools.removeAllOccurrences(a, 77);
-		assertEquals(2, a.length);
-	}
-
-	public void testRemoveAllOccurrencesIntArrayInt_Empty() {
-		int[] a = new int[0];
-		a = ArrayTools.removeAllOccurrences(a, 22);
-		assertEquals(0, a.length);
-	}
-
-
-	// ********** remove duplicate elements **********
-
-	public void testRemoveDuplicateElementsObjectArray() {
-		List<String> list = this.buildStringVector1();
-		list.add("zero");
-		list.add("zero");
-		list.add("two");
-		list.add("zero");
-		String[] array = ArrayTools.removeDuplicateElements(list.toArray(new String[list.size()]));
-		int i = 0;
-		assertEquals("zero", array[i++]);
-		assertEquals("one", array[i++]);
-		assertEquals("two", array[i++]);
-		assertEquals(i, array.length);
-	}
-
-	public void testRemoveDuplicateElementsObjectArray_Empty() {
-		String[] array = ArrayTools.removeDuplicateElements(new String[0]);
-		assertEquals(0, array.length);
-	}
-
-	public void testRemoveDuplicateElementsObjectArray_SingleElement() {
-		String[] array = ArrayTools.removeDuplicateElements(new String[] { "foo" });
-		assertEquals(1, array.length);
-	}
-
-	public void testRemoveDuplicateElementsObjectArray_NoDuplicates() {
-		String[] a1 = new String[] { "foo", "bar", "baz" };
-		String[] a2 = ArrayTools.removeDuplicateElements(a1);
-		assertEquals(3, a2.length);
-		assertTrue(Arrays.equals(a1, a2));
-	}
-
-
-	// ********** remove element at index **********
-
-	public void testRemoveElementAtIndexObjectArrayInt() {
-		String[] a = new String[] { "A", "B", "A", "C", "A", "D" };
-		a = ArrayTools.removeElementAtIndex(a, 3);
-		assertTrue(Arrays.equals(new String[] { "A", "B", "A", "A", "D" }, a));
-	}
-
-	public void testRemoveElementAtIndexCharArrayInt() {
-		char[] a = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
-		a = ArrayTools.removeElementAtIndex(a, 3);
-		assertTrue(Arrays.equals(new char[] { 'A', 'B', 'A', 'A', 'D' }, a));
-	}
-
-	public void testRemoveElementAtIndexIntArrayInt() {
-		int[] a = new int[] { 8, 6, 7, 33, 2, 11 };
-		a = ArrayTools.removeElementsAtIndex(a, 3, 3);
-		assertTrue(Arrays.equals(new int[] { 8, 6, 7 }, a));
-	}
-
-	public void testRemoveFirstObjectArray() {
-		String[] a = new String[] { "A", "B", "A", "C", "A", "D" };
-		a = ArrayTools.removeFirst(a);
-		assertTrue(Arrays.equals(new String[] { "B", "A", "C", "A", "D" }, a));
-	}
-
-	public void testRemoveFirstCharArray() {
-		char[] a = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
-		a = ArrayTools.removeFirst(a);
-		assertTrue(Arrays.equals(new char[] { 'B', 'A', 'C', 'A', 'D' }, a));
-	}
-
-	public void testRemoveFirstIntArray() {
-		int[] a = new int[] { 8, 6, 7, 33, 2, 11 };
-		a = ArrayTools.removeFirst(a);
-		assertTrue(Arrays.equals(new int[] { 6, 7, 33, 2, 11 }, a));
-	}
-
-	public void testRemoveLastObjectArray() {
-		String[] a = new String[] { "A", "B", "A", "C", "A", "D" };
-		a = ArrayTools.removeLast(a);
-		assertTrue(Arrays.equals(new String[] { "A", "B", "A", "C", "A" }, a));
-	}
-
-	public void testRemoveLastCharArray() {
-		char[] a = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
-		a = ArrayTools.removeLast(a);
-		assertTrue(Arrays.equals(new char[] { 'A', 'B', 'A', 'C', 'A' }, a));
-	}
-
-	public void testRemoveLastIntArray() {
-		int[] a = new int[] { 8, 6, 7, 33, 2, 11 };
-		a = ArrayTools.removeLast(a);
-		assertTrue(Arrays.equals(new int[] { 8, 6, 7, 33, 2 }, a));
-	}
-
-
-	// ********** remove elements at index **********
-
-	public void testRemoveElementsAtIndexObjectArrayIntInt() {
-		String[] a = new String[] { "A", "B", "A", "C", "A", "D" };
-		a = ArrayTools.removeElementsAtIndex(a, 3, 2);
-		assertTrue(Arrays.equals(new String[] { "A", "B", "A", "D" }, a));
-	}
-
-	public void testRemoveElementsAtIndexObjectArrayIntInt_ZeroLength() {
-		String[] a1 = new String[] { "A", "B", "A", "C", "A", "D" };
-		String[] a2 = ArrayTools.removeElementsAtIndex(a1, 3, 0);
-		assertTrue(Arrays.equals(a1, a2));
-	}
-
-	public void testRemoveElementsAtIndexObjectArrayIntInt_Empty() {
-		String[] a = new String[] { "A", "B", "A", "C", "A", "D" };
-		a = ArrayTools.removeElementsAtIndex(a, 0, 6);
-		assertEquals(0, a.length);
-	}
-
-	public void testRemoveElementsAtIndexCharArrayIntInt() {
-		char[] a = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
-		a = ArrayTools.removeElementsAtIndex(a, 0, 5);
-		assertTrue(Arrays.equals(new char[] { 'D' }, a));
-	}
-
-	public void testRemoveElementsAtIndexCharArrayIntInt_ZeroLength() {
-		char[] a1 = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
-		char[] a2 = ArrayTools.removeElementsAtIndex(a1, 3, 0);
-		assertTrue(Arrays.equals(a1, a2));
-	}
-
-	public void testRemoveElementsAtIndexCharArrayIntInt_Empty() {
-		char[] a = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
-		a = ArrayTools.removeElementsAtIndex(a, 0, 6);
-		assertEquals(0, a.length);
-	}
-
-	public void testRemoveElementsAtIndexIntArrayIntInt() {
-		int[] a = new int[] { 8, 6, 7, 33, 2, 11 };
-		a = ArrayTools.removeElementsAtIndex(a, 3, 3);
-		assertTrue(Arrays.equals(new int[] { 8, 6, 7 }, a));
-	}
-
-	public void testRemoveElementsAtIndexIntArrayIntInt_ZeroLength() {
-		int[] a1 = new int[] { 8, 6, 7, 33, 2, 11 };
-		int[] a2 = ArrayTools.removeElementsAtIndex(a1, 3, 0);
-		assertTrue(Arrays.equals(a1, a2));
-	}
-
-	public void testRemoveElementsAtIndexIntArrayIntInt_Empty() {
-		int[] a = new int[] { 8, 6, 7, 33, 2, 11 };
-		a = ArrayTools.removeElementsAtIndex(a, 0, 6);
-		assertEquals(0, a.length);
-	}
-
-
-	// ********** replace all **********
-
-	public void testReplaceAllObjectArrayObjectObject_Object() {
-		Object[] a = new Object[] { "A", "B", "A", "C", "A", "D" };
-		a = ArrayTools.replaceAll(a, "A", "Z");
-		assertTrue(Arrays.equals(new Object[] { "Z", "B", "Z", "C", "Z", "D" }, a));
-	}
-
-	public void testReplaceAllObjectArrayObjectObject_String() {
-		String[] a = new String[] { "A", "B", "A", "C", "A", "D" };
-		a = ArrayTools.replaceAll(a, "A", "Z");
-		assertTrue(Arrays.equals(new String[] { "Z", "B", "Z", "C", "Z", "D" }, a));
-	}
-
-	public void testReplaceAllObjectArrayObjectObject_Null() {
-		String[] a = new String[] { null, "B", null, "C", null, "D" };
-		a = ArrayTools.replaceAll(a, null, "Z");
-		assertTrue(Arrays.equals(new String[] { "Z", "B", "Z", "C", "Z", "D" }, a));
-	}
-
-	public void testReplaceAllCharArrayCharChar() {
-		char[] a = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
-		a = ArrayTools.replaceAll(a, 'A', 'Z');
-		assertTrue(Arrays.equals(new char[] { 'Z', 'B', 'Z', 'C', 'Z', 'D' }, a));
-	}
-
-	public void testReplaceAllIntArrayIntInt() {
-		int[] a = new int[] { 0, 1, 0, 7, 0, 99 };
-		a = ArrayTools.replaceAll(a, 0, 13);
-		assertTrue(Arrays.equals(new int[] { 13, 1, 13, 7, 13, 99 }, a));
-	}
-
-
-	// ********** retain all **********
-
-	public void testRetainAllObjectArrayObjectArray() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Object[] a2 = new Object[] { "E", "B", new Integer(7) };
-		assertTrue(Arrays.equals(new String[] { "B", "B", "E", "E" }, ArrayTools.retainAll(a1, a2)));
-	}
-
-	public void testRetainAllObjectArrayObjectArray_EmptyObjectArray1() {
-		String[] a1 = new String[0];
-		String[] a2 = new String[] { "E", "B", "" };
-		String[] a3 = ArrayTools.retainAll(a1, a2);
-		assertEquals(0, a3.length);
-	}
-
-	public void testRetainAllObjectArrayObjectArray_EmptyObjectArray2() {
-		String[] a1 = new String[] { "E", "B", "" };
-		String[] a2 = new String[0];
-		String[] a3 = ArrayTools.retainAll(a1, a2);
-		assertEquals(0, a3.length);
-	}
-
-	public void testRetainAllObjectArrayObjectArray_BothEmpty() {
-		String[] a1 = new String[0];
-		String[] a2 = new String[0];
-		String[] a3 = ArrayTools.retainAll(a1, a2);
-		assertEquals(0, a3.length);
-	}
-
-	public void testRetainAllObjectArrayIterable() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Iterable<String> iterable = Arrays.asList(new String[] { "E", "B", "" });
-		assertTrue(Arrays.equals(new String[] { "B", "B", "E", "E" }, ArrayTools.retainAll(a1, iterable)));
-	}
-
-	public void testRetainAllObjectArrayIterable_EmptyObjectArray() {
-		String[] a1 = new String[0];
-		Iterable<String> iterable = Arrays.asList(new String[] { "E", "B", "" });
-		String[] a3 = ArrayTools.retainAll(a1, iterable);
-		assertEquals(0, a3.length);
-	}
-
-	public void testRetainAllObjectArrayIterableInt() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Iterable<String> iterable = Arrays.asList(new String[] { "E", "B", "" });
-		assertTrue(Arrays.equals(new String[] { "B", "B", "E", "E" }, ArrayTools.retainAll(a1, iterable, 3)));
-	}
-
-	public void testRetainAllObjectArrayIterableInt_EmptyObjectArray() {
-		String[] a1 = new String[0];
-		Iterable<String> iterable = Arrays.asList(new String[] { "E", "B", "" });
-		String[] a3 = ArrayTools.retainAll(a1, iterable, 3);
-		assertEquals(0, a3.length);
-	}
-
-	public void testRetainAllObjectArrayIterator() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Iterator<String> iterator = Arrays.asList(new String[] { "E", "B", "" }).iterator();
-		assertTrue(Arrays.equals(new String[] { "B", "B", "E", "E" }, ArrayTools.retainAll(a1, iterator)));
-	}
-
-	public void testRetainAllObjectArrayIterator_EmptyObjectArray() {
-		String[] a1 = new String[0];
-		Iterator<String> iterator = Arrays.asList(new String[] { "E", "B", "" }).iterator();
-		String[] a3 = ArrayTools.retainAll(a1, iterator);
-		assertEquals(0, a3.length);
-	}
-
-	public void testRetainAllObjectArrayIterator_EmptyIterator() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		assertTrue(Arrays.equals(new String[0], ArrayTools.retainAll(a1, EmptyIterator.instance())));
-	}
-
-	public void testRetainAllObjectArrayIteratorInt() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Iterator<String> iterator = Arrays.asList(new String[] { "E", "B", "" }).iterator();
-		assertTrue(Arrays.equals(new String[] { "B", "B", "E", "E" }, ArrayTools.retainAll(a1, iterator, 3)));
-	}
-
-	public void testRetainAllObjectArrayIteratorInt_EmptyIterator() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		assertTrue(Arrays.equals(new String[0], ArrayTools.retainAll(a1, EmptyIterator.instance(), 3)));
-	}
-
-	public void testRetainAllObjectArrayIteratorInt_EmptyObjectArray() {
-		String[] a1 = new String[0];
-		Iterator<String> iterator = Arrays.asList(new String[] { "E", "B", "" }).iterator();
-		String[] a3 = ArrayTools.retainAll(a1, iterator, 3);
-		assertEquals(0, a3.length);
-	}
-
-	public void testRetainAllObjectArrayCollection() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Collection<String> collection = Arrays.asList(new String[] { "E", "B", "" });
-		assertTrue(Arrays.equals(new String[] { "B", "B", "E", "E" }, ArrayTools.retainAll(a1, collection)));
-	}
-
-	public void testRetainAllObjectArrayCollection_EmptyObjectArray() {
-		String[] a1 = new String[0];
-		Collection<String> collection = Arrays.asList(new String[] { "E", "B", "" });
-		String[] a3 = ArrayTools.retainAll(a1, collection);
-		assertEquals(0, a3.length);
-	}
-
-	public void testRetainAllObjectArrayCollection_EmptyCollection() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Collection<String> collection = new ArrayList<String>();
-		String[] a3 = ArrayTools.retainAll(a1, collection);
-		assertEquals(0, a3.length);
-	}
-
-	public void testRetainAllObjectArrayCollection_All() {
-		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
-		Collection<String> collection = Arrays.asList(new String[] { "A", "B", "C", "D", "E", "F" });
-		assertTrue(Arrays.equals(a1, ArrayTools.retainAll(a1, collection)));
-	}
-
-	public void testRetainAllCharArrayCharArray() {
-		char[] a1 = new char[] { 'A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'E', 'E', 'F', 'F' };
-		char[] a2 = new char[] { 'E', 'B' };
-		assertTrue(Arrays.equals(new char[] { 'B', 'B', 'E', 'E' }, ArrayTools.retainAll(a1, a2)));
-	}
-
-	public void testRetainAllCharArrayCharArray_EmptyCharArray1() {
-		char[] a1 = new char[0];
-		char[] a2 = new char[] { 'E', 'B' };
-		assertSame(a1, ArrayTools.retainAll(a1, a2));
-	}
-
-	public void testRetainAllCharArrayCharArray_EmptyCharArray2() {
-		char[] a1 = new char[] { 'E', 'B' };
-		char[] a2 = new char[0];
-		assertEquals(0, ArrayTools.retainAll(a1, a2).length);
-	}
-
-	public void testRetainAllCharArrayCharArray_RetainAll() {
-		char[] a1 = new char[] { 'E', 'B', 'E', 'B', 'E', 'B', 'E', 'B', 'E' };
-		char[] a2 = new char[] { 'E', 'B' };
-		assertSame(a1, ArrayTools.retainAll(a1, a2));
-	}
-
-	public void testRetainAllIntArrayIntArray() {
-		int[] a1 = new int[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6 };
-		int[] a2 = new int[] { 5, 2 };
-		assertTrue(Arrays.equals(new int[] { 2, 2, 5, 5 }, ArrayTools.retainAll(a1, a2)));
-	}
-
-	public void testRetainAllIntArrayIntArray_EmptyIntArray1() {
-		int[] a1 = new int[0];
-		int[] a2 = new int[] { 5, 2 };
-		assertSame(a1, ArrayTools.retainAll(a1, a2));
-	}
-
-	public void testRetainAllIntArrayIntArray_EmptyIntArray2() {
-		int[] a1 = new int[] { 5, 2 };
-		int[] a2 = new int[0];
-		assertEquals(0, ArrayTools.retainAll(a1, a2).length);
-	}
-
-	public void testRetainAllIntArrayIntArray_RetainAll() {
-		int[] a1 = new int[] { 5, 2, 5, 2, 5, 2, 5, 2, 5, 2, 5 };
-		int[] a2 = new int[] { 5, 2 };
-		assertSame(a1, ArrayTools.retainAll(a1, a2));
-	}
-
-
-	// ********** reverse **********
-
-	public void testReverseObjectArray_Object() {
-		Object[] a = this.buildObjectArray1();
-		a = ArrayTools.reverse(a);
-		assertEquals("two", a[0]);
-		assertEquals("one", a[1]);
-		assertEquals("zero", a[2]);
-	}
-
-	public void testReverseObjectArray_String() {
-		String[] a = this.buildStringArray1();
-		a = ArrayTools.reverse(a);
-		assertEquals("two", a[0]);
-		assertEquals("one", a[1]);
-		assertEquals("zero", a[2]);
-	}
-
-	public void testReverseObjectArray_Singleton() {
-		String[] a1 = new String[] { "foo" };
-		String[] a2 = ArrayTools.reverse(a1);
-		assertTrue(Arrays.equals(a1, a2));
-	}
-
-	public void testReverseCharArray() {
-		char[] a = this.buildCharArray();
-		a = ArrayTools.reverse(a);
-		assertEquals('c', a[0]);
-		assertEquals('b', a[1]);
-		assertEquals('a', a[2]);
-	}
-
-	public void testReverseCharArray_Singleton() {
-		char[] a1 = new char[] { 'f' };
-		char[] a2 = ArrayTools.reverse(a1);
-		assertTrue(Arrays.equals(a1, a2));
-	}
-
-	public void testReverseIntArray() {
-		int[] a = this.buildIntArray();
-		a = ArrayTools.reverse(a);
-		assertEquals(20, a[0]);
-		assertEquals(10, a[1]);
-		assertEquals(0, a[2]);
-	}
-
-	public void testReverseIntArray_Singleton() {
-		int[] a1 = new int[] { 7 };
-		int[] a2 = ArrayTools.reverse(a1);
-		assertTrue(Arrays.equals(a1, a2));
-	}
-
-
-	// ********** rotate **********
-
-	public void testRotateObjectArray() {
-		String[] a = this.buildStringArray1();
-		a = ArrayTools.rotate(a);
-		assertEquals("two", a[0]);
-		assertEquals("zero", a[1]);
-		assertEquals("one", a[2]);
-	}
-
-	public void testRotateObjectArray_Zero() {
-		String[] a1 = new String[0];
-		String[] a2 = ArrayTools.rotate(a1);
-		assertSame(a1, a2);
-	}
-
-	public void testRotateObjectArray_One() {
-		String[] a1 = new String[] { "foo  " };
-		String[] a2 = ArrayTools.rotate(a1);
-		assertSame(a1, a2);
-	}
-
-	public void testRotateObjectArrayInt() {
-		String[] a = this.buildStringArray1();
-		a = ArrayTools.rotate(a, 2);
-		assertEquals("one", a[0]);
-		assertEquals("two", a[1]);
-		assertEquals("zero", a[2]);
-	}
-
-	public void testRotateObjectArrayInt_ZeroDistance() {
-		String[] a1 = this.buildStringArray1();
-		String[] a2 = ArrayTools.rotate(a1, 0);
-		assertSame(a1, a2);
-	}
-
-	public void testRotateObjectArrayInt_NegativeDistance() {
-		String[] a1 = this.buildStringArray1();
-		String[] a2 = ArrayTools.rotate(a1, -1);
-		assertEquals("one", a2[0]);
-		assertEquals("two", a2[1]);
-		assertEquals("zero", a2[2]);
-	}
-
-	public void testRotateObjectArrayInt_Zero() {
-		String[] a1 = new String[0];
-		String[] a2 = ArrayTools.rotate(a1, 7);
-		assertSame(a1, a2);
-	}
-
-	public void testRotateObjectArrayInt_One() {
-		String[] a1 = new String[] { "foo  " };
-		String[] a2 = ArrayTools.rotate(a1, 8);
-		assertSame(a1, a2);
-	}
-
-	public void testRotateCharArray() {
-		char[] a = this.buildCharArray();
-		a = ArrayTools.rotate(a);
-		assertEquals('c', a[0]);
-		assertEquals('a', a[1]);
-		assertEquals('b', a[2]);
-	}
-
-	public void testRotateCharArray_Zero() {
-		char[] a1 = new char[0];
-		char[] a2 = ArrayTools.rotate(a1);
-		assertSame(a1, a2);
-	}
-
-	public void testRotateCharArray_One() {
-		char[] a1 = new char[] { 'a' };
-		char[] a2 = ArrayTools.rotate(a1);
-		assertSame(a1, a2);
-	}
-
-	public void testRotateCharArrayInt() {
-		char[] a = this.buildCharArray();
-		a = ArrayTools.rotate(a, 2);
-		assertEquals('b', a[0]);
-		assertEquals('c', a[1]);
-		assertEquals('a', a[2]);
-	}
-
-	public void testRotateCharArrayInt_ZeroDistance() {
-		char[] a1 = new char[] { 'a', 'b', 'c' };
-		char[] a2 = ArrayTools.rotate(a1, 0);
-		assertSame(a1, a2);
-	}
-
-	public void testRotateCharArrayInt_NegativeDistance() {
-		char[] a = this.buildCharArray();
-		a = ArrayTools.rotate(a, -1);
-		assertEquals('b', a[0]);
-		assertEquals('c', a[1]);
-		assertEquals('a', a[2]);
-	}
-
-	public void testRotateCharArrayInt_Zero() {
-		char[] a1 = new char[0];
-		char[] a2 = ArrayTools.rotate(a1, 2001);
-		assertSame(a1, a2);
-	}
-
-	public void testRotateCharArrayInt_One() {
-		char[] a1 = new char[] { 'a' };
-		char[] a2 = ArrayTools.rotate(a1, 22);
-		assertSame(a1, a2);
-	}
-
-	public void testRotateIntArray() {
-		int[] a = this.buildIntArray();
-		a = ArrayTools.rotate(a);
-		assertEquals(20, a[0]);
-		assertEquals(0, a[1]);
-		assertEquals(10, a[2]);
-	}
-
-	public void testRotateIntArray_Zero() {
-		int[] a1 = new int[0];
-		int[] a2 = ArrayTools.rotate(a1);
-		assertSame(a1, a2);
-	}
-
-	public void testRotateIntArray_One() {
-		int[] a1 = new int[] { 77 };
-		int[] a2 = ArrayTools.rotate(a1);
-		assertSame(a1, a2);
-	}
-
-	public void testRotateIntArrayInt() {
-		int[] a = this.buildIntArray();
-		a = ArrayTools.rotate(a, 2);
-		assertEquals(10, a[0]);
-		assertEquals(20, a[1]);
-		assertEquals(0, a[2]);
-	}
-
-	public void testRotateIntArrayInt_ZeroDistance() {
-		int[] a1 = new int[] { 3, 2, 1 };
-		int[] a2 = ArrayTools.rotate(a1, 0);
-		assertSame(a1, a2);
-	}
-
-	public void testRotateIntArrayInt_NegativeDistance() {
-		int[] a = this.buildIntArray();
-		a = ArrayTools.rotate(a, -1);
-		assertEquals(10, a[0]);
-		assertEquals(20, a[1]);
-		assertEquals(0, a[2]);
-	}
-
-	public void testRotateIntArrayInt_Zero() {
-		int[] a1 = new int[0];
-		int[] a2 = ArrayTools.rotate(a1, 3);
-		assertSame(a1, a2);
-	}
-
-	public void testRotateIntArrayInt_One() {
-		int[] a1 = new int[] { 77 };
-		int[] a2 = ArrayTools.rotate(a1, 44);
-		assertSame(a1, a2);
-	}
-
-
-	// ********** shuffle **********
-
-	public void testShuffleObjectArray() {
-		String[] array1 = this.buildStringArray1();
-		String[] array2 = ArrayTools.shuffle(this.buildStringArray1());
-		assertEquals(array1.length, array2.length);
-		assertTrue(ArrayTools.containsAll(array1, (Object[]) array2));
-	}
-
-	public void testShuffleObjectArray_Singleton() {
-		String[] array1 = new String[] { "foo" };
-		String[] array2 = ArrayTools.shuffle(new String[] { "foo" });
-		assertEquals(array1.length, array2.length);
-		assertTrue(ArrayTools.containsAll(array1, (Object[]) array2));
-	}
-
-	public void testShuffleCharArray() {
-		char[] array1 = this.buildCharArray();
-		char[] array2 = ArrayTools.shuffle(this.buildCharArray());
-		assertEquals(array1.length, array2.length);
-		assertTrue(ArrayTools.containsAll(array1, array2));
-	}
-
-	public void testShuffleCharArray_Singleton() {
-		char[] array1 = new char[] { 'f' };
-		char[] array2 = ArrayTools.shuffle(new char[] { 'f' });
-		assertEquals(array1.length, array2.length);
-		assertTrue(ArrayTools.containsAll(array1, array2));
-	}
-
-	public void testShuffleIntArray() {
-		int[] array1 = this.buildIntArray();
-		int[] array2 = ArrayTools.shuffle(this.buildIntArray());
-		assertEquals(array1.length, array2.length);
-		assertTrue(ArrayTools.containsAll(array1, array2));
-	}
-
-	public void testShuffleIntArray_Singleton() {
-		int[] array1 = new int[] { 7 };
-		int[] array2 = ArrayTools.shuffle(new int[] { 7 });
-		assertEquals(array1.length, array2.length);
-		assertTrue(ArrayTools.containsAll(array1, array2));
-	}
-
-
-	// ********** sub-array **********
-
-	public void testSubArrayObjectArrayIntInt() {
-		String[] array = new String[] {"foo", "bar", "baz", "joo", "jar", "jaz"};
-		String[] result = new String[] {"foo", "bar", "baz", "joo"};
-		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 0, 4)));
-
-		result = new String[] {"jar"};
-		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 4, 5)));
-
-		result = new String[0];
-		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 5, 5)));
-
-		result = new String[] {"joo", "jar", "jaz"};
-		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 3, 6)));
-	}
-
-	public void testSubArrayIntArrayIntInt() {
-		int[] array = new int[] {77, 99, 333, 4, 9090, 42};
-		int[] result = new int[] {77, 99, 333, 4};
-		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 0, 4)));
-
-		result = new int[] {9090};
-		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 4, 5)));
-
-		result = new int[0];
-		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 5, 5)));
-
-		result = new int[] {4, 9090, 42};
-		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 3, 6)));
-	}
-
-	public void testSubArrayCharArrayIntInt() {
-		char[] array = new char[] {'a', 'b', 'c', 'd', 'e', 'f'};
-		char[] result = new char[] {'a', 'b', 'c', 'd'};
-		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 0, 4)));
-
-		result = new char[] {'e'};
-		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 4, 5)));
-
-		result = new char[0];
-		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 5, 5)));
-
-		result = new char[] {'d', 'e', 'f'};
-		assertTrue(Arrays.equals(result, ArrayTools.subArray(array, 3, 6)));
-	}
-
-
-	// ********** swap **********
-
-	public void testSwapObjectArray() {
-		String[] a = this.buildStringArray1();
-		a = ArrayTools.swap(a, 1, 2);
-		assertEquals("zero", a[0]);
-		assertEquals("two", a[1]);
-		assertEquals("one", a[2]);
-	}
-
-	public void testSwapObjectArray_SameIndices() {
-		String[] a1 = this.buildStringArray1();
-		String[] a2 = this.buildStringArray1();
-		a1 = ArrayTools.swap(a1, 1, 1);
-		assertTrue(Arrays.equals(a1, a2));
-	}
-
-	public void testSwapCharArray() {
-		char[] a = this.buildCharArray();
-		a = ArrayTools.swap(a, 1, 2);
-		assertEquals('a', a[0]);
-		assertEquals('c', a[1]);
-		assertEquals('b', a[2]);
-	}
-
-	public void testSwapCharArray_SameIndices() {
-		char[] a1 = this.buildCharArray();
-		char[] a2 = this.buildCharArray();
-		a1 = ArrayTools.swap(a1, 1, 1);
-		assertTrue(Arrays.equals(a1, a2));
-	}
-
-	public void testSwapIntArray() {
-		int[] a = this.buildIntArray();
-		a = ArrayTools.swap(a, 1, 2);
-		assertEquals(0, a[0]);
-		assertEquals(20, a[1]);
-		assertEquals(10, a[2]);
-	}
-
-	public void testSwapIntArray_SameIndices() {
-		int[] a1 = this.buildIntArray();
-		int[] a2 = this.buildIntArray();
-		a1 = ArrayTools.swap(a1, 1, 1);
-		assertTrue(Arrays.equals(a1, a2));
-	}
-
-
-	// ********** Arrays enhancements **********
-
-	public void testFillBooleanArrayBoolean() {
-		boolean[] a1 = new boolean[9];
-		boolean[] a2 = ArrayTools.fill(a1, true);
-		for (boolean x : a1) {
-			assertTrue(x);
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testFillBooleanArrayIntIntBoolean() {
-		boolean[] a1 = new boolean[9];
-		boolean[] a2 = ArrayTools.fill(a1, false);
-		int from = 3;
-		int to = 6;
-		boolean[] a3 = ArrayTools.fill(a2, from, to, true);
-		for (int i = 0; i < a1.length; i++) {
-			boolean x = a1[i];
-			if (i < from || i >= to) {
-				assertFalse(x);
-			} else {
-				assertTrue(x);
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testFillByteArrayByte() {
-		byte[] a1 = new byte[9];
-		byte[] a2 = ArrayTools.fill(a1, (byte) 77);
-		for (byte x : a1) {
-			assertEquals(77, x);
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testFillByteArrayIntIntByte() {
-		byte[] a1 = new byte[9];
-		byte[] a2 = ArrayTools.fill(a1, (byte) 3);
-		int from = 3;
-		int to = 6;
-		byte[] a3 = ArrayTools.fill(a2, from, to, (byte) 77);
-		for (int i = 0; i < a1.length; i++) {
-			byte x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals(3, x);
-			} else {
-				assertEquals(77, x);
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testFillCharArrayChar() {
-		char[] a1 = new char[9];
-		char[] a2 = ArrayTools.fill(a1, 'c');
-		for (char x : a1) {
-			assertEquals('c', x);
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testFillCharArrayIntIntChar() {
-		char[] a1 = new char[9];
-		char[] a2 = ArrayTools.fill(a1, 'a');
-		int from = 3;
-		int to = 6;
-		char[] a3 = ArrayTools.fill(a2, from, to, 'c');
-		for (int i = 0; i < a1.length; i++) {
-			char x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals('a', x);
-			} else {
-				assertEquals('c', x);
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testFillDoubleArrayDouble() {
-		double[] a1 = new double[9];
-		double[] a2 = ArrayTools.fill(a1, 77.77);
-		for (double x : a1) {
-			assertEquals(77.77, x, 0.0);
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testFillDoubleArrayIntIntDouble() {
-		double[] a1 = new double[9];
-		double[] a2 = ArrayTools.fill(a1, 3.3);
-		int from = 3;
-		int to = 6;
-		double[] a3 = ArrayTools.fill(a2, from, to, 77.77);
-		for (int i = 0; i < a1.length; i++) {
-			double x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals(3.3, x, 0.0);
-			} else {
-				assertEquals(77.77, x, 0.0);
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testFillFloatArrayFloat() {
-		float[] a1 = new float[9];
-		float[] a2 = ArrayTools.fill(a1, 77.77f);
-		for (float x : a1) {
-			assertEquals(77.77f, x, 0.0);
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testFillFloatArrayIntIntFloat() {
-		float[] a1 = new float[9];
-		float[] a2 = ArrayTools.fill(a1, 3.3f);
-		int from = 3;
-		int to = 6;
-		float[] a3 = ArrayTools.fill(a2, from, to, 77.77f);
-		for (int i = 0; i < a1.length; i++) {
-			float x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals(3.3f, x, 0.0);
-			} else {
-				assertEquals(77.77f, x, 0.0);
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testFillIntArrayInt() {
-		int[] a1 = new int[9];
-		int[] a2 = ArrayTools.fill(a1, 77);
-		for (int x : a1) {
-			assertEquals(77, x);
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testFillIntArrayIntIntInt() {
-		int[] a1 = new int[9];
-		int[] a2 = ArrayTools.fill(a1, 3);
-		int from = 3;
-		int to = 6;
-		int[] a3 = ArrayTools.fill(a2, from, to, 77);
-		for (int i = 0; i < a1.length; i++) {
-			int x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals(3, x);
-			} else {
-				assertEquals(77, x);
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testFillObjectArrayObject() {
-		String[] a1 = new String[9];
-		String[] a2 = ArrayTools.fill(a1, "77");
-		for (String x : a1) {
-			assertEquals("77", x);
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testFillObjectArrayIntIntObject() {
-		String[] a1 = new String[9];
-		String[] a2 = ArrayTools.fill(a1, "3");
-		int from = 3;
-		int to = 6;
-		String[] a3 = ArrayTools.fill(a2, from, to, "77");
-		for (int i = 0; i < a1.length; i++) {
-			String x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals("3", x);
-			} else {
-				assertEquals("77", x);
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testFillLongArrayLong() {
-		long[] a1 = new long[9];
-		long[] a2 = ArrayTools.fill(a1, 77);
-		for (long x : a1) {
-			assertEquals(77, x);
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testFillLongArrayIntIntLong() {
-		long[] a1 = new long[9];
-		long[] a2 = ArrayTools.fill(a1, 3);
-		int from = 3;
-		int to = 6;
-		long[] a3 = ArrayTools.fill(a2, from, to, 77);
-		for (int i = 0; i < a1.length; i++) {
-			long x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals(3, x);
-			} else {
-				assertEquals(77, x);
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testFillShortArrayShort() {
-		short[] a1 = new short[9];
-		short[] a2 = ArrayTools.fill(a1, (short) 77);
-		for (short x : a1) {
-			assertEquals(77, x);
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testFillShortArrayIntIntShort() {
-		short[] a1 = new short[9];
-		short[] a2 = ArrayTools.fill(a1, (short) 3);
-		int from = 3;
-		int to = 6;
-		short[] a3 = ArrayTools.fill(a2, from, to, (short) 77);
-		for (int i = 0; i < a1.length; i++) {
-			short x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals(3, x);
-			} else {
-				assertEquals(77, x);
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testSortByteArray() {
-		byte[] a1 = new byte[3];
-		a1[0] = (byte) 33;
-		a1[1] = (byte) 11;
-		a1[2] = (byte) 22;
-		byte[] a2 = ArrayTools.sort(a1);
-		byte last = (byte) 0;
-		for (byte x : a1) {
-			assertTrue(last < x);
-			last = x;
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testSortByteArrayIntInt() {
-		byte[] a1 = new byte[9];
-		byte[] a2 = ArrayTools.fill(a1, (byte) 3);
-		a2[3] = (byte) 33;
-		a2[4] = (byte) 11;
-		a2[5] = (byte) 22;
-		int from = 3;
-		int to = 6;
-		byte[] a3 = ArrayTools.sort(a2, from, to);
-		byte last = (byte) 0;
-		for (int i = 0; i < a1.length; i++) {
-			byte x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals(3, x);
-			} else {
-				assertTrue(last < x);
-				last = x;
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testSortCharArray() {
-		char[] a1 = new char[3];
-		a1[0] = 'z';
-		a1[1] = 'b';
-		a1[2] = 'm';
-		char[] a2 = ArrayTools.sort(a1);
-		char last = 'a';
-		for (char x : a1) {
-			assertTrue(last < x);
-			last = x;
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testSortCharArrayIntInt() {
-		char[] a1 = new char[9];
-		char[] a2 = ArrayTools.fill(a1, 'c');
-		a2[3] = 'z';
-		a2[4] = 'b';
-		a2[5] = 'm';
-		int from = 3;
-		int to = 6;
-		char[] a3 = ArrayTools.sort(a2, from, to);
-		char last = 'a';
-		for (int i = 0; i < a1.length; i++) {
-			char x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals('c', x);
-			} else {
-				assertTrue(last < x);
-				last = x;
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testSortDoubleArray() {
-		double[] a1 = new double[3];
-		a1[0] = 33.33;
-		a1[1] = 11.11;
-		a1[2] = 22.22;
-		double[] a2 = ArrayTools.sort(a1);
-		double last = 0;
-		for (double x : a1) {
-			assertTrue(last < x);
-			last = x;
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testSortDoubleArrayIntInt() {
-		double[] a1 = new double[9];
-		double[] a2 = ArrayTools.fill(a1, 3.3);
-		a2[3] = 33.33;
-		a2[4] = 11.11;
-		a2[5] = 22.22;
-		int from = 3;
-		int to = 6;
-		double[] a3 = ArrayTools.sort(a2, from, to);
-		double last = 0;
-		for (int i = 0; i < a1.length; i++) {
-			double x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals(3.3, x, 0.0);
-			} else {
-				assertTrue(last < x);
-				last = x;
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testSortFloatArray() {
-		float[] a1 = new float[3];
-		a1[0] = 33.33f;
-		a1[1] = 11.11f;
-		a1[2] = 22.22f;
-		float[] a2 = ArrayTools.sort(a1);
-		float last = 0;
-		for (float x : a1) {
-			assertTrue(last < x);
-			last = x;
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testSortFloatArrayIntInt() {
-		float[] a1 = new float[9];
-		float[] a2 = ArrayTools.fill(a1, 3.3f);
-		a2[3] = 33.33f;
-		a2[4] = 11.11f;
-		a2[5] = 22.22f;
-		int from = 3;
-		int to = 6;
-		float[] a3 = ArrayTools.sort(a2, from, to);
-		float last = 0;
-		for (int i = 0; i < a1.length; i++) {
-			float x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals(3.3f, x, 0.0);
-			} else {
-				assertTrue(last < x);
-				last = x;
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testSortIntArray() {
-		int[] a1 = new int[3];
-		a1[0] = 33;
-		a1[1] = 11;
-		a1[2] = 22;
-		int[] a2 = ArrayTools.sort(a1);
-		int last = 0;
-		for (int x : a1) {
-			assertTrue(last < x);
-			last = x;
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testSortIntArrayIntInt() {
-		int[] a1 = new int[9];
-		int[] a2 = ArrayTools.fill(a1, 3);
-		a2[3] = 33;
-		a2[4] = 11;
-		a2[5] = 22;
-		int from = 3;
-		int to = 6;
-		int[] a3 = ArrayTools.sort(a2, from, to);
-		int last = 0;
-		for (int i = 0; i < a1.length; i++) {
-			int x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals(3, x);
-			} else {
-				assertTrue(last < x);
-				last = x;
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testSortObjectArray() {
-		String[] a1 = new String[3];
-		a1[0] = "y";
-		a1[1] = "b";
-		a1[2] = "m";
-		String[] a2 = ArrayTools.sort(a1);
-		String last = "a";
-		for (String x : a1) {
-			assertTrue(last.compareTo(x) < 0);
-			last = x;
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testSortObjectArrayComparator() {
-		String[] a1 = new String[3];
-		a1[0] = "y";
-		a1[1] = "b";
-		a1[2] = "m";
-		String[] a2 = ArrayTools.sort(a1, new ReverseComparator<String>());
-		String last = "z";
-		for (String x : a1) {
-			assertTrue(last.compareTo(x) > 0);
-			last = x;
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testSortObjectArrayIntInt() {
-		String[] a1 = new String[9];
-		String[] a2 = ArrayTools.fill(a1, "c");
-		a2[3] = "y";
-		a2[4] = "b";
-		a2[5] = "m";
-		int from = 3;
-		int to = 6;
-		String[] a3 = ArrayTools.sort(a2, from, to);
-		String last = "a";
-		for (int i = 0; i < a1.length; i++) {
-			String x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals("c", x);
-			} else {
-				assertTrue(last.compareTo(x) < 0);
-				last = x;
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testSortObjectArrayIntIntComparator() {
-		String[] a1 = new String[9];
-		String[] a2 = ArrayTools.fill(a1, "c");
-		a2[3] = "y";
-		a2[4] = "b";
-		a2[5] = "m";
-		int from = 3;
-		int to = 6;
-		String[] a3 = ArrayTools.sort(a2, from, to, new ReverseComparator<String>());
-		String last = "z";
-		for (int i = 0; i < a1.length; i++) {
-			String x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals("c", x);
-			} else {
-				assertTrue(last.compareTo(x) > 0);
-				last = x;
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testSortLongArray() {
-		long[] a1 = new long[3];
-		a1[0] = 33;
-		a1[1] = 11;
-		a1[2] = 22;
-		long[] a2 = ArrayTools.sort(a1);
-		long last = 0;
-		for (long x : a1) {
-			assertTrue(last < x);
-			last = x;
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testSortLongArrayIntInt() {
-		long[] a1 = new long[9];
-		long[] a2 = ArrayTools.fill(a1, 3);
-		a2[3] = 33;
-		a2[4] = 11;
-		a2[5] = 22;
-		int from = 3;
-		int to = 6;
-		long[] a3 = ArrayTools.sort(a2, from, to);
-		long last = 0;
-		for (int i = 0; i < a1.length; i++) {
-			long x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals(3, x);
-			} else {
-				assertTrue(last < x);
-				last = x;
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-	public void testSortShortArray() {
-		short[] a1 = new short[3];
-		a1[0] = (short) 33;
-		a1[1] = (short) 11;
-		a1[2] = (short) 22;
-		short[] a2 = ArrayTools.sort(a1);
-		short last = (short) 0;
-		for (short x : a1) {
-			assertTrue(last < x);
-			last = x;
-		}
-		assertSame(a1, a2);
-	}
-
-	public void testSortShortArrayIntInt() {
-		short[] a1 = new short[9];
-		short[] a2 = ArrayTools.fill(a1, (short) 3);
-		a2[3] = (short) 33;
-		a2[4] = (short) 11;
-		a2[5] = (short) 22;
-		int from = 3;
-		int to = 6;
-		short[] a3 = ArrayTools.sort(a2, from, to);
-		short last = (short) 0;
-		for (int i = 0; i < a1.length; i++) {
-			short x = a1[i];
-			if (i < from || i >= to) {
-				assertEquals(3, x);
-			} else {
-				assertTrue(last < x);
-				last = x;
-			}
-		}
-		assertSame(a1, a2);
-		assertSame(a1, a3);
-	}
-
-
-	// ********** constructor **********
-
-	public void testConstructor() {
-		boolean exCaught = false;
-		try {
-			Object at = ReflectionTools.newInstance(ArrayTools.class);
-			fail("bogus: " + at);
-		} catch (RuntimeException ex) {
-			if (ex.getCause() instanceof InvocationTargetException) {
-				if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-
-	// ********** utility **********
-
-	private Object[] buildObjectArray1() {
-		return new Object[] { "zero", "one", "two" };
-	}
-
-	private String[] buildStringArray1() {
-		return new String[] { "zero", "one", "two" };
-	}
-
-	private char[] buildCharArray() {
-		return new char[] { 'a', 'b', 'c' };
-	}
-
-	private int[] buildIntArray() {
-		return new int[] { 0, 10, 20 };
-	}
-
-	private Object[] buildObjectArray2() {
-		return new Object[] { "three", "four", "five" };
-	}
-
-	private String[] buildStringArray2() {
-		return new String[] { "three", "four", "five" };
-	}
-
-	private List<String> buildStringList1() {
-		List<String> l = new ArrayList<String>();
-		this.addToCollection1(l);
-		return l;
-	}
-
-	private List<Object> buildObjectList1() {
-		List<Object> l = new ArrayList<Object>();
-		this.addToCollection1(l);
-		return l;
-	}
-
-	private void addToCollection1(Collection<? super String> c) {
-		c.add("zero");
-		c.add("one");
-		c.add("two");
-	}
-
-	private List<String> buildStringList2() {
-		List<String> l = new ArrayList<String>();
-		this.addToCollection2(l);
-		return l;
-	}
-
-	private void addToCollection2(Collection<? super String> c) {
-		c.add("three");
-		c.add("four");
-		c.add("five");
-	}
-
-	private Vector<String> buildStringVector1() {
-		Vector<String> v = new Vector<String>();
-		this.addToCollection1(v);
-		return v;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BagTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BagTests.java
deleted file mode 100644
index 4f89f11..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BagTests.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.Bag;
-import org.eclipse.persistence.tools.utility.HashBag;
-
-@SuppressWarnings("nls")
-public class BagTests extends TestCase {
-
-	public BagTests(String name) {
-		super(name);
-	}
-
-	public void testEmptyBag_iterator() throws Exception {
-		assertFalse(Bag.Empty.instance().iterator().hasNext());
-	}
-
-	public void testEmptyBag_size() throws Exception {
-		assertEquals(0, Bag.Empty.instance().size());
-	}
-
-	public void testEmptyBag_uniqueIterator() throws Exception {
-		assertFalse(Bag.Empty.instance().uniqueIterator().hasNext());
-	}
-
-	public void testEmptyBag_uniqueCount() throws Exception {
-		assertEquals(0, Bag.Empty.instance().uniqueCount());
-	}
-
-	public void testEmptyBag_count() throws Exception {
-		assertEquals(0, Bag.Empty.instance().count("foo"));
-	}
-
-	public void testEmptyBag_entries() throws Exception {
-		assertFalse(Bag.Empty.instance().entries().hasNext());
-	}
-
-	public void testEmptyBag_remove() throws Exception {
-		assertFalse(Bag.Empty.instance().remove("foo", 3));
-	}
-
-	public void testEmptyBag_add() throws Exception {
-		boolean exCaught = false;
-		try {
-			Bag.Empty.instance().add("foo", 3);
-			fail();
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testEmptyBag_equals() throws Exception {
-		assertTrue(Bag.Empty.instance().equals(Bag.Empty.instance()));
-		assertFalse(Bag.Empty.instance().equals("foo"));
-
-		Bag<Object> bag = new HashBag<Object>();
-		assertTrue(Bag.Empty.instance().equals(bag));
-		bag.add("foo");
-		assertFalse(Bag.Empty.instance().equals(bag));
-	}
-
-	public void testEmptyBag_hashCode() throws Exception {
-		assertEquals(0, Bag.Empty.instance().hashCode());
-	}
-
-	public void testEmptyBag_serialization() throws Exception {
-		Bag<?> xxx = TestTools.serialize(Bag.Empty.instance());
-		assertSame(Bag.Empty.instance(), xxx);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BidiFilterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BidiFilterTests.java
deleted file mode 100644
index ee4bdf7..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BidiFilterTests.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.BidiFilter;
-
-@SuppressWarnings("nls")
-public class BidiFilterTests extends TestCase {
-
-	public BidiFilterTests(String name) {
-		super(name);
-	}
-
-	public void testNullBidiFilter_accept() throws Exception {
-		assertTrue(BidiFilter.Null.instance().accept("foo"));
-	}
-
-	public void testNullBidiFilter_reverseAccept() throws Exception {
-		assertTrue(BidiFilter.Null.instance().reverseAccept("foo"));
-	}
-
-	public void testNullBidiFilter_toString() throws Exception {
-		assertNotNull(BidiFilter.Null.instance().toString());
-	}
-
-	public void testNullBidiFilter_serialization() throws Exception {
-		BidiFilter<?> xxx = TestTools.serialize(BidiFilter.Null.instance());
-		assertSame(BidiFilter.Null.instance(), xxx);
-	}
-
-	public void testOpaqueBidiFilter_accept() throws Exception {
-		assertFalse(BidiFilter.Opaque.instance().accept("foo"));
-	}
-
-	public void testOpaqueBidiFilter_reverseAccept() throws Exception {
-		assertFalse(BidiFilter.Opaque.instance().reverseAccept("foo"));
-	}
-
-	public void testOpaqueBidiFilter_toString() throws Exception {
-		assertNotNull(BidiFilter.Opaque.instance().toString());
-	}
-
-	public void testOpaqueBidiFilter_serialization() throws Exception {
-		BidiFilter<?> xxx = TestTools.serialize(BidiFilter.Opaque.instance());
-		assertSame(BidiFilter.Opaque.instance(), xxx);
-	}
-
-	public void testDisabledBidiFilter_accept() throws Exception {
-		boolean exCaught = false;
-		try {
-			BidiFilter.Disabled.instance().accept("foo");
-			fail();
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testDisabledBidiFilter_reverseAccept() throws Exception {
-		boolean exCaught = false;
-		try {
-			BidiFilter.Disabled.instance().reverseAccept("foo");
-			fail();
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testDisabledBidiFilter_toString() throws Exception {
-		assertNotNull(BidiFilter.Disabled.instance().toString());
-	}
-
-	public void testDisabledBidiFilter_serialization() throws Exception {
-		BidiFilter<?> xxx = TestTools.serialize(BidiFilter.Disabled.instance());
-		assertSame(BidiFilter.Disabled.instance(), xxx);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BidiStringConverterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BidiStringConverterTests.java
deleted file mode 100644
index 29e3593..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BidiStringConverterTests.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.BidiStringConverter;
-
-@SuppressWarnings("nls")
-public class BidiStringConverterTests extends TestCase {
-
-	public BidiStringConverterTests(String name) {
-		super(name);
-	}
-
-	public void testDefaultBidiStringConverter_convertToString() throws Exception {
-		assertEquals("foo", BidiStringConverter.Default.instance().convertToString("foo"));
-		assertNull(BidiStringConverter.Default.instance().convertToString(null));
-	}
-
-	public void testDefaultBidiStringConverter_convertToObject() throws Exception {
-		assertEquals("foo", BidiStringConverter.Default.instance().convertToObject("foo"));
-		assertNull(BidiStringConverter.Default.instance().convertToString(null));
-	}
-
-	public void testDefaultBidiStringConverter_toString() throws Exception {
-		assertNotNull(BidiStringConverter.Default.instance().toString());
-	}
-
-	public void testDefaultBidiStringConverter_serialization() throws Exception {
-		BidiStringConverter<?> xxx = TestTools.serialize(BidiStringConverter.Default.instance());
-		assertSame(BidiStringConverter.Default.instance(), xxx);
-	}
-
-	public void testDisabledBidiStringConverter_convertToString() throws Exception {
-		boolean exCaught = false;
-		try {
-			BidiStringConverter.Disabled.instance().convertToString("foo");
-			fail();
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testDisabledBidiStringConverter_convertToObject() throws Exception {
-		boolean exCaught = false;
-		try {
-			BidiStringConverter.Disabled.instance().convertToObject("foo");
-			fail();
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testDisabledBidiStringConverter_toString() throws Exception {
-		assertNotNull(BidiStringConverter.Disabled.instance().toString());
-	}
-
-	public void testDisabledBidiStringConverter_serialization() throws Exception {
-		BidiStringConverter<?> xxx = TestTools.serialize(BidiStringConverter.Disabled.instance());
-		assertSame(BidiStringConverter.Disabled.instance(), xxx);
-	}
-
-	public void testBooleanBidiStringConverter_convertToString() throws Exception {
-		assertEquals("true", BidiStringConverter.BooleanConverter.instance().convertToString(Boolean.TRUE));
-		assertEquals("false", BidiStringConverter.BooleanConverter.instance().convertToString(Boolean.FALSE));
-		assertNull(BidiStringConverter.BooleanConverter.instance().convertToString(null));
-	}
-
-	public void testBooleanBidiStringConverter_convertToObject() throws Exception {
-		assertEquals(Boolean.TRUE, BidiStringConverter.BooleanConverter.instance().convertToObject("true"));
-		assertEquals(Boolean.TRUE, BidiStringConverter.BooleanConverter.instance().convertToObject("TRUE"));
-		assertEquals(Boolean.FALSE, BidiStringConverter.BooleanConverter.instance().convertToObject("false"));
-		assertEquals(Boolean.FALSE, BidiStringConverter.BooleanConverter.instance().convertToObject("xxxx"));
-		assertNull(BidiStringConverter.BooleanConverter.instance().convertToObject(null));
-	}
-
-	public void testBooleanBidiStringConverter_toString() throws Exception {
-		assertNotNull(BidiStringConverter.BooleanConverter.instance().toString());
-	}
-
-	public void testBooleanBidiStringConverter_serialization() throws Exception {
-		BidiStringConverter<?> xxx = TestTools.serialize(BidiStringConverter.BooleanConverter.instance());
-		assertSame(BidiStringConverter.BooleanConverter.instance(), xxx);
-	}
-
-	public void testIntegerBidiStringConverter_convertToString() throws Exception {
-		assertEquals("7", BidiStringConverter.IntegerConverter.instance().convertToString(Integer.valueOf(7)));
-		assertNull(BidiStringConverter.IntegerConverter.instance().convertToString(null));
-	}
-
-	public void testIntegerBidiStringConverter_convertToObject() throws Exception {
-		assertEquals(Integer.valueOf(7), BidiStringConverter.IntegerConverter.instance().convertToObject("7"));
-		assertNull(BidiStringConverter.IntegerConverter.instance().convertToObject(null));
-	}
-
-	public void testIntegerBidiStringConverter_toString() throws Exception {
-		assertNotNull(BidiStringConverter.IntegerConverter.instance().toString());
-	}
-
-	public void testIntegerBidiStringConverter_serialization() throws Exception {
-		BidiStringConverter<?> xxx = TestTools.serialize(BidiStringConverter.IntegerConverter.instance());
-		assertSame(BidiStringConverter.IntegerConverter.instance(), xxx);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BidiTransformerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BidiTransformerTests.java
deleted file mode 100644
index 855284f..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BidiTransformerTests.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.BidiTransformer;
-
-@SuppressWarnings("nls")
-public class BidiTransformerTests extends TestCase {
-
-	public BidiTransformerTests(String name) {
-		super(name);
-	}
-
-	public void testNullBidiTransformer_transform() throws Exception {
-		assertEquals("foo", BidiTransformer.Null.instance().transform("foo"));
-		assertNull(BidiTransformer.Null.instance().transform(null));
-	}
-
-	public void testNullBidiTransformer_reverseTransform() throws Exception {
-		assertEquals("foo", BidiTransformer.Null.instance().reverseTransform("foo"));
-		assertNull(BidiTransformer.Null.instance().transform(null));
-	}
-
-	public void testNullBidiTransformer_toString() throws Exception {
-		assertNotNull(BidiTransformer.Null.instance().toString());
-	}
-
-	public void testNullBidiTransformer_serialization() throws Exception {
-		BidiTransformer<?, ?> xxx = TestTools.serialize(BidiTransformer.Null.instance());
-		assertSame(BidiTransformer.Null.instance(), xxx);
-	}
-
-	public void testDisabledBidiTransformer_transform() throws Exception {
-		boolean exCaught = false;
-		try {
-			BidiTransformer.Disabled.instance().transform("foo");
-			fail();
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testDisabledBidiTransformer_reverseTransform() throws Exception {
-		boolean exCaught = false;
-		try {
-			BidiTransformer.Disabled.instance().reverseTransform("foo");
-			fail();
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testDisabledBidiTransformer_toString() throws Exception {
-		assertNotNull(BidiTransformer.Disabled.instance().toString());
-	}
-
-	public void testDisabledBidiTransformer_serialization() throws Exception {
-		BidiTransformer<?, ?> xxx = TestTools.serialize(BidiTransformer.Disabled.instance());
-		assertSame(BidiTransformer.Disabled.instance(), xxx);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BitToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BitToolsTests.java
deleted file mode 100644
index 5873af8..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BitToolsTests.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.lang.reflect.InvocationTargetException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.BitTools;
-import org.eclipse.persistence.tools.utility.ReflectionTools;
-
-public class BitToolsTests extends TestCase {
-
-	public BitToolsTests(String name) {
-		super(name);
-	}
-
-	public void testFlagIsSetIntInt() {
-		assertTrue(BitTools.flagIsSet(0x0003, 0x0001));
-		assertTrue(BitTools.flagIsSet(0x0303, 0x0001));
-		assertTrue(BitTools.flagIsSet(0x0303, 0x0101));
-		assertTrue(BitTools.flagIsSet(0x0303, 0x0103));
-
-		assertFalse(BitTools.flagIsSet(0x0303, 0x1103));
-		assertFalse(BitTools.flagIsSet(0x0000, 0x1103));
-	}
-
-	public void testFlagIsOffIntInt() {
-		assertFalse(BitTools.flagIsOff(0x0003, 0x0001));
-		assertFalse(BitTools.flagIsOff(0x0303, 0x0001));
-		assertFalse(BitTools.flagIsOff(0x0303, 0x0101));
-		assertFalse(BitTools.flagIsOff(0x0303, 0x0103));
-
-		assertTrue(BitTools.flagIsOff(0x2204, 0x1103));
-		assertTrue(BitTools.flagIsOff(0x0000, 0x1103));
-	}
-
-	public void testOnlyFlagIsSetIntInt() {
-		assertFalse(BitTools.onlyFlagIsSet(0x0003, 0x0001));
-		assertTrue(BitTools.onlyFlagIsSet(0x0001, 0x0001));
-
-		assertFalse(BitTools.onlyFlagIsSet(0x0303, 0x0001));
-		assertTrue(BitTools.onlyFlagIsSet(0x0001, 0x0001));
-
-		assertFalse(BitTools.onlyFlagIsSet(0x0303, 0x0101));
-		assertTrue(BitTools.onlyFlagIsSet(0x0101, 0x0101));
-
-		assertFalse(BitTools.onlyFlagIsSet(0x0303, 0x0103));
-		assertTrue(BitTools.onlyFlagIsSet(0x0103, 0x0103));
-
-		assertFalse(BitTools.onlyFlagIsSet(0x0303, 0x1103));
-		assertTrue(BitTools.onlyFlagIsSet(0x1103, 0x1103));
-
-		assertFalse(BitTools.onlyFlagIsSet(0x0000, 0x1103));
-		assertTrue(BitTools.onlyFlagIsSet(0x0103, 0x0103));
-	}
-
-	public void testOnlyFlagIsOffIntInt() {
-		assertFalse(BitTools.onlyFlagIsOff(0x0003, 0x0001));
-		assertFalse(BitTools.onlyFlagIsOff(0x0303, 0x0001));
-		assertTrue(BitTools.onlyFlagIsOff(0xFFFFFFFE, 0x0001));
-
-		assertFalse(BitTools.onlyFlagIsOff(0x0303, 0x0101));
-		assertTrue(BitTools.onlyFlagIsOff(0xFFFFFEFE, 0x0101));
-
-		assertFalse(BitTools.onlyFlagIsOff(0x0303, 0x0103));
-		assertTrue(BitTools.onlyFlagIsOff(0xFFFFFEFC, 0x0103));
-
-		assertFalse(BitTools.onlyFlagIsOff(0x0303, 0x1103));
-		assertTrue(BitTools.onlyFlagIsOff(0xFFFFEEFC, 0x1103));
-	}
-
-	public void testAllFlagsAreSetIntInt() {
-		assertTrue(BitTools.allFlagsAreSet(0x0003, 0x0001));
-		assertTrue(BitTools.allFlagsAreSet(0x0303, 0x0001));
-		assertTrue(BitTools.allFlagsAreSet(0x0303, 0x0101));
-		assertTrue(BitTools.allFlagsAreSet(0x0303, 0x0103));
-
-		assertFalse(BitTools.allFlagsAreSet(0x0303, 0x1103));
-		assertFalse(BitTools.allFlagsAreSet(0x0000, 0x1103));
-	}
-
-	public void testAllFlagsAreOffIntInt() {
-		assertFalse(BitTools.allFlagsAreOff(0x0003, 0x0001));
-		assertFalse(BitTools.allFlagsAreOff(0x0303, 0x0001));
-		assertFalse(BitTools.allFlagsAreOff(0x0303, 0x0101));
-		assertFalse(BitTools.allFlagsAreOff(0x0303, 0x0103));
-
-		assertTrue(BitTools.allFlagsAreOff(0x2204, 0x1103));
-		assertTrue(BitTools.allFlagsAreOff(0x0000, 0x1103));
-	}
-
-	public void testOnlyFlagsAreSetIntInt() {
-		assertFalse(BitTools.onlyFlagsAreSet(0x0003, 0x0001));
-		assertTrue(BitTools.onlyFlagsAreSet(0x0001, 0x0001));
-
-		assertFalse(BitTools.onlyFlagsAreSet(0x0303, 0x0001));
-		assertTrue(BitTools.onlyFlagsAreSet(0x0001, 0x0001));
-
-		assertFalse(BitTools.onlyFlagsAreSet(0x0303, 0x0101));
-		assertTrue(BitTools.onlyFlagsAreSet(0x0101, 0x0101));
-
-		assertFalse(BitTools.onlyFlagsAreSet(0x0303, 0x0103));
-		assertTrue(BitTools.onlyFlagsAreSet(0x0103, 0x0103));
-
-		assertFalse(BitTools.onlyFlagsAreSet(0x0303, 0x1103));
-		assertTrue(BitTools.onlyFlagsAreSet(0x1103, 0x1103));
-
-		assertFalse(BitTools.onlyFlagsAreSet(0x0000, 0x1103));
-		assertTrue(BitTools.onlyFlagsAreSet(0x0103, 0x0103));
-	}
-
-	public void testOnlyFlagsAreOffIntInt() {
-		assertFalse(BitTools.onlyFlagsAreOff(0x0003, 0x0001));
-		assertFalse(BitTools.onlyFlagsAreOff(0x0303, 0x0001));
-		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFFFE, 0x0001));
-
-		assertFalse(BitTools.onlyFlagsAreOff(0x0303, 0x0101));
-		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFEFE, 0x0101));
-
-		assertFalse(BitTools.onlyFlagsAreOff(0x0303, 0x0103));
-		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFEFC, 0x0103));
-
-		assertFalse(BitTools.onlyFlagsAreOff(0x0303, 0x1103));
-		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFEEFC, 0x1103));
-	}
-
-	public void testAnyFlagsAreSetIntInt() {
-		assertTrue(BitTools.anyFlagsAreSet(0x0003, 0x0001));
-		assertTrue(BitTools.anyFlagsAreSet(0xFFFF, 0x0001));
-		assertTrue(BitTools.anyFlagsAreSet(0x0003, 0xFFFF));
-
-		assertFalse(BitTools.anyFlagsAreSet(0x0303, 0x1010));
-		assertFalse(BitTools.anyFlagsAreSet(0x0000, 0xFFFF));
-	}
-
-	public void testAnyFlagsAreOffIntInt() {
-		assertTrue(BitTools.anyFlagsAreOff(0x333E, 0x0001));
-		assertTrue(BitTools.anyFlagsAreOff(0xFFFE, 0x0001));
-		assertTrue(BitTools.anyFlagsAreOff(0x0003, 0xFFFF));
-
-		assertFalse(BitTools.anyFlagsAreOff(0x7373, 0x1010));
-		assertFalse(BitTools.anyFlagsAreOff(0xFFFF, 0xFFFF));
-	}
-
-	public void testAllFlagsAreSetIntIntArray() {
-		assertTrue(BitTools.allFlagsAreSet(0x0003, new int[] { 0x0001 }));
-		assertTrue(BitTools.allFlagsAreSet(0x0303, new int[] { 0x0001 }));
-		assertTrue(BitTools.allFlagsAreSet(0x0303, new int[] { 0x0100, 0x0001 }));
-		assertTrue(BitTools.allFlagsAreSet(0x0303, new int[] { 0x0100, 0x0002, 0x0001 }));
-
-		assertFalse(BitTools.allFlagsAreSet(0x0303, new int[] { 0x1000, 0x0100, 0x0002, 0x0001 }));
-		assertFalse(BitTools.allFlagsAreSet(0x0000, new int[] { 0x1000, 0x0100, 0x0002, 0x0001 }));
-	}
-
-	public void testAllFlagsAreOffIntIntArray() {
-		assertFalse(BitTools.allFlagsAreOff(0x0003, new int[] { 0x0001 }));
-		assertFalse(BitTools.allFlagsAreOff(0x0303, new int[] { 0x0001 }));
-		assertFalse(BitTools.allFlagsAreOff(0x0303, new int[] { 0x0100, 0x0001 }));
-		assertFalse(BitTools.allFlagsAreOff(0x0303, new int[] { 0x0100, 0x0002, 0x0001 }));
-
-		assertTrue(BitTools.allFlagsAreOff(0x0303, new int[] { 0x1000, 0x0400, 0x0020, 0x0000 }));
-		assertTrue(BitTools.allFlagsAreOff(0x0000, new int[] { 0x1000, 0x0100, 0x0002, 0x0001 }));
-	}
-
-	public void testOnlyFlagsAreSetIntIntArray() {
-		assertFalse(BitTools.onlyFlagsAreSet(0x0003, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
-		assertTrue(BitTools.onlyFlagsAreSet(0x0001, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
-
-		assertFalse(BitTools.onlyFlagsAreSet(0x0303, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
-		assertTrue(BitTools.onlyFlagsAreSet(0x0001, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
-
-		assertFalse(BitTools.onlyFlagsAreSet(0x0303, new int[] { 0x001, 0x0100, 0x0000, 0x0001 }));
-		assertTrue(BitTools.onlyFlagsAreSet(0x0101, new int[] { 0x001, 0x0100, 0x0000, 0x0001 }));
-
-		assertFalse(BitTools.onlyFlagsAreSet(0x0303, new int[] { 0x001, 0x0100, 0x0002, 0x0001 }));
-		assertTrue(BitTools.onlyFlagsAreSet(0x0103, new int[] { 0x001, 0x0100, 0x0002, 0x0001 }));
-
-		assertFalse(BitTools.onlyFlagsAreSet(0x0303, new int[] { 0x011, 0x0100, 0x0002, 0x0001 }));
-		assertTrue(BitTools.onlyFlagsAreSet(0x1103, new int[] { 0x1100, 0x0100, 0x0002, 0x0001 }));
-
-		assertFalse(BitTools.onlyFlagsAreSet(0x0000, new int[] { 0x011, 0x0100, 0x0002, 0x0001 }));
-		assertTrue(BitTools.onlyFlagsAreSet(0x0103, new int[] { 0x0101, 0x0100, 0x0002, 0x0001 }));
-	}
-
-	public void testOnlyFlagsAreOffIntIntArray() {
-		assertFalse(BitTools.onlyFlagsAreOff(0x0003, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
-		assertFalse(BitTools.onlyFlagsAreOff(0x0303, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
-		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFFFE, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
-
-		assertFalse(BitTools.onlyFlagsAreOff(0x0303, new int[] { 0x001, 0x0100, 0x0000, 0x0001 }));
-		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFEFE, new int[] { 0x001, 0x0100, 0x0000, 0x0001 }));
-
-		assertFalse(BitTools.onlyFlagsAreOff(0x0303, new int[] { 0x001, 0x0100, 0x0002, 0x0001 }));
-		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFEFC, new int[] { 0x001, 0x0100, 0x0002, 0x0001 }));
-
-		assertFalse(BitTools.onlyFlagsAreOff(0x0303, new int[] { 0x1100, 0x0100, 0x0002, 0x0001 }));
-		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFEEFC, new int[] { 0x1100, 0x0100, 0x0002, 0x0001 }));
-	}
-
-	public void testAnyFlagsAreSetIntIntArray() {
-		assertTrue(BitTools.anyFlagsAreSet(0x0003, new int[] { 0x0001 }));
-		assertTrue(BitTools.anyFlagsAreSet(0xFFFF, new int[] { 0x0001 }));
-		assertTrue(BitTools.anyFlagsAreSet(0x0303, new int[] { 0xF000, 0x0F00, 0x00F0, 0x000F }));
-
-		assertFalse(BitTools.anyFlagsAreSet(0x0303, new int[] { 0x1000, 0x0010 }));
-		assertFalse(BitTools.anyFlagsAreSet(0x0000, new int[] { 0xF000, 0x0F00, 0x00F0, 0x000F }));
-	}
-
-	public void testAnyFlagsAreOffIntIntArray() {
-		assertFalse(BitTools.anyFlagsAreOff(0x0003, new int[] { 0x0001 }));
-		assertFalse(BitTools.anyFlagsAreOff(0xFFFF, new int[] { 0x0001 }));
-		assertFalse(BitTools.anyFlagsAreOff(0x0303, new int[] { 0x0100, 0x0200, 0x0003, 0x0002 }));
-
-		assertTrue(BitTools.anyFlagsAreOff(0x0303, new int[] { 0x0100, 0x0010 }));
-		assertTrue(BitTools.anyFlagsAreOff(0x0000, new int[] { 0xF000, 0x0F00, 0x00F0, 0x000F }));
-	}
-
-	public void testOrFlags() {
-		assertEquals(0x0001, BitTools.orFlags(new int[] { 0x0001, 0x0000 }));
-		assertEquals(0x0011, BitTools.orFlags(new int[] { 0x0001, 0x0011 }));
-		assertEquals(0xF011, BitTools.orFlags(new int[] { 0x0001, 0x0011, 0xF000 }));
-	}
-
-	public void testAndFlags() {
-		assertEquals(0x0001, BitTools.andFlags(new int[] { 0x0001, 0x0001 }));
-		assertEquals(0x0001, BitTools.andFlags(new int[] { 0x0001, 0x0011 }));
-		assertEquals(0x0000, BitTools.andFlags(new int[] { 0x0001, 0x0011, 0xF000 }));
-		assertEquals(0x0001, BitTools.andFlags(new int[] { 0x0001, 0x0011, 0xF001 }));
-	}
-
-	public void testXorFlags() {
-		assertEquals(0x0001, BitTools.xorFlags(new int[] { 0x0001, 0x0000 }));
-		assertEquals(0x0010, BitTools.xorFlags(new int[] { 0x0001, 0x0011 }));
-		assertEquals(0xF010, BitTools.xorFlags(new int[] { 0x0001, 0x0011, 0xF000 }));
-		assertEquals(0xFF11, BitTools.xorFlags(new int[] { 0x0001, 0x0011, 0xF000, 0x0F01 }));
-		assertEquals(0xF010, BitTools.xorFlags(new int[] { 0x0001, 0x0011, 0xF000, 0x0F01, 0x0F01 }));
-	}
-
-	public void testConstructor() {
-		boolean exCaught = false;
-		try {
-			Object at = ReflectionTools.newInstance(BitTools.class);
-			fail("bogus: " + at); //$NON-NLS-1$
-		} catch (RuntimeException ex) {
-			if (ex.getCause() instanceof InvocationTargetException) {
-				if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BooleanToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BooleanToolsTests.java
deleted file mode 100644
index f1e41c0..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/BooleanToolsTests.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.lang.reflect.InvocationTargetException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.BooleanTools;
-import org.eclipse.persistence.tools.utility.ReflectionTools;
-
-public class BooleanToolsTests extends TestCase {
-	private static final Boolean TRUE = Boolean.TRUE;
-	private static final Boolean FALSE = Boolean.FALSE;
-
-	public BooleanToolsTests(String name) {
-		super(name);
-	}
-
-	public void testNOT() {
-		assertEquals(FALSE, BooleanTools.not(TRUE));
-		assertEquals(TRUE, BooleanTools.not(FALSE));
-	}
-
-	public void testAND() {
-		assertEquals(TRUE, BooleanTools.and(TRUE, TRUE));
-		assertEquals(FALSE, BooleanTools.and(TRUE, FALSE));
-		assertEquals(FALSE, BooleanTools.and(FALSE, TRUE));
-		assertEquals(FALSE, BooleanTools.and(FALSE, FALSE));
-	}
-
-	public void testOR() {
-		assertEquals(TRUE, BooleanTools.or(TRUE, TRUE));
-		assertEquals(TRUE, BooleanTools.or(TRUE, FALSE));
-		assertEquals(TRUE, BooleanTools.or(FALSE, TRUE));
-		assertEquals(FALSE, BooleanTools.or(FALSE, FALSE));
-	}
-
-	public void testXOR() {
-		assertEquals(FALSE, BooleanTools.xor(TRUE, TRUE));
-		assertEquals(TRUE, BooleanTools.xor(TRUE, FALSE));
-		assertEquals(TRUE, BooleanTools.xor(FALSE, TRUE));
-		assertEquals(FALSE, BooleanTools.xor(FALSE, FALSE));
-	}
-
-	public void testNAND() {
-		assertEquals(FALSE, BooleanTools.nand(TRUE, TRUE));
-		assertEquals(TRUE, BooleanTools.nand(TRUE, FALSE));
-		assertEquals(TRUE, BooleanTools.nand(FALSE, TRUE));
-		assertEquals(TRUE, BooleanTools.nand(FALSE, FALSE));
-	}
-
-	public void testNOR() {
-		assertEquals(FALSE, BooleanTools.nor(TRUE, TRUE));
-		assertEquals(FALSE, BooleanTools.nor(TRUE, FALSE));
-		assertEquals(FALSE, BooleanTools.nor(FALSE, TRUE));
-		assertEquals(TRUE, BooleanTools.nor(FALSE, FALSE));
-	}
-
-	public void testXNOR() {
-		assertEquals(TRUE, BooleanTools.xnor(TRUE, TRUE));
-		assertEquals(FALSE, BooleanTools.xnor(TRUE, FALSE));
-		assertEquals(FALSE, BooleanTools.xnor(FALSE, TRUE));
-		assertEquals(TRUE, BooleanTools.xnor(FALSE, FALSE));
-	}
-
-	public void testConstructor() {
-		boolean exCaught = false;
-		try {
-			Object at = ReflectionTools.newInstance(BooleanTools.class);
-			fail("bogus: " + at); //$NON-NLS-1$
-		} catch (RuntimeException ex) {
-			if (ex.getCause() instanceof InvocationTargetException) {
-				if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ClassNameTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ClassNameTests.java
deleted file mode 100644
index aaf5808..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ClassNameTests.java
+++ /dev/null
@@ -1,372 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationTargetException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.ClassName;
-import org.eclipse.persistence.tools.utility.ReflectionTools;
-
-@SuppressWarnings("nls")
-public class ClassNameTests extends TestCase {
-
-	public ClassNameTests(String name) {
-		super(name);
-	}
-
-	public void testIsArray() {
-		assertFalse(ClassName.isArray(int.class.getName()));
-		assertTrue(ClassName.isArray(int[].class.getName()));
-		assertTrue(ClassName.isArray(int[][].class.getName()));
-
-		assertFalse(ClassName.isArray(java.lang.String.class.getName()));
-		assertTrue(ClassName.isArray(java.lang.String[].class.getName()));
-		assertTrue(ClassName.isArray(java.lang.String[][].class.getName()));
-	}
-
-	public void testGetElementTypeName() {
-		assertEquals(java.util.Vector.class.getName(), ClassName.getElementTypeName(java.util.Vector.class.getName()));
-		assertEquals(int.class.getName(), ClassName.getElementTypeName(int.class.getName()));
-		assertEquals(void.class.getName(), ClassName.getElementTypeName(void.class.getName()));
-		assertEquals(java.util.Vector.class.getName(), ClassName.getElementTypeName(java.util.Vector[].class.getName()));
-		assertEquals(int.class.getName(), ClassName.getElementTypeName(int[].class.getName()));
-		assertEquals(java.util.Vector.class.getName(), ClassName.getElementTypeName(java.util.Vector[][][].class.getName()));
-		assertEquals(int.class.getName(), ClassName.getElementTypeName(int[][][].class.getName()));
-	}
-
-	public void testGetArrayDepth() {
-		assertEquals(0, ClassName.getArrayDepth(java.util.Vector.class.getName()));
-		assertEquals(0, ClassName.getArrayDepth(int.class.getName()));
-		assertEquals(0, ClassName.getArrayDepth(void.class.getName()));
-		assertEquals(1, ClassName.getArrayDepth(java.util.Vector[].class.getName()));
-		assertEquals(1, ClassName.getArrayDepth(int[].class.getName()));
-		assertEquals(3, ClassName.getArrayDepth(java.util.Vector[][][].class.getName()));
-		assertEquals(3, ClassName.getArrayDepth(int[][][].class.getName()));
-	}
-
-	public void testGetComponentTypeName() {
-		assertEquals(null, ClassName.getComponentTypeName(java.lang.Object.class.getName()));
-		assertEquals(java.lang.Object.class.getName(), ClassName.getComponentTypeName(java.lang.Object[].class.getName()));
-		assertEquals(java.lang.Object[].class.getName(), ClassName.getComponentTypeName(java.lang.Object[][].class.getName()));
-
-		assertEquals(null, ClassName.getComponentTypeName(int.class.getName()));
-		assertEquals(int.class.getName(), ClassName.getComponentTypeName(int[].class.getName()));
-		assertEquals(int[].class.getName(), ClassName.getComponentTypeName(int[][].class.getName()));
-	}
-
-	public void testGetSimpleName() throws Exception {
-		assertEquals("Object", ClassName.getSimpleName(java.lang.Object.class.getName()));
-		assertEquals("Object[]", ClassName.getSimpleName(java.lang.Object[].class.getName()));
-		assertEquals("Object[][]", ClassName.getSimpleName(java.lang.Object[][].class.getName()));
-
-		assertEquals(java.util.Map.class.getSimpleName(), ClassName.getSimpleName(java.util.Map.class.getName()));
-		assertEquals(java.util.Map.Entry.class.getSimpleName(), ClassName.getSimpleName(java.util.Map.Entry.class.getName()));
-
-		assertEquals("int", ClassName.getSimpleName(int.class.getName()));
-		assertEquals("int[]", ClassName.getSimpleName(int[].class.getName()));
-		assertEquals("int[][]", ClassName.getSimpleName(int[][].class.getName()));
-
-		Object anonObject = new Object() {
-			// anonymous class
-		};
-		assertEquals("", ClassName.getSimpleName(anonObject.getClass().getName()));
-
-		class Local {
-			// anonymous class
-		}
-		Local localObject = new Local();
-		assertEquals("Local", ClassName.getSimpleName(localObject.getClass().getName()));
-	}
-
-	public void testGetPackageName() throws Exception {
-		assertEquals(java.lang.Object.class.getPackage().getName(), ClassName.getPackageName(java.lang.Object.class.getName()));
-		assertEquals("", ClassName.getPackageName(java.lang.Object[].class.getName()));
-		assertEquals("", ClassName.getPackageName(java.lang.Object[][].class.getName()));
-
-		assertEquals(java.util.Map.class.getPackage().getName(), ClassName.getPackageName(java.util.Map.class.getName()));
-		assertEquals(java.util.Map.Entry.class.getPackage().getName(), ClassName.getPackageName(java.util.Map.Entry.class.getName()));
-
-		assertEquals("", ClassName.getPackageName(int.class.getName()));
-		assertEquals("", ClassName.getPackageName(int[].class.getName()));
-		assertEquals("", ClassName.getPackageName(int[][].class.getName()));
-
-		assertEquals("", ClassName.getPackageName(void.class.getName()));
-
-		Object anonObject = new Object() {
-			// anonymous class
-		};
-		assertEquals(anonObject.getClass().getPackage().getName(), ClassName.getPackageName(anonObject.getClass().getName()));
-	}
-
-	public void testIsTopLevel() throws Exception {
-		assertTrue(ClassName.isTopLevel(java.util.Map.class.getName())); // top-level
-		assertFalse(ClassName.isTopLevel(java.util.Map.Entry.class.getName())); // member
-		assertFalse(ClassName.isTopLevel(Class.forName(this.getClass().getName() + "$1LocalClass").getName())); // local
-		assertFalse(ClassName.isTopLevel(Class.forName("java.util.Vector$1").getName())); // anonymous
-
-		Object[] array = new java.util.Map[0]; // top-level
-		assertFalse(ClassName.isTopLevel(array.getClass().getName()));
-		array = new java.util.Map.Entry[0]; // member
-		assertFalse(ClassName.isTopLevel(array.getClass().getName()));
-		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
-		array = (Object[]) Array.newInstance(localClass, 0);
-		assertFalse(ClassName.isTopLevel(array.getClass().getName()));
-		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
-		array = (Object[]) Array.newInstance(anonClass, 0);
-		assertFalse(ClassName.isTopLevel(array.getClass().getName()));
-	}
-
-	public void testIsMember() throws Exception {
-		assertFalse(ClassName.isMember(java.util.Map.class.getName())); // top-level
-		assertTrue(ClassName.isMember(java.util.Map.Entry.class.getName())); // member
-		assertFalse(ClassName.isMember(Class.forName(this.getClass().getName() + "$1LocalClass").getName())); // local
-		assertFalse(ClassName.isMember(Class.forName("java.util.Vector$1").getName())); // anonymous
-
-		Object[] array = new java.util.Map[0]; // top-level
-		assertFalse(ClassName.isMember(array.getClass().getName()));
-		array = new java.util.Map.Entry[0]; // member
-		assertFalse(ClassName.isMember(array.getClass().getName()));
-		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
-		array = (Object[]) Array.newInstance(localClass, 0);
-		assertFalse(ClassName.isMember(array.getClass().getName()));
-		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
-		array = (Object[]) Array.newInstance(anonClass, 0);
-		assertFalse(ClassName.isMember(array.getClass().getName()));
-
-		// test a few edge cases
-		assertTrue(ClassName.isMember("java.util.Map$a1"));
-		assertTrue(ClassName.isMember("java.util.Map$1aa$aaa"));  // member inside local
-		assertTrue(ClassName.isMember("java.util.Map$1$aaa"));  // member inside anonymous
-		assertTrue(ClassName.isMember("java.util.Map$a1$aaa$bbb"));
-		assertTrue(ClassName.isMember("java.util.Map$1a1$aaa"));  // member inside local
-		assertFalse(ClassName.isMember("java.util.Map$1a"));
-		assertTrue(ClassName.isMember("java.util.Map$a12345$b12345"));
-		assertFalse(ClassName.isMember("java.util.Map$12345a"));
-		assertFalse(ClassName.isMember("java.util.Map$333"));
-		assertFalse(ClassName.isMember("java.util.Map3$333"));
-	}
-
-	public void testIsLocal() throws Exception {
-		class LocalClass {
-			void foo() {
-				System.getProperty("foo");
-			}
-		}
-		new LocalClass().foo();
-		assertFalse(ClassName.isLocal(java.util.Map.class.getName())); // top-level
-		assertFalse(ClassName.isLocal(java.util.Map.Entry.class.getName())); // member
-		assertTrue(ClassName.isLocal(Class.forName(this.getClass().getName() + "$1LocalClass").getName())); // local
-		assertFalse(ClassName.isLocal(Class.forName("java.util.Vector$1").getName())); // anonymous
-
-		Object[] array = new java.util.Map[0]; // top-level
-		assertFalse(ClassName.isLocal(array.getClass().getName()));
-		array = new java.util.Map.Entry[0]; // member
-		assertFalse(ClassName.isLocal(array.getClass().getName()));
-		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
-		array = (Object[]) Array.newInstance(localClass, 0);
-		assertFalse(ClassName.isLocal(array.getClass().getName()));
-		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
-		array = (Object[]) Array.newInstance(anonClass, 0);
-		assertFalse(ClassName.isLocal(array.getClass().getName()));
-
-		// test a few edge cases
-		assertFalse(ClassName.isLocal("java.util.Map$a1"));
-		assertFalse(ClassName.isLocal("java.util.Map$a1$aaa$bbb"));
-		assertFalse(ClassName.isLocal("java.util.Map$11$aaa"));
-		assertTrue(ClassName.isLocal("java.util.Map$1a"));
-		assertTrue(ClassName.isLocal("java.util.Map$2abc"));
-		assertTrue(ClassName.isLocal("java.util.Map$2abc1"));
-		assertFalse(ClassName.isLocal("java.util.Map$a12345$b12345"));
-		assertTrue(ClassName.isLocal("java.util.Map$12345$1234a"));
-		assertFalse(ClassName.isLocal("java.util.Map$333"));
-		assertFalse(ClassName.isLocal("java.util.Map3$333"));
-	}
-
-	public void testIsAnonymous() throws Exception {
-		assertFalse(ClassName.isAnonymous(java.util.Map.class.getName())); // top-level
-		assertFalse(ClassName.isAnonymous(java.util.Map.Entry.class.getName())); // member
-		assertFalse(ClassName.isAnonymous(Class.forName(this.getClass().getName() + "$1LocalClass").getName())); // local
-		assertTrue(ClassName.isAnonymous(Class.forName("java.util.Vector$1").getName())); // anonymous
-
-		Object[] array = new java.util.Map[0]; // top-level
-		assertFalse(ClassName.isAnonymous(array.getClass().getName()));
-		array = new java.util.Map.Entry[0]; // member
-		assertFalse(ClassName.isAnonymous(array.getClass().getName()));
-		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
-		array = (Object[]) Array.newInstance(localClass, 0);
-		assertFalse(ClassName.isAnonymous(array.getClass().getName()));
-		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
-		array = (Object[]) Array.newInstance(anonClass, 0);
-		assertFalse(ClassName.isAnonymous(array.getClass().getName()));
-
-		// test a few edge cases
-		assertFalse(ClassName.isAnonymous("java.util.Map$a1"));
-		assertFalse(ClassName.isAnonymous("java.util.Map$a1$aaa$bbb"));
-		assertFalse(ClassName.isAnonymous("java.util.Map$1a1$aaa"));
-		assertFalse(ClassName.isAnonymous("java.util.Map$1$a"));
-		assertFalse(ClassName.isAnonymous("java.util.Map$1a"));
-		assertFalse(ClassName.isAnonymous("java.util.Map$a12345$b12345"));
-		assertFalse(ClassName.isAnonymous("java.util.Map$12345$a1234"));
-		assertTrue(ClassName.isAnonymous("java.util.Map$333"));
-		assertTrue(ClassName.isAnonymous("java.util.Map3$333"));
-	}
-
-	public void testIsReference() throws Exception {
-		assertFalse(ClassName.isReference(int.class.getName())); // top-level
-
-		assertTrue(ClassName.isReference(java.util.Map.class.getName())); // top-level
-		assertTrue(ClassName.isReference(java.util.Map.Entry.class.getName())); // member
-		assertTrue(ClassName.isReference(Class.forName(this.getClass().getName() + "$1LocalClass").getName())); // local
-		assertTrue(ClassName.isReference(Class.forName("java.util.Vector$1").getName())); // anonymous
-
-		Object[] array = new java.util.Map[0]; // top-level
-		assertTrue(ClassName.isReference(array.getClass().getName()));
-		array = new java.util.Map.Entry[0]; // member
-		assertTrue(ClassName.isReference(array.getClass().getName()));
-		Class<?> localClass = Class.forName(this.getClass().getName() + "$1LocalClass"); // local
-		array = (Object[]) Array.newInstance(localClass, 0);
-		assertTrue(ClassName.isReference(array.getClass().getName()));
-		Class<?> anonClass = Class.forName("java.util.Vector$1"); // local
-		array = (Object[]) Array.newInstance(anonClass, 0);
-		assertTrue(ClassName.isReference(array.getClass().getName()));
-	}
-
-	public void testIsPrimitive() {
-		assertTrue(void.class.isPrimitive());
-
-		assertTrue(ClassName.isPrimitive(void.class.getName()));
-		assertTrue(ClassName.isPrimitive(int.class.getName()));
-		assertTrue(ClassName.isPrimitive(float.class.getName()));
-		assertTrue(ClassName.isPrimitive(boolean.class.getName()));
-
-		assertFalse(ClassName.isPrimitive(java.lang.Number.class.getName()));
-		assertFalse(ClassName.isPrimitive(java.lang.String.class.getName()));
-		assertFalse(ClassName.isPrimitive(java.lang.Boolean.class.getName()));
-		assertFalse(ClassName.isPrimitive(java.lang.Integer.class.getName()));
-	}
-
-	public void testIsPrimitiveWrapper() {
-		assertFalse(ClassName.isPrimitiveWrapper(void.class.getName()));
-		assertFalse(ClassName.isPrimitiveWrapper(int.class.getName()));
-		assertFalse(ClassName.isPrimitiveWrapper(float.class.getName()));
-		assertFalse(ClassName.isPrimitiveWrapper(boolean.class.getName()));
-
-		assertFalse(ClassName.isPrimitiveWrapper(java.lang.reflect.Field.class.getName()));
-		assertFalse(ClassName.isPrimitiveWrapper(java.lang.String.class.getName()));
-		assertTrue(ClassName.isPrimitiveWrapper(java.lang.Boolean.class.getName()));
-		assertTrue(ClassName.isPrimitiveWrapper(java.lang.Integer.class.getName()));
-	}
-
-	public void testIsVariablePrimitive() {
-		assertFalse(ClassName.isVariablePrimitive(void.class.getName()));
-
-		assertTrue(ClassName.isVariablePrimitive(int.class.getName()));
-		assertTrue(ClassName.isVariablePrimitive(float.class.getName()));
-		assertTrue(ClassName.isVariablePrimitive(boolean.class.getName()));
-
-		assertFalse(ClassName.isVariablePrimitive(java.lang.Number.class.getName()));
-		assertFalse(ClassName.isVariablePrimitive(java.lang.String.class.getName()));
-		assertFalse(ClassName.isVariablePrimitive(java.lang.Boolean.class.getName()));
-	}
-
-	public void testIsVariablePrimitiveWrapper() {
-		assertFalse(ClassName.isVariablePrimitiveWrapper(java.lang.Void.class.getName()));
-
-		assertTrue(ClassName.isVariablePrimitiveWrapper(java.lang.Integer.class.getName()));
-		assertTrue(ClassName.isVariablePrimitiveWrapper(java.lang.Float.class.getName()));
-		assertTrue(ClassName.isVariablePrimitiveWrapper(java.lang.Boolean.class.getName()));
-
-		assertFalse(ClassName.isVariablePrimitiveWrapper(java.lang.Number.class.getName()));
-		assertFalse(ClassName.isVariablePrimitiveWrapper(java.lang.String.class.getName()));
-		assertFalse(ClassName.isVariablePrimitiveWrapper(java.lang.Object.class.getName()));
-	}
-
-	public void testGetWrapperClassName() {
-		assertEquals(java.lang.Void.class.getName(), ClassName.getWrapperClassName(void.class.getName()));
-		assertEquals(java.lang.Integer.class.getName(), ClassName.getWrapperClassName(int.class.getName()));
-		assertEquals(java.lang.Float.class.getName(), ClassName.getWrapperClassName(float.class.getName()));
-		assertEquals(java.lang.Boolean.class.getName(), ClassName.getWrapperClassName(boolean.class.getName()));
-
-		assertNull(ClassName.getWrapperClassName(java.lang.String.class.getName()));
-	}
-
-	public void testGetPrimitiveClassName() {
-		assertEquals(void.class.getName(), ClassName.getPrimitiveClassName(java.lang.Void.class.getName()));
-		assertEquals(int.class.getName(), ClassName.getPrimitiveClassName(java.lang.Integer.class.getName()));
-		assertEquals(float.class.getName(), ClassName.getPrimitiveClassName(java.lang.Float.class.getName()));
-		assertEquals(boolean.class.getName(), ClassName.getPrimitiveClassName(java.lang.Boolean.class.getName()));
-
-		assertNull(ClassName.getPrimitiveClassName(java.lang.String.class.getName()));
-	}
-
-	public void testAreAutoboxEquivalents() {
-		assertTrue(ClassName.areAutoboxEquivalents(Integer.class.getName(), Integer.class.getName()));
-		assertTrue(ClassName.areAutoboxEquivalents(int.class.getName(), Integer.class.getName()));
-		assertTrue(ClassName.areAutoboxEquivalents(Integer.class.getName(), int.class.getName()));
-		assertFalse(ClassName.areAutoboxEquivalents(int.class.getName(), Boolean.class.getName()));
-		assertTrue(ClassName.areAutoboxEquivalents(String.class.getName(), String.class.getName()));
-	}
-
-	public void testForCode() {
-		assertEquals("byte", ClassName.forCode('B'));
-		assertEquals("char", ClassName.forCode('C'));
-		assertEquals("double", ClassName.forCode('D'));
-		assertEquals("float", ClassName.forCode('F'));
-		assertEquals("int", ClassName.forCode('I'));
-		assertEquals("long", ClassName.forCode('J'));
-		assertEquals("short", ClassName.forCode('S'));
-		assertEquals("boolean", ClassName.forCode('Z'));
-		assertEquals("void", ClassName.forCode('V'));
-
-		assertNull(ClassName.forCode('X'));
-
-		assertEquals("byte", ClassName.forCode((int) 'B'));
-		assertEquals("char", ClassName.forCode((int) 'C'));
-		assertEquals("double", ClassName.forCode((int) 'D'));
-		assertEquals("float", ClassName.forCode((int) 'F'));
-		assertEquals("int", ClassName.forCode((int) 'I'));
-		assertEquals("long", ClassName.forCode((int) 'J'));
-		assertEquals("short", ClassName.forCode((int) 'S'));
-		assertEquals("boolean", ClassName.forCode((int) 'Z'));
-		assertEquals("void", ClassName.forCode((int) 'V'));
-
-		assertNull(ClassName.forCode((int) 'X'));
-	}
-
-	public void testGetCodeForClassName() {
-		assertEquals('I', ClassName.getCodeForClassName(int.class.getName()));
-		assertEquals('I', ClassName.getCodeForClassName("int"));
-		assertEquals('B', ClassName.getCodeForClassName(byte.class.getName()));
-		assertEquals('B', ClassName.getCodeForClassName("byte"));
-
-		assertEquals((char) 0, ClassName.getCodeForClassName(java.lang.Object.class.getName()));
-	}
-
-	public void testConstructor() {
-		boolean exCaught = false;
-		try {
-			Object at = ReflectionTools.newInstance(ClassName.class);
-			fail("bogus: " + at); //$NON-NLS-1$
-		} catch (RuntimeException ex) {
-			if (ex.getCause() instanceof InvocationTargetException) {
-				if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ClasspathTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ClasspathTests.java
deleted file mode 100644
index b665ffb..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ClasspathTests.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.ArrayTools;
-import org.eclipse.persistence.tools.utility.Classpath;
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.Tools;
-
-@SuppressWarnings("nls")
-public class ClasspathTests extends TestCase {
-	private static final String JAVA_HOME = System.getProperty("java.home");
-
-	public ClasspathTests(String name) {
-		super(name);
-	}
-
-	public void testCompressed() {
-		String path = "";
-
-		// no changes
-		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
-		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
-
-		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
-		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
-
-		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
-		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
-
-		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar;C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
-		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
-
-		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\i18n.jar;C:\\jdk\\i18n.jar;C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
-		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
-
-		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar;C:\\jdk\\rt.jar;;;;C:\\jdk\\jaws.jar;C:\\jdk\\jaws.jar;C:\\jdk\\rt.jar;;;")).compressed().getPath();
-		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
-
-		// no changes
-		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
-		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
-
-		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
-		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
-
-		path = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\..\\jdk\\i18n.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
-		assertEquals(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
-
-		path = new Classpath(this.morph("C:\\jdk1\\jdk2\\jdk3\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk1\\jdk2\\jdk3\\..\\..\\..\\jdk1\\jdk2\\jdk3\\i18n.jar;C:\\jdk\\jaws.jar")).compressed().getPath();
-		assertEquals(this.morph("C:\\jdk1\\jdk2\\jdk3\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar"), path);
-
-	}
-
-	public void testConvertToClassName() {
-		String fileName = "java/lang/String.class";
-		File file = new File(fileName);
-		String className = Classpath.convertToClassName(file);
-		assertEquals(java.lang.String.class.getName(), className);
-	}
-
-	public void testConvertToClass() throws ClassNotFoundException {
-		String fileName = "java/lang/String.class";
-		File file = new File(fileName);
-		Class<?> javaClass = Classpath.convertToClass(file);
-		assertEquals(java.lang.String.class, javaClass);
-	}
-
-	public void testConvertToArchiveClassFileEntryName() {
-		String fileName = Classpath.convertToArchiveClassFileEntryName(java.lang.String.class);
-		assertEquals("java/lang/String.class", fileName);
-	}
-
-	public void testConvertToArchiveEntryNameBase() {
-		String fileName = Classpath.convertToArchiveEntryNameBase(java.lang.String.class);
-		assertEquals("java/lang/String", fileName);
-	}
-
-	public void testConvertToClassFileName() {
-		char sc = File.separatorChar;
-		String fileName = Classpath.convertToClassFileName(java.lang.String.class);
-		assertEquals("java" + sc + "lang" + sc + "String.class", fileName);
-	}
-
-	public void testConvertToClassFileString() {
-		char sc = File.separatorChar;
-		File file = Classpath.convertToClassFile(java.lang.String.class.getName());
-		assertEquals("java" + sc + "lang" + sc + "String.class", file.getPath());
-	}
-
-	public void testConvertToClassFileClass() {
-		char sc = File.separatorChar;
-		File file = Classpath.convertToClassFile(java.lang.String.class);
-		assertEquals("java" + sc + "lang" + sc + "String.class", file.getPath());
-	}
-
-	public void testConvertToJavaFileName() {
-		char sc = File.separatorChar;
-		String fileName = Classpath.convertToJavaFileName(java.lang.String.class);
-		assertEquals("java" + sc + "lang" + sc + "String.java", fileName);
-	}
-
-	public void testConvertToJavaFileString() {
-		char sc = File.separatorChar;
-		File file = Classpath.convertToJavaFile(java.lang.String.class.getName());
-		assertEquals("java" + sc + "lang" + sc + "String.java", file.getPath());
-	}
-
-	public void testConvertToJavaFileClass() {
-		char sc = File.separatorChar;
-		File file = Classpath.convertToJavaFile(java.lang.String.class);
-		assertEquals("java" + sc + "lang" + sc + "String.java", file.getPath());
-	}
-
-	public void testConvertToFileNameBase() {
-		char sc = File.separatorChar;
-		String fileName = Classpath.convertToFileNameBase(java.lang.String.class);
-		assertEquals("java" + sc + "lang" + sc + "String", fileName);
-	}
-
-	public void testConvertToURLs() {
-		Iterator<URL> entries = new Classpath(this.morph("C:\\jdk\\rt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar")).getURLs().iterator();
-		assertEquals(this.morphURL("/C:/jdk/rt.jar"), entries.next().getPath());
-		assertEquals(this.morphURL("/C:/jdk/i18n.jar"), entries.next().getPath());
-		assertEquals(this.morphURL("/C:/jdk/jaws.jar"), entries.next().getPath());
-		assertEquals(this.morphURL("/C:/foo/classes"), entries.next().getPath());
-		assertEquals(this.morphURL("/C:/bar/bar.jar"), entries.next().getPath());
-		assertFalse(entries.hasNext());
-	}
-
-	public void testGetEntries() {
-		Classpath cp = new Classpath(this.morph("C:\\jdk\\rt.jar;;.;C:\\jdk\\i18n.jar;;;C:\\jdk\\jaws.jar;;C:\\foo\\classes;C:\\bar\\bar.jar;C:\\bar\\bar.jar;"));
-		Iterator<Classpath.Entry> entries = cp.getEntries().iterator();
-		assertEquals(this.morph("C:\\jdk\\rt.jar"), entries.next().getFileName());
-		assertEquals(this.morph("."), entries.next().getFileName());
-		assertEquals(this.morph("C:\\jdk\\i18n.jar"), entries.next().getFileName());
-		assertEquals(this.morph("C:\\jdk\\jaws.jar"), entries.next().getFileName());
-		assertEquals(this.morph("C:\\foo\\classes"), entries.next().getFileName());
-		assertEquals(this.morph("C:\\bar\\bar.jar"), entries.next().getFileName());
-		assertEquals(this.morph("C:\\bar\\bar.jar"), entries.next().getFileName());
-		assertFalse(entries.hasNext());
-
-		cp = cp.compressed();
-		entries = cp.getEntries().iterator();
-		assertEquals(this.morph("C:\\jdk\\rt.jar"), entries.next().getFileName());
-		assertEquals(this.morph("."), entries.next().getFileName());
-		assertEquals(this.morph("C:\\jdk\\i18n.jar"), entries.next().getFileName());
-		assertEquals(this.morph("C:\\jdk\\jaws.jar"), entries.next().getFileName());
-		assertEquals(this.morph("C:\\foo\\classes"), entries.next().getFileName());
-		assertEquals(this.morph("C:\\bar\\bar.jar"), entries.next().getFileName());
-		assertFalse(entries.hasNext());
-	}
-
-	public void testGetEntryForFileNamed() {
-		Classpath.Entry entry = null;
-
-		// in the middle - qualified
-		entry = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\rt.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar")).getEntryForFileNamed("rt.jar");
-		assertEquals(this.morph("C:\\jdk\\rt.jar"), entry.getFileName());
-
-		// in the middle - unqualified
-		entry = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;rt.jar;C:\\foo\\classes;C:\\bar\\bar.jar")).getEntryForFileNamed("rt.jar");
-		assertEquals("rt.jar", entry.getFileName());
-
-		// at the beginning - qualified
-		entry = new Classpath(this.morph("C:\\jdk\\rt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar")).getEntryForFileNamed("rt.jar");
-		assertEquals(this.morph("C:\\jdk\\rt.jar"), entry.getFileName());
-
-		// at the beginning - unqualified
-		entry = new Classpath(this.morph("rt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar")).getEntryForFileNamed("rt.jar");
-		assertEquals("rt.jar", entry.getFileName());
-
-		// at the end - qualified
-		entry = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar;C:\\jdk\\rt.jar")).getEntryForFileNamed("rt.jar");
-		assertEquals(this.morph("C:\\jdk\\rt.jar"), entry.getFileName());
-
-		// at the end - unqualified
-		entry = new Classpath(this.morph("C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar;rt.jar")).getEntryForFileNamed("rt.jar");
-		assertEquals("rt.jar", entry.getFileName());
-
-		// alone - qualified
-		entry = new Classpath(this.morph("C:\\jdk\\rt.jar")).getEntryForFileNamed("rt.jar");
-		assertEquals(this.morph("C:\\jdk\\rt.jar"), entry.getFileName());
-
-		// alone - unqualified
-		entry = new Classpath("rt.jar").getEntryForFileNamed("rt.jar");
-		assertEquals("rt.jar", entry.getFileName());
-
-		// trick entry at the beginning
-		entry = new Classpath(this.morph("rt.jar.new;C:\\jdk\\rt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar")).getEntryForFileNamed("rt.jar");
-		assertEquals(this.morph("C:\\jdk\\rt.jar"), entry.getFileName());
-
-		// trick entry in the middle
-		entry = new Classpath(this.morph("rt.jar.new;C:\\jdk\\rtrtrt.jar;C:\\jdk\\rt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar")).getEntryForFileNamed("rt.jar");
-		assertEquals(this.morph("C:\\jdk\\rt.jar"), entry.getFileName());
-
-		// trick entry at the end
-		entry = new Classpath(this.morph("rt.jar.new;C:\\jdk\\rtrtrt.jar;C:\\jdk\\rt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar;C:\\jdk\\rtrtrt.jar")).getEntryForFileNamed("rt.jar");
-		assertEquals(this.morph("C:\\jdk\\rt.jar"), entry.getFileName());
-
-		// missing
-		entry = new Classpath(this.morph("rt.jar.new;C:\\jdk\\rtrtrt.jar;C:\\jdk\\i18n.jar;C:\\jdk\\jaws.jar;C:\\foo\\classes;C:\\bar\\bar.jar;C:\\jdk\\rtrtrt.jar")).getEntryForFileNamed("rt.jar");
-		assertEquals("path entry should not be found", null, entry);
-
-	}
-
-	public void testGetEntryForClassNamed() {
-		assertNotNull(Classpath.completeClasspath().getEntryForClassNamed(java.lang.String.class.getName()));
-		assertNull(Classpath.completeClasspath().getEntryForClassNamed("foo.bar.Baz"));
-	}
-
-	public void testLocationForClass() {
-		Class<?> javaClass = Classpath.class;
-		File entry = new File(Classpath.locationFor(javaClass));
-		if (entry.isFile() || entry.isDirectory()) {
-			assertTrue(entry.exists());
-		}
-		if (entry.isDirectory()) {
-			assertTrue(new File(entry, Classpath.convertToClassFileName(javaClass)).exists());
-		}
-	}
-
-	public void testRtJarName() throws IOException {
-		File rtFile = new File(Classpath.rtJarName());
-		assertTrue("rt.jar does not exist", rtFile.exists());
-
-		JarFile rtJarFile = new JarFile(rtFile);
-		JarEntry entry = rtJarFile.getJarEntry("java/lang/Object.class");
-		rtJarFile.close();
-		assertTrue("bogus rt.jar", entry != null);
-	}
-
-	public void testJREClassNames() {
-		assertTrue("Vector is missing from JRE class names", CollectionTools.contains(Classpath.bootClasspath().getClassNames(), java.util.Vector.class.getName()));
-		assertTrue("File is missing from JRE class names", CollectionTools.contains(Classpath.bootClasspath().getClassNames(), java.io.File.class.getName()));
-	}
-
-	public void testJavaExtensionDirectoryNames() {
-		char sep = File.separatorChar;
-		String stdExtDirName = JAVA_HOME + sep + "lib" + sep + "ext";
-		assertTrue("standard extension dir name missing: " + stdExtDirName, ArrayTools.contains(Classpath.javaExtensionDirectoryNames(), stdExtDirName));
-	}
-
-	public void testJavaExtensionDirectories() {
-		char sep = File.separatorChar;
-		File stdExtDir = new File(JAVA_HOME + sep + "lib" + sep + "ext");
-		assertTrue("standard extension dir missing: " + stdExtDir.getParent(), ArrayTools.contains(Classpath.javaExtensionDirectories(), stdExtDir));
-	}
-
-	public void testJavaExtensionClasspathEntries() {
-		char sep = File.separatorChar;
-		String jdk = System.getProperty("java.version");
-		if (jdk.startsWith("1.4") || jdk.startsWith("1.5") || jdk.startsWith("1.6")) {
-			Collection<String> jarNames = new ArrayList<String>();
-			Iterable<Classpath.Entry> entries = Classpath.javaExtensionClasspath().getEntries();
-			for (Classpath.Entry entry : entries) {
-				jarNames.add(entry.getFileName());
-			}
-			String stdExtJarName = JAVA_HOME + sep + "lib" + sep + "ext" + sep + "dnsns.jar";
-			String msg = "jdk 1.4.x standard extension jar missing: " + stdExtJarName;
-			boolean jarPresent = jarNames.contains(stdExtJarName);
-			if (Tools.jvmIsSun() || (Tools.jvmIsIBM() && jdk.startsWith("1.6"))) {
-				assertTrue(msg, jarPresent);
-			}
-		} else {
-			fail("we need to update this test for the current jdk");
-		}
-	}
-
-	public void testJavaExtensionClassNames() {
-		String jdk = System.getProperty("java.version");
-		if (jdk.startsWith("1.4") || jdk.startsWith("1.5") || jdk.startsWith("1.6")) {
-			String className = "sun.net.spi.nameservice.dns.DNSNameService";
-			String msg = "jdk 1.4.x standard extension class missing: " + className;
-			boolean classPresent = CollectionTools.contains(Classpath.javaExtensionClasspath().classNames(), className);
-			if (Tools.jvmIsSun() || (Tools.jvmIsIBM() && jdk.startsWith("1.6"))) {
-				assertTrue(msg, classPresent);
-			}
-		} else {
-			fail("we need to update this test for the current jdk");
-		}
-	}
-
-	public void testJavaClasspathClassNames() {
-		String className = this.getClass().getName();
-		ClassLoader cl = this.getClass().getClassLoader();
-		// make sure we are running under the "normal" class loader;
-		// when the tests are executed as an ANT task, they are run under
-		// an ANT class loader and the "Java" classpath does not include this class
-		if (cl.getClass().getName().startsWith("sun.misc")) {
-			assertTrue("class missing: " + className, CollectionTools.contains(Classpath.javaClasspath().getClassNames(), className));
-		}
-	}
-
-	public void testCompleteClasspathClassNames() {
-		String className = this.getClass().getName();
-		ClassLoader cl = this.getClass().getClassLoader();
-		// make sure we are running under the "normal" class loader;
-		// when the tests are executed as an ANT task, they are run under
-		// an ANT class loader and the "Java" classpath does not include this class
-		if (cl.getClass().getName().startsWith("sun.misc")) {
-			assertTrue("class missing: " + className, CollectionTools.contains(Classpath.completeClasspath().getClassNames(), className));
-		}
-	}
-
-	public void testClasspathForClass() {
-		assertNotNull(Classpath.classpathFor(java.lang.String.class));
-	}
-
-	public void testAddClassNamesTo() {
-		Collection<String> classNames = new ArrayList<String>(1000);
-		Classpath.bootClasspath().addClassNamesTo(classNames);
-		assertTrue(classNames.contains(java.util.Vector.class.getName()));
-	}
-
-	public void testToString() {
-		assertNotNull(Classpath.bootClasspath().toString());
-	}
-
-	public void testEntry_getCanonicalFile() {
-		Classpath.Entry entry = Classpath.bootClasspath().getEntryForClassNamed(java.lang.String.class.getName());
-		assertTrue(entry.getCanonicalFile().getPath().endsWith(".jar"));
-	}
-
-	public void testEntry_getCanonicalFileName() {
-		Classpath.Entry entry = Classpath.bootClasspath().getEntryForClassNamed(java.lang.String.class.getName());
-		String name = entry.getCanonicalFileName();
-		if (Tools.jvmIsSun()) {
-			assertTrue(name.endsWith("rt.jar"));
-		} else if (Tools.jvmIsIBM()) {
-			assertTrue(name.endsWith("vm.jar"));
-		}
-	}
-
-	public void testEntry_equals() {
-		Classpath.Entry entry = Classpath.bootClasspath().getEntryForClassNamed(java.lang.String.class.getName());
-		assertFalse(entry.equals("foo"));
-	}
-
-	public void testEntry_containsClass() {
-		Classpath.Entry entry = Classpath.bootClasspath().getEntryForClassNamed(java.lang.String.class.getName());
-		assertTrue(entry.contains(java.lang.String.class));
-	}
-
-	public void testEntry_containsString() {
-		Classpath.Entry entry = Classpath.bootClasspath().getEntryForClassNamed(java.lang.String.class.getName());
-		assertTrue(entry.contains(java.lang.String.class.getName()));
-	}
-
-	public void testEntry_getClassNames() {
-		Classpath.Entry entry = Classpath.bootClasspath().getEntryForClassNamed(java.lang.String.class.getName());
-		assertTrue(CollectionTools.contains(entry.getClassNames(), java.lang.String.class.getName()));
-	}
-
-	public void testEntry_classNames() {
-		Classpath.Entry entry = Classpath.bootClasspath().getEntryForClassNamed(java.lang.String.class.getName());
-		assertTrue(CollectionTools.contains(entry.classNames(), java.lang.String.class.getName()));
-	}
-
-	/**
-	 * morph the specified path to a platform-independent path
-	 */
-	private String morph(String path) {
-		String result = path;
-		result = result.replace('\\', File.separatorChar);
-		result = result.replace(';', File.pathSeparatorChar);
-		if (!ArrayTools.contains(File.listRoots(), new File("C:\\"))) {
-			result = result.replaceAll("C:", "");
-		}
-		return result;
-	}
-
-	/**
-	 * morph the specified URL to a platform-independent path
-	 */
-	private String morphURL(String url) {
-		String result = url;
-		if (!ArrayTools.contains(File.listRoots(), new File("C:\\"))) {
-			result = result.replaceAll("/C:", "");
-		}
-		return result;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/CollectionToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/CollectionToolsTests.java
deleted file mode 100644
index bfdfc63..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/CollectionToolsTests.java
+++ /dev/null
@@ -1,2422 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-import java.util.Random;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.Vector;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.Bag;
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.HashBag;
-import org.eclipse.persistence.tools.utility.Range;
-import org.eclipse.persistence.tools.utility.ReflectionTools;
-import org.eclipse.persistence.tools.utility.ReverseComparator;
-import org.eclipse.persistence.tools.utility.enumerations.EmptyEnumeration;
-import org.eclipse.persistence.tools.utility.iterables.EmptyIterable;
-import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
-import org.eclipse.persistence.tools.utility.iterators.EmptyIterator;
-
-@SuppressWarnings("nls")
-public class CollectionToolsTests extends TestCase {
-
-	public CollectionToolsTests(String name) {
-		super(name);
-	}
-
-
-	// ********** add all **********
-
-	public void testAddAllCollectionIterable_StringModified() {
-		List<String> list1 = this.buildStringList1();
-		Iterable<String> iterable2 = this.buildStringList2();
-		assertTrue(CollectionTools.addAll(list1, iterable2.iterator()));
-		assertEquals(6, list1.size());
-		assertTrue(list1.containsAll(this.buildStringList2()));
-	}
-
-	public void testAddAllCollectionIterable_StringUnmodified() {
-		Set<String> set1 = this.buildStringSet1();
-		Iterable<String> iterable3 = this.buildStringList1(); // same elements as set1
-		assertFalse(CollectionTools.addAll(set1, iterable3.iterator()));
-		assertEquals(3, set1.size());
-		assertTrue(set1.containsAll(this.buildStringList1()));
-	}
-
-	public void testAddAllCollectionIterable_ObjectModified() {
-		List<Object> list1 = this.buildObjectList1();
-		Iterable<String> iterable2 = this.buildStringList2();
-		assertTrue(CollectionTools.addAll(list1, iterable2));
-		assertEquals(6, list1.size());
-		assertTrue(list1.containsAll((List<String>) iterable2));
-	}
-
-	public void testAddAllCollectionIterable_ObjectUnmodified() {
-		Set<Object> set1 = this.buildObjectSet1();
-		Iterable<String> iterable3 = this.buildStringList1(); // same elements as set1
-		assertFalse(CollectionTools.addAll(set1, iterable3));
-		assertEquals(3, set1.size());
-		assertTrue(set1.containsAll((List<String>) iterable3));
-	}
-
-	public void testAddAllCollectionIterable_EmptyIterable() {
-		Set<Object> set1 = this.buildObjectSet1();
-		assertFalse(CollectionTools.addAll(set1, EmptyIterable.instance()));
-		assertEquals(3, set1.size());
-	}
-
-	public void testAddAllCollectionIterableInt_Modified() {
-		List<String> list1 = this.buildStringList1();
-		List<String> list2 = this.buildStringList2();
-		Iterable<String> iterable2 = list2;
-		assertTrue(CollectionTools.addAll(list1, iterable2, list2.size()));
-		assertEquals(6, list1.size());
-		assertTrue(list1.containsAll(this.buildStringList2()));
-	}
-
-	public void testAddAllCollectionIterableInt_Unmodified() {
-		Set<String> set1 = this.buildStringSet1();
-		List<String> list1 = this.buildStringList1(); // same elements as set1
-		Iterable<String> iterable3 = list1;
-		assertFalse(CollectionTools.addAll(set1, iterable3, list1.size()));
-		assertEquals(3, set1.size());
-		assertTrue(set1.containsAll(this.buildStringList1()));
-	}
-
-	public void testAddAllCollectionIterator_StringModified() {
-		List<String> list1 = this.buildStringList1();
-		List<String> list2 = this.buildStringList2();
-		assertTrue(CollectionTools.addAll(list1, list2.iterator()));
-		assertEquals(6, list1.size());
-		assertTrue(list1.containsAll(list2));
-	}
-
-	public void testAddAllCollectionIterator_StringUnmodified() {
-		Set<String> set1 = this.buildStringSet1();
-		List<String> list3 = this.buildStringList1(); // same elements as s1
-		assertFalse(CollectionTools.addAll(set1, list3.iterator()));
-		assertEquals(3, set1.size());
-		assertTrue(set1.containsAll(list3));
-	}
-
-	public void testAddAllCollectionIterator_ObjectModified() {
-		List<Object> list1 = this.buildObjectList1();
-		List<String> list2 = this.buildStringList2();
-		assertTrue(CollectionTools.addAll(list1, list2.iterator()));
-		assertEquals(6, list1.size());
-		assertTrue(list1.containsAll(list2));
-	}
-
-	public void testAddAllCollectionIterator_ObjectUnmodified() {
-		Set<Object> set1 = this.buildObjectSet1();
-		List<String> list3 = this.buildStringList1(); // same elements as s1
-		assertFalse(CollectionTools.addAll(set1, list3.iterator()));
-		assertEquals(3, set1.size());
-		assertTrue(set1.containsAll(list3));
-	}
-
-	public void testAddAllCollectionIterator_EmptyIterator() {
-		List<String> list1 = this.buildStringList1();
-		assertFalse(CollectionTools.addAll(list1, EmptyIterator.<String>instance()));
-		assertEquals(3, list1.size());
-	}
-
-	public void testAddAllCollectionIteratorInt_Modified() {
-		List<String> list1 = this.buildStringList1();
-		List<String> list2 = this.buildStringList2();
-		assertTrue(CollectionTools.addAll(list1, list2.iterator(), 3));
-		assertEquals(6, list1.size());
-		assertTrue(list1.containsAll(list2));
-	}
-
-	public void testAddAllCollectionIteratorInt_Unmodified() {
-		Set<String> set1 = this.buildStringSet1();
-		List<String> list3 = this.buildStringList1(); // same elements as s1
-		assertFalse(CollectionTools.addAll(set1, list3.iterator(), 3));
-		assertEquals(3, set1.size());
-		assertTrue(set1.containsAll(list3));
-	}
-
-	public void testAddAllCollectionIteratorInt_EmptyIterator() {
-		List<String> list1 = this.buildStringList1();
-		assertFalse(CollectionTools.addAll(list1, EmptyIterator.<String>instance(), 0));
-		assertEquals(3, list1.size());
-	}
-
-	public void testAddAllCollectionObjectArray_StringModified() {
-		List<String> list = this.buildStringList1();
-		String[] a = this.buildStringArray1();
-		assertTrue(CollectionTools.addAll(list, a));
-		assertEquals(6, list.size());
-		assertTrue(list.containsAll(CollectionTools.collection(a)));
-	}
-
-	public void testAddAllCollectionObjectArray_StringListEmptyArray() {
-		List<String> list = this.buildStringList1();
-		assertFalse(CollectionTools.addAll(list, new String[0]));
-	}
-
-	public void testAddAllCollectionObjectArray_StringUnmodified() {
-		Set<String> set = this.buildStringSet1();
-		String[] a = this.buildStringArray1();
-		assertFalse(CollectionTools.addAll(set, a));
-		assertEquals(3, set.size());
-		assertTrue(set.containsAll(CollectionTools.collection(a)));
-
-		assertFalse(CollectionTools.addAll(set, new String[0]));
-	}
-
-	public void testAddAllCollectionObjectArray_StringSetEmptyArray() {
-		Set<String> set = this.buildStringSet1();
-		assertFalse(CollectionTools.addAll(set, new String[0]));
-	}
-
-	public void testAddAllCollectionObjectArray_ObjectModified() {
-		List<Object> list = this.buildObjectList1();
-		String[] a = this.buildStringArray1();
-
-		assertTrue(CollectionTools.addAll(list, a));
-		assertEquals(6, list.size());
-		assertTrue(list.containsAll(CollectionTools.collection(a)));
-	}
-
-	public void testAddAllCollectionObjectArray_ObjectUnmodified() {
-		String[] a = this.buildStringArray1();
-		Set<Object> set = this.buildObjectSet1();
-		assertFalse(CollectionTools.addAll(set, a));
-		assertEquals(3, set.size());
-		assertTrue(set.containsAll(CollectionTools.collection(a)));
-	}
-
-	public void testAddAllListIntObjectArray() {
-		List<String> list = this.buildStringList1();
-		CollectionTools.addAll(list, 2, new String[] { "X", "X", "X" });
-		assertEquals(6, list.size());
-		assertTrue(list.contains("X"));
-		assertTrue(Arrays.equals(new Object[] { "zero", "one", "X", "X", "X", "two" }, list.toArray()));
-	}
-
-	public void testAddAllListIntObjectArray_Zero() {
-		List<String> list = new ArrayList<String>();
-		CollectionTools.addAll(list, 0, new String[] { "X", "X", "X" });
-		assertEquals(3, list.size());
-		assertTrue(list.contains("X"));
-		assertTrue(Arrays.equals(new Object[] { "X", "X", "X" }, list.toArray()));
-	}
-
-	public void testAddAllListIntObjectArray_EmptyArray() {
-		List<String> list = this.buildStringList1();
-		CollectionTools.addAll(list, 2, new String[0]);
-		assertEquals(3, list.size());
-		assertTrue(Arrays.equals(new Object[] { "zero", "one", "two" }, list.toArray()));
-	}
-
-	public void testAddAllListIntIterable() {
-		List<String> list = this.buildStringList1();
-		Iterable<String> iterable = Arrays.asList(new String[] { "X", "X", "X" });
-		CollectionTools.addAll(list, 2, iterable);
-		assertEquals(6, list.size());
-		assertTrue(list.contains("X"));
-		assertTrue(Arrays.equals(new Object[] { "zero", "one", "X", "X", "X", "two" }, list.toArray()));
-	}
-
-	public void testAddAllListIntIterable_Zero() {
-		List<String> list = new ArrayList<String>();
-		Iterable<String> iterable = Arrays.asList(new String[] { "X", "X", "X" });
-		CollectionTools.addAll(list, 0, iterable);
-		assertEquals(3, list.size());
-		assertTrue(list.contains("X"));
-		assertTrue(Arrays.equals(new Object[] { "X", "X", "X" }, list.toArray()));
-	}
-
-	public void testAddAllListIntIterable_EmptyIterable() {
-		List<String> list = this.buildStringList1();
-		Iterable<String> iterable = EmptyIterable.instance();
-		CollectionTools.addAll(list, 2, iterable);
-		assertEquals(3, list.size());
-		assertTrue(Arrays.equals(new Object[] { "zero", "one", "two" }, list.toArray()));
-	}
-
-	public void testAddAllListIntIterableInt() {
-		List<String> list = this.buildStringList1();
-		Iterable<String> iterable = Arrays.asList(new String[] { "X", "X", "X" });
-		CollectionTools.addAll(list, 2, iterable, 3);
-		assertEquals(6, list.size());
-		assertTrue(list.contains("X"));
-		assertTrue(Arrays.equals(new Object[] { "zero", "one", "X", "X", "X", "two" }, list.toArray()));
-	}
-
-	public void testAddAllListIntIterableInt_Zero() {
-		List<String> list = new ArrayList<String>();
-		Iterable<String> iterable = Arrays.asList(new String[] { "X", "X", "X" });
-		CollectionTools.addAll(list, 0, iterable, 3);
-		assertEquals(3, list.size());
-		assertTrue(list.contains("X"));
-		assertTrue(Arrays.equals(new Object[] { "X", "X", "X" }, list.toArray()));
-	}
-
-	public void testAddAllListIntIterableInt_EmptyIterable() {
-		List<String> list = this.buildStringList1();
-		Iterable<String> iterable = EmptyIterable.instance();
-		CollectionTools.addAll(list, 2, iterable, 0);
-		assertEquals(3, list.size());
-		assertTrue(Arrays.equals(new Object[] { "zero", "one", "two" }, list.toArray()));
-	}
-
-	public void testAddAllListIntIterator() {
-		List<String> list = this.buildStringList1();
-		Iterator<String> iterator = Arrays.asList(new String[] { "X", "X", "X" }).iterator();
-		CollectionTools.addAll(list, 2, iterator);
-		assertEquals(6, list.size());
-		assertTrue(list.contains("X"));
-		assertTrue(Arrays.equals(new Object[] { "zero", "one", "X", "X", "X", "two" }, list.toArray()));
-	}
-
-	public void testAddAllListIntIterator_Zero() {
-		List<String> list = new ArrayList<String>();
-		Iterator<String> iterator = Arrays.asList(new String[] { "X", "X", "X" }).iterator();
-		CollectionTools.addAll(list, 0, iterator);
-		assertEquals(3, list.size());
-		assertTrue(list.contains("X"));
-		assertTrue(Arrays.equals(new Object[] { "X", "X", "X" }, list.toArray()));
-	}
-
-	public void testAddAllListIntIterator_EmptyIterator() {
-		List<String> list = this.buildStringList1();
-		Iterator<String> iterator = EmptyIterator.instance();
-		CollectionTools.addAll(list, 2, iterator);
-		assertEquals(3, list.size());
-		assertTrue(Arrays.equals(new Object[] { "zero", "one", "two" }, list.toArray()));
-	}
-
-	public void testAddAllListIntIteratorInt() {
-		List<String> list = this.buildStringList1();
-		Iterator<String> iterator = Arrays.asList(new String[] { "X", "X", "X" }).iterator();
-		CollectionTools.addAll(list, 2, iterator, 3);
-		assertEquals(6, list.size());
-		assertTrue(list.contains("X"));
-		assertTrue(Arrays.equals(new Object[] { "zero", "one", "X", "X", "X", "two" }, list.toArray()));
-	}
-
-	public void testAddAllListIntIteratorInt_Zero() {
-		List<String> list = new ArrayList<String>();
-		Iterator<String> iterator = Arrays.asList(new String[] { "X", "X", "X" }).iterator();
-		CollectionTools.addAll(list, 0, iterator, 3);
-		assertEquals(3, list.size());
-		assertTrue(list.contains("X"));
-		assertTrue(Arrays.equals(new Object[] { "X", "X", "X" }, list.toArray()));
-	}
-
-	public void testAddAllListIntIteratorInt_EmptyIterator() {
-		List<String> list = this.buildStringList1();
-		Iterator<String> iterator = EmptyIterator.instance();
-		CollectionTools.addAll(list, 2, iterator, 0);
-		assertEquals(3, list.size());
-		assertTrue(Arrays.equals(new Object[] { "zero", "one", "two" }, list.toArray()));
-	}
-
-
-	// ********** bag **********
-
-	public void testBagEnumeration_String() {
-		Bag<String> b = CollectionTools.bag(this.buildStringVector1().elements());
-		assertEquals(3, b.size());
-		assertTrue(b.containsAll(this.buildStringVector1()));
-	}
-
-	public void testBagEnumeration_Object() {
-		Bag<Object> b = CollectionTools.<Object>bag(this.buildStringVector1().elements());
-		assertEquals(3, b.size());
-		assertTrue(b.containsAll(this.buildStringVector1()));
-	}
-
-	public void testBagEnumeration_Empty() {
-		Bag<Object> b = CollectionTools.<Object>bag(EmptyEnumeration.instance());
-		assertEquals(0, b.size());
-	}
-
-	public void testBagEnumerationInt() {
-		Bag<String> b = CollectionTools.bag(this.buildStringVector1().elements(), 3);
-		assertEquals(3, b.size());
-		assertTrue(b.containsAll(this.buildStringVector1()));
-	}
-
-	public void testBagEnumerationInt_Empty() {
-		Bag<String> b = CollectionTools.bag(EmptyEnumeration.<String>instance(), 3);
-		assertEquals(0, b.size());
-	}
-
-	public void testBagIterable() {
-		Iterable<String> iterable = this.buildStringList1();
-		Bag<String> b = CollectionTools.bag(iterable);
-		assertEquals(3, b.size());
-		assertTrue(b.containsAll(this.buildStringList1()));
-	}
-
-	public void testBagIterableInt() {
-		Iterable<String> iterable = this.buildStringList1();
-		Bag<String> b = CollectionTools.bag(iterable, 3);
-		assertEquals(3, b.size());
-		assertTrue(b.containsAll(this.buildStringList1()));
-	}
-
-	public void testBagIterator_String() {
-		Bag<String> b = CollectionTools.bag(this.buildStringList1().iterator());
-		assertEquals(3, b.size());
-		assertTrue(b.containsAll(this.buildStringList1()));
-	}
-
-	public void testBagIterator_StringObject() {
-		Collection<String> c = new ArrayList<String>();
-		c.add("zero");
-		c.add("one");
-		c.add("two");
-		c.add("three");
-		Bag<Object> b = CollectionTools.<Object>bag(c.iterator());
-		assertEquals(4, b.size());
-		assertTrue(b.containsAll(c));
-	}
-
-	public void testBagIterator_Empty() {
-		Bag<String> b = CollectionTools.bag(EmptyIterator.<String>instance());
-		assertEquals(0, b.size());
-	}
-
-	public void testBagIteratorInt() {
-		Bag<String> b = CollectionTools.bag(this.buildStringList1().iterator(), 3);
-		assertEquals(3, b.size());
-		assertTrue(b.containsAll(this.buildStringList1()));
-	}
-
-	public void testBagIteratorInt_Empty() {
-		Bag<String> b = CollectionTools.bag(EmptyIterator.<String>instance(), 3);
-		assertEquals(0, b.size());
-	}
-
-	public void testBagObjectArray() {
-		Bag<String> b = CollectionTools.bag(this.buildStringArray1());
-		assertEquals(3, b.size());
-		assertTrue(CollectionTools.containsAll(b, (Object[]) this.buildStringArray1()));
-	}
-
-	public void testBagObjectArray_Vararg() {
-		Bag<String> b = CollectionTools.bag("foo", "bar", "baz");
-		assertEquals(3, b.size());
-		assertTrue(CollectionTools.containsAll(b, new Object[]{"foo", "bar", "baz"}));
-	}
-
-	public void testBagObjectArray_Empty() {
-		Bag<String> b = CollectionTools.bag(Bag.Empty.<String>instance());
-		assertEquals(0, b.size());
-	}
-
-
-	// ********** collection **********
-
-	public void testCollectionEnumeration() {
-		Collection<String> c = CollectionTools.collection(this.buildStringVector1().elements());
-		assertEquals(3, c.size());
-		assertTrue(c.containsAll(this.buildStringVector1()));
-	}
-
-	public void testCollectionEnumeration_ObjectString() {
-		Collection<Object> c = CollectionTools.<Object>collection(this.buildStringVector1().elements());
-		assertEquals(3, c.size());
-		assertTrue(c.containsAll(this.buildStringVector1()));
-	}
-
-	public void testCollectionEnumerationInt() {
-		Collection<String> c = CollectionTools.collection(this.buildStringVector1().elements(), 3);
-		assertEquals(3, c.size());
-		assertTrue(c.containsAll(this.buildStringVector1()));
-	}
-
-	public void testCollectionIterable() {
-		Iterable<String> iterable = this.buildStringList1();
-		Collection<String> c = CollectionTools.collection(iterable);
-		assertEquals(3, c.size());
-		assertTrue(c.containsAll(this.buildStringList1()));
-	}
-
-	public void testCollectionIterableInt() {
-		Iterable<String> iterable = this.buildStringList1();
-		Collection<String> c = CollectionTools.collection(iterable, 3);
-		assertEquals(3, c.size());
-		assertTrue(c.containsAll(this.buildStringList1()));
-	}
-
-	public void testCollectionIterator() {
-		Collection<String> c = CollectionTools.collection(this.buildStringList1().iterator());
-		assertEquals(3, c.size());
-		assertTrue(c.containsAll(this.buildStringList1()));
-	}
-
-	public void testCollectionIterator_ObjectString() {
-		Collection<Object> c = CollectionTools.<Object>collection(this.buildStringList1().iterator());
-		assertEquals(3, c.size());
-		assertTrue(c.containsAll(this.buildStringList1()));
-	}
-
-	public void testCollectionIteratorInt() {
-		Collection<String> c = CollectionTools.collection(this.buildStringList1().iterator(), 3);
-		assertEquals(3, c.size());
-		assertTrue(c.containsAll(this.buildStringList1()));
-	}
-
-	public void testCollectionObjectArray() {
-		Collection<String> c = CollectionTools.collection(this.buildStringArray1());
-		assertEquals(3, c.size());
-		assertTrue(CollectionTools.containsAll(c, (Object[]) this.buildStringArray1()));
-	}
-
-
-	// ********** contains **********
-
-	public void testContainsEnumerationObject_String() {
-		Vector<String> v = this.buildStringVector1();
-		assertTrue(CollectionTools.contains(v.elements(), "one"));
-		assertFalse(CollectionTools.contains(v.elements(), null));
-		v.add(null);
-		assertTrue(CollectionTools.contains(v.elements(), null));
-	}
-
-	public void testContainsEnumerationObject_Object() {
-		Vector<Object> c = new Vector<Object>();
-		c.add("zero");
-		c.add("one");
-		c.add("two");
-		c.add("three");
-		String one = "one";
-		assertTrue(CollectionTools.contains(c.elements(), one));
-		assertFalse(CollectionTools.contains(c.elements(), null));
-		c.add(null);
-		assertTrue(CollectionTools.contains(c.elements(), null));
-	}
-
-	public void testContainsIterableObject() {
-		Collection<String> c = this.buildStringList1();
-		Iterable<String> iterable = c;
-		assertTrue(CollectionTools.contains(iterable, "one"));
-		assertFalse(CollectionTools.contains(iterable, null));
-		c.add(null);
-		assertTrue(CollectionTools.contains(iterable, null));
-	}
-
-	public void testContainsIteratorObject_String() {
-		Collection<String> c = this.buildStringList1();
-		assertTrue(CollectionTools.contains(c.iterator(), "one"));
-		assertFalse(CollectionTools.contains(c.iterator(), null));
-		c.add(null);
-		assertTrue(CollectionTools.contains(c.iterator(), null));
-	}
-
-	public void testContainsIteratorObject_Object() {
-		Collection<Object> c = new HashBag<Object>();
-		c.add("zero");
-		c.add("one");
-		c.add("two");
-		c.add("three");
-		String one = "one";
-		assertTrue(CollectionTools.contains(c.iterator(), one));
-		assertFalse(CollectionTools.contains(c.iterator(), null));
-		c.add(null);
-		assertTrue(CollectionTools.contains(c.iterator(), null));
-	}
-
-
-	// ********** contains all **********
-
-	public void testContainsAllCollectionIterable() {
-		Iterable<String> iterable = this.buildStringList1();
-		assertTrue(CollectionTools.containsAll(this.buildStringList1(), iterable));
-	}
-
-	public void testContainsAllCollectionIterator_String() {
-		assertTrue(CollectionTools.containsAll(this.buildStringList1(), this.buildStringList1().iterator()));
-	}
-
-	public void testContainsAllCollectionIterator_Object() {
-		Collection<Object> c1 = new ArrayList<Object>();
-		c1.add("zero");
-		c1.add("one");
-		c1.add("two");
-		Collection<String> c2 = new ArrayList<String>();
-		c2.add("two");
-		c2.add("zero");
-		c2.add("one");
-		assertTrue(CollectionTools.containsAll(c1, c2.iterator()));
-	}
-
-	public void testContainsAllCollectionObjectArray_StringObject() {
-		assertTrue(CollectionTools.containsAll(this.buildStringList1(), this.buildObjectArray1()));
-	}
-
-	public void testContainsAllCollectionObjectArray() {
-		Object[] a = new Object[] { "zero", "one", "two" };
-		assertTrue(CollectionTools.containsAll(this.buildStringList1(), a));
-	}
-
-	public void testContainsAllIterableCollection() {
-		Iterable<String> iterable = this.buildStringList1();
-		assertTrue(CollectionTools.containsAll(iterable, this.buildStringList1()));
-	}
-
-	public void testContainsAllIterableIntCollection() {
-		Iterable<String> iterable = this.buildStringList1();
-		assertTrue(CollectionTools.containsAll(iterable, 3, this.buildStringList1()));
-	}
-
-	public void testContainsAllIterableIterable() {
-		Iterable<String> iterable1 = this.buildStringList1();
-		Iterable<String> iterable2 = this.buildStringList1();
-		assertTrue(CollectionTools.containsAll(iterable1, iterable2));
-	}
-
-	public void testContainsAllIterableIntIterable() {
-		Iterable<String> iterable1 = this.buildStringList1();
-		Iterable<String> iterable2 = this.buildStringList1();
-		assertTrue(CollectionTools.containsAll(iterable1, 3, iterable2));
-	}
-
-	public void testContainsAllIterableIterator() {
-		Iterable<String> iterable = this.buildStringList1();
-		assertTrue(CollectionTools.containsAll(iterable, this.buildStringList1().iterator()));
-	}
-
-	public void testContainsAllIterableIntIterator() {
-		Iterable<String> iterable = this.buildStringList1();
-		assertTrue(CollectionTools.containsAll(iterable, 3, this.buildStringList1().iterator()));
-	}
-
-	public void testContainsAllIterableObjectArray() {
-		Iterable<String> iterable = this.buildStringList1();
-		assertTrue(CollectionTools.containsAll(iterable, this.buildObjectArray1()));
-		iterable = this.buildStringList2();
-		assertFalse(CollectionTools.containsAll(iterable, this.buildObjectArray1()));
-	}
-
-	public void testContainsAllIterableIntObjectArray() {
-		Iterable<String> iterable = this.buildStringList1();
-		assertTrue(CollectionTools.containsAll(iterable, 3, this.buildObjectArray1()));
-		iterable = this.buildStringList2();
-		assertFalse(CollectionTools.containsAll(iterable, 3, this.buildObjectArray1()));
-	}
-
-	public void testContainsAllIteratorCollection_StringString() {
-		assertTrue(CollectionTools.containsAll(this.buildStringList1().iterator(), this.buildStringList1()));
-		assertFalse(CollectionTools.containsAll(this.buildStringList1().iterator(), this.buildStringList2()));
-	}
-
-	public void testContainsAllIteratorCollection_ObjectString() {
-		Collection<Object> c1 = new ArrayList<Object>();
-		c1.add("zero");
-		c1.add("one");
-		c1.add("two");
-		Collection<String> c2 = new ArrayList<String>();
-		c2.add("zero");
-		c2.add("one");
-		c2.add("two");
-		assertTrue(CollectionTools.containsAll(c1.iterator(), c2));
-	}
-
-	public void testContainsAllIteratorIntCollection() {
-		assertTrue(CollectionTools.containsAll(this.buildStringList1().iterator(), 5, this.buildStringList1()));
-		assertFalse(CollectionTools.containsAll(this.buildStringList1().iterator(), 5, this.buildStringList2()));
-	}
-
-	public void testContainsAllIteratorIterable() {
-		Iterable<String> iterable = this.buildStringList1();
-		assertTrue(CollectionTools.containsAll(this.buildStringList1().iterator(), iterable));
-		iterable = this.buildStringList2();
-		assertFalse(CollectionTools.containsAll(this.buildStringList1().iterator(), iterable));
-	}
-
-	public void testContainsAllIteratorIntIterable() {
-		Iterable<String> iterable = this.buildStringList1();
-		assertTrue(CollectionTools.containsAll(this.buildStringList1().iterator(), 3, iterable));
-		iterable = this.buildStringList2();
-		assertFalse(CollectionTools.containsAll(this.buildStringList1().iterator(), 3, iterable));
-	}
-
-	public void testContainsAllIteratorIterator_StringString() {
-		assertTrue(CollectionTools.containsAll(this.buildStringList1().iterator(), this.buildStringList1().iterator()));
-		assertFalse(CollectionTools.containsAll(this.buildStringList1().iterator(), this.buildStringList2().iterator()));
-	}
-
-	public void testContainsAllIteratorIterator_ObjectString() {
-		Collection<Object> c1 = new ArrayList<Object>();
-		c1.add("zero");
-		c1.add("one");
-		c1.add("two");
-		Collection<String> c2 = new ArrayList<String>();
-		c2.add("zero");
-		c2.add("one");
-		c2.add("two");
-		assertTrue(CollectionTools.containsAll(c1.iterator(), c2.iterator()));
-	}
-
-	public void testContainsAllIteratorIntIterator() {
-		assertTrue(CollectionTools.containsAll(this.buildStringList1().iterator(), 3, this.buildStringList1().iterator()));
-		assertFalse(CollectionTools.containsAll(this.buildStringList1().iterator(), 3, this.buildStringList2().iterator()));
-	}
-
-	public void testContainsAllIteratorObjectArray() {
-		assertTrue(CollectionTools.containsAll(this.buildStringList1().iterator(), this.buildObjectArray1()));
-		assertFalse(CollectionTools.containsAll(this.buildStringList1().iterator(), this.buildObjectArray2()));
-	}
-
-	public void testContainsAllIteratorIntObjectArray() {
-		assertTrue(CollectionTools.containsAll(this.buildStringList1().iterator(), 3, this.buildObjectArray1()));
-		assertFalse(CollectionTools.containsAll(this.buildStringList1().iterator(), 3, this.buildObjectArray2()));
-	}
-
-
-	// ********** diff **********
-
-	public void testDiffEndListList() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("a");
-		list1.add("b");
-		list1.add("c");
-		List<String> list2 = new ArrayList<String>();
-		list2.add(new String("a"));
-		list2.add(new String("b"));
-		list2.add(new String("c"));
-		assertEquals(-1, CollectionTools.diffEnd(list1, list2));
-	}
-
-	public void testDiffRangeListList() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("a");
-		list1.add("b");
-		list1.add("c");
-		List<String> list2 = new ArrayList<String>();
-		list2.add(new String("a"));
-		list2.add(new String("b"));
-		list2.add(new String("c"));
-		assertEquals(new Range(3, -1), CollectionTools.diffRange(list1, list2));
-	}
-
-	public void testDiffStartListList() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("a");
-		list1.add("b");
-		list1.add("c");
-		List<String> list2 = new ArrayList<String>();
-		list2.add(new String("a"));
-		list2.add(new String("b"));
-		list2.add(new String("c"));
-		assertEquals(3, CollectionTools.diffStart(list1, list2));
-	}
-
-
-	// ********** identity diff **********
-
-	public void testIdentityDiffEndListList() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("a");
-		list1.add("b");
-		list1.add("c");
-		List<String> list2 = new ArrayList<String>();
-		list2.add("a");
-		list2.add("b");
-		list2.add("c");
-		assertEquals(-1, CollectionTools.identityDiffEnd(list1, list2));
-	}
-
-	public void testIdentityDiffRangeListList() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("a");
-		list1.add("b");
-		list1.add("c");
-		List<String> list2 = new ArrayList<String>();
-		list2.add("a");
-		list2.add("b");
-		list2.add("c");
-		assertEquals(new Range(3, -1), CollectionTools.identityDiffRange(list1, list2));
-	}
-
-	public void testIdentityDiffStartListList() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("a");
-		list1.add("b");
-		list1.add("c");
-		List<String> list2 = new ArrayList<String>();
-		list2.add("a");
-		list2.add("b");
-		list2.add("c");
-		assertEquals(3, CollectionTools.identityDiffStart(list1, list2));
-	}
-
-
-	// ********** elements are equal **********
-
-	public void testElementsAreDifferentIterableIterable() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("1000");
-		list1.add("2000");
-		list1.add("3000");
-		list1.add("4000");
-
-		List<String> list2 = new ArrayList<String>();
-
-		assertTrue(CollectionTools.elementsAreDifferent(list1, list2));
-		assertFalse(CollectionTools.elementsAreEqual(list1, list2));
-	}
-
-	public void testElementsAreDifferentIteratorIterator() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("1000");
-		list1.add("2000");
-		list1.add("3000");
-		list1.add("4000");
-
-		List<String> list2 = new ArrayList<String>();
-
-		assertTrue(CollectionTools.elementsAreDifferent(list1.iterator(), list2.iterator()));
-		assertFalse(CollectionTools.elementsAreEqual(list1, list2));
-	}
-
-	public void testElementsAreEqualIterableIterable() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("1000");
-		list1.add("2000");
-		list1.add("3000");
-		list1.add("4000");
-
-		List<String> list2 = new ArrayList<String>();
-		for (int i = 0; i < list1.size(); i++) {
-			list2.add(String.valueOf((i + 1) * 1000));
-		}
-		assertFalse(CollectionTools.elementsAreIdentical(list1, list2));
-		assertFalse(CollectionTools.elementsAreDifferent(list1, list2));
-		assertTrue(CollectionTools.elementsAreEqual(list1, list2));
-	}
-
-	public void testElementsAreEqualIteratorIterator() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("1000");
-		list1.add("2000");
-		list1.add("3000");
-		list1.add("4000");
-
-		List<String> list2 = new ArrayList<String>();
-		for (int i = 0; i < list1.size(); i++) {
-			list2.add(String.valueOf((i + 1) * 1000));
-		}
-		assertFalse(CollectionTools.elementsAreIdentical(list1.iterator(), list2.iterator()));
-		assertFalse(CollectionTools.elementsAreDifferent(list1.iterator(), list2.iterator()));
-		assertTrue(CollectionTools.elementsAreEqual(list1.iterator(), list2.iterator()));
-	}
-
-
-	// ********** elements are identical **********
-
-	public void testElementsAreIdenticalIterableIterable() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("0");
-		list1.add("1");
-		list1.add("2");
-		list1.add("3");
-		Iterable<String> iterable1 = list1;
-
-		List<String> list2 = new ArrayList<String>();
-		for (String s : list1) {
-			list2.add(s);
-		}
-		Iterable<String> iterable2 = list2;
-		assertTrue(CollectionTools.elementsAreIdentical(iterable1, iterable2));
-		assertTrue(CollectionTools.elementsAreEqual(iterable1, iterable2));
-	}
-
-	public void testElementsAreIdenticalIteratorIterator() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("0");
-		list1.add("1");
-		list1.add("2");
-		list1.add("3");
-
-		List<String> list2 = new ArrayList<String>();
-		for (String s : list1) {
-			list2.add(s);
-		}
-		assertTrue(CollectionTools.elementsAreIdentical(list1.iterator(), list2.iterator()));
-		assertTrue(CollectionTools.elementsAreEqual(list1.iterator(), list2.iterator()));
-	}
-
-	public void testElementsAreIdenticalIteratorIterator_Not() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("0");
-		list1.add("1");
-		list1.add("2");
-		list1.add("3");
-
-		List<String> list2 = new ArrayList<String>();
-		for (String s : list1) {
-			list2.add(s);
-		}
-		list2.remove(0);
-		assertFalse(CollectionTools.elementsAreIdentical(list1.iterator(), list2.iterator()));
-		assertFalse(CollectionTools.elementsAreEqual(list1.iterator(), list2.iterator()));
-	}
-
-	public void testElementsAreIdenticalIteratorIterator_DifferentSizes() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("0");
-		list1.add("1");
-		list1.add("2");
-		list1.add("3");
-
-		List<String> list2 = new ArrayList<String>();
-		for (String s : list1) {
-			list2.add(s);
-		}
-		list2.remove(3);
-		assertFalse(CollectionTools.elementsAreIdentical(list1.iterator(), list2.iterator()));
-		assertFalse(CollectionTools.elementsAreEqual(list1.iterator(), list2.iterator()));
-	}
-
-	public void testElementsAreNotIdenticalIterableIterable() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("0");
-		list1.add("1");
-		list1.add("2");
-		list1.add("3");
-		Iterable<String> iterable1 = list1;
-
-		List<String> list2 = new ArrayList<String>();
-		for (String s : list1) {
-			list2.add(s);
-		}
-		Iterable<String> iterable2 = list2;
-		assertFalse(CollectionTools.elementsAreNotIdentical(iterable1, iterable2));
-		assertTrue(CollectionTools.elementsAreEqual(iterable1, iterable2));
-	}
-
-	public void testElementsAreNotIdenticalIteratorIterator() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("0");
-		list1.add("1");
-		list1.add("2");
-		list1.add("3");
-
-		List<String> list2 = new ArrayList<String>();
-		for (String s : list1) {
-			list2.add(s);
-		}
-		assertFalse(CollectionTools.elementsAreNotIdentical(list1.iterator(), list2.iterator()));
-		assertTrue(CollectionTools.elementsAreEqual(list1.iterator(), list2.iterator()));
-	}
-
-	public void testElementsAreNotIdenticalIteratorIterator_Not() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("0");
-		list1.add("1");
-		list1.add("2");
-		list1.add("3");
-
-		List<String> list2 = new ArrayList<String>();
-		for (String s : list1) {
-			list2.add(s);
-		}
-		list2.remove(0);
-		assertTrue(CollectionTools.elementsAreNotIdentical(list1.iterator(), list2.iterator()));
-		assertFalse(CollectionTools.elementsAreEqual(list1.iterator(), list2.iterator()));
-	}
-
-	public void testElementsAreNotIdenticalIteratorIterator_DifferentSizes() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("0");
-		list1.add("1");
-		list1.add("2");
-		list1.add("3");
-
-		List<String> list2 = new ArrayList<String>();
-		for (String s : list1) {
-			list2.add(s);
-		}
-		list2.remove(3);
-		assertTrue(CollectionTools.elementsAreNotIdentical(list1.iterator(), list2.iterator()));
-		assertFalse(CollectionTools.elementsAreEqual(list1.iterator(), list2.iterator()));
-	}
-
-
-	// ********** get **********
-
-	public void testGetIterableInt() {
-		List<String> list = this.buildStringList1();
-		Iterable<String> iterable = list;
-		String o = CollectionTools.get(iterable, 1);
-		assertEquals("one", o);
-		list.add(null);
-		o = CollectionTools.get(iterable, 3);
-		assertNull(o);
-	}
-
-	public void testGetIteratorInt1() {
-		List<String> list = this.buildStringList1();
-		String o = CollectionTools.get(list.iterator(), 1);
-		assertEquals("one", o);
-		list.add(null);
-		o = CollectionTools.get(list.iterator(), list.size() - 1);
-		assertNull(o);
-	}
-
-	public void testGetIteratorInt2() {
-		List<String> list = this.buildStringList1();
-		boolean exCaught = false;
-		try {
-			CollectionTools.get(list.iterator(), list.size());
-			fail();
-		} catch (IndexOutOfBoundsException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-
-	// ********** hash code **********
-
-	public void testHashCodeIterable1() {
-		Iterable<String> iterable = null;
-		assertEquals(0, CollectionTools.hashCode(iterable));
-	}
-
-	public void testHashCodeIterable2() {
-		List<String> list = this.buildStringList1();
-		Iterable<String> iterable = list;
-		int hashCode = CollectionTools.hashCode(iterable);
-		assertEquals(list.hashCode(), hashCode);
-
-		list.add(null);
-		hashCode = CollectionTools.hashCode(iterable);
-		assertEquals(list.hashCode(), hashCode);
-	}
-
-
-	// ********** index of **********
-
-	public void testIndexOfIterableObject_String() {
-		Iterable<String> iterable = this.buildStringList1();
-		assertEquals(1, CollectionTools.indexOf(iterable, "one"));
-	}
-
-	public void testIndexOfIteratorObject_String() {
-		List<String> list = this.buildStringList1();
-		assertEquals(1, CollectionTools.indexOf(list.iterator(), "one"));
-	}
-
-	public void testIndexOfIteratorObject_String_Not() {
-		List<String> list = this.buildStringList1();
-		assertEquals(-1, CollectionTools.indexOf(list.iterator(), null));
-		assertEquals(-1, CollectionTools.indexOf(list.iterator(), "shazam"));
-	}
-
-	public void testIndexOfIteratorObject_Null() {
-		List<String> list = this.buildStringList1();
-		list.add(null);
-		assertEquals(list.size() - 1, CollectionTools.indexOf(list.iterator(), null));
-	}
-
-	public void testIndexOfIteratorObject_Object() {
-		List<Object> list = new ArrayList<Object>();
-		list.add("0");
-		list.add("1");
-		list.add("2");
-		list.add("3");
-
-		String one = "1";
-		assertEquals(1, CollectionTools.indexOf(list.iterator(), one));
-		list.add(null);
-		assertEquals(list.size() - 1, CollectionTools.indexOf(list.iterator(), null));
-	}
-
-
-	// ********** insertion index of **********
-
-	public void testInsertionIndexOfListComparableRandomAccess() {
-		List<String> list = Arrays.asList(new String[] { "A", "C", "D" });
-		assertEquals(1, CollectionTools.insertionIndexOf(list, "B"));
-
-		list = Arrays.asList(new String[] { "A", "B", "C", "D" });
-		assertEquals(2, CollectionTools.insertionIndexOf(list, "B"));
-
-		list = Arrays.asList(new String[] { "A", "B", "B", "B", "C", "D" });
-		assertEquals(4, CollectionTools.insertionIndexOf(list, "B"));
-
-		list = Arrays.asList(new String[] { "A", "B", "B", "B", "C", "D" });
-		assertEquals(6, CollectionTools.insertionIndexOf(list, "E"));
-
-		list = Arrays.asList(new String[] { "B", "B", "B", "C", "D" });
-		assertEquals(0, CollectionTools.insertionIndexOf(list, "A"));
-
-		list = Arrays.asList(new String[] { "A", "A", "B", "B", "C", "D" });
-		assertEquals(2, CollectionTools.insertionIndexOf(list, "A"));
-	}
-
-	public void testInsertionIndexOfListComparableNonRandomAccess() {
-		List<String> list = new LinkedList<String>(Arrays.asList(new String[] { "A", "C", "D" }));
-		assertEquals(1, CollectionTools.insertionIndexOf(list, "B"));
-
-		list = new LinkedList<String>(Arrays.asList(new String[] { "A", "B", "C", "D" }));
-		assertEquals(1, CollectionTools.insertionIndexOf(list, "B"));
-
-		list = new LinkedList<String>(Arrays.asList(new String[] { "A", "B", "B", "B", "C", "D" }));
-		assertEquals(1, CollectionTools.insertionIndexOf(list, "B"));
-
-		list = new LinkedList<String>(Arrays.asList(new String[] { "A", "B", "B", "B", "C", "D" }));
-		assertEquals(6, CollectionTools.insertionIndexOf(list, "E"));
-
-		list = new LinkedList<String>(Arrays.asList(new String[] { "B", "B", "B", "C", "D" }));
-		assertEquals(0, CollectionTools.insertionIndexOf(list, "A"));
-
-		list = new LinkedList<String>(Arrays.asList(new String[] { "A", "A", "B", "B", "C", "D" }));
-		assertEquals(0, CollectionTools.insertionIndexOf(list, "A"));
-	}
-
-	public void testInsertionIndexOfListObjectComparatorRandomAccess() {
-		Comparator<String> c = new ReverseComparator<String>();
-		List<String> list = Arrays.asList(new String[] { "D", "C", "A" });
-		assertEquals(2, CollectionTools.insertionIndexOf(list, "B", c));
-
-		list = Arrays.asList(new String[] { "D", "C", "B", "A" });
-		assertEquals(3, CollectionTools.insertionIndexOf(list, "B", c));
-
-		list = Arrays.asList(new String[] { "D", "C", "B", "B", "B", "A" });
-		assertEquals(5, CollectionTools.insertionIndexOf(list, "B", c));
-
-		list = Arrays.asList(new String[] { "D", "C", "B", "B", "B", "A" });
-		assertEquals(0, CollectionTools.insertionIndexOf(list, "E", c));
-
-		list = Arrays.asList(new String[] { "D", "C", "B", "B", "B" });
-		assertEquals(5, CollectionTools.insertionIndexOf(list, "A", c));
-
-		list = Arrays.asList(new String[] { "D", "C", "B", "B", "A", "A" });
-		assertEquals(6, CollectionTools.insertionIndexOf(list, "A", c));
-	}
-
-	public void testInsertionIndexOfListObjectComparatorNonRandomAccess() {
-		Comparator<String> c = new ReverseComparator<String>();
-		List<String> list = new LinkedList<String>(Arrays.asList(new String[] { "D", "C", "A" }));
-		assertEquals(2, CollectionTools.insertionIndexOf(list, "B", c));
-
-		list = new LinkedList<String>(Arrays.asList(new String[] { "D", "C", "B", "A" }));
-		assertEquals(2, CollectionTools.insertionIndexOf(list, "B", c));
-
-		list = new LinkedList<String>(Arrays.asList(new String[] { "D", "C", "B", "B", "B", "A" }));
-		assertEquals(2, CollectionTools.insertionIndexOf(list, "B", c));
-
-		list = new LinkedList<String>(Arrays.asList(new String[] { "D", "C", "B", "B", "B", "A" }));
-		assertEquals(0, CollectionTools.insertionIndexOf(list, "E", c));
-
-		list = new LinkedList<String>(Arrays.asList(new String[] { "D", "C", "B", "B", "B" }));
-		assertEquals(5, CollectionTools.insertionIndexOf(list, "A", c));
-
-		list = new LinkedList<String>(Arrays.asList(new String[] { "D", "C", "B", "B", "A", "A" }));
-		assertEquals(4, CollectionTools.insertionIndexOf(list, "A", c));
-	}
-
-
-	// ********** is empty **********
-
-	public void testIsEmptyIterable() {
-		assertFalse(CollectionTools.isEmpty(buildObjectList1()));
-		assertTrue(CollectionTools.isEmpty(EmptyIterable.instance()));
-	}
-
-	public void testIsEmptyIterator() {
-		assertFalse(CollectionTools.isEmpty(buildObjectList1().iterator()));
-		assertTrue(CollectionTools.isEmpty(EmptyIterator.instance()));
-	}
-
-
-	// ********** iterable/iterator **********
-
-	public void testIterableObjectArray() {
-		String[] strings = this.buildStringArray1();
-		int i = 0;
-		for (String string : CollectionTools.iterable(strings)) {
-			assertEquals(strings[i++], string);
-		}
-	}
-
-	public void testIteratorObjectArray() {
-		String[] a = this.buildStringArray1();
-		int i = 0;
-		for (Iterator<String> stream = CollectionTools.iterator(a); stream.hasNext(); i++) {
-			assertEquals(a[i], stream.next());
-		}
-	}
-
-
-	// ********** last **********
-
-	public void testLastIterable1() {
-		List<String> list = this.buildStringList1();
-		Iterable<String> iterable = list;
-		assertEquals("two", CollectionTools.last(iterable));
-		list.add(null);
-		assertEquals(null, CollectionTools.last(iterable));
-	}
-
-	public void testLastIterable2() {
-		Iterable<String> iterable = new ArrayList<String>();
-		boolean exCaught = false;
-		try {
-			CollectionTools.last(iterable);
-			fail();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testLastIterator1() {
-		List<String> list = this.buildStringList1();
-		assertEquals("two", CollectionTools.last(list.iterator()));
-		list.add(null);
-		assertEquals(null, CollectionTools.last(list.iterator()));
-	}
-
-	public void testLastIterator2() {
-		List<String> list = new ArrayList<String>();
-		boolean exCaught = false;
-		try {
-			CollectionTools.last(list.iterator());
-			fail();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-
-	// ********** last index of **********
-
-	public void testLastIndexOfIterableObject() {
-		List<String> list = this.buildStringList1();
-		Iterable<String> iterable = list;
-		assertEquals(1, CollectionTools.lastIndexOf(iterable, "one"));
-		list.add(null);
-		assertEquals(list.size() - 1, CollectionTools.lastIndexOf(iterable, null));
-	}
-
-	public void testLastIndexOfIterableIntObject() {
-		List<String> list = this.buildStringList1();
-		Iterable<String> iterable = list;
-		assertEquals(1, CollectionTools.lastIndexOf(iterable, 23, "one"));
-		list.add(null);
-		assertEquals(list.size() - 1, CollectionTools.lastIndexOf(iterable, 42, null));
-	}
-
-	public void testLastIndexOfIteratorObject() {
-		List<String> list = this.buildStringList1();
-		assertEquals(1, CollectionTools.lastIndexOf(list.iterator(), "one"));
-		list.add(null);
-		assertEquals(list.size() - 1, CollectionTools.lastIndexOf(list.iterator(), null));
-	}
-
-	public void testLastIndexOfIteratorObject_Empty() {
-		assertEquals(-1, CollectionTools.lastIndexOf(EmptyIterator.instance(), "foo"));
-	}
-
-	public void testLastIndexOfIteratorIntObject() {
-		List<String> list = this.buildStringList1();
-		assertEquals(1, CollectionTools.lastIndexOf(list.iterator(), 3, "one"));
-		list.add(null);
-		assertEquals(list.size() - 1, CollectionTools.lastIndexOf(list.iterator(), 4, null));
-	}
-
-	public void testLastIndexOfIteratorIntObject_Empty() {
-		assertEquals(-1, CollectionTools.lastIndexOf(EmptyIterator.instance(), 42, "foo"));
-	}
-
-
-	// ********** list **********
-
-	public void testListIterable() {
-		Iterable<String> iterable = this.buildStringList1();
-		assertEquals(this.buildStringList1(), CollectionTools.list(iterable));
-	}
-
-	public void testListIterableInt() {
-		Iterable<String> iterable = this.buildStringList1();
-		assertEquals(this.buildStringList1(), CollectionTools.list(iterable, 3));
-	}
-
-	public void testListIterator_String() {
-		List<String> list = CollectionTools.list(this.buildStringList1().iterator());
-		assertEquals(this.buildStringList1(), list);
-	}
-
-	public void testListIterator_StringObject() {
-		List<String> list1 = new ArrayList<String>();
-		list1.add("0");
-		list1.add("1");
-		list1.add("2");
-		list1.add("3");
-
-		List<Object> list2 = CollectionTools.<Object>list(list1.iterator());
-		assertEquals(list1, list2);
-	}
-
-	public void testListIterator_Empty() {
-		assertEquals(0, CollectionTools.list(EmptyIterator.instance()).size());
-	}
-
-	public void testListIteratorInt() {
-		List<String> list = CollectionTools.list(this.buildStringList1().iterator(), 3);
-		assertEquals(this.buildStringList1(), list);
-	}
-
-	public void testListIteratorInt_Empty() {
-		assertEquals(0, CollectionTools.list(EmptyIterator.instance(), 5).size());
-	}
-
-	public void testListObjectArray() {
-		List<String> list = CollectionTools.list(this.buildStringArray1());
-		assertEquals(this.buildStringList1(), list);
-	}
-
-	public void testListIteratorObjectArray() {
-		String[] a = this.buildStringArray1();
-		int i = 0;
-		for (ListIterator<String> stream = CollectionTools.listIterator(a); stream.hasNext(); i++) {
-			assertEquals(a[i], stream.next());
-		}
-	}
-
-	public void testListIteratorObjectArrayInt() {
-		String[] a = this.buildStringArray1();
-		int i = 1;
-		for (ListIterator<String> stream = CollectionTools.listIterator(a, 1); stream.hasNext(); i++) {
-			assertEquals(a[i], stream.next());
-		}
-	}
-
-
-	// ********** move **********
-
-	public void testMoveListIntIntRandomAccess() {
-		List<String> list = new ArrayList<String>();
-		CollectionTools.addAll(list, new String[] { "0", "1", "2", "3", "4", "5" });
-
-		List<String> result = CollectionTools.move(list, 4, 2);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result.toArray()));
-
-		result = CollectionTools.move(list, 0, 5);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result.toArray()));
-
-		result = CollectionTools.move(list, 2, 4);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result.toArray()));
-
-		result = CollectionTools.move(list, 2, 2);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result.toArray()));
-	}
-
-	public void testMoveListIntIntSequentialAccess() {
-		List<String> list = new LinkedList<String>();
-		CollectionTools.addAll(list, new String[] { "0", "1", "2", "3", "4", "5" });
-
-		List<String> result = CollectionTools.move(list, 4, 2);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result.toArray()));
-
-		result = CollectionTools.move(list, 0, 5);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result.toArray()));
-
-		result = CollectionTools.move(list, 2, 4);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result.toArray()));
-
-		result = CollectionTools.move(list, 2, 2);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result.toArray()));
-	}
-
-	public void testMoveListIntIntIntRandomAccess() {
-		List<String> list = new ArrayList<String>(Arrays.asList(new String[] { "0", "1", "2", "3", "4", "5" }));
-
-		List<String> result = CollectionTools.move(list, 4, 2, 1);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result.toArray()));
-
-		result = CollectionTools.move(list, 0, 5, 1);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result.toArray()));
-
-		result = CollectionTools.move(list, 2, 4, 1);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result.toArray()));
-
-		result = CollectionTools.move(list, 2, 4, 2);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
-
-		result = CollectionTools.move(list, 0, 1, 4);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "0", "3", "2", "4", "5", "1" }, result.toArray()));
-
-		result = CollectionTools.move(list, 1, 0, 4);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
-
-		result = CollectionTools.move(list, 1, 1, 4);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
-
-		result = CollectionTools.move(list, 1, 0, 0);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
-	}
-
-	public void testMoveListIntIntIntSequentialAccess() {
-		List<String> list = new LinkedList<String>(Arrays.asList(new String[] { "0", "1", "2", "3", "4", "5" }));
-
-		List<String> result = CollectionTools.move(list, 4, 2, 1);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result.toArray()));
-
-		result = CollectionTools.move(list, 0, 5, 1);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result.toArray()));
-
-		result = CollectionTools.move(list, 2, 4, 1);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result.toArray()));
-
-		result = CollectionTools.move(list, 2, 4, 2);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
-
-		result = CollectionTools.move(list, 0, 1, 4);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "0", "3", "2", "4", "5", "1" }, result.toArray()));
-
-		result = CollectionTools.move(list, 1, 0, 4);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
-
-		result = CollectionTools.move(list, 1, 1, 4);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
-
-		result = CollectionTools.move(list, 1, 0, 0);
-		assertSame(list, result);  // the array is modified in place and returned
-		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
-	}
-
-
-	// ********** remove all **********
-
-	public void testRemoveAllCollectionIterable() {
-		Collection<String> c = this.buildStringList1();
-		Iterable<String> iterable = this.buildStringList1();
-		assertTrue(CollectionTools.removeAll(c, iterable));
-		assertEquals(0, c.size());
-		assertFalse(c.contains("one"));
-		assertFalse(c.contains("two"));
-		assertFalse(c.contains("three"));
-
-		c = this.buildStringList1();
-		iterable = this.buildStringList2();
-		assertFalse(CollectionTools.removeAll(c, iterable));
-		assertEquals(this.buildStringList1().size(), c.size());
-		assertEquals(this.buildStringList1(), c);
-	}
-
-	public void testRemoveAllCollectionIterableInt() {
-		Collection<String> c = this.buildStringList1();
-		Iterable<String> iterable = this.buildStringList1();
-		assertTrue(CollectionTools.removeAll(c, iterable, 4));
-		assertEquals(0, c.size());
-		assertFalse(c.contains("one"));
-		assertFalse(c.contains("two"));
-		assertFalse(c.contains("three"));
-
-		c = this.buildStringList1();
-		iterable = this.buildStringList2();
-		assertFalse(CollectionTools.removeAll(c, iterable, 55));
-		assertEquals(this.buildStringList1().size(), c.size());
-		assertEquals(this.buildStringList1(), c);
-	}
-
-	public void testRemoveAllCollectionIterator_Empty() {
-		Collection<String> c = this.buildStringList1();
-		assertTrue(CollectionTools.removeAll(c, this.buildStringList1().iterator()));
-		assertEquals(0, c.size());
-		assertFalse(c.contains("one"));
-		assertFalse(c.contains("two"));
-		assertFalse(c.contains("three"));
-
-		c = this.buildStringList1();
-		assertFalse(CollectionTools.removeAll(c, this.buildStringList2().iterator()));
-		assertEquals(this.buildStringList1().size(), c.size());
-		assertEquals(this.buildStringList1(), c);
-
-		c = this.buildStringList1();
-		assertFalse(CollectionTools.removeAll(c, EmptyIterator.instance()));
-		assertEquals(this.buildStringList1().size(), c.size());
-		assertEquals(this.buildStringList1(), c);
-	}
-
-	public void testRemoveAllCollectionIteratorInt_Empty() {
-		Collection<String> c = this.buildStringList1();
-		assertTrue(CollectionTools.removeAll(c, this.buildStringList1().iterator(), 5));
-		assertEquals(0, c.size());
-		assertFalse(c.contains("one"));
-		assertFalse(c.contains("two"));
-		assertFalse(c.contains("three"));
-
-		c = this.buildStringList1();
-		assertFalse(CollectionTools.removeAll(c, this.buildStringList2().iterator(), 5));
-		assertEquals(this.buildStringList1().size(), c.size());
-		assertEquals(this.buildStringList1(), c);
-
-		c = this.buildStringList1();
-		assertFalse(CollectionTools.removeAll(c, EmptyIterator.instance(), 0));
-		assertEquals(this.buildStringList1().size(), c.size());
-		assertEquals(this.buildStringList1(), c);
-	}
-
-	public void testRemoveAllCollectionIterator_Duplicates() {
-		Collection<String> c = new ArrayList<String>();
-		c.add("a");
-		c.add("a");
-		c.add("b");
-		c.add("c");
-		c.add("d");
-		c.add("d");
-		String[] a = new String[] { "a", "d" };
-		Iterator<String> iterator = new ArrayIterator<String>(a);
-		assertTrue(CollectionTools.removeAll(c, iterator));
-		assertEquals(2, c.size());
-		assertFalse(c.contains("a"));
-		assertTrue(c.contains("b"));
-		assertTrue(c.contains("c"));
-		assertFalse(c.contains("d"));
-
-		iterator = new ArrayIterator<String>(a);
-		assertFalse(CollectionTools.removeAll(c, iterator));
-	}
-
-	public void testRemoveAllCollectionIterator_ObjectString() {
-		Collection<Object> c = new ArrayList<Object>();
-		c.add("a");
-		c.add("a");
-		c.add("b");
-		c.add("c");
-		c.add("d");
-		c.add("d");
-		String[] a = new String[] { "a", "d" };
-		Iterator<String> iterator = new ArrayIterator<String>(a);
-		assertTrue(CollectionTools.removeAll(c, iterator));
-		assertEquals(2, c.size());
-		assertFalse(c.contains("a"));
-		assertTrue(c.contains("b"));
-		assertTrue(c.contains("c"));
-		assertFalse(c.contains("d"));
-
-		iterator = new ArrayIterator<String>(a);
-		assertFalse(CollectionTools.removeAll(c, iterator));
-	}
-
-	public void testRemoveAllCollectionObjectArray_Empty() {
-		Collection<String> c = this.buildStringList1();
-		assertTrue(CollectionTools.removeAll(c, this.buildObjectArray1()));
-		assertEquals(0, c.size());
-		assertFalse(c.contains("one"));
-		assertFalse(c.contains("two"));
-		assertFalse(c.contains("three"));
-
-		c = this.buildStringList1();
-		assertFalse(CollectionTools.removeAll(c, this.buildObjectArray2()));
-		assertEquals(this.buildStringList1().size(), c.size());
-		assertEquals(this.buildStringList1(), c);
-
-		c = this.buildStringList1();
-		assertFalse(CollectionTools.removeAll(c, new Object[0]));
-		assertEquals(this.buildStringList1().size(), c.size());
-		assertEquals(this.buildStringList1(), c);
-	}
-
-	public void testRemoveAllCollectionObjectArray_Duplicates() {
-		Collection<String> c = new ArrayList<String>();
-		c.add("a");
-		c.add("a");
-		c.add("b");
-		c.add("c");
-		c.add("d");
-		c.add("d");
-		String[] a = new String[] { "a", "d" };
-		assertTrue(CollectionTools.removeAll(c, (Object[]) a));
-		assertEquals(2, c.size());
-		assertFalse(c.contains("a"));
-		assertTrue(c.contains("b"));
-		assertTrue(c.contains("c"));
-		assertFalse(c.contains("d"));
-
-		assertFalse(CollectionTools.removeAll(c,(Object[])  a));
-	}
-
-	public void testRemoveAllCollectionObjectArray_MoreDuplicates() {
-		Collection<String> c = new ArrayList<String>();
-		c.add("a");
-		c.add("b");
-		c.add("c");
-		c.add("d");
-		c.add("a");
-		c.add("d");
-		c.add("d");
-		c.add("a");
-		c.add("c");
-		String[] a = new String[] { "a", "d" };
-		assertTrue(CollectionTools.removeAll(c, (Object[]) a));
-		assertEquals(3, c.size());
-		assertFalse(c.contains("a"));
-		assertTrue(c.contains("b"));
-		assertTrue(c.contains("c"));
-		assertFalse(c.contains("d"));
-
-		assertFalse(CollectionTools.removeAll(c, (Object[]) a));
-	}
-
-
-	// ********** remove all occurrences **********
-
-	public void testRemoveAllOccurrencesCollectionObject() {
-		Collection<String> c = this.buildStringList1();
-		assertEquals(3, c.size());
-		assertFalse(CollectionTools.removeAllOccurrences(c, "three"));
-		assertTrue(CollectionTools.removeAllOccurrences(c, "two"));
-		assertFalse(CollectionTools.removeAllOccurrences(c, "two"));
-		assertEquals(2, c.size());
-
-		c.add("five");
-		c.add("five");
-		c.add("five");
-		assertEquals(5, c.size());
-		assertTrue(CollectionTools.removeAllOccurrences(c, "five"));
-		assertFalse(CollectionTools.removeAllOccurrences(c, "five"));
-		assertEquals(2, c.size());
-
-		c.add(null);
-		c.add(null);
-		c.add(null);
-		assertEquals(5, c.size());
-		assertTrue(CollectionTools.removeAllOccurrences(c, null));
-		assertFalse(CollectionTools.removeAllOccurrences(c, null));
-		assertEquals(2, c.size());
-	}
-
-
-	// ********** remove elements at index **********
-
-	public void testRemoveElementsAtIndexListIntInt() {
-		List<String> list = new ArrayList<String>(Arrays.asList(new String[] { "A", "B", "A", "C", "A", "D" }));
-		List<String> removed = CollectionTools.removeElementsAtIndex(list, 3, 2);
-		assertTrue(Arrays.equals(new String[] { "A", "B", "A", "D" }, list.toArray()));
-		assertTrue(Arrays.equals(new String[] { "C", "A" }, removed.toArray()));
-
-		list = new ArrayList<String>(Arrays.asList(new String[] { "A", "B", "C", "D", "E", "F" }));
-		removed = CollectionTools.removeElementsAtIndex(list, 3, 3);
-		assertTrue(Arrays.equals(new String[] { "A", "B", "C" }, list.toArray()));
-		assertTrue(Arrays.equals(new String[] { "D", "E", "F" }, removed.toArray()));
-
-		list = new ArrayList<String>(Arrays.asList(new String[] { "A", "B", "C", "D", "E", "F" }));
-		removed = CollectionTools.removeElementsAtIndex(list, 0, 3);
-		assertTrue(Arrays.equals(new String[] { "D", "E", "F" }, list.toArray()));
-		assertTrue(Arrays.equals(new String[] { "A", "B", "C" }, removed.toArray()));
-	}
-
-
-	// ********** remove duplicate elements **********
-
-	public void testRemoveDuplicateElementsList1() {
-		List<String> list = this.buildStringVector1();
-		list.add("zero");
-		list.add("zero");
-		list.add("two");
-		list.add("zero");
-		assertTrue(CollectionTools.removeDuplicateElements(list));
-		int i = 0;
-		assertEquals("zero", list.get(i++));
-		assertEquals("one", list.get(i++));
-		assertEquals("two", list.get(i++));
-		assertEquals(i, list.size());
-	}
-
-	public void testRemoveDuplicateElementsList2() {
-		List<String> list = this.buildStringVector1();
-		assertFalse(CollectionTools.removeDuplicateElements(list));
-		int i = 0;
-		assertEquals("zero", list.get(i++));
-		assertEquals("one", list.get(i++));
-		assertEquals("two", list.get(i++));
-		assertEquals(i, list.size());
-	}
-
-	public void testRemoveDuplicateElementsList_Empty() {
-		List<String> list = new ArrayList<String>();
-		assertFalse(CollectionTools.removeDuplicateElements(list));
-		assertEquals(0, list.size());
-	}
-
-	public void testRemoveDuplicateElementsList_SingleElement() {
-		List<String> list = new ArrayList<String>();
-		list.add("zero");
-		assertFalse(CollectionTools.removeDuplicateElements(list));
-		assertEquals(1, list.size());
-	}
-
-
-	// ********** retain all **********
-
-	public void testRetainAllCollectionIterable() {
-		Collection<String> c = this.buildStringList1();
-		Iterable<String> iterable = this.buildStringList1();
-		assertFalse(CollectionTools.retainAll(c, iterable));
-		assertEquals(this.buildStringList1().size(), c.size());
-		assertEquals(this.buildStringList1(), c);
-
-		iterable = this.buildStringList2();
-		assertTrue(CollectionTools.retainAll(c, iterable));
-		assertEquals(0, c.size());
-		assertFalse(c.contains("one"));
-		assertFalse(c.contains("two"));
-		assertFalse(c.contains("three"));
-	}
-
-	public void testRetainAllCollectionIterableInt() {
-		Collection<String> c = this.buildStringList1();
-		Iterable<String> iterable = this.buildStringList1();
-		assertFalse(CollectionTools.retainAll(c, iterable));
-		assertEquals(this.buildStringList1().size(), c.size());
-		assertEquals(this.buildStringList1(), c);
-
-		iterable = this.buildStringList2();
-		assertTrue(CollectionTools.retainAll(c, iterable, 7));
-		assertEquals(0, c.size());
-		assertFalse(c.contains("one"));
-		assertFalse(c.contains("two"));
-		assertFalse(c.contains("three"));
-	}
-
-	public void testRetainAllCollectionIterator() {
-		Collection<String> c = this.buildStringList1();
-		assertFalse(CollectionTools.retainAll(c, this.buildStringList1().iterator()));
-		assertEquals(this.buildStringList1().size(), c.size());
-		assertEquals(this.buildStringList1(), c);
-
-		assertTrue(CollectionTools.retainAll(c, this.buildStringList2().iterator()));
-		assertEquals(0, c.size());
-		assertFalse(c.contains("one"));
-		assertFalse(c.contains("two"));
-		assertFalse(c.contains("three"));
-	}
-
-	public void testRetainAllCollectionIterator_ObjectString() {
-		Collection<Object> c1 = new ArrayList<Object>();
-		c1.add("zero");
-		c1.add("one");
-		c1.add("two");
-
-		Collection<String> c2 = new ArrayList<String>();
-		c2.add("zero");
-		c2.add("one");
-		c2.add("two");
-
-		assertFalse(CollectionTools.retainAll(c1, c2.iterator()));
-		assertEquals(c2.size(), c1.size());
-		assertEquals(c2, c1);
-
-		Collection<String> c3 = new ArrayList<String>();
-		c3.add("three");
-		c3.add("four");
-		c3.add("five");
-	}
-
-	public void testRetainAllCollectionIterator_EmptyIterator() {
-		Collection<String> c = this.buildStringList1();
-		assertTrue(CollectionTools.retainAll(c, EmptyIterator.instance()));
-		assertEquals(0, c.size());
-	}
-
-	public void testRetainAllCollectionIterator_EmptyCollection() {
-		Collection<String> c = new ArrayList<String>();
-		assertFalse(CollectionTools.retainAll(c, this.buildStringList1().iterator()));
-		assertEquals(0, c.size());
-	}
-
-	public void testRetainAllCollectionIterator_EmptyCollectionEmptyIterator() {
-		Collection<String> c = new ArrayList<String>();
-		assertFalse(CollectionTools.retainAll(c, EmptyIterator.instance()));
-		assertEquals(0, c.size());
-	}
-
-	public void testRetainAllCollectionIteratorInt() {
-		Collection<String> c = this.buildStringList1();
-		assertFalse(CollectionTools.retainAll(c, this.buildStringList1().iterator(), 8));
-		assertEquals(this.buildStringList1().size(), c.size());
-		assertEquals(this.buildStringList1(), c);
-
-		assertTrue(CollectionTools.retainAll(c, this.buildStringList2().iterator(), 9));
-		assertEquals(0, c.size());
-		assertFalse(c.contains("one"));
-		assertFalse(c.contains("two"));
-		assertFalse(c.contains("three"));
-	}
-
-	public void testRetainAllCollectionIteratorInt_EmptyIterator() {
-		Collection<String> c = this.buildStringList1();
-		assertTrue(CollectionTools.retainAll(c, EmptyIterator.instance(), 0));
-		assertEquals(0, c.size());
-	}
-
-	public void testRetainAllCollectionIteratorInt_EmptyCollection() {
-		Collection<String> c = new ArrayList<String>();
-		assertFalse(CollectionTools.retainAll(c, this.buildStringList1().iterator(), 3));
-		assertEquals(0, c.size());
-	}
-
-	public void testRetainAllCollectionIteratorInt_EmptyCollectionEmptyIterator() {
-		Collection<String> c = new ArrayList<String>();
-		assertFalse(CollectionTools.retainAll(c, EmptyIterator.instance(), 0));
-		assertEquals(0, c.size());
-	}
-
-	public void testRetainAllCollectionObjectArray() {
-		Collection<String> c = this.buildStringList1();
-		assertFalse(CollectionTools.retainAll(c, this.buildObjectArray1()));
-		assertEquals(this.buildStringList1().size(), c.size());
-		assertEquals(this.buildStringList1(), c);
-
-		assertTrue(CollectionTools.retainAll(c, this.buildObjectArray2()));
-		assertEquals(0, c.size());
-		assertFalse(c.contains("one"));
-		assertFalse(c.contains("two"));
-		assertFalse(c.contains("three"));
-	}
-
-	public void testRetainAllCollectionObjectArray_EmptyObjectArray() {
-		Collection<String> c = this.buildStringList1();
-		assertTrue(CollectionTools.retainAll(c, new Object[0]));
-		assertEquals(0, c.size());
-	}
-
-	public void testRetainAllCollectionObjectArray_EmptyCollection() {
-		Collection<String> c = new ArrayList<String>();
-		assertFalse(CollectionTools.retainAll(c, (Object[]) new String[] { "foo" }));
-		assertEquals(0, c.size());
-	}
-
-	public void testRetainAllCollectionObjectArray_EmptyCollectionEmptyObjectArray() {
-		Collection<String> c = new ArrayList<String>();
-		assertFalse(CollectionTools.retainAll(c, (Object[]) new String[0]));
-		assertEquals(0, c.size());
-	}
-
-
-	// ********** reverse list **********
-
-	public void testReverseListIterable() {
-		Iterable<String> iterable = this.buildStringList1();
-		List<String> actual = CollectionTools.reverseList(iterable);
-		List<String> expected = this.buildStringList1();
-		Collections.reverse(expected);
-		assertEquals(expected, actual);
-	}
-
-	public void testReverseListIterableInt() {
-		Iterable<String> iterable = this.buildStringList1();
-		List<String> actual = CollectionTools.reverseList(iterable, 10);
-		List<String> expected = this.buildStringList1();
-		Collections.reverse(expected);
-		assertEquals(expected, actual);
-	}
-
-	public void testReverseListIterator_String() {
-		List<String> actual = CollectionTools.reverseList(this.buildStringList1().iterator());
-		List<String> expected = this.buildStringList1();
-		Collections.reverse(expected);
-		assertEquals(expected, actual);
-	}
-
-	public void testReverseListIterator_Object() {
-		List<Object> actual = CollectionTools.<Object>reverseList(this.buildStringList1().iterator());
-		List<Object> expected = this.buildObjectList1();
-		Collections.reverse(expected);
-		assertEquals(expected, actual);
-	}
-
-	public void testReverseListIteratorInt() {
-		List<String> actual = CollectionTools.reverseList(this.buildStringList1().iterator(), 33);
-		List<String> expected = this.buildStringList1();
-		Collections.reverse(expected);
-		assertEquals(expected, actual);
-	}
-
-
-	// ********** rotate **********
-
-	public void testRotateList() {
-		List<String> actual = CollectionTools.rotate(this.buildStringList1());
-		List<String> expected = this.buildStringList1();
-		Collections.rotate(expected, 1);
-		assertEquals(expected, actual);
-	}
-
-
-	// ********** set **********
-
-	public void testSetIterable() {
-		Iterable<String> iterable = this.buildStringSet1();
-		assertEquals(this.buildStringSet1(), CollectionTools.set(iterable));
-	}
-
-	public void testSetIterableInt() {
-		Iterable<String> iterable = this.buildStringSet1();
-		assertEquals(this.buildStringSet1(), CollectionTools.set(iterable, 22));
-	}
-
-	public void testSetIterator_String() {
-		assertEquals(this.buildStringSet1(), CollectionTools.set(this.buildStringSet1().iterator()));
-	}
-
-	public void testSetIterator_Object() {
-		List<String> list = new ArrayList<String>();
-		list.add("0");
-		list.add("1");
-		list.add("2");
-		list.add("3");
-		list.add("0");
-		list.add("1");
-		list.add("2");
-		list.add("3");
-		Set<String> set = new HashSet<String>();
-		set.addAll(list);
-
-		assertEquals(set, CollectionTools.<Object>set(list.iterator()));
-	}
-
-	public void testSetIteratorInt() {
-		assertEquals(this.buildStringSet1(), CollectionTools.set(this.buildStringSet1().iterator(), 3));
-	}
-
-	public void testSetObjectArray() {
-		assertEquals(this.buildStringSet1(), CollectionTools.set(this.buildStringSet1().toArray()));
-	}
-
-
-	// ********** singleton iterator **********
-
-	public void testSingletonIterator_String() {
-		Iterator<String> stream = CollectionTools.singletonIterator("foo");
-		assertTrue(stream.hasNext());
-		assertEquals("foo", stream.next());
-	}
-
-	public void testSingletonIterator_Object() {
-		Iterator<Object> stream = CollectionTools.<Object>singletonIterator("foo");
-		assertTrue(stream.hasNext());
-		assertEquals("foo", stream.next());
-	}
-
-	public void testSingletonIterator_Cast() {
-		Iterator<Object> stream = CollectionTools.singletonIterator((Object) "foo");
-		assertTrue(stream.hasNext());
-		assertEquals("foo", stream.next());
-	}
-
-	public void testSingletonListIterator_String() {
-		ListIterator<String> stream = CollectionTools.singletonListIterator("foo");
-		assertTrue(stream.hasNext());
-		assertEquals("foo", stream.next());
-		assertFalse(stream.hasNext());
-		assertTrue(stream.hasPrevious());
-		assertEquals("foo", stream.previous());
-	}
-
-
-	// ********** size **********
-
-	public void testSizeIterable() {
-		Iterable<Object> iterable = this.buildObjectList1();
-		assertEquals(3, CollectionTools.size(iterable));
-	}
-
-	public void testSizeIterator() {
-		assertEquals(3, CollectionTools.size(this.buildObjectList1().iterator()));
-	}
-
-
-	// ********** sort **********
-
-	public void testSortIterable() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("0");
-		list.add("2");
-		list.add("3");
-		list.add("1");
-
-		SortedSet<String> ss = new TreeSet<String>();
-		ss.addAll(list);
-
-		Iterable<String> iterable1 = list;
-		Iterable<String> iterable2 = CollectionTools.<String>sort(iterable1);
-		assertTrue(CollectionTools.elementsAreEqual(ss, iterable2));
-	}
-
-	public void testSortIterableInt() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("0");
-		list.add("2");
-		list.add("3");
-		list.add("1");
-
-		SortedSet<String> ss = new TreeSet<String>();
-		ss.addAll(list);
-
-		Iterable<String> iterable1 = list;
-		Iterable<String> iterable2 = CollectionTools.<String>sort(iterable1, 77);
-		assertTrue(CollectionTools.elementsAreEqual(ss, iterable2));
-	}
-
-	public void testSortIterableComparator() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("0");
-		list.add("2");
-		list.add("3");
-		list.add("1");
-
-		SortedSet<String> ss = new TreeSet<String>(new ReverseComparator<String>());
-		ss.addAll(list);
-
-		Iterable<String> iterable1 = list;
-		Iterable<String> iterable2 = CollectionTools.<String>sort(iterable1, new ReverseComparator<String>());
-		assertTrue(CollectionTools.elementsAreEqual(ss, iterable2));
-	}
-
-	public void testSortIterableComparatorInt() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("0");
-		list.add("2");
-		list.add("3");
-		list.add("1");
-
-		SortedSet<String> ss = new TreeSet<String>(new ReverseComparator<String>());
-		ss.addAll(list);
-
-		Iterable<String> iterable1 = list;
-		Iterable<String> iterable2 = CollectionTools.<String>sort(iterable1, new ReverseComparator<String>(), 77);
-		assertTrue(CollectionTools.elementsAreEqual(ss, iterable2));
-	}
-
-	public void testSortIterator() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("0");
-		list.add("2");
-		list.add("3");
-		list.add("1");
-
-		SortedSet<String> ss = new TreeSet<String>();
-		ss.addAll(list);
-
-		Iterator<String> iterator1 = list.iterator();
-		Iterator<String> iterator2 = CollectionTools.<String>sort(iterator1);
-		assertTrue(CollectionTools.elementsAreEqual(ss.iterator(), iterator2));
-	}
-
-	public void testSortIteratorInt() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("0");
-		list.add("2");
-		list.add("3");
-		list.add("1");
-
-		SortedSet<String> ss = new TreeSet<String>();
-		ss.addAll(list);
-
-		Iterator<String> iterator1 = list.iterator();
-		Iterator<String> iterator2 = CollectionTools.<String>sort(iterator1, 77);
-		assertTrue(CollectionTools.elementsAreEqual(ss.iterator(), iterator2));
-	}
-
-	public void testSortIteratorComparator() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("0");
-		list.add("2");
-		list.add("3");
-		list.add("1");
-
-		SortedSet<String> ss = new TreeSet<String>(new ReverseComparator<String>());
-		ss.addAll(list);
-
-		Iterator<String> iterator1 = list.iterator();
-		Iterator<String> iterator2 = CollectionTools.<String>sort(iterator1, new ReverseComparator<String>());
-		assertTrue(CollectionTools.elementsAreEqual(ss.iterator(), iterator2));
-	}
-
-	public void testSortIteratorComparatorInt() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("0");
-		list.add("2");
-		list.add("3");
-		list.add("1");
-
-		SortedSet<String> ss = new TreeSet<String>(new ReverseComparator<String>());
-		ss.addAll(list);
-
-		Iterator<String> iterator1 = list.iterator();
-		Iterator<String> iterator2 = CollectionTools.<String>sort(iterator1, new ReverseComparator<String>(), 77);
-		assertTrue(CollectionTools.elementsAreEqual(ss.iterator(), iterator2));
-	}
-
-
-	// ********** sorted set **********
-
-	public void testSortedSetIterable() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("0");
-		list.add("2");
-		list.add("3");
-		list.add("1");
-
-		SortedSet<String> ss1 = new TreeSet<String>();
-		ss1.addAll(list);
-
-		Iterable<String> iterable = list;
-		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(iterable);
-		assertEquals(ss1, ss2);
-	}
-
-	public void testSortedSetIterableInt() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("0");
-		list.add("2");
-		list.add("3");
-		list.add("1");
-
-		SortedSet<String> ss1 = new TreeSet<String>();
-		ss1.addAll(list);
-
-		Iterable<String> iterable = list;
-		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(iterable, 5);
-		assertEquals(ss1, ss2);
-	}
-
-	public void testSortedSetIterableComparator() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("0");
-		list.add("2");
-		list.add("3");
-		list.add("1");
-
-		SortedSet<String> ss1 = new TreeSet<String>(new ReverseComparator<String>());
-		ss1.addAll(list);
-
-		Iterable<String> iterable = list;
-		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(iterable, new ReverseComparator<String>());
-		assertEquals(ss1, ss2);
-	}
-
-	public void testSortedSetIterableComparatorInt() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("0");
-		list.add("2");
-		list.add("3");
-		list.add("1");
-
-		SortedSet<String> ss1 = new TreeSet<String>(new ReverseComparator<String>());
-		ss1.addAll(list);
-
-		Iterable<String> iterable = list;
-		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(iterable, new ReverseComparator<String>(), 5);
-		assertEquals(ss1, ss2);
-	}
-
-	public void testSortedSetIterator() {
-		assertEquals(this.buildSortedStringSet1(), CollectionTools.sortedSet(this.buildSortedStringSet1().iterator()));
-	}
-
-	public void testSortedSetIterator_TreeSet() {
-		SortedSet<String> ss1 = new TreeSet<String>();
-		ss1.add("0");
-		ss1.add("2");
-		ss1.add("3");
-		ss1.add("1");
-
-		SortedSet<String> set2 = CollectionTools.<String>sortedSet(ss1.iterator());
-		assertEquals(ss1, set2);
-	}
-
-	public void testSortedSetIteratorInt() {
-		assertEquals(this.buildSortedStringSet1(), CollectionTools.sortedSet(this.buildSortedStringSet1().iterator(), 8));
-	}
-
-	public void testSortedSetObjectArray() {
-		assertEquals(this.buildSortedStringSet1(), CollectionTools.sortedSet(this.buildStringSet1().toArray(new String[0])));
-	}
-
-	public void testSortedSetObjectArrayComparator() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("0");
-		list.add("2");
-		list.add("3");
-		list.add("1");
-
-		SortedSet<String> ss1 = new TreeSet<String>(new ReverseComparator<String>());
-		ss1.addAll(list);
-
-		String[] array = list.toArray(new String[list.size()]);
-		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(array, new ReverseComparator<String>());
-		assertEquals(ss1, ss2);
-	}
-
-
-	// ********** Old School Vector **********
-
-	public void testVectorIterable() {
-		Iterable<String> iterable = this.buildStringList1();
-		Vector<String> v = CollectionTools.vector(iterable);
-		assertEquals(3, v.size());
-		assertTrue(v.containsAll(this.buildStringList1()));
-	}
-
-	public void testVectorIterableInt() {
-		Iterable<String> iterable = this.buildStringList1();
-		Vector<String> v = CollectionTools.vector(iterable, 8);
-		assertEquals(3, v.size());
-		assertTrue(v.containsAll(this.buildStringList1()));
-	}
-
-	public void testVectorIterator_String() {
-		Vector<String> v = CollectionTools.vector(this.buildStringList1().iterator());
-		assertEquals(3, v.size());
-		assertTrue(v.containsAll(this.buildStringList1()));
-	}
-
-	public void testVectorIterator_Object() {
-		Vector<Object> v = CollectionTools.<Object>vector(this.buildStringList1().iterator());
-		assertEquals(3, v.size());
-		assertTrue(v.containsAll(this.buildStringList1()));
-	}
-
-	public void testVectorIteratorInt() {
-		Vector<String> v = CollectionTools.vector(this.buildStringList1().iterator(), 7);
-		assertEquals(3, v.size());
-		assertTrue(v.containsAll(this.buildStringList1()));
-	}
-
-	public void testVectorObjectArray() {
-		Vector<String> v = CollectionTools.vector(this.buildStringArray1());
-		assertEquals(3, v.size());
-		assertTrue(v.containsAll(this.buildStringList1()));
-	}
-
-
-	// ********** single-use iterable **********
-
-	public void testIterableIterator() {
-		Iterator<Object> emptyIterator = EmptyIterator.instance();
-		Iterable<Object> emptyIterable = CollectionTools.iterable(emptyIterator);
-
-		assertFalse(emptyIterable.iterator().hasNext());
-
-		boolean exceptionThrown = false;
-		try {
-			emptyIterator = emptyIterable.iterator();
-			fail("invalid iterator: " + emptyIterator);
-		} catch (IllegalStateException ise) {
-			exceptionThrown = true;
-		}
-		assertTrue("IllegalStateException not thrown.", exceptionThrown);
-	}
-
-	public void testIterableIterator_NPE() {
-		Iterator<Object> nullIterator = null;
-		boolean exceptionThrown = false;
-		try {
-			Iterable<Object> emptyIterable = CollectionTools.iterable(nullIterator);
-			fail("invalid iterable: " + emptyIterable);
-		} catch (NullPointerException ise) {
-			exceptionThrown = true;
-		}
-		assertTrue(exceptionThrown);
-	}
-
-	public void testIterableIterator_ToString() {
-		Iterator<Object> emptyIterator = EmptyIterator.instance();
-		Iterable<Object> emptyIterable = CollectionTools.iterable(emptyIterator);
-		assertNotNull(emptyIterable.toString());
-	}
-
-
-	// ********** java.util.Collections enhancements **********
-
-	public void testCopyListList() {
-		List<String> src = this.buildStringList1();
-		List<String> dest = new ArrayList<String>();
-		for (String s : src) {
-			dest.add(s.toUpperCase());
-		}
-		List<String> result = CollectionTools.copy(dest, src);
-		assertSame(dest, result);
-		assertTrue(CollectionTools.elementsAreIdentical(src, dest));
-	}
-
-	public void testFillListObject() {
-		List<String> list = this.buildStringList1();
-		List<String> result = CollectionTools.fill(list, "foo");
-		assertSame(list, result);
-		for (String string : result) {
-			assertEquals("foo", string);
-		}
-	}
-
-	public void testShuffleList() {
-		List<String> list = this.buildStringList1();
-		List<String> result = CollectionTools.shuffle(list);
-		assertSame(list, result);
-	}
-
-	public void testShuffleListRandom() {
-		List<String> list = this.buildStringList1();
-		List<String> result = CollectionTools.shuffle(list, new Random());
-		assertSame(list, result);
-	}
-
-	public void testSortList() {
-		List<String> list = this.buildStringList1();
-		SortedSet<String> ss = new TreeSet<String>();
-		ss.addAll(list);
-		List<String> result = CollectionTools.sort(list);
-		assertSame(list, result);
-		assertTrue(CollectionTools.elementsAreEqual(ss, result));
-	}
-
-	public void testSwapListIntInt() {
-		List<String> list = this.buildStringList1();
-		List<String> result = CollectionTools.swap(list, 0, 1);
-		assertSame(list, result);
-		List<String> original = this.buildStringList1();
-		assertEquals(original.get(0), result.get(1));
-		assertEquals(original.get(1), result.get(0));
-		assertEquals(original.get(2), result.get(2));
-	}
-
-	public void testConstructor() {
-		boolean exCaught = false;
-		try {
-			Object at = ReflectionTools.newInstance(CollectionTools.class);
-			fail("bogus: " + at); //$NON-NLS-1$
-		} catch (RuntimeException ex) {
-			if (ex.getCause() instanceof InvocationTargetException) {
-				if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-
-	// ********** test harness **********
-
-	private Object[] buildObjectArray1() {
-		return new Object[] { "zero", "one", "two" };
-	}
-
-	private String[] buildStringArray1() {
-		return new String[] { "zero", "one", "two" };
-	}
-
-	private Object[] buildObjectArray2() {
-		return new Object[] { "three", "four", "five" };
-	}
-
-	private Vector<String> buildStringVector1() {
-		Vector<String> v = new Vector<String>();
-		this.addToCollection1(v);
-		return v;
-	}
-
-	private List<String> buildStringList1() {
-		List<String> l = new ArrayList<String>();
-		this.addToCollection1(l);
-		return l;
-	}
-
-	private List<Object> buildObjectList1() {
-		List<Object> l = new ArrayList<Object>();
-		this.addToCollection1(l);
-		return l;
-	}
-
-	private void addToCollection1(Collection<? super String> c) {
-		c.add("zero");
-		c.add("one");
-		c.add("two");
-	}
-
-	private List<String> buildStringList2() {
-		List<String> l = new ArrayList<String>();
-		this.addToCollection2(l);
-		return l;
-	}
-
-	private void addToCollection2(Collection<? super String> c) {
-		c.add("three");
-		c.add("four");
-		c.add("five");
-	}
-
-	private Set<String> buildStringSet1() {
-		Set<String> s = new HashSet<String>();
-		this.addToCollection1(s);
-		return s;
-	}
-
-	private Set<Object> buildObjectSet1() {
-		Set<Object> s = new HashSet<Object>();
-		this.addToCollection1(s);
-		return s;
-	}
-
-	private SortedSet<String> buildSortedStringSet1() {
-		SortedSet<String> s = new TreeSet<String>();
-		this.addToCollection1(s);
-		return s;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/CommonUtilityTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/CommonUtilityTests.java
deleted file mode 100644
index 7f100f0..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/CommonUtilityTests.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import org.eclipse.persistence.tools.utility.tests.internal.command.UtilityCommandTests;
-import org.eclipse.persistence.tools.utility.tests.internal.enumerations.UtilityEnumerationsTests;
-import org.eclipse.persistence.tools.utility.tests.internal.iterables.UtilityIterablesTests;
-import org.eclipse.persistence.tools.utility.tests.internal.iterators.UtilityIteratorsTests;
-import org.eclipse.persistence.tools.utility.tests.internal.model.UtilityModelTests;
-import org.eclipse.persistence.tools.utility.tests.internal.node.UtilityNodeTests;
-import org.eclipse.persistence.tools.utility.tests.internal.synchronizers.UtilitySynchronizersTests;
-
-/**
- * decentralize test creation code
- */
-public class CommonUtilityTests {
-
-	public static Test suite() {
-		TestSuite suite = new TestSuite(CommonUtilityTests.class.getPackage().getName());
-
-		suite.addTest(UtilityCommandTests.suite());
-		suite.addTest(UtilityEnumerationsTests.suite());
-		suite.addTest(UtilityIterablesTests.suite());
-		suite.addTest(UtilityIteratorsTests.suite());
-		suite.addTest(UtilityModelTests.suite());
-		suite.addTest(UtilityNodeTests.suite());
-		suite.addTest(UtilitySynchronizersTests.suite());
-
-		suite.addTestSuite(ArrayToolsTests.class);
-		suite.addTestSuite(BagTests.class);
-		suite.addTestSuite(BidiFilterTests.class);
-		suite.addTestSuite(BidiStringConverterTests.class);
-		suite.addTestSuite(BidiTransformerTests.class);
-		suite.addTestSuite(BitToolsTests.class);
-		suite.addTestSuite(SimpleBooleanReferenceTests.class);
-		suite.addTestSuite(BooleanToolsTests.class);
-		suite.addTestSuite(ClasspathTests.class);
-		suite.addTestSuite(ClassNameTests.class);
-		suite.addTestSuite(CollectionToolsTests.class);
-		suite.addTestSuite(ExceptionHandlerTests.class);
-		suite.addTestSuite(FileToolsTests.class);
-		suite.addTestSuite(FilterTests.class);
-		suite.addTestSuite(HashBagTests.class);
-		suite.addTestSuite(IdentityHashBagTests.class);
-		suite.addTestSuite(IndentingPrintWriterTests.class);
-		suite.addTestSuite(SimpleIntReferenceTests.class);
-		suite.addTestSuite(JavaTypeTests.class);
-		suite.addTestSuite(JDBCTypeTests.class);
-		suite.addTestSuite(KeyedSetTests.class);
-		suite.addTestSuite(ListenerListTests.class);
-		suite.addTestSuite(MethodSignatureTests.class);
-		suite.addTestSuite(NameToolsTests.class);
-		suite.addTestSuite(NotNullFilterTests.class);
-		suite.addTestSuite(RangeTests.class);
-		suite.addTestSuite(ReflectionToolsTests.class);
-		suite.addTestSuite(ReverseComparatorTests.class);
-		suite.addTestSuite(SimpleAssociationTests.class);
-		suite.addTestSuite(SimpleObjectReferenceTests.class);
-		suite.addTestSuite(SimpleQueueTests.class);
-		suite.addTestSuite(SimpleStackTests.class);
-		suite.addTestSuite(StringToolsTests.class);
-		suite.addTestSuite(SynchronizedBooleanTests.class);
-		suite.addTestSuite(SynchronizedIntTests.class);
-		suite.addTestSuite(SynchronizedObjectTests.class);
-		suite.addTestSuite(SynchronizedQueueTests.class);
-		suite.addTestSuite(SynchronizedStackTests.class);
-		suite.addTestSuite(ToolsTests.class);
-		suite.addTestSuite(VersionComparatorTests.class);
-		suite.addTestSuite(XMLStringEncoderTests.class);
-
-		return suite;
-	}
-
-	private CommonUtilityTests() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ExceptionHandlerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ExceptionHandlerTests.java
deleted file mode 100644
index b92ebf9..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ExceptionHandlerTests.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-import org.eclipse.persistence.tools.utility.ExceptionHandler;
-
-public class ExceptionHandlerTests extends TestCase {
-
-	public ExceptionHandlerTests(String name) {
-		super(name);
-	}
-
-	public void testNullExceptionHandler() {
-		ExceptionHandler exceptionHandler = ExceptionHandler.Null.instance();
-		exceptionHandler.handleException(new NullPointerException());  // just make sure it doesn't blow up?
-	}
-
-	public void testNullExceptionHandlerToString() {
-		ExceptionHandler exceptionHandler = ExceptionHandler.Null.instance();
-		assertNotNull(exceptionHandler.toString());
-	}
-
-	public void testRuntimeExceptionHandler1() {
-		Exception npe = new Exception();
-		ExceptionHandler exceptionHandler = ExceptionHandler.Runtime.instance();
-		boolean exCaught = false;
-		try {
-			exceptionHandler.handleException(npe);
-			fail();
-		} catch (RuntimeException ex) {
-			assertSame(npe, ex.getCause());
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testRuntimeExceptionHandler2() {
-		Exception npe = new NullPointerException();
-		ExceptionHandler exceptionHandler = ExceptionHandler.Runtime.instance();
-		boolean exCaught = false;
-		try {
-			exceptionHandler.handleException(npe);
-			fail();
-		} catch (RuntimeException ex) {
-			assertSame(npe, ex);
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testRuntimeExceptionHandlerToString() {
-		ExceptionHandler exceptionHandler = ExceptionHandler.Runtime.instance();
-		assertNotNull(exceptionHandler.toString());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/FileToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/FileToolsTests.java
deleted file mode 100644
index f6557e6..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/FileToolsTests.java
+++ /dev/null
@@ -1,595 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.Reader;
-import java.io.Writer;
-import java.lang.reflect.InvocationTargetException;
-import java.net.URL;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.FileTools;
-import org.eclipse.persistence.tools.utility.ReflectionTools;
-import org.eclipse.persistence.tools.utility.Tools;
-
-@SuppressWarnings("nls")
-public class FileToolsTests extends TestCase {
-	private File tempDir;
-
-	public FileToolsTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.tempDir = this.buildTempDir();
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		super.tearDown();
-		this.deleteDir(this.tempDir);
-	}
-
-	public void testFilesIn() {
-		Collection<File> files = CollectionTools.collection(FileTools.filesIn(this.tempDir.getPath()));
-		assertEquals("invalid file count", 3, files.size());
-	}
-
-	public void testDirectoriesIn() {
-		Collection<File> files = CollectionTools.collection(FileTools.directoriesIn(this.tempDir.getPath()));
-		assertEquals("invalid directory count", 2, files.size());
-	}
-
-	public void testFilesInTree() {
-		Collection<File> files = CollectionTools.collection(FileTools.filesInTree(this.tempDir.getPath()));
-		assertEquals("invalid file count", 9, files.size());
-	}
-
-	public void testDirectoriesInTree() {
-		Collection<File> files = CollectionTools.collection(FileTools.directoriesInTree(this.tempDir.getPath()));
-		assertEquals("invalid directory count", 3, files.size());
-	}
-
-	public void testDeleteDirectory() throws IOException {
-		// build another temporary directory just for this test
-		File dir = this.buildTempDir();
-		assertTrue("temporary directory not created", dir.exists());
-		FileTools.deleteDirectory(dir.getPath());
-		assertFalse("temporary directory not deleted", dir.exists());
-	}
-
-	public void testDeleteDirectoryContents() throws IOException {
-		// build another temporary directory just for this test
-		File dir = this.buildTempDir();
-		assertTrue("temporary directory not created", dir.exists());
-		FileTools.deleteDirectoryContents(dir.getPath());
-		assertTrue("temporary directory should not have been deleted", dir.exists());
-		assertTrue("temporary directory contents not deleted", dir.listFiles().length == 0);
-		dir.delete();
-	}
-
-	public void testCopyToFile() throws IOException {
-		File destFile = new File(this.tempDir, "destfile.txt");
-		this.copyToFile(destFile, "testCopyToFile");
-	}
-
-	public void testCopyToPreExistingFile() throws IOException {
-		File destFile = new File(this.tempDir, "destfile.txt");
-		Writer writer = new OutputStreamWriter(new FileOutputStream(destFile));
-		writer.write("this text should be replaced...");
-		writer.close();
-		this.copyToFile(destFile, "testCopyToPreExistingFile");
-	}
-
-	private void copyToFile(File destFile, String writeString) throws IOException {
-		File sourceFile = new File(this.tempDir, "sourcefile.txt");
-		char[] readBuffer = new char[writeString.length()];
-
-		Writer writer = new OutputStreamWriter(new FileOutputStream(sourceFile));
-		writer.write(writeString);
-		writer.close();
-
-		FileTools.copyToFile(sourceFile, destFile);
-
-		Reader reader = new InputStreamReader(new FileInputStream(destFile));
-		reader.read(readBuffer);
-		reader.close();
-		String readString = new String(readBuffer);
-		assertEquals(writeString, readString);
-	}
-
-	public void testCopyToDirectory() throws IOException {
-		File sourceFile = new File(this.tempDir, "sourcefile.txt");
-		String writeString = "testCopyToDirectory";
-
-		File destDir = new File(this.tempDir, "destdir");
-		destDir.mkdir();
-		File destFile = new File(destDir, "sourcefile.txt");
-		char[] readBuffer = new char[writeString.length()];
-
-		Writer writer = new OutputStreamWriter(new FileOutputStream(sourceFile));
-		writer.write(writeString);
-		writer.close();
-
-		FileTools.copyToDirectory(sourceFile, destDir);
-
-		Reader reader = new InputStreamReader(new FileInputStream(destFile));
-		reader.read(readBuffer);
-		reader.close();
-		String readString = new String(readBuffer);
-		assertEquals(writeString, readString);
-
-		FileTools.copyToDirectory(sourceFile, destDir); //Try again with the directory is already created
-		reader = new InputStreamReader(new FileInputStream(destFile));
-		reader.read(readBuffer);
-		reader.close();
-		readString = new String(readBuffer);
-		assertEquals(writeString, readString);
-	}
-
-	public void testFilter() throws IOException {
-		String prefix = "XXXtestFileXXX";
-		File testFile1 = new File(this.tempDir, prefix + "1");
-		testFile1.createNewFile();
-		File testFile2 = new File(this.tempDir, prefix + "2");
-		testFile2.createNewFile();
-
-		FileFilter filter = this.buildFileFilter(prefix);
-		Iterator<File> filteredFilesIterator = FileTools.filter(FileTools.filesIn(this.tempDir), filter);
-		Collection<File> filteredFiles = CollectionTools.collection(filteredFilesIterator);
-		assertEquals(2, filteredFiles.size());
-		assertTrue(filteredFiles.contains(testFile1));
-		assertTrue(filteredFiles.contains(testFile2));
-	}
-
-	private FileFilter buildFileFilter(final String prefix) {
-		return new FileFilter() {
-			public boolean accept(File file) {
-				return file.getName().startsWith(prefix);
-			}
-		};
-	}
-
-	public void testStripExtension() {
-		assertEquals("foo", FileTools.stripExtension("foo.xml"));
-		assertEquals("foo.bar", FileTools.stripExtension("foo.bar.xml"));
-		assertEquals("foo", FileTools.stripExtension("foo"));
-		assertEquals("foo", FileTools.stripExtension("foo."));
-	}
-
-	public void testExtension() {
-		assertEquals(".xml", FileTools.extension("foo.xml"));
-		assertEquals(".xml", FileTools.extension("foo.bar.xml"));
-		assertEquals("", FileTools.extension("foo"));
-		assertEquals("", FileTools.extension("foo,xml"));
-		assertEquals(".", FileTools.extension("foo."));
-	}
-
-	public void testEmptyTemporaryDirectory() throws IOException {
-		File tempDir1 = FileTools.temporaryDirectory();
-		File testFile1 = new File(tempDir1, "junk");
-		testFile1.createNewFile();
-
-		File tempDir2 = FileTools.emptyTemporaryDirectory();
-		assertEquals(tempDir1, tempDir2);
-		assertTrue(tempDir2.isDirectory());
-		assertEquals(0, tempDir2.listFiles().length);
-		tempDir2.delete();
-	}
-
-	public void testCanonicalFileName() {
-		File file1 = new File("foo");
-		file1 = new File(file1, "bar");
-		file1 = new File(file1, "baz");
-		file1 = new File(file1, "..");
-		file1 = new File(file1, "..");
-		file1 = new File(file1, "bar");
-		file1 = new File(file1, "baz");
-		File file2 = new File(System.getProperty("user.dir"));
-		file2 = new File(file2, "foo");
-		file2 = new File(file2, "bar");
-		file2 = new File(file2, "baz");
-		File file3 = FileTools.canonicalFile(file1);
-		assertEquals(file2, file3);
-	}
-
-	public void testPathFiles() {
-		File[] expected;
-		File[] actual;
-
-		if (Tools.osIsWindows()) {
-			expected = new File[] { new File("C:/"), new File("C:/foo"), new File("C:/foo/bar"), new File("C:/foo/bar/baz.txt") };
-			actual = this.pathFiles(new File("C:/foo/bar/baz.txt"));
-			assertTrue(Arrays.equals(expected, actual));
-		}
-
-		expected = new File[] { new File("/"), new File("/foo"), new File("/foo/bar"), new File("/foo/bar/baz.txt") };
-		actual = this.pathFiles(new File("/foo/bar/baz.txt"));
-		assertTrue(Arrays.equals(expected, actual));
-
-		expected = new File[] { new File("foo"), new File("foo/bar"), new File("foo/bar/baz.txt") };
-		actual = this.pathFiles(new File("foo/bar/baz.txt"));
-		assertTrue(Arrays.equals(expected, actual));
-
-		expected = new File[] { new File(".."), new File("../foo"), new File("../foo/bar"), new File("../foo/bar/baz.txt") };
-		actual = this.pathFiles(new File("../foo/bar/baz.txt"));
-		assertTrue(Arrays.equals(expected, actual));
-
-		expected = new File[] { new File("."), new File("./foo"), new File("./foo/bar"), new File("./foo/bar/baz.txt") };
-		actual = this.pathFiles(new File("./foo/bar/baz.txt"));
-		assertTrue(Arrays.equals(expected, actual));
-	}
-
-	private File[] pathFiles(File file) {
-		return (File[]) ReflectionTools.executeStaticMethod(FileTools.class, "pathFiles", File.class, file);
-	}
-
-	public void testRelativeParentFile() {
-		assertEquals(new File(".."), this.relativeParentFile(1));
-		assertEquals(new File("../.."), this.relativeParentFile(2));
-		assertEquals(new File("../../.."), this.relativeParentFile(3));
-
-		boolean exCaught = false;
-		try {
-			File file = this.relativeParentFile(0);
-			fail("invalid return: " + file);
-		} catch (RuntimeException ex) {
-			if (ex.getCause() instanceof InvocationTargetException) {
-				InvocationTargetException ite = (InvocationTargetException) ex.getCause();
-				if (ite.getTargetException() instanceof IllegalArgumentException) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-	private File relativeParentFile(int len) {
-		return (File) ReflectionTools.executeStaticMethod(FileTools.class, "relativeParentFile", int.class, new Integer(len));
-	}
-
-	public void testConvertToRelativeFile() {
-		String prefix = Tools.osIsWindows() ? "C:" : "";
-		File file;
-		File dir;
-		File relativeFile;
-
-		if (Tools.osIsWindows()) {
-			// on Windows, a drive must be specified for a file to be absolute (i.e. not relative)
-			this.verifyUnchangedRelativeFile("/dir1/dir2/file.txt", "C:/dir1/dir2");
-			// different drives
-			this.verifyUnchangedRelativeFile("D:/dir1/dir2/file.txt", "C:/dir1/dir2");
-		}
-		this.verifyUnchangedRelativeFile("dir1/dir2/file.txt", prefix + "/dir1/dir2");
-		this.verifyUnchangedRelativeFile("./dir1/dir2/file.txt", prefix + "/dir1/dir2");
-		this.verifyUnchangedRelativeFile("../../dir1/dir2/file.txt", prefix + "/dir1/dir2");
-
-		file = new File(prefix + "/dir1/dir2");
-		dir = new File(prefix + "/dir1/dir2");
-		relativeFile = FileTools.convertToRelativeFile(file, dir);
-		assertEquals(new File("."), relativeFile);
-
-		file = new File(prefix + "/dir1/dir2/file.txt");
-		dir = new File(prefix + "/dir1/dir2");
-		relativeFile = FileTools.convertToRelativeFile(file, dir);
-		assertEquals(new File("file.txt"), relativeFile);
-
-		file = new File(prefix + "/dir1/dir2/../dir2/file.txt");
-		dir = new File(prefix + "/dir1/dir2");
-		relativeFile = FileTools.convertToRelativeFile(file, dir);
-		assertEquals(new File("file.txt"), relativeFile);
-
-		file = new File(prefix + "/dir1/dir2/dir3/dir4/dir5/file.txt");
-		dir = new File(prefix + "/dir1/dir2");
-		relativeFile = FileTools.convertToRelativeFile(file, dir);
-		assertEquals(new File("dir3/dir4/dir5/file.txt"), relativeFile);
-
-		file = new File(prefix + "/dir1/dir2/file.txt");
-		dir = new File(prefix + "/dir1/dir2/dir3/dir4/dir5");
-		relativeFile = FileTools.convertToRelativeFile(file, dir);
-		assertEquals(new File("../../../file.txt"), relativeFile);
-
-		file = new File(prefix + "/dir1/dir2/file.txt");
-		dir = new File(prefix + "/dir1/dir2/dir3");
-		relativeFile = FileTools.convertToRelativeFile(file, dir);
-		assertEquals(new File("../file.txt"), relativeFile);
-
-		file = new File(prefix + "/dir1/dir2/dirA/dirB/dirC/file.txt");
-		dir = new File(prefix + "/dir1/dir2/dir3/dir4/dir5");
-		relativeFile = FileTools.convertToRelativeFile(file, dir);
-		assertEquals(new File("../../../dirA/dirB/dirC/file.txt"), relativeFile);
-
-		file = new File(prefix + "/dir1/dir2");
-		dir = new File(prefix + "/dir1/dir2/dir3/dir4/dir5");
-		relativeFile = FileTools.convertToRelativeFile(file, dir);
-		assertEquals(new File("../../.."), relativeFile);
-
-		file = new File(prefix + "/My Documents/My Workspace/Project 1/lib/toplink.jar");
-		dir = new File(prefix + "/My Documents/My Workspace/Project 1");
-		relativeFile = FileTools.convertToRelativeFile(file, dir);
-		assertEquals(new File("lib/toplink.jar"), relativeFile);
-	}
-
-	private void verifyUnchangedRelativeFile(String fileName, String dirName) {
-		File file = new File(fileName);
-		File dir = new File(dirName);
-		File relativeFile = FileTools.convertToRelativeFile(file, dir);
-		assertEquals(file, relativeFile);
-	}
-
-	public void testConvertToAbsoluteFile() {
-		String prefix = Tools.osIsWindows() ? "C:" : "";
-		File file;
-		File dir;
-		File absoluteFile;
-
-		if (Tools.osIsWindows()) {
-			// on Windows, a drive must be specified for a file to be absolute (i.e. not relative)
-			this.verifyUnchangedAbsoluteFile("C:/dir1/dir2/file.txt", "C:/dir1/dir2");
-			// different drives
-			this.verifyUnchangedAbsoluteFile("D:/dir1/dir2/file.txt", "C:/dir1/dir2");
-		}
-		this.verifyUnchangedAbsoluteFile(prefix + "/dir1/dir2/file.txt", prefix + "/dir1/dir2");
-		this.verifyUnchangedAbsoluteFile(prefix + "/./dir1/dir2/file.txt", prefix + "/dir1/dir2");
-		this.verifyUnchangedAbsoluteFile(prefix + "/dir1/dir2/../../dir1/dir2/file.txt", prefix + "/dir1/dir2");
-
-		file = new File(".");
-		dir = new File(prefix + "/dir1/dir2");
-		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
-		assertEquals(new File(prefix + "/dir1/dir2"), absoluteFile);
-
-		file = new File("./file.txt");
-		dir = new File(prefix + "/dir1/dir2");
-		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
-		assertEquals(new File(prefix + "/dir1/dir2/file.txt"), absoluteFile);
-
-		file = new File("file.txt");
-		dir = new File(prefix + "/dir1/dir2");
-		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
-		assertEquals(new File(prefix + "/dir1/dir2/file.txt"), absoluteFile);
-
-		file = new File("../dir2/file.txt");
-		dir = new File(prefix + "/dir1/dir2");
-		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
-		assertEquals(new File(prefix + "/dir1/dir2/file.txt"), absoluteFile);
-
-		file = new File("dir3/dir4/dir5/file.txt");
-		dir = new File(prefix + "/dir1/dir2");
-		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
-		assertEquals(new File(prefix + "/dir1/dir2/dir3/dir4/dir5/file.txt"), absoluteFile);
-
-		file = new File("../../../file.txt");
-		dir = new File(prefix + "/dir1/dir2/dir3/dir4/dir5");
-		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
-		assertEquals(new File(prefix + "/dir1/dir2/file.txt"), absoluteFile);
-
-		// too many ".." directories will resolve to the root;
-		// this is consistent with Windows and Linux command shells
-		file = new File("../../../../../../../../file.txt");
-		dir = new File(prefix + "/dir1/dir2");
-		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
-		assertEquals(new File(prefix + "/file.txt"), absoluteFile);
-
-		file = new File("../file.txt");
-		dir = new File(prefix + "/dir1/dir2/dir3");
-		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
-		assertEquals(new File(prefix + "/dir1/dir2/file.txt"), absoluteFile);
-
-		file = new File("../../../dirA/dirB/dirC/file.txt");
-		dir = new File(prefix + "/dir1/dir2/dir3/dir4/dir5");
-		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
-		assertEquals(new File(prefix + "/dir1/dir2/dirA/dirB/dirC/file.txt"), absoluteFile);
-
-		file = new File("../../..");
-		dir = new File(prefix + "/dir1/dir2/dir3/dir4/dir5");
-		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
-		assertEquals(new File(prefix + "/dir1/dir2"), absoluteFile);
-
-		file = new File("lib/toplink.jar");
-		dir = new File(prefix + "/My Documents/My Workspace/Project 1");
-		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
-		assertEquals(new File(prefix + "/My Documents/My Workspace/Project 1/lib/toplink.jar"), absoluteFile);
-	}
-
-	public void testFileNameIsReserved() {
-		boolean expected = Tools.osIsWindows();
-		assertEquals(expected, FileTools.fileNameIsReserved("CON"));
-		assertEquals(expected, FileTools.fileNameIsReserved("con"));
-		assertEquals(expected, FileTools.fileNameIsReserved("cON"));
-		assertEquals(expected, FileTools.fileNameIsReserved("AUX"));
-		assertEquals(expected, FileTools.fileNameIsReserved("COM3"));
-		assertEquals(expected, FileTools.fileNameIsReserved("LPT3"));
-		assertEquals(expected, FileTools.fileNameIsReserved("nUL"));
-		assertEquals(expected, FileTools.fileNameIsReserved("Prn"));
-	}
-
-	public void testFileHasAnyReservedComponents() {
-		boolean expected = Tools.osIsWindows();
-		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("C:/CON")));
-		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("/con/foo")));
-		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("c:/temp/cON")));
-		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("bar//baz//AUX")));
-		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("COM3//ttt")));
-		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("d:/LPT3/xxx")));
-		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("c:/my docs and stuff/tuesday/nUL")));
-		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("Prn")));
-	}
-
-	public void testShortenFileNameFile() {
-		if (Tools.osIsWindows()) {
-			this.verifyShortenFileNameFileWin();
-		} else {
-			this.verifyShortenFileNameFileNonWin();
-		}
-	}
-
-	private void verifyShortenFileNameFileWin() {
-		File file = new File("C:\\Documents and Settings\\Administrator\\Desktop\\Project\\Text.txt");
-		String fileName = FileTools.shortenFileName(file);
-		assertEquals("C:\\Documents and Settings\\...\\Desktop\\Project\\Text.txt", fileName);
-		assertTrue(fileName.length() <= FileTools.MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
-
-		file = new File("C:/");
-		fileName = FileTools.shortenFileName(file);
-		assertEquals("C:\\", fileName);
-		assertTrue(fileName.length() <= FileTools.MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
-	}
-
-	private void verifyShortenFileNameFileNonWin() {
-		File file = new File("/home/administrator/documents and settings/desktop/Project/Text.txt");
-		String fileName = FileTools.shortenFileName(file);
-		assertEquals("/home/administrator/.../desktop/Project/Text.txt", fileName);
-		assertTrue(fileName.length() <= FileTools.MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
-
-		file = new File("/home");
-		fileName = FileTools.shortenFileName(file);
-		assertEquals("/home", fileName);
-		assertTrue(fileName.length() <= FileTools.MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
-	}
-
-	public void testShortenFileNameFileInt() {
-		if (Tools.osIsWindows()) {
-			this.verifyShortenFileNameFileIntWin();
-		} else {
-			this.verifyShortenFileNameFileIntNonWin();
-		}
-	}
-
-	private void verifyShortenFileNameFileIntWin() {
-		File file = new File("C:\\Documents and Settings\\Administrator\\Desktop\\Project\\Text.txt");
-		String fileName = FileTools.shortenFileName(file, 31);
-		assertEquals("C:\\...\\Desktop\\Project\\Text.txt", fileName);
-		assertEquals(31, fileName.length());
-
-		file = new File("C:/This is the file name.txt");
-		fileName = FileTools.shortenFileName(file, 10);
-		assertEquals("C:\\This is the file name.txt", fileName);
-		assertEquals(28, fileName.length());
-	}
-
-	private void verifyShortenFileNameFileIntNonWin() {
-		File file = new File("/home/administrator/documents and settings/desktop/Project/Text.txt");
-		String fileName = FileTools.shortenFileName(file, 31);
-		assertEquals("/home/.../desktop/Project/Text.txt", fileName);
-		assertEquals(34, fileName.length());
-
-		file = new File("/This is the file name.txt");
-		fileName = FileTools.shortenFileName(file, 10);
-		assertEquals("/This is the file name.txt", fileName);
-		assertEquals(26, fileName.length());
-	}
-
-	public void testShortenFileNameURL() throws Exception {
-		if (Tools.osIsWindows()) {
-			this.verifyShortenFileNameURLWin();
-		} else {
-			this.verifyShortenFileNameURLNonWin();
-		}
-	}
-
-	private void verifyShortenFileNameURLWin() throws Exception {
-		URL url = new URL("file", "", "C:/Documents and Settings/Administrator/Desktop/Project/Text.txt");
-		String fileName = FileTools.shortenFileName(url);
-		assertEquals("C:\\Documents and Settings\\...\\Desktop\\Project\\Text.txt", fileName);
-		assertTrue(fileName.length() <= FileTools.MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
-	}
-
-	private void verifyShortenFileNameURLNonWin() throws Exception {
-		URL url = new URL("file", "", "/home/administrator/documents and settings/desktop/Project/Text.txt");
-		String fileName = FileTools.shortenFileName(url);
-		assertEquals("/home/administrator/.../desktop/Project/Text.txt", fileName);
-		assertTrue(fileName.length() <= FileTools.MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
-	}
-
-	public void testShortenFileNameURLInt() throws Exception {
-		if (Tools.osIsWindows()) {
-			this.verifyShortenFileNameURLIntWin();
-		} else {
-			this.verifyShortenFileNameURLIntNonWin();
-		}
-	}
-
-	private void verifyShortenFileNameURLIntWin() throws Exception {
-		URL url = new URL("file", "", "/C:/Documents and Settings/Administrator/Desktop/Project/Text.txt");
-		String fileName = FileTools.shortenFileName(url, 31);
-		assertEquals("C:\\...\\Desktop\\Project\\Text.txt", fileName);
-		assertEquals(31, fileName.length());
-	}
-
-	private void verifyShortenFileNameURLIntNonWin() throws Exception {
-		URL url = new URL("file", "", "/home/administrator/documents and settings/desktop/Project/Text.txt");
-		String fileName = FileTools.shortenFileName(url, 31);
-		assertEquals("/home/.../desktop/Project/Text.txt", fileName);
-		assertEquals(34, fileName.length());
-	}
-
-	private void verifyUnchangedAbsoluteFile(String fileName, String dirName) {
-		File file = new File(fileName);
-		File dir = new File(dirName);
-		File absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
-		assertEquals(file, absoluteFile);
-	}
-
-	private File buildTempDir() throws IOException {
-		// build a new directory for each test, to prevent any cross-test effects
-		File dir = FileTools.newTemporaryDirectory(this.getClass().getSimpleName() + "." + this.getName());
-
-		File file0a = new File(dir, "file0a");
-		file0a.createNewFile();
-		File file0b = new File(dir, "file0b");
-		file0b.createNewFile();
-		File file0c = new File(dir, "file0c");
-		file0c.createNewFile();
-
-		File subdir1 = new File(dir, "subdir1");
-		subdir1.mkdir();
-		File file1a = new File(subdir1, "file1a");
-		file1a.createNewFile();
-		File file1b = new File(subdir1, "file1b");
-		file1b.createNewFile();
-
-		File subdir2 = new File(dir, "subdir2");
-		subdir2.mkdir();
-		File file2a = new File(subdir2, "file2a");
-		file2a.createNewFile();
-		File file2b = new File(subdir2, "file2b");
-		file2b.createNewFile();
-
-		File subdir3 = new File(subdir2, "subdir3");
-		subdir3.mkdir();
-		File file3a = new File(subdir3, "file3a");
-		file3a.createNewFile();
-		File file3b = new File(subdir3, "file3b");
-		file3b.createNewFile();
-
-		return dir;
-	}
-
-	private void deleteDir(File dir) {
-		FileTools.deleteDirectory(dir);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/FilterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/FilterTests.java
deleted file mode 100644
index fe39ac6..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/FilterTests.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-import org.eclipse.persistence.tools.utility.Filter;
-
-@SuppressWarnings("nls")
-public class FilterTests extends TestCase {
-
-	public FilterTests(String name) {
-		super(name);
-	}
-
-	public void testNullFilter() {
-		Filter<String> filter = Filter.Transparent.instance();
-		assertTrue(filter.accept(""));
-		assertTrue(filter.accept("foo"));
-		assertTrue(filter.accept("bar"));
-	}
-
-	public void testNullFilter_toString() {
-		Filter<String> filter = Filter.Transparent.instance();
-		assertNotNull(filter.toString());
-	}
-
-	public void testNullFilter_serialization() throws Exception {
-		Filter<String> filter = Filter.Transparent.instance();
-		assertSame(filter, TestTools.serialize(filter));
-	}
-
-	public void testOpaqueFilter() {
-		Filter<String> filter = Filter.Opaque.instance();
-		assertFalse(filter.accept(""));
-		assertFalse(filter.accept("foo"));
-		assertFalse(filter.accept("bar"));
-	}
-
-	public void testOpaqueFilter_toString() {
-		Filter<String> filter = Filter.Opaque.instance();
-		assertNotNull(filter.toString());
-	}
-
-	public void testOpaqueFilter_serialization() throws Exception {
-		Filter<String> filter = Filter.Opaque.instance();
-		assertSame(filter, TestTools.serialize(filter));
-	}
-
-	public void testDisabledFilter() {
-		Filter<String> filter = Filter.Disabled.instance();
-		boolean exCaught = false;
-		try {
-			assertFalse(filter.accept("foo"));
-			fail();
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testDisabledFilter_toString() {
-		Filter<String> filter = Filter.Disabled.instance();
-		assertNotNull(filter.toString());
-	}
-
-	public void testDisabledFilter_serialization() throws Exception {
-		Filter<String> filter = Filter.Disabled.instance();
-		assertSame(filter, TestTools.serialize(filter));
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/HashBagTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/HashBagTests.java
deleted file mode 100644
index 2006789..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/HashBagTests.java
+++ /dev/null
@@ -1,557 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.ArrayTools;
-import org.eclipse.persistence.tools.utility.Bag;
-import org.eclipse.persistence.tools.utility.HashBag;
-import org.eclipse.persistence.tools.utility.Tools;
-
-@SuppressWarnings("nls")
-public class HashBagTests extends TestCase {
-	private HashBag<String> bag;
-
-	public HashBagTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.bag = this.buildBag();
-	}
-
-	private HashBag<String> buildBag() {
-		HashBag<String> b = new HashBag<String>();
-		b.add(null);
-		b.add(new String("one"));
-		b.add(new String("two"));
-		b.add(new String("two"));
-		b.add(new String("three"));
-		b.add(new String("three"));
-		b.add(new String("three"));
-		b.add(new String("four"));
-		b.add(new String("four"));
-		b.add(new String("four"));
-		b.add(new String("four"));
-		return b;
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		TestTools.clear(this);
-		super.tearDown();
-	}
-
-	private Collection<String> buildCollection() {
-		Collection<String> c = new ArrayList<String>();
-		c.add(new String("foo"));
-		c.add(new String("foo"));
-		c.add(new String("bar"));
-		c.add(new String("bar"));
-		c.add(new String("bar"));
-		return c;
-	}
-
-	public void testCtorCollection() {
-		Collection<String> c = this.buildCollection();
-		Bag<String> b = new HashBag<String>(c);
-		for (String s : c) {
-			assertTrue(b.contains(s));
-		}
-	}
-
-	public void testCtorIntFloat() {
-		boolean exCaught;
-
-		exCaught = false;
-		try {
-			this.bag = new HashBag<String>(-20, 0.66f);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		exCaught = false;
-		try {
-			this.bag = new HashBag<String>(20, -0.66f);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testAdd() {
-		// the other adds took place in setUp
-		assertTrue(this.bag.add("five"));
-
-		assertTrue(this.bag.contains("one"));
-		assertTrue(this.bag.contains("two"));
-		assertTrue(this.bag.contains("three"));
-		assertTrue(this.bag.contains("four"));
-		assertTrue(this.bag.contains("five"));
-	}
-
-	public void testAddCount() {
-		// the other adds took place in setUp
-		this.bag.add("minus3", -3);
-		this.bag.add("zero", 0);
-		this.bag.add("five", 5);
-
-		assertFalse(this.bag.contains("minus3"));
-		assertFalse(this.bag.contains("zero"));
-		assertEquals(1, this.bag.count("one"));
-		assertEquals(2, this.bag.count("two"));
-		assertEquals(3, this.bag.count("three"));
-		assertEquals(4, this.bag.count("four"));
-		assertEquals(5, this.bag.count("five"));
-
-		this.bag.add("three", 2);
-		assertEquals(5, this.bag.count("three"));
-	}
-
-	public void testAddAll() {
-		Collection<String> c = this.buildCollection();
-		assertTrue(this.bag.addAll(c));
-		for (String s : c) {
-			assertTrue(this.bag.contains(s));
-		}
-	}
-
-	public void testClear() {
-		assertTrue(this.bag.contains("one"));
-		assertTrue(this.bag.contains("two"));
-		assertTrue(this.bag.contains("three"));
-		assertTrue(this.bag.contains("four"));
-		assertTrue(this.bag.contains(null));
-		assertEquals(11, this.bag.size());
-		this.bag.clear();
-		assertFalse(this.bag.contains("one"));
-		assertFalse(this.bag.contains("two"));
-		assertFalse(this.bag.contains("three"));
-		assertFalse(this.bag.contains("four"));
-		assertFalse(this.bag.contains(null));
-		assertEquals(0, this.bag.size());
-	}
-
-	public void testClone() {
-		Bag<String> bag2 = this.bag.clone();
-		assertTrue(this.bag != bag2);
-		assertEquals(this.bag, bag2);
-		assertTrue(this.bag.hashCode() == bag2.hashCode());
-	}
-
-	public void testContains() {
-		assertTrue(this.bag.contains(null));
-		assertTrue(this.bag.contains("one"));
-		assertTrue(this.bag.contains("two"));
-		assertTrue(this.bag.contains("three"));
-		assertTrue(this.bag.contains("four"));
-		assertTrue(this.bag.contains(new String("four")));
-		assertTrue(this.bag.contains("fo" + "ur"));
-		assertFalse(this.bag.contains("five"));
-	}
-
-	public void testContainsAll() {
-		Collection<String> c = new ArrayList<String>();
-		c.add(null);
-		c.add(new String("one"));
-		c.add(new String("two"));
-		c.add(new String("three"));
-		c.add(new String("four"));
-		assertTrue(this.bag.containsAll(c));
-	}
-
-	public void testCount() {
-		assertEquals(0, this.bag.count("zero"));
-		assertEquals(1, this.bag.count("one"));
-		assertEquals(2, this.bag.count("two"));
-		assertEquals(3, this.bag.count("three"));
-		assertEquals(4, this.bag.count("four"));
-		assertEquals(0, this.bag.count("five"));
-	}
-
-	public void testEquals() {
-		Bag<String> bag2 = this.buildBag();
-		assertEquals(this.bag, bag2);
-		bag2.add("five");
-		assertFalse(this.bag.equals(bag2));
-		Collection<String> c = new ArrayList<String>(this.bag);
-		assertFalse(this.bag.equals(c));
-	}
-
-	public void testHashCode() {
-		Bag<String> bag2 = this.buildBag();
-		assertEquals(this.bag.hashCode(), bag2.hashCode());
-	}
-
-	public void testIsEmpty() {
-		assertFalse(this.bag.isEmpty());
-		this.bag.clear();
-		assertTrue(this.bag.isEmpty());
-		this.bag.add("foo");
-		assertFalse(this.bag.isEmpty());
-	}
-
-	public void testEmptyIterator() {
-		this.bag.clear();
-		Iterator<String> iterator = this.bag.iterator();
-		assertFalse(iterator.hasNext());
-
-		boolean exCaught = false;
-		Object element = null;
-		try {
-			element = iterator.next();
-			fail(element.toString());
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		exCaught = false;
-		try {
-			iterator.remove();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testIterator() {
-		int i = 0;
-		Iterator<String> iterator = this.bag.iterator();
-		assertTrue(iterator.hasNext());
-		while (iterator.hasNext()) {
-			iterator.next();
-			i++;
-		}
-		assertEquals(11, i);
-		assertFalse(iterator.hasNext());
-
-		boolean exCaught = false;
-		Object element = null;
-		try {
-			element = iterator.next();
-			fail(element.toString());
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		iterator.remove();
-		assertEquals(10, this.bag.size());
-
-		exCaught = false;
-		try {
-			iterator.remove();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		// start over
-		iterator = this.bag.iterator();
-		this.bag.add("five");
-		exCaught = false;
-		try {
-			iterator.next();
-		} catch (ConcurrentModificationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testUniqueIterator() {
-		int i = 0;
-		Iterator<String> iterator = this.bag.uniqueIterator();
-		assertTrue(iterator.hasNext());
-		while (iterator.hasNext()) {
-			iterator.next();
-			i++;
-		}
-		assertEquals(5, i);
-		assertFalse(iterator.hasNext());
-
-		boolean exCaught = false;
-		Object element = null;
-		try {
-			element = iterator.next();
-			fail(element.toString());
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		// start over
-		iterator = this.bag.uniqueIterator();
-		Object next = null;
-		while (iterator.hasNext() && !"four".equals(next)) {
-			next = iterator.next();
-		}
-		iterator.remove();
-		assertEquals(7, this.bag.size());
-
-		exCaught = false;
-		try {
-			iterator.remove();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		// start over
-		iterator = this.bag.uniqueIterator();
-		this.bag.add("five");
-		exCaught = false;
-		try {
-			iterator.next();
-		} catch (ConcurrentModificationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testEntries() {
-		int i = 0;
-		Iterator<Bag.Entry<String>> iterator = this.bag.entries();
-		assertTrue(iterator.hasNext());
-		while (iterator.hasNext()) {
-			iterator.next();
-			i++;
-		}
-		assertEquals(5, i);
-		assertFalse(iterator.hasNext());
-
-		boolean exCaught = false;
-		Object element = null;
-		try {
-			element = iterator.next();
-			fail(element.toString());
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		// start over
-		iterator = this.bag.entries();
-		Bag.Entry<String> next = null;
-		while (iterator.hasNext()) {
-			next = iterator.next();
-			if (next.getElement().equals("four")) {
-				iterator.remove();
-				break;
-			}
-		}
-		assertEquals(7, this.bag.size());
-
-		exCaught = false;
-		try {
-			iterator.remove();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		// start over
-		iterator = this.bag.entries();
-		this.bag.add("five");
-		exCaught = false;
-		try {
-			iterator.next();
-		} catch (ConcurrentModificationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testHashingDistribution() throws Exception {
-		Bag<String> bigBag = new HashBag<String>();
-		for (int i = 0; i < 10000; i++) {
-			bigBag.add("object" + i);
-		}
-
-		java.lang.reflect.Field field = bigBag.getClass().getDeclaredField("table");
-		field.setAccessible(true);
-		Object[] table = (Object[]) field.get(bigBag);
-		int bucketCount = table.length;
-		int filledBucketCount = 0;
-		for (Object o : table) {
-			if (o != null) {
-				filledBucketCount++;
-			}
-		}
-		float loadFactor = ((float) filledBucketCount) / ((float) bucketCount);
-		if ((loadFactor < 0.20) || (loadFactor > 0.80)) {
-			String msg = "poor load factor: " + loadFactor;
-			if (Tools.jvmIsSun()) {
-				fail(msg);
-			} else {
-				// poor load factor is seen in the Eclipse build environment for some reason...
-				System.out.println(this.getClass().getName() + '.' + this.getName() + " - " + msg);
-				TestTools.printSystemProperties();
-			}
-		}
-	}
-
-	public void testRemove() {
-		assertTrue(this.bag.remove("one"));
-		assertFalse(this.bag.contains("one"));
-		assertFalse(this.bag.remove("one"));
-
-		assertTrue(this.bag.remove("two"));
-		assertTrue(this.bag.remove("two"));
-		assertFalse(this.bag.contains("two"));
-		assertFalse(this.bag.remove("two"));
-	}
-
-	public void testRemoveCount() {
-		assertFalse(this.bag.remove("one", 0));
-		assertTrue(this.bag.contains("one"));
-
-		assertTrue(this.bag.remove("one", 1));
-		assertFalse(this.bag.contains("one"));
-		assertFalse(this.bag.remove("one"));
-
-		assertFalse(this.bag.remove("two", -3));
-		assertTrue(this.bag.remove("two", 1));
-		assertTrue(this.bag.contains("two"));
-
-		assertTrue(this.bag.remove("two", 1));
-		assertFalse(this.bag.contains("two"));
-		assertFalse(this.bag.remove("two"));
-
-		assertTrue(this.bag.remove("three", 3));
-		assertFalse(this.bag.contains("three"));
-		assertFalse(this.bag.remove("three"));
-	}
-
-	public void testRemoveAll() {
-		Collection<String> c = new ArrayList<String>();
-		c.add("one");
-		c.add("three");
-		assertTrue(this.bag.removeAll(c));
-		assertFalse(this.bag.contains("one"));
-		assertFalse(this.bag.contains("three"));
-		assertFalse(this.bag.remove("one"));
-		assertFalse(this.bag.remove("three"));
-		assertFalse(this.bag.removeAll(c));
-	}
-
-	public void testRetainAll() {
-		Collection<String> c = new ArrayList<String>();
-		c.add("one");
-		c.add("three");
-		assertTrue(this.bag.retainAll(c));
-		assertTrue(this.bag.contains("one"));
-		assertTrue(this.bag.contains("three"));
-		assertFalse(this.bag.contains("two"));
-		assertFalse(this.bag.contains("four"));
-		assertFalse(this.bag.remove("two"));
-		assertFalse(this.bag.remove("four"));
-		assertFalse(this.bag.retainAll(c));
-	}
-
-	public void testSize() {
-		assertTrue(this.bag.size() == 11);
-		this.bag.add("five");
-		this.bag.add("five");
-		this.bag.add("five");
-		this.bag.add("five");
-		this.bag.add("five");
-		assertEquals(16, this.bag.size());
-	}
-
-	public void testSerialization() throws Exception {
-		Bag<String> bag2 = TestTools.serialize(this.bag);
-
-		assertTrue("same object?", this.bag != bag2);
-		assertEquals(11, bag2.size());
-		assertEquals(this.bag, bag2);
-		// look for similar elements
-		assertTrue(bag2.contains(null));
-		assertTrue(bag2.contains("one"));
-		assertTrue(bag2.contains("two"));
-		assertTrue(bag2.contains("three"));
-		assertTrue(bag2.contains("four"));
-
-		int nullCount = 0, oneCount = 0, twoCount = 0, threeCount = 0, fourCount = 0;
-		for (String s : bag2) {
-			if (s == null) {
-				nullCount++;
-			} else if (s.equals("one")) {
-				oneCount++;
-			} else if (s.equals("two")) {
-				twoCount++;
-			} else if (s.equals("three")) {
-				threeCount++;
-			} else if (s.equals("four")) {
-				fourCount++;
-			}
-		}
-		assertEquals(1, nullCount);
-		assertEquals(1, oneCount);
-		assertEquals(2, twoCount);
-		assertEquals(3, threeCount);
-		assertEquals(4, fourCount);
-	}
-
-	public void testToArray() {
-		Object[] a = this.bag.toArray();
-		assertEquals(11, a.length);
-		assertTrue(ArrayTools.contains(a, null));
-		assertTrue(ArrayTools.contains(a, "one"));
-		assertTrue(ArrayTools.contains(a, "two"));
-		assertTrue(ArrayTools.contains(a, "three"));
-		assertTrue(ArrayTools.contains(a, "four"));
-	}
-
-	public void testToArrayObjectArray() {
-		String[] a = new String[12];
-		a[11] = "not null";
-		String[] b = this.bag.toArray(a);
-		assertEquals(a, b);
-		assertEquals(12, a.length);
-		assertTrue(ArrayTools.contains(a, null));
-		assertTrue(ArrayTools.contains(a, "one"));
-		assertTrue(ArrayTools.contains(a, "two"));
-		assertTrue(ArrayTools.contains(a, "three"));
-		assertTrue(ArrayTools.contains(a, "four"));
-		assertTrue(a[11] == null);
-	}
-
-	public void testToString() {
-		String s = this.bag.toString();
-		assertTrue(s.startsWith("["));
-		assertTrue(s.endsWith("]"));
-		int commaCount = 0;
-		for (int i = 0; i < s.length(); i++) {
-			if (s.charAt(i) == ',') {
-				commaCount++;
-			}
-		}
-		assertEquals(10, commaCount);
-		assertTrue(s.indexOf("one") != -1);
-		assertTrue(s.indexOf("two") != -1);
-		assertTrue(s.indexOf("three") != -1);
-		assertTrue(s.indexOf("four") != -1);
-		assertTrue(s.indexOf("null") != -1);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/IdentityHashBagTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/IdentityHashBagTests.java
deleted file mode 100644
index 95dd13e..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/IdentityHashBagTests.java
+++ /dev/null
@@ -1,576 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.ArrayTools;
-import org.eclipse.persistence.tools.utility.Bag;
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.IdentityHashBag;
-import org.eclipse.persistence.tools.utility.Tools;
-
-@SuppressWarnings("nls")
-public class IdentityHashBagTests extends TestCase {
-	private IdentityHashBag<String> bag;
-	private String one = "one";
-	private String two = "two";
-	private String three = "three";
-	private String four = "four";
-	private String foo = "foo";
-	private String bar = "bar";
-
-	public IdentityHashBagTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.bag = this.buildBag();
-	}
-
-	protected IdentityHashBag<String> buildBag() {
-		IdentityHashBag<String> result = new IdentityHashBag<String>();
-		result.add(null);
-		result.add(this.one);
-		result.add(this.two);
-		result.add(this.two);
-		result.add(this.three);
-		result.add(this.three);
-		result.add(this.three);
-		result.add(this.four);
-		result.add(this.four);
-		result.add(this.four);
-		result.add(this.four);
-		return result;
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		TestTools.clear(this);
-		super.tearDown();
-	}
-
-	private Collection<String> buildCollection() {
-		Collection<String> c = new ArrayList<String>();
-		c.add(this.foo);
-		c.add(this.foo);
-		c.add(this.bar);
-		c.add(this.bar);
-		c.add(this.bar);
-		return c;
-	}
-
-	public void testCtorCollection() {
-		Collection<String> c = this.buildCollection();
-		IdentityHashBag<String> localBag = new IdentityHashBag<String>(c);
-		for (String s : c) {
-			assertTrue(localBag.contains(s));
-		}
-	}
-
-	public void testCtorIntFloat() {
-		boolean exCaught;
-
-		exCaught = false;
-		try {
-			this.bag = new IdentityHashBag<String>(-20, 0.66f);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue("IllegalArgumentException not thrown", exCaught);
-
-		exCaught = false;
-		try {
-			this.bag = new IdentityHashBag<String>(20, -0.66f);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue("IllegalArgumentException not thrown", exCaught);
-	}
-
-	public void testAdd() {
-		// the other adds took place in setUp
-		String five = "five";
-		assertTrue(this.bag.add(five));
-
-		assertTrue(this.bag.contains(this.one));
-		assertTrue(this.bag.contains(this.two));
-		assertTrue(this.bag.contains(this.three));
-		assertTrue(this.bag.contains(this.four));
-		assertTrue(this.bag.contains(five));
-	}
-
-	public void testAddCount() {
-		String minus3 = "minus3";
-		String zero = "zero";
-		String five = "five";
-		// the other adds took place in setUp
-		this.bag.add(minus3, -3);
-		this.bag.add(zero, 0);
-		this.bag.add(five, 5);
-
-		assertFalse(this.bag.contains(minus3));
-		assertFalse(this.bag.contains(zero));
-		assertEquals(1, this.bag.count(this.one));
-		assertEquals(2, this.bag.count(this.two));
-		assertEquals(3, this.bag.count(this.three));
-		assertEquals(4, this.bag.count(this.four));
-		assertEquals(5, this.bag.count(five));
-
-		this.bag.add(this.three, 2);
-		assertEquals(5, this.bag.count(this.three));
-	}
-
-	public void testAddAll() {
-		Collection<String> c = this.buildCollection();
-		assertTrue(this.bag.addAll(c));
-		for (String s : c) {
-			assertTrue(this.bag.contains(s));
-		}
-	}
-
-	public void testClear() {
-		assertTrue(this.bag.contains(this.one));
-		assertTrue(this.bag.contains(this.two));
-		assertTrue(this.bag.contains(this.three));
-		assertTrue(this.bag.contains(this.four));
-		assertTrue(this.bag.contains(null));
-		assertEquals(11, this.bag.size());
-		this.bag.clear();
-		assertFalse(this.bag.contains(this.one));
-		assertFalse(this.bag.contains(this.two));
-		assertFalse(this.bag.contains(this.three));
-		assertFalse(this.bag.contains(this.four));
-		assertFalse(this.bag.contains(null));
-		assertEquals(0, this.bag.size());
-	}
-
-	public void testClone() {
-		IdentityHashBag<String> bag2 = this.bag.clone();
-		assertTrue("bad clone", this.bag != bag2);
-		assertEquals("bad clone", this.bag, bag2);
-		assertTrue("bad clone", this.bag.hashCode() == bag2.hashCode());
-	}
-
-	public void testContains() {
-		assertTrue(this.bag.contains(null));
-		assertTrue(this.bag.contains(this.one));
-		assertTrue(this.bag.contains(this.two));
-		assertTrue(this.bag.contains(this.three));
-		assertTrue(this.bag.contains(this.four));
-
-		assertFalse(this.bag.contains(new String("four")));
-		assertFalse(this.bag.contains("five"));
-	}
-
-	public void testContainsAll() {
-		Collection<String> c = new ArrayList<String>();
-		c.add(null);
-		c.add(this.one);
-		c.add(this.two);
-		c.add(this.three);
-		c.add(this.four);
-		assertTrue(this.bag.containsAll(c));
-		c.add(new String(this.four));
-		assertFalse(this.bag.containsAll(c));
-	}
-
-	public void testCount() {
-		assertEquals(0, this.bag.count("zero"));
-		assertEquals(1, this.bag.count("one"));
-		assertEquals(2, this.bag.count("two"));
-		assertEquals(3, this.bag.count("three"));
-		assertEquals(4, this.bag.count("four"));
-		assertEquals(0, this.bag.count("five"));
-	}
-
-	public void testEquals() {
-		IdentityHashBag<String> bag2 = this.buildBag();
-		assertEquals(this.bag, bag2);
-		bag2.add("five");
-		assertFalse(this.bag.equals(bag2));
-		Collection<String> c = new ArrayList<String>(this.bag);
-		assertFalse(this.bag.equals(c));
-	}
-
-	public void testHashCode() {
-		IdentityHashBag<String> bag2 = this.buildBag();
-		assertEquals(this.bag.hashCode(), bag2.hashCode());
-	}
-
-	public void testIsEmpty() {
-		assertFalse(this.bag.isEmpty());
-		this.bag.clear();
-		assertTrue(this.bag.isEmpty());
-		this.bag.add("foo");
-		assertFalse(this.bag.isEmpty());
-	}
-
-	public void testEmptyIterator() {
-		this.bag.clear();
-		Iterator<String> iterator = this.bag.iterator();
-		assertFalse(iterator.hasNext());
-
-		boolean exCaught = false;
-		Object element = null;
-		try {
-			element = iterator.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + element, exCaught);
-
-		exCaught = false;
-		try {
-			iterator.remove();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue("IllegalStateException not thrown", exCaught);
-	}
-
-	public void testIterator() {
-		int i = 0;
-		Iterator<String> iterator = this.bag.iterator();
-		assertTrue(iterator.hasNext());
-		while (iterator.hasNext()) {
-			iterator.next();
-			i++;
-		}
-		assertEquals(11, i);
-		assertFalse(iterator.hasNext());
-
-		boolean exCaught = false;
-		Object element = null;
-		try {
-			element = iterator.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + element, exCaught);
-
-		iterator.remove();
-		assertEquals(10, this.bag.size());
-
-		exCaught = false;
-		try {
-			iterator.remove();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue("IllegalStateException not thrown", exCaught);
-
-		// start over
-		iterator = this.bag.iterator();
-		this.bag.add("five");
-		exCaught = false;
-		try {
-			iterator.next();
-		} catch (ConcurrentModificationException ex) {
-			exCaught = true;
-		}
-		assertTrue("ConcurrentModificationException not thrown", exCaught);
-	}
-
-	public void testUniqueIterator() {
-		int i = 0;
-		Iterator<String> iterator = this.bag.uniqueIterator();
-		assertTrue(iterator.hasNext());
-		while (iterator.hasNext()) {
-			iterator.next();
-			i++;
-		}
-		assertEquals(5, i);
-		assertFalse(iterator.hasNext());
-
-		boolean exCaught = false;
-		Object element = null;
-		try {
-			element = iterator.next();
-			fail(element.toString());
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		// start over
-		iterator = this.bag.uniqueIterator();
-		Object next = null;
-		while (iterator.hasNext() && !this.four.equals(next)) {
-			next = iterator.next();
-		}
-		iterator.remove();
-		assertEquals(7, this.bag.size());
-
-		exCaught = false;
-		try {
-			iterator.remove();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		// start over
-		iterator = this.bag.uniqueIterator();
-		String five = "five";
-		this.bag.add(five);
-		exCaught = false;
-		try {
-			iterator.next();
-		} catch (ConcurrentModificationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testEntries() {
-		int i = 0;
-		Iterator<Bag.Entry<String>> iterator = this.bag.entries();
-		assertTrue(iterator.hasNext());
-		while (iterator.hasNext()) {
-			iterator.next();
-			i++;
-		}
-		assertEquals(5, i);
-		assertFalse(iterator.hasNext());
-
-		boolean exCaught = false;
-		Object element = null;
-		try {
-			element = iterator.next();
-			fail(element.toString());
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		// start over
-		iterator = this.bag.entries();
-		Bag.Entry<String> next = null;
-		while (iterator.hasNext()) {
-			next = iterator.next();
-			if (next.getElement().equals(this.four)) {
-				iterator.remove();
-				break;
-			}
-		}
-		assertEquals(7, this.bag.size());
-
-		exCaught = false;
-		try {
-			iterator.remove();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		// start over
-		iterator = this.bag.entries();
-		String five = "five";
-		this.bag.add(five);
-		exCaught = false;
-		try {
-			iterator.next();
-		} catch (ConcurrentModificationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testHashingDistribution() throws Exception {
-		IdentityHashBag<String> bigBag = new IdentityHashBag<String>();
-		for (int i = 0; i < 10000; i++) {
-			bigBag.add("object" + i);
-		}
-
-		java.lang.reflect.Field field = bigBag.getClass().getDeclaredField("table");
-		field.setAccessible(true);
-		Object[] table = (Object[]) field.get(bigBag);
-		int bucketCount = table.length;
-		int filledBucketCount = 0;
-		for (int i = 0; i < bucketCount; i++) {
-			if (table[i] != null) {
-				filledBucketCount++;
-			}
-		}
-		float loadFactor = ((float) filledBucketCount) / ((float) bucketCount);
-		if ((loadFactor < 0.20) || (loadFactor > 0.80)) {
-			String msg = "poor load factor: " + loadFactor;
-			if (Tools.jvmIsSun()) {
-				fail(msg);
-			} else {
-				// poor load factor is seen in the Eclipse build environment for some reason...
-				System.out.println(this.getClass().getName() + '.' + this.getName() + " - " + msg);
-				TestTools.printSystemProperties();
-			}
-		}
-	}
-
-	public void testRemove() {
-		assertTrue(this.bag.remove(this.one));
-		assertFalse(this.bag.contains(this.one));
-		assertFalse(this.bag.remove(this.one));
-
-		assertTrue(this.bag.remove(this.two));
-		assertTrue(this.bag.remove(this.two));
-		assertFalse(this.bag.contains(this.two));
-		assertFalse(this.bag.remove(this.two));
-
-		assertFalse(this.bag.remove(new String(this.three)));
-	}
-
-	public void testRemoveCount() {
-		assertFalse(this.bag.remove(this.one, 0));
-		assertTrue(this.bag.contains(this.one));
-
-		assertTrue(this.bag.remove(this.one, 1));
-		assertFalse(this.bag.contains(this.one));
-		assertFalse(this.bag.remove(this.one));
-
-		assertFalse(this.bag.remove(this.two, -3));
-		assertTrue(this.bag.remove(this.two, 1));
-		assertTrue(this.bag.contains(this.two));
-
-		assertTrue(this.bag.remove(this.two, 1));
-		assertFalse(this.bag.contains(this.two));
-		assertFalse(this.bag.remove(this.two));
-
-		assertTrue(this.bag.remove(this.three, 3));
-		assertFalse(this.bag.contains(this.three));
-		assertFalse(this.bag.remove(this.three));
-	}
-
-	public void testRemoveAll() {
-		Collection<String> c = new ArrayList<String>();
-		c.add(this.one);
-		c.add(new String(this.two));
-		c.add(this.three);
-		assertTrue(this.bag.removeAll(c));
-		assertFalse(this.bag.contains(this.one));
-		assertTrue(this.bag.contains(this.two));
-		assertFalse(this.bag.contains(this.three));
-		assertFalse(this.bag.remove(this.one));
-		assertTrue(this.bag.remove(this.two));
-		assertFalse(this.bag.remove(this.three));
-		assertFalse(this.bag.removeAll(c));
-	}
-
-	public void testRetainAll() {
-		Collection<String> c = new ArrayList<String>();
-		c.add(this.one);
-		c.add(new String(this.two));
-		c.add(this.three);
-		assertTrue(this.bag.retainAll(c));
-		assertTrue(this.bag.contains(this.one));
-		assertFalse(this.bag.contains(this.two));
-		assertTrue(this.bag.contains(this.three));
-		assertFalse(this.bag.contains(this.four));
-		assertFalse(this.bag.remove(this.two));
-		assertFalse(this.bag.remove(this.four));
-		assertFalse(this.bag.retainAll(c));
-	}
-
-	public void testSize() {
-		assertTrue(this.bag.size() == 11);
-		String five = "five";
-		this.bag.add(five);
-		this.bag.add(five);
-		this.bag.add(five);
-		this.bag.add(five);
-		this.bag.add(new String(five));
-		assertEquals(16, this.bag.size());
-	}
-
-	public void testSerialization() throws Exception {
-		IdentityHashBag<String> bag2 = TestTools.serialize(this.bag);
-
-		assertTrue("same object?", this.bag != bag2);
-		assertEquals(11, bag2.size());
-		assertEquals(CollectionTools.bag(this.bag.iterator()), CollectionTools.bag(bag2.iterator()));
-		// look for similar elements
-		assertTrue(CollectionTools.bag(bag2.iterator()).contains(null));
-		assertTrue(CollectionTools.bag(bag2.iterator()).contains("one"));
-		assertTrue(CollectionTools.bag(bag2.iterator()).contains("two"));
-		assertTrue(CollectionTools.bag(bag2.iterator()).contains("three"));
-		assertTrue(CollectionTools.bag(bag2.iterator()).contains("four"));
-
-		int nullCount = 0, oneCount = 0, twoCount = 0, threeCount = 0, fourCount = 0;
-		for (String next : bag2) {
-			if (next == null)
-				nullCount++;
-			else if (next.equals("one"))
-				oneCount++;
-			else if (next.equals("two"))
-				twoCount++;
-			else if (next.equals("three"))
-				threeCount++;
-			else if (next.equals("four"))
-				fourCount++;
-		}
-		assertEquals(1, nullCount);
-		assertEquals(1, oneCount);
-		assertEquals(2, twoCount);
-		assertEquals(3, threeCount);
-		assertEquals(4, fourCount);
-	}
-
-	public void testToArray() {
-		Object[] a = this.bag.toArray();
-		assertEquals(11, a.length);
-		assertTrue(ArrayTools.contains(a, null));
-		assertTrue(ArrayTools.contains(a, this.one));
-		assertTrue(ArrayTools.contains(a, this.two));
-		assertTrue(ArrayTools.contains(a, this.three));
-		assertTrue(ArrayTools.contains(a, this.four));
-	}
-
-	public void testToArrayObjectArray() {
-		String[] a = new String[12];
-		a[11] = "not null";
-		String[] b = this.bag.toArray(a);
-		assertEquals(a, b);
-		assertEquals(12, a.length);
-		assertTrue(ArrayTools.contains(a, null));
-		assertTrue(ArrayTools.contains(a, this.one));
-		assertTrue(ArrayTools.contains(a, this.two));
-		assertTrue(ArrayTools.contains(a, this.three));
-		assertTrue(ArrayTools.contains(a, this.four));
-		assertTrue(a[11] == null);
-	}
-
-	public void testToString() {
-		String s = this.bag.toString();
-		assertTrue(s.startsWith("["));
-		assertTrue(s.endsWith("]"));
-		int commaCount = 0;
-		for (int i = 0; i < s.length(); i++) {
-			if (s.charAt(i) == ',') {
-				commaCount++;
-			}
-		}
-		assertEquals("invalid number of commas", 10, commaCount);
-		assertTrue(s.indexOf("one") != -1);
-		assertTrue(s.indexOf("two") != -1);
-		assertTrue(s.indexOf("three") != -1);
-		assertTrue(s.indexOf("four") != -1);
-		assertTrue(s.indexOf("null") != -1);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/IndentingPrintWriterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/IndentingPrintWriterTests.java
deleted file mode 100644
index 6b8ab06..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/IndentingPrintWriterTests.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.io.StringWriter;
-import junit.framework.TestCase;
-import org.eclipse.persistence.tools.utility.IndentingPrintWriter;
-
-@SuppressWarnings("nls")
-public class IndentingPrintWriterTests extends TestCase {
-	StringWriter sw1;
-	StringWriter sw2;
-	IndentingPrintWriter ipw1;
-	IndentingPrintWriter ipw2;
-
-	static final String CR = System.getProperty("line.separator");
-
-	public IndentingPrintWriterTests(String name) {
-		super(name);
-	}
-
-	@Override
-	public void setUp() throws Exception {
-		super.setUp();
-		this.sw1 = new StringWriter();
-		this.ipw1 = new IndentingPrintWriter(this.sw1);
-		this.sw2 = new StringWriter();
-		this.ipw2 = new IndentingPrintWriter(this.sw2, "    "); // indent with 4 spaces instead of a tab
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		TestTools.clear(this);
-		super.tearDown();
-	}
-
-	public void testIndent() {
-		assertEquals("wrong indent level", 0, this.ipw1.getIndentLevel());
-		this.ipw1.indent();
-		assertEquals("wrong indent level", 1, this.ipw1.getIndentLevel());
-	}
-
-	public void testUndent() {
-		assertEquals("wrong indent level", 0, this.ipw1.getIndentLevel());
-		this.ipw1.indent();
-		assertEquals("wrong indent level", 1, this.ipw1.getIndentLevel());
-		this.ipw1.undent();
-		assertEquals("wrong indent level", 0, this.ipw1.getIndentLevel());
-	}
-
-	public void testIncrementIndentLevel() {
-		assertEquals("wrong indent level", 0, this.ipw1.getIndentLevel());
-		this.ipw1.incrementIndentLevel();
-		assertEquals("wrong indent level", 1, this.ipw1.getIndentLevel());
-	}
-
-	public void testDecrementIndentLevel() {
-		assertEquals("wrong indent level", 0, this.ipw1.getIndentLevel());
-		this.ipw1.incrementIndentLevel();
-		assertEquals("wrong indent level", 1, this.ipw1.getIndentLevel());
-		this.ipw1.decrementIndentLevel();
-		assertEquals("wrong indent level", 0, this.ipw1.getIndentLevel());
-	}
-
-	public void testPrintTab() {
-		String expected = "foo0" + CR + "\tfoo1" + CR + "\tfoo1" + CR + "\t\tfoo2" + CR + "\tfoo1" + CR + "\tfoo1" + CR + "foo0" + CR;
-
-		this.ipw1.println("foo0");
-		this.ipw1.indent();
-		this.ipw1.println("foo1");
-		this.ipw1.println("foo1");
-		this.ipw1.indent();
-		this.ipw1.println("foo2");
-		this.ipw1.undent();
-		this.ipw1.println("foo1");
-		this.ipw1.println("foo1");
-		this.ipw1.undent();
-		this.ipw1.println("foo0");
-
-		assertEquals("bogus output", expected, this.sw1.toString());
-	}
-
-	public void testPrintSpaces() {
-		String expected = "foo0" + CR + "    foo1" + CR + "    foo1" + CR + "        foo2" + CR + "    foo1" + CR + "    foo1" + CR + "foo0" + CR;
-
-		this.ipw2.println("foo0");
-		this.ipw2.indent();
-		this.ipw2.println("foo1");
-		this.ipw2.println("foo1");
-		this.ipw2.indent();
-		this.ipw2.println("foo2");
-		this.ipw2.undent();
-		this.ipw2.println("foo1");
-		this.ipw2.println("foo1");
-		this.ipw2.undent();
-		this.ipw2.println("foo0");
-
-		assertEquals("bogus output", expected, this.sw2.toString());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/JDBCTypeTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/JDBCTypeTests.java
deleted file mode 100644
index 3627098..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/JDBCTypeTests.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.sql.Types;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.JDBCType;
-
-@SuppressWarnings("nls")
-public class JDBCTypeTests extends TestCase {
-
-	public JDBCTypeTests(String name) {
-		super(name);
-	}
-
-	public void testTypesSize() {
-		assertEquals(Types.class.getDeclaredFields().length, JDBCType.types().length);
-	}
-
-	public void testName() {
-		JDBCType jdbcType;
-		jdbcType = JDBCType.type(Types.VARCHAR);
-		assertEquals("VARCHAR", jdbcType.name());
-
-		jdbcType = JDBCType.type(Types.INTEGER);
-		assertEquals("INTEGER", jdbcType.name());
-	}
-
-	public void testCode() {
-		JDBCType jdbcType;
-		jdbcType = JDBCType.type(Types.VARCHAR);
-		assertEquals(Types.VARCHAR, jdbcType.code());
-
-		jdbcType = JDBCType.type(Types.INTEGER);
-		assertEquals(Types.INTEGER, jdbcType.code());
-	}
-
-	public void testInvalidTypeCode() throws Exception {
-		boolean exCaught = false;
-		try {
-			JDBCType jdbcType = JDBCType.type(55);
-			fail("invalid JDBCType: " + jdbcType);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testInvalidTypeName() throws Exception {
-		boolean exCaught = false;
-		try {
-			JDBCType jdbcType = JDBCType.type("VARCHAR2");
-			fail("invalid JDBCType: " + jdbcType);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/JavaTypeTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/JavaTypeTests.java
deleted file mode 100644
index 3c81acd..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/JavaTypeTests.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-import org.eclipse.persistence.tools.utility.JavaType;
-import org.eclipse.persistence.tools.utility.SimpleJavaType;
-
-@SuppressWarnings("nls")
-public class JavaTypeTests extends TestCase {
-
-	public JavaTypeTests(String name) {
-		super(name);
-	}
-
-	public void testInvalidElementTypeNull() throws Exception {
-		boolean exCaught = false;
-		try {
-			JavaType javaType = new SimpleJavaType(null, 0);
-			fail("invalid JavaType: " + javaType);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testInvalidElementTypeEmpty() throws Exception {
-		boolean exCaught = false;
-		try {
-			JavaType javaType = new SimpleJavaType("", 0);
-			fail("invalid JavaType: " + javaType);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testInvalidElementTypeArray() throws Exception {
-		boolean exCaught = false;
-		try {
-			JavaType javaType = new SimpleJavaType(java.lang.Object[].class.getName(), 0);
-			fail("invalid JavaType: " + javaType);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testInvalidArrayDepthNegative() throws Exception {
-		boolean exCaught = false;
-		try {
-			JavaType javaType = new SimpleJavaType(java.lang.Object.class.getName(), -2);
-			fail("invalid JavaType: " + javaType);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testInvalidVoidArray() throws Exception {
-		boolean exCaught = false;
-		try {
-			JavaType javaType = new SimpleJavaType(void.class.getName(), 2);
-			fail("invalid JavaType: " + javaType);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testElementTypeName() throws Exception {
-		JavaType javaType;
-		javaType = new SimpleJavaType(java.lang.Object.class);
-		assertEquals("java.lang.Object", javaType.getElementTypeName());
-
-		javaType = new SimpleJavaType(java.lang.Object[].class);
-		assertEquals("java.lang.Object", javaType.getElementTypeName());
-
-		javaType = new SimpleJavaType(int.class);
-		assertEquals("int", javaType.getElementTypeName());
-
-		javaType = new SimpleJavaType(int[].class);
-		assertEquals("int", javaType.getElementTypeName());
-
-		javaType = new SimpleJavaType(void.class);
-		assertEquals("void", javaType.getElementTypeName());
-
-		javaType = new SimpleJavaType(java.util.Map.Entry.class);
-		assertEquals("java.util.Map$Entry", javaType.getElementTypeName());
-
-		javaType = new SimpleJavaType(java.util.Map.Entry[][].class);
-		assertEquals("java.util.Map$Entry", javaType.getElementTypeName());
-	}
-
-	public void testArrayDepth() throws Exception {
-		JavaType javaType;
-		javaType = new SimpleJavaType(java.lang.Object.class);
-		assertEquals(0, javaType.getArrayDepth());
-
-		javaType = new SimpleJavaType(java.lang.Object[].class);
-		assertEquals(1, javaType.getArrayDepth());
-
-		javaType = new SimpleJavaType(int.class);
-		assertEquals(0, javaType.getArrayDepth());
-
-		javaType = new SimpleJavaType(int[].class);
-		assertEquals(1, javaType.getArrayDepth());
-
-		javaType = new SimpleJavaType(void.class);
-		assertEquals(0, javaType.getArrayDepth());
-
-		javaType = new SimpleJavaType(java.util.Map.Entry.class);
-		assertEquals(0, javaType.getArrayDepth());
-
-		javaType = new SimpleJavaType(java.util.Map.Entry[][].class);
-		assertEquals(2, javaType.getArrayDepth());
-	}
-
-	public void testIsArray() throws Exception {
-		JavaType javaType;
-		javaType = new SimpleJavaType(java.lang.Object.class);
-		assertFalse(javaType.isArray());
-
-		javaType = new SimpleJavaType(java.lang.Object[].class);
-		assertTrue(javaType.isArray());
-
-		javaType = new SimpleJavaType(int.class);
-		assertFalse(javaType.isArray());
-
-		javaType = new SimpleJavaType(int[].class);
-		assertTrue(javaType.isArray());
-
-		javaType = new SimpleJavaType(void.class);
-		assertFalse(javaType.isArray());
-
-		javaType = new SimpleJavaType(java.util.Map.Entry.class);
-		assertFalse(javaType.isArray());
-
-		javaType = new SimpleJavaType(java.util.Map.Entry[][].class);
-		assertTrue(javaType.isArray());
-	}
-
-	public void testJavaClass() throws Exception {
-		this.verifyJavaClass(java.lang.Object.class);
-		this.verifyJavaClass(java.lang.Object[].class);
-		this.verifyJavaClass(int.class);
-		this.verifyJavaClass(int[].class);
-		this.verifyJavaClass(void.class);
-		this.verifyJavaClass(java.util.Map.Entry.class);
-		this.verifyJavaClass(java.util.Map.Entry[][].class);
-	}
-
-	private void verifyJavaClass(Class<?> javaClass) throws Exception {
-		JavaType javaType = new SimpleJavaType(javaClass);
-		assertEquals(javaClass, javaType.getJavaClass());
-	}
-
-	public void testJavaClassName() throws Exception {
-		JavaType javaType;
-		javaType = new SimpleJavaType(java.lang.Object.class);
-		assertEquals("java.lang.Object", javaType.getJavaClassName());
-
-		javaType = new SimpleJavaType(java.lang.Object[].class);
-		assertEquals("[Ljava.lang.Object;", javaType.getJavaClassName());
-
-		javaType = new SimpleJavaType(int.class);
-		assertEquals("int", javaType.getJavaClassName());
-
-		javaType = new SimpleJavaType(int[].class);
-		assertEquals("[I", javaType.getJavaClassName());
-
-		javaType = new SimpleJavaType(void.class);
-		assertEquals("void", javaType.getJavaClassName());
-
-		javaType = new SimpleJavaType(java.util.Map.Entry.class);
-		assertEquals("java.util.Map$Entry", javaType.getJavaClassName());
-
-		javaType = new SimpleJavaType(java.util.Map.Entry[][].class);
-		assertEquals("[[Ljava.util.Map$Entry;", javaType.getJavaClassName());
-	}
-
-	public void testDescribes() throws Exception {
-		this.verifyDescribes(java.lang.Object.class);
-		this.verifyDescribes(java.lang.Object[].class);
-		this.verifyDescribes(int.class);
-		this.verifyDescribes(int[].class);
-		this.verifyDescribes(void.class);
-		this.verifyDescribes(java.util.Map.Entry.class);
-		this.verifyDescribes(java.util.Map.Entry[][].class);
-	}
-
-	private void verifyDescribes(Class<?> javaClass) throws Exception {
-		JavaType javaType = new SimpleJavaType(javaClass);
-		assertTrue(javaType.describes(javaClass));
-	}
-
-	public void testDeclaration() throws Exception {
-		JavaType javaType;
-		javaType = new SimpleJavaType(java.lang.Object.class);
-		assertEquals("java.lang.Object", javaType.declaration());
-
-		javaType = new SimpleJavaType(java.lang.Object[].class);
-		assertEquals("java.lang.Object[]", javaType.declaration());
-
-		javaType = new SimpleJavaType(int.class);
-		assertEquals("int", javaType.declaration());
-
-		javaType = new SimpleJavaType(int[].class);
-		assertEquals("int[]", javaType.declaration());
-
-		javaType = new SimpleJavaType(void.class);
-		assertEquals("void", javaType.declaration());
-
-		javaType = new SimpleJavaType(java.util.Map.Entry.class);
-		assertEquals("java.util.Map.Entry", javaType.declaration());
-
-		javaType = new SimpleJavaType(java.util.Map.Entry[][].class);
-		assertEquals("java.util.Map.Entry[][]", javaType.declaration());
-	}
-
-	public void testIsPrimitive() throws Exception {
-		JavaType javaType;
-		javaType = new SimpleJavaType(java.lang.Object.class);
-		assertFalse(javaType.isPrimitive());
-
-		javaType = new SimpleJavaType(java.lang.Object[].class);
-		assertFalse(javaType.isPrimitive());
-
-		javaType = new SimpleJavaType(int.class);
-		assertTrue(javaType.isPrimitive());
-
-		javaType = new SimpleJavaType(int[].class);
-		assertFalse(javaType.isPrimitive());
-
-		javaType = new SimpleJavaType(void.class);
-		assertTrue(javaType.isPrimitive());
-
-		javaType = new SimpleJavaType(java.util.Map.Entry.class);
-		assertFalse(javaType.isPrimitive());
-
-		javaType = new SimpleJavaType(java.util.Map.Entry[][].class);
-		assertFalse(javaType.isPrimitive());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/KeyedSetTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/KeyedSetTests.java
deleted file mode 100644
index 839e570..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/KeyedSetTests.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*******************************************************************************
- *  Copyright (c) 2010  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.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.KeyedSet;
-
-@SuppressWarnings("nls")
-public class KeyedSetTests
-		extends TestCase {
-	
-	private KeyedSet<String, String> nicknames;
-	
-	
-	public KeyedSetTests(String name) {
-		super(name);
-	}
-	
-	
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.nicknames = this.buildNicknames();
-	}
-	
-	private KeyedSet<String, String> buildNicknames() {
-		KeyedSet<String, String> ks = new KeyedSet<String, String>();
-		ks.addItem("Jimmy", "James Sullivan");
-		ks.addKey("Sully", "James Sullivan");
-		ks.addItem("Bob", "Robert McKenna");
-		ks.addKey("Mac", "Robert McKenna");
-		return ks;
-	}
-	
-	@Override
-	protected void tearDown() throws Exception {
-		TestTools.clear(this);
-		super.tearDown();
-	}
-	
-	public void testAddItem() {
-		// items added in setup
-		assertTrue(this.nicknames.containsItem("James Sullivan"));
-		assertTrue(this.nicknames.containsItem("Robert McKenna"));
-		
-		assertFalse(this.nicknames.containsItem("John Teasdale"));
-		this.nicknames.addItem("Jack", "John Teasdale");
-		assertTrue(this.nicknames.containsItem("John Teasdale"));
-		
-		this.nicknames.addItem("Teaser", "John Teasdale");
-		assertTrue(this.nicknames.containsItem("John Teasdale"));
-		assertTrue(this.nicknames.containsKey("Teaser"));
-	}
-	
-	public void testAddKey() {
-		// items added in setup
-		assertTrue(this.nicknames.containsKey("Jimmy"));
-		assertTrue(this.nicknames.containsKey("Sully"));
-		assertTrue(this.nicknames.containsKey("Bob"));
-		assertTrue(this.nicknames.containsKey("Mac"));
-		
-		assertFalse(this.nicknames.containsKey("Robbie"));
-		this.nicknames.addKey("Robbie", "Robert McKenna");
-		assertTrue(this.nicknames.containsKey("Robbie"));
-		
-		boolean exceptionCaught = false;
-		try {
-			this.nicknames.addKey("Teaser", "John Teasdale");
-		}
-		catch (IllegalArgumentException iae) {
-			exceptionCaught = true;
-		}
-		assertTrue(exceptionCaught);	
-	}
-	
-	public void testGetItem() {
-		// items added in setup
-		assertEquals(this.nicknames.getItem("Jimmy"), "James Sullivan");
-		assertEquals(this.nicknames.getItem("Sully"), "James Sullivan");
-		assertEquals(this.nicknames.getItem("Bob"), "Robert McKenna");
-		assertEquals(this.nicknames.getItem("Mac"), "Robert McKenna");
-		assertNull(this.nicknames.getItem("Jack"));
-	}
-	
-	public void testRemoveItem() {
-		// items added in setup
-		assertTrue(this.nicknames.containsItem("James Sullivan"));
-		assertTrue(this.nicknames.containsKey("Jimmy"));
-		assertTrue(this.nicknames.containsKey("Sully"));
-		
-		assertTrue(this.nicknames.removeItem("James Sullivan"));
-		assertFalse(this.nicknames.containsItem("James Sullivan"));
-		assertFalse(this.nicknames.containsKey("Jimmy"));
-		assertFalse(this.nicknames.containsKey("Sully"));
-		
-		assertFalse(this.nicknames.removeItem("William Goldberg"));
-	}
-	
-	public void testRemoveKey() {
-		// items added in setup
-		assertTrue(this.nicknames.containsItem("James Sullivan"));
-		assertTrue(this.nicknames.containsKey("Jimmy"));
-		assertTrue(this.nicknames.containsKey("Sully"));
-		
-		assertTrue(this.nicknames.removeKey("Jimmy"));
-		assertTrue(this.nicknames.containsItem("James Sullivan"));
-		assertFalse(this.nicknames.containsKey("Jimmy"));
-		assertTrue(this.nicknames.containsKey("Sully"));
-		
-		assertTrue(this.nicknames.removeKey("Sully"));
-		assertFalse(this.nicknames.containsItem("James Sullivan"));
-		assertFalse(this.nicknames.containsKey("Jimmy"));
-		assertFalse(this.nicknames.containsKey("Sully"));
-		
-		assertFalse(this.nicknames.removeKey("Billy"));
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ListenerListTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ListenerListTests.java
deleted file mode 100644
index 9e94c12..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ListenerListTests.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.io.Serializable;
-import java.util.EventListener;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.ListenerList;
-import org.eclipse.persistence.tools.utility.Tools;
-
-@SuppressWarnings("nls")
-public class ListenerListTests extends TestCase {
-
-	public ListenerListTests(String name) {
-		super(name);
-	}
-
-	public void testGetListeners() throws Exception {
-		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
-		Listener listener1 = new LocalListener();
-		Listener listener2 = new LocalListener();
-		Iterable<Listener> listeners = listenerList.getListeners();
-		assertEquals(0, CollectionTools.size(listeners));
-
-		listenerList.add(listener1);
-		listenerList.add(listener2);
-		listeners = listenerList.getListeners();
-		assertEquals(2, CollectionTools.size(listeners));
-		assertTrue(CollectionTools.contains(listeners, listener1));
-		assertTrue(CollectionTools.contains(listeners, listener2));
-	}
-
-	public void testSize() throws Exception {
-		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
-		Listener listener1 = new LocalListener();
-		Listener listener2 = new LocalListener();
-		assertEquals(0, listenerList.size());
-
-		listenerList.add(listener1);
-		listenerList.add(listener2);
-		assertEquals(2, listenerList.size());
-	}
-
-	public void testIsEmpty() throws Exception {
-		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
-		Listener listener1 = new LocalListener();
-		Listener listener2 = new LocalListener();
-		assertTrue(listenerList.isEmpty());
-
-		listenerList.add(listener1);
-		listenerList.add(listener2);
-		assertFalse(listenerList.isEmpty());
-	}
-
-	public void testAdd_null() throws Exception {
-		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
-		boolean exCaught = false;
-		try {
-			listenerList.add(null);
-			fail("invalid listener list: " + listenerList);
-		} catch (NullPointerException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testAdd_duplicate() throws Exception {
-		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
-		Listener listener = new LocalListener();
-		listenerList.add(listener);
-
-		boolean exCaught = false;
-		try {
-			listenerList.add(listener);
-			fail("invalid listener list: " + listenerList);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testRemove() throws Exception {
-		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
-		Listener listener1 = new LocalListener();
-		Listener listener2 = new LocalListener();
-		listenerList.add(listener1);
-		listenerList.add(listener2);
-		assertTrue(CollectionTools.contains(listenerList.getListeners(), listener1));
-		assertTrue(CollectionTools.contains(listenerList.getListeners(), listener2));
-
-		listenerList.remove(listener1);
-		assertFalse(CollectionTools.contains(listenerList.getListeners(), listener1));
-		assertTrue(CollectionTools.contains(listenerList.getListeners(), listener2));
-
-		listenerList.remove(listener2);
-		assertFalse(CollectionTools.contains(listenerList.getListeners(), listener2));
-	}
-
-	public void testRemove_null() throws Exception {
-		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
-		boolean exCaught = false;
-		try {
-			listenerList.remove(null);
-			fail("invalid listener list: " + listenerList);
-		} catch (NullPointerException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testRemove_unregistered() throws Exception {
-		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
-		Listener listener = new LocalListener();
-		listenerList.add(listener);
-		listenerList.remove(listener);
-
-		boolean exCaught = false;
-		try {
-			listenerList.remove(listener);
-			fail("invalid listener list: " + listenerList);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testClear() throws Exception {
-		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
-		Listener listener1 = new LocalListener();
-		Listener listener2 = new LocalListener();
-		listenerList.add(listener1);
-		listenerList.add(listener2);
-		assertTrue(CollectionTools.contains(listenerList.getListeners(), listener1));
-		assertTrue(CollectionTools.contains(listenerList.getListeners(), listener2));
-
-		listenerList.clear();
-		assertFalse(CollectionTools.contains(listenerList.getListeners(), listener1));
-		assertFalse(CollectionTools.contains(listenerList.getListeners(), listener2));
-	}
-
-	public void testSerialization() throws Exception {
-		// This test doesn't pass in the Eclipse build environment (Linux/IBM VM) for some reason
-		if (Tools.jvmIsSun()) {
-			this.verifySerialization();
-		}
-	}
-
-	private void verifySerialization() throws Exception {
-		ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
-		Listener listener1 = new LocalListener();
-		Listener listener2 = new LocalListener();
-		listenerList.add(listener1);
-		listenerList.add(listener2);
-
-		ListenerList<Listener> listenerList2 = TestTools.serialize(listenerList);
-		assertNotSame(listenerList, listenerList2);
-		assertEquals(2, listenerList2.size());
-
-		Listener listener3 = new NonSerializableListener();
-		listenerList.add(listener3);
-
-		listenerList2 = TestTools.serialize(listenerList);
-		assertNotSame(listenerList, listenerList2);
-		assertEquals(2, listenerList2.size());
-
-	}
-
-	interface Listener extends EventListener {
-		void somethingHappened();
-	}
-
-	static class LocalListener implements Listener, Serializable {
-		public void somethingHappened() {
-			// do nothing
-		}
-	}
-
-	static class NonSerializableListener implements Listener {
-		public void somethingHappened() {
-			// do nothing
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/MethodSignatureTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/MethodSignatureTests.java
deleted file mode 100644
index cf50cd6..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/MethodSignatureTests.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import junit.framework.TestCase;
-import org.eclipse.persistence.tools.utility.JavaType;
-import org.eclipse.persistence.tools.utility.MethodSignature;
-import org.eclipse.persistence.tools.utility.SimpleJavaType;
-import org.eclipse.persistence.tools.utility.SimpleMethodSignature;
-
-@SuppressWarnings("nls")
-public class MethodSignatureTests extends TestCase {
-
-	public MethodSignatureTests(String name) {
-		super(name);
-	}
-
-	public void testInvalidNameNull() throws Exception {
-		boolean exCaught = false;
-		try {
-			MethodSignature methodSignature = new SimpleMethodSignature((String) null);
-			fail("invalid MethodSignature: " + methodSignature);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testInvalidNameEmpty() throws Exception {
-		boolean exCaught = false;
-		try {
-			MethodSignature methodSignature = new SimpleMethodSignature("");
-			fail("invalid MethodSignature: " + methodSignature);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testInvalidParameterTypesNull() throws Exception {
-		boolean exCaught = false;
-		try {
-			MethodSignature methodSignature = new SimpleMethodSignature("foo", (JavaType[]) null);
-			fail("invalid MethodSignature: " + methodSignature);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testInvalidParameterTypesNullItem() throws Exception {
-		boolean exCaught = false;
-		try {
-			MethodSignature methodSignature = new SimpleMethodSignature("foo", new JavaType[1]);
-			fail("invalid MethodSignature: " + methodSignature);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testInvalidParameterTypesVoidItem() throws Exception {
-		JavaType jt = new SimpleJavaType(void.class.getName());
-		boolean exCaught = false;
-		try {
-			MethodSignature methodSignature = new SimpleMethodSignature("foo", new JavaType[] {jt});
-			fail("invalid MethodSignature: " + methodSignature);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testInvalidParameterTypeNamesNull() throws Exception {
-		boolean exCaught = false;
-		try {
-			MethodSignature methodSignature = new SimpleMethodSignature("foo", (String[]) null);
-			fail("invalid MethodSignature: " + methodSignature);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testInvalidParameterTypeNamesNullItem() throws Exception {
-		boolean exCaught = false;
-		try {
-			MethodSignature methodSignature = new SimpleMethodSignature("foo", new String[1]);
-			fail("invalid MethodSignature: " + methodSignature);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testInvalidParameterJavaClassesNull() throws Exception {
-		boolean exCaught = false;
-		try {
-			MethodSignature methodSignature = new SimpleMethodSignature("foo", (Class<?>[]) null);
-			fail("invalid MethodSignature: " + methodSignature);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testInvalidParameterJavaClassesNullItem() throws Exception {
-		boolean exCaught = false;
-		try {
-			MethodSignature methodSignature = new SimpleMethodSignature("foo", new Class[1]);
-			fail("invalid MethodSignature: " + methodSignature);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testGetSignature0() throws Exception {
-		MethodSignature ms = new SimpleMethodSignature(this.getMethod("method0"));
-		assertEquals("method0()", ms.getSignature());
-	}
-
-	public void testGetSignature1() throws Exception {
-		MethodSignature ms = new SimpleMethodSignature(this.getMethod("method1"));
-		assertEquals("method1(int)", ms.getSignature());
-	}
-
-	public void testGetSignature2() throws Exception {
-		MethodSignature ms = new SimpleMethodSignature(this.getMethod("method2"));
-		assertEquals("method2(int, java.lang.String)", ms.getSignature());
-	}
-
-	public void testGetSignature3() throws Exception {
-		MethodSignature ms = new SimpleMethodSignature(this.getMethod("method3"));
-		assertEquals("method3(int, java.lang.String, java.lang.Object[][])", ms.getSignature());
-	}
-
-	public void testGetName() throws Exception {
-		MethodSignature ms = new SimpleMethodSignature(this.getMethod("method2"));
-		assertEquals("method2", ms.getName());
-	}
-
-	public void testGetParameterTypes() throws Exception {
-		MethodSignature ms = new SimpleMethodSignature(this.getMethod("method3"));
-		JavaType[] expected = new JavaType[3];
-		expected[0] = new SimpleJavaType("int");
-		expected[1] = new SimpleJavaType("java.lang.String");
-		expected[2] = new SimpleJavaType("java.lang.Object", 2);
-		assertTrue(Arrays.equals(expected, ms.getParameterTypes()));
-	}
-
-	public void testEquals() throws Exception {
-		Object ms1 = new SimpleMethodSignature(this.getMethod("method3"));
-		Object ms2 = new SimpleMethodSignature(this.getMethod("method3"));
-		assertNotSame(ms1, ms2);
-		assertEquals(ms1, ms1);
-		assertEquals(ms1, ms2);
-		assertEquals(ms1.hashCode(), ms2.hashCode());
-
-		Object ms3 = new SimpleMethodSignature(this.getMethod("method2"));
-		assertNotSame(ms1, ms3);
-		assertFalse(ms1.equals(ms3));
-	}
-
-	public void testClone() throws Exception {
-		SimpleMethodSignature ms1 = new SimpleMethodSignature(this.getMethod("method3"));
-		SimpleMethodSignature ms2 = (SimpleMethodSignature) ms1.clone();
-		assertNotSame(ms1, ms2);
-		assertEquals(ms1, ms2);
-	}
-
-	public void testSerialization() throws Exception {
-		SimpleMethodSignature ms1 = new SimpleMethodSignature(this.getMethod("method3"));
-		SimpleMethodSignature ms2 = TestTools.serialize(ms1);
-		assertNotSame(ms1, ms2);
-		assertEquals(ms1, ms2);
-	}
-
-	private Method getMethod(String methodName) {
-		for (Method method : this.getClass().getMethods()) {
-			if (method.getName().equals(methodName)) {
-				return method;
-			}
-		}
-		throw new IllegalArgumentException("method not found: " + methodName);
-	}
-
-	public void method0() { /* used by tests */ }
-	@SuppressWarnings("unused") public void method1(int foo) { /* used by tests */ }
-	@SuppressWarnings("unused") public void method2(int foo, String bar) { /* used by tests */ }
-	@SuppressWarnings("unused") public void method3(int foo, String bar, Object[][] baz) { /* used by tests */ }
-
-	@SuppressWarnings("unused") public void methodA(int foo, String bar) { /* used by tests */ }
-	@SuppressWarnings("unused") public void methodA(int foo, String bar, String baz) { /* used by tests */ }
-
-	@SuppressWarnings("unused") public void methodB(int foo, Object bar) { /* used by tests */ }
-	@SuppressWarnings("unused") public void methodB(int foo, String bar) { /* used by tests */ }
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/MultiThreadedTestCase.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/MultiThreadedTestCase.java
deleted file mode 100644
index 47e8662..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/MultiThreadedTestCase.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.util.ArrayList;
-import java.util.Vector;
-import java.util.concurrent.ThreadFactory;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.CompositeException;
-
-/**
- * This test case helps simplify the testing of multi-threaded code.
- */
-@SuppressWarnings("nls")
-public abstract class MultiThreadedTestCase
-	extends TestCase
-{
-	private final ArrayList<Thread> threads = new ArrayList<Thread>();
-	/* private */ final Vector<Throwable> exceptions = new Vector<Throwable>();
-
-	/**
-	 * The default "tick" is one second.
-	 * Specify the appropriate system property to override.
-	 */
-	public static final String TICK_SYSTEM_PROPERTY_NAME = "org.eclipse.jpt.common.utility.tests.tick";
-	public static final long TICK = Long.getLong(TICK_SYSTEM_PROPERTY_NAME, 1000).longValue();
-	public static final long TWO_TICKS = 2 * TICK;
-	public static final long THREE_TICKS = 3 * TICK;
-
-	/**
-	 * Default constructor.
-	 */
-	public MultiThreadedTestCase() {
-		super();
-	}
-
-	/**
-	 * Named constructor.
-	 */
-	public MultiThreadedTestCase(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-	}
-
-	/**
-	 * Stop all the threads constructed during the test case.
-	 * If any exceptions were thrown by the threads, re-throw them here.
-	 */
-	@Override
-	protected void tearDown() throws Exception {
-		for (Thread thread : this.threads) {
-			if (thread.isAlive()) {
-				throw new IllegalStateException("thread is still alive: " + thread);
-			}
-		}
-		if ( ! this.exceptions.isEmpty()) {
-			throw new CompositeException(this.exceptions);
-		}
-		TestTools.clear(this);
-		super.tearDown();
-	}
-
-	protected Thread buildThread(Runnable runnable) {
-		return this.buildThread(runnable, null);
-	}
-
-	protected Thread buildThread(Runnable runnable, String name) {
-		Thread thread = new Thread(new RunnableWrapper(runnable));
-		if (name != null) {
-			thread.setName(name);
-		}
-		this.threads.add(thread);
-		return thread;
-	}
-
-	protected ThreadFactory buildThreadFactory() {
-		return new TestThreadFactory();
-	}
-
-	/**
-	 * Convenience method that handles {@link InterruptedException}.
-	 */
-	public void sleep(long millis) {
-		TestTools.sleep(millis);
-	}
-
-
-	/**
-	 * Wrap a runnable and log any exception it throws.
-	 */
-	public class TestThreadFactory implements ThreadFactory {
-		public Thread newThread(Runnable r) {
-			return MultiThreadedTestCase.this.buildThread(r);
-		}
-	}
-
-	/**
-	 * Simplify runnables that execute call that throws checked exceptions.
-	 */
-	public abstract class TestRunnable implements Runnable {
-		public final void run() {
-			try {
-				this.run_();
-			} catch (Throwable ex) {
-				throw new RuntimeException(ex);
-			}
-		}
-		protected abstract void run_() throws Throwable;
-	}
-
-	/**
-	 * Wrap a runnable and log any exception it throws.
-	 */
-	private class RunnableWrapper implements Runnable {
-		private final Runnable runnable;
-		RunnableWrapper(Runnable runnable) {
-			super();
-			this.runnable = runnable;
-		}
-		public void run() {
-			try {
-				this.runnable.run();
-			} catch (RuntimeException ex) {
-				MultiThreadedTestCase.this.exceptions.add(ex);
-			}
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/NameToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/NameToolsTests.java
deleted file mode 100644
index 625cafb..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/NameToolsTests.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.NameTools;
-
-@SuppressWarnings("nls")
-public class NameToolsTests extends TestCase {
-
-	public NameToolsTests(String name) {
-		super(name);
-	}
-
-	public void testStringAbsentIgnoreCase() {
-		List<String> colorCollection = this.buildColorCollection();
-		String returned = NameTools.uniqueNameForIgnoreCase("Taupe", colorCollection);
-		assertEquals("Taupe", returned);
-	}
-
-	public void testStringPresentCaseDiffers() {
-		List<String> colorCollection = this.buildColorCollection();
-		String returned = NameTools.uniqueNameFor("green", colorCollection);
-		assertEquals("green", returned);
-	}
-
-	public void testStringPresentIgnoreCase() {
-		List<String> colorCollection = this.buildColorCollection();
-		String returned = NameTools.uniqueNameForIgnoreCase("green", colorCollection);
-		assertEquals("green2", returned);
-	}
-
-	public void testStringPresentWithAppendices() {
-		List<String> colorCollection = this.buildColorCollection();
-		colorCollection.add("Red1");
-		colorCollection.add("red2");
-		String returned = NameTools.uniqueNameForIgnoreCase("red", colorCollection);
-		colorCollection.remove("Red1");
-		colorCollection.remove("red2");
-		assertEquals("red3", returned);
-	}
-
-	private List<String> buildColorCollection() {
-		List<String> colorCollection = new ArrayList<String>();
-		colorCollection.add("Red");
-		colorCollection.add("Orange");
-		colorCollection.add("Yellow");
-		colorCollection.add("Green");
-		colorCollection.add("Blue");
-		colorCollection.add("Indigo");
-		colorCollection.add("Violet");
-		return colorCollection;
-	}
-
-	public void testUniqueNameForCollection1() {
-		Collection<String> strings = new ArrayList<String>();
-		strings.add("Oracle");
-		strings.add("Oracle Corporation");
-		strings.add("Oracle2");
-		strings.add("oracle1");
-		strings.add("Oracl");
-
-		assertEquals("Oracle3", NameTools.uniqueNameFor("Oracle", strings));
-		assertEquals("Test", NameTools.uniqueNameFor("Test", strings));
-
-		assertEquals("Oracle3", NameTools.uniqueNameForIgnoreCase("Oracle", strings));
-		assertEquals("oracle3", NameTools.uniqueNameForIgnoreCase("oracle", strings));
-		assertEquals("Test", NameTools.uniqueNameForIgnoreCase("Test", strings));
-	}
-
-	public void testUniqueNameForCollection2() {
-		Collection<String> strings = new ArrayList<String>();
-		strings.add("Oracle");
-		strings.add("oracle");
-		strings.add("Oracle2");
-		strings.add("Oracle1");
-
-		assertEquals("Oracle3", NameTools.uniqueNameFor("Oracle", strings));
-		assertEquals("Test", NameTools.uniqueNameFor("Test", strings));
-
-		strings.add("Oracle Corporation");
-		assertEquals("Oracle3", NameTools.uniqueNameForIgnoreCase("Oracle", strings));
-		assertEquals("oracle3", NameTools.uniqueNameForIgnoreCase("oracle", strings));
-		assertEquals("Test", NameTools.uniqueNameForIgnoreCase("Test", strings));
-	}
-
-	public void testUniqueNameForCollection3() {
-		Collection<String> strings = new ArrayList<String>();
-		strings.add("Oracle");
-		strings.add("Oracle");
-		strings.add("Oracle2");
-		strings.add("Oracle1");
-
-		assertEquals("Oracle3", NameTools.uniqueNameFor("Oracle", strings));
-	}
-
-	public void testUniqueNameForIterator1() {
-		Collection<String> strings = new ArrayList<String>();
-		strings.add("Oracle");
-		strings.add("Oracle Corporation");
-		strings.add("Oracle2");
-		strings.add("oracle1");
-		strings.add("Oracl");
-
-		assertEquals("Oracle3", NameTools.uniqueNameFor("Oracle", strings.iterator()));
-		assertEquals("Test", NameTools.uniqueNameFor("Test", strings.iterator()));
-
-		assertEquals("Oracle3", NameTools.uniqueNameForIgnoreCase("Oracle", strings.iterator()));
-		assertEquals("oracle3", NameTools.uniqueNameForIgnoreCase("oracle", strings.iterator()));
-		assertEquals("Test", NameTools.uniqueNameForIgnoreCase("Test", strings.iterator()));
-	}
-
-	public void testUniqueNameForIterator2() {
-		Collection<String> strings = new ArrayList<String>();
-		strings.add("Oracle");
-		strings.add("oracle");
-		strings.add("Oracle2");
-		strings.add("Oracle1");
-
-		assertEquals("Oracle3", NameTools.uniqueNameFor("Oracle", strings.iterator()));
-		assertEquals("Test", NameTools.uniqueNameFor("Test", strings.iterator()));
-
-		strings.add("Oracle Corporation");
-		assertEquals("Oracle3", NameTools.uniqueNameForIgnoreCase("Oracle", strings.iterator()));
-		assertEquals("oracle3", NameTools.uniqueNameForIgnoreCase("oracle", strings.iterator()));
-		assertEquals("Test", NameTools.uniqueNameForIgnoreCase("Test", strings.iterator()));
-	}
-
-	public void testUniqueNameForIterator3() {
-		Collection<String> strings = new ArrayList<String>();
-		strings.add("Oracle");
-		strings.add("Oracle");
-		strings.add("Oracle2");
-		strings.add("Oracle1");
-
-		assertEquals("Oracle3", NameTools.uniqueNameFor("Oracle", strings.iterator()));
-	}
-
-	public void testBuildQualifiedDatabaseObjectName() {
-		assertEquals("catalog.schema.name", NameTools.buildQualifiedDatabaseObjectName("catalog", "schema", "name"));
-		assertEquals("catalog..name", NameTools.buildQualifiedDatabaseObjectName("catalog", null, "name"));
-		assertEquals("schema.name", NameTools.buildQualifiedDatabaseObjectName(null, "schema", "name"));
-		assertEquals("name", NameTools.buildQualifiedDatabaseObjectName(null, null, "name"));
-	}
-
-	public void testJavaReservedWords() {
-		assertTrue(CollectionTools.contains(NameTools.javaReservedWords(), "class"));
-		assertFalse(CollectionTools.contains(NameTools.javaReservedWords(), "Class"));
-		assertTrue(CollectionTools.contains(NameTools.javaReservedWords(), "private"));
-	}
-
-	public void testconvertToJavaIdentifierString() {
-		assertEquals("foo", NameTools.convertToJavaIdentifier("foo"));
-		assertEquals("foo1", NameTools.convertToJavaIdentifier("foo1"));
-		assertEquals("private_", NameTools.convertToJavaIdentifier("private"));
-		assertEquals("throw_", NameTools.convertToJavaIdentifier("throw"));
-		assertEquals("_foo", NameTools.convertToJavaIdentifier("1foo"));
-		assertEquals("foo_", NameTools.convertToJavaIdentifier("foo%"));
-		assertEquals("foo__bar__", NameTools.convertToJavaIdentifier("foo  bar  "));
-	}
-
-	public void testconvertToJavaIdentifierStringChar() {
-		assertEquals("foo", NameTools.convertToJavaIdentifier("foo", '$'));
-		assertEquals("foo1", NameTools.convertToJavaIdentifier("foo1", '$'));
-		assertEquals("private$", NameTools.convertToJavaIdentifier("private", '$'));
-		assertEquals("throwss", NameTools.convertToJavaIdentifier("throw", 's'));
-		assertEquals("$foo", NameTools.convertToJavaIdentifier("1foo", '$'));
-		assertEquals("foo$", NameTools.convertToJavaIdentifier("foo%", '$'));
-		assertEquals("foo$$bar$$", NameTools.convertToJavaIdentifier("foo  bar  ", '$'));
-
-		boolean exCaught = false;
-		try {
-			String s = NameTools.convertToJavaIdentifier("1foo", '7');
-			fail("invalid string: \"" + s + "\"");
-		} catch (IllegalArgumentException ex) {
-			if (ex.getMessage().indexOf('7') != -1) {
-				exCaught = true;
-			}
-		}
-		assertTrue(exCaught);
-
-		exCaught = false;
-		try {
-			String s = NameTools.convertToJavaIdentifier("foo%", '^');
-			fail("invalid string: \"" + s + "\"");
-		} catch (IllegalArgumentException ex) {
-			if (ex.getMessage().indexOf('^') != -1) {
-				exCaught = true;
-			}
-		}
-		assertTrue(exCaught);
-
-		exCaught = false;
-		try {
-			String s = NameTools.convertToJavaIdentifier("private", '^');
-			fail("invalid string: \"" + s + "\"");
-		} catch (IllegalArgumentException ex) {
-			if (ex.getMessage().indexOf('^') != -1) {
-				exCaught = true;
-			}
-		}
-		assertTrue(exCaught);
-
-	}
-
-	public void testStringIsLegalJavaIdentifier() {
-		assertFalse(NameTools.stringIsLegalJavaIdentifier("class"));
-		assertTrue(NameTools.stringIsLegalJavaIdentifier("clasS"));
-
-		assertFalse(NameTools.stringIsLegalJavaIdentifier("7foo"));
-		assertFalse(NameTools.stringIsLegalJavaIdentifier("foo@bar"));
-		assertTrue(NameTools.stringIsLegalJavaIdentifier("_foo"));
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/NotNullFilterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/NotNullFilterTests.java
deleted file mode 100644
index b6f4948..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/NotNullFilterTests.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-import org.eclipse.persistence.tools.utility.Filter;
-import org.eclipse.persistence.tools.utility.NotNullFilter;
-
-@SuppressWarnings("nls")
-public class NotNullFilterTests extends TestCase {
-
-	public NotNullFilterTests(String name) {
-		super(name);
-	}
-
-	public void testNotNullFilter() {
-		Filter<String> filter = NotNullFilter.instance();
-		assertTrue(filter.accept(""));
-		assertFalse(filter.accept(null));
-		assertTrue(filter.accept("foo"));
-		assertTrue(filter.accept("bar"));
-	}
-
-	public void testToString() {
-		Filter<String> filter = NotNullFilter.instance();
-		assertNotNull(filter.toString());
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/RangeTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/RangeTests.java
deleted file mode 100644
index 7345620..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/RangeTests.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.Range;
-
-public class RangeTests extends TestCase {
-
-	public RangeTests(String name) {
-		super(name);
-	}
-
-	public void testIncludes() {
-		Range range = new Range(5, 17);
-		assertFalse(range.includes(-55));
-		assertFalse(range.includes(0));
-		assertFalse(range.includes(4));
-		assertTrue(range.includes(5));
-		assertTrue(range.includes(6));
-		assertTrue(range.includes(16));
-		assertTrue(range.includes(17));
-		assertFalse(range.includes(18));
-		assertFalse(range.includes(200));
-	}
-
-	public void testEquals() {
-		Range range1 = new Range(5, 17);
-		Range range2 = new Range(5, 17);
-		assertNotSame(range1, range2);
-		assertEquals(range1, range1);
-		assertEquals(range1, range2);
-		assertEquals(range2, range1);
-		assertEquals(range1.hashCode(), range2.hashCode());
-
-		range2 = new Range(17, 5);
-		assertFalse(range1.equals(range2));
-		assertFalse(range2.equals(range1));
-		// although they are unequal, they can have the same hash code
-		assertEquals(range1.hashCode(), range2.hashCode());
-
-		range2 = new Range(5, 15);
-		assertFalse(range1.equals(range2));
-		assertFalse(range2.equals(range1));
-	}
-
-	public void testClone() {
-		Range range1 = new Range(5, 17);
-		Range range2 = range1.clone();
-		assertNotSame(range1, range2);
-		assertEquals(range1, range1);
-		assertEquals(range1, range2);
-		assertEquals(range2, range1);
-		assertEquals(range1.hashCode(), range2.hashCode());
-	}
-
-	public void testSerialization() throws Exception {
-		Range range1 = new Range(5, 17);
-		Range range2 = TestTools.serialize(range1);
-		assertNotSame(range1, range2);
-		assertEquals(range1, range1);
-		assertEquals(range1, range2);
-		assertEquals(range2, range1);
-		assertEquals(range1.hashCode(), range2.hashCode());
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ReflectionToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ReflectionToolsTests.java
deleted file mode 100644
index b20b28d..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ReflectionToolsTests.java
+++ /dev/null
@@ -1,441 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.Vector;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.ReflectionTools;
-import org.eclipse.persistence.tools.utility.iterables.TransformationIterable;
-
-@SuppressWarnings("nls")
-public class ReflectionToolsTests extends TestCase {
-
-	private static String testStaticField;
-
-	public ReflectionToolsTests(String name) {
-		super(name);
-	}
-
-// this is no longer true - it appears the JLS now defines the generated names...
-//	/**
-//	 * Return the compiler-generated class name. The Eclipse compiler generates
-//	 * "local" classes with names in the form "com.foo.Outer$1$Local"; while the
-//	 * JDK compiler generates "com.foo.Outer$1Local". There might be other
-//	 * differences.... ~bjv
-//	 */
-//	public static String compilerDependentClassNameFor(String className) {
-//		int index = className.indexOf("$1$");
-//		if (index == -1) {
-//			return className;
-//		}
-//		try {
-//			Class.forName(className);
-//		} catch (ClassNotFoundException ex) {
-//			return className.substring(0, index + 2) + className.substring(index + 3);
-//		}
-//		return className;
-//	}
-//
-//	private static String munge(String className) {
-//		return compilerDependentClassNameFor(className);
-//	}
-
-	public void testAllFields() {
-		int fieldCount = 0;
-		fieldCount += java.util.Vector.class.getDeclaredFields().length;
-		fieldCount += java.util.AbstractList.class.getDeclaredFields().length;
-		fieldCount += java.util.AbstractCollection.class.getDeclaredFields().length;
-		fieldCount += java.lang.Object.class.getDeclaredFields().length;
-		Iterable<Field> fields = ReflectionTools.getAllFields(java.util.Vector.class);
-		assertEquals(fieldCount, CollectionTools.size(fields));
-		assertTrue(CollectionTools.contains(this.fieldNames(fields), "modCount"));
-		assertTrue(CollectionTools.contains(this.fieldNames(fields), "serialVersionUID"));
-		assertTrue(CollectionTools.contains(this.fieldNames(fields), "capacityIncrement"));
-		assertTrue(CollectionTools.contains(this.fieldNames(fields), "elementCount"));
-		assertTrue(CollectionTools.contains(this.fieldNames(fields), "elementData"));
-		assertTrue(fields.iterator().next().isAccessible());
-	}
-
-	public void testAllMethods() {
-		int methodCount = 0;
-		methodCount += java.util.Vector.class.getDeclaredMethods().length;
-		methodCount += java.util.AbstractList.class.getDeclaredMethods().length;
-		methodCount += java.util.AbstractCollection.class.getDeclaredMethods().length;
-		methodCount += java.lang.Object.class.getDeclaredMethods().length;
-		Iterable<Method> methods = ReflectionTools.getAllMethods(java.util.Vector.class);
-		assertEquals(methodCount, CollectionTools.size(methods));
-		assertTrue(CollectionTools.contains(this.methodNames(methods), "wait"));
-		assertTrue(CollectionTools.contains(this.methodNames(methods), "addElement"));
-		assertTrue(methods.iterator().next().isAccessible());
-	}
-
-	public void testNewInstanceClass() {
-		Vector<?> v = ReflectionTools.newInstance(java.util.Vector.class);
-		assertNotNull(v);
-		assertEquals(0, v.size());
-	}
-
-	public void testNewInstanceClassClassObject() {
-		int initialCapacity = 200;
-		Vector<?> v = ReflectionTools.newInstance(java.util.Vector.class, int.class, new Integer(initialCapacity));
-		assertNotNull(v);
-		assertEquals(0, v.size());
-		Object[] elementData = (Object[]) ReflectionTools.getFieldValue(v, "elementData");
-		assertEquals(initialCapacity, elementData.length);
-	}
-
-	public void testNewInstanceClassClassArrayObjectArray() {
-		int initialCapacity = 200;
-		Class<?>[] parmTypes = new Class[1];
-		parmTypes[0] = int.class;
-		Object[] parms = new Object[1];
-		parms[0] = new Integer(initialCapacity);
-		Vector<?> v = ReflectionTools.newInstance(java.util.Vector.class, parmTypes, parms);
-		assertNotNull(v);
-		assertEquals(0, v.size());
-		Object[] elementData = (Object[]) ReflectionTools.getFieldValue(v, "elementData");
-		assertEquals(initialCapacity, elementData.length);
-
-		parms[0] = new Integer(-1);
-		boolean exCaught = false;
-		try {
-			v = ReflectionTools.newInstance(java.util.Vector.class, parmTypes, parms);
-		} catch (RuntimeException ex) {
-			exCaught = true;
-		}
-		assertTrue("RuntimeException not thrown", exCaught);
-
-		parmTypes[0] = java.lang.String.class;
-		parms[0] = "foo";
-		exCaught = false;
-		try {
-			v = ReflectionTools.newInstance(java.util.Vector.class, parmTypes, parms);
-		} catch (RuntimeException ex) {
-			if (ex.getCause() instanceof NoSuchMethodException) {
-				exCaught = true;
-			}
-		}
-		assertTrue("NoSuchMethodException not thrown", exCaught);
-	}
-
-	public void testFieldValue() {
-		int initialCapacity = 200;
-		Vector<?> v = new Vector<Object>(initialCapacity);
-		Object[] elementData = (Object[]) ReflectionTools.getFieldValue(v, "elementData");
-		assertEquals(initialCapacity, elementData.length);
-
-		// test inherited field
-		Integer modCountInteger = (Integer) ReflectionTools.getFieldValue(v, "modCount");
-		int modCount = modCountInteger.intValue();
-		assertEquals(0, modCount);
-
-		boolean exCaught = false;
-		Object bogusFieldValue = null;
-		try {
-			bogusFieldValue = ReflectionTools.getFieldValue(v, "bogusField");
-		} catch (RuntimeException ex) {
-			if (ex.getCause() instanceof NoSuchFieldException) {
-				exCaught = true;
-			}
-		}
-		assertTrue("NoSuchFieldException not thrown: " + bogusFieldValue, exCaught);
-	}
-
-	public void testExecuteMethodObjectString() {
-		Vector<String> v = new Vector<String>();
-		int size = ((Integer) ReflectionTools.executeMethod(v, "size")).intValue();
-		assertEquals(0, size);
-
-		v.addElement("foo");
-		size = ((Integer) ReflectionTools.executeMethod(v, "size")).intValue();
-		assertEquals(1, size);
-	}
-
-	public void testExecuteMethodObjectStringClassObject() {
-		Vector<String> v = new Vector<String>();
-		boolean booleanResult = ((Boolean) ReflectionTools.executeMethod(v, "add", Object.class, "foo")).booleanValue();
-		assertTrue(booleanResult);
-		assertTrue(v.contains("foo"));
-		Object voidResult = ReflectionTools.executeMethod(v, "addElement", Object.class, "bar");
-		assertNull(voidResult);
-	}
-
-	public void testExecuteMethodObjectStringClassArrayObjectArray() {
-		Vector<String> v = new Vector<String>();
-		Class<?>[] parmTypes = new Class[1];
-		parmTypes[0] = java.lang.Object.class;
-		Object[] parms = new Object[1];
-		parms[0] = "foo";
-		boolean booleanResult = ((Boolean) ReflectionTools.executeMethod(v, "add", parmTypes, parms)).booleanValue();
-		assertTrue(booleanResult);
-		assertTrue(v.contains("foo"));
-
-		boolean exCaught = false;
-		Object bogusMethodReturnValue = null;
-		try {
-			bogusMethodReturnValue = ReflectionTools.executeMethod(v, "bogusMethod", parmTypes, parms);
-		} catch (RuntimeException ex) {
-			if (ex.getCause() instanceof NoSuchMethodException) {
-				exCaught = true;
-			}
-		}
-		assertTrue("NoSuchMethodException not thrown: " + bogusMethodReturnValue, exCaught);
-	}
-
-	public void testExecuteStaticMethodClassString() {
-		Double randomObject = (Double) ReflectionTools.executeStaticMethod(java.lang.Math.class, "random");
-		assertNotNull(randomObject);
-		double random = randomObject.doubleValue();
-		assertTrue(random >= 0);
-		assertTrue(random < 1);
-	}
-
-	public void testExecuteStaticMethodClassStringClassObject() {
-		String s = (String) ReflectionTools.executeStaticMethod(java.lang.String.class, "valueOf", boolean.class, Boolean.TRUE);
-		assertNotNull(s);
-		assertEquals("true", s);
-	}
-
-	public void testExecuteStaticMethodClassStringClassArrayObjectArray() {
-		Class<?>[] parmTypes = new Class[1];
-		parmTypes[0] = boolean.class;
-		Object[] parms = new Object[1];
-		parms[0] = Boolean.TRUE;
-		String s = (String) ReflectionTools.executeStaticMethod(java.lang.String.class, "valueOf", parmTypes, parms);
-		assertNotNull(s);
-		assertEquals("true", s);
-
-		boolean exCaught = false;
-		Object bogusStaticMethodReturnValue = null;
-		try {
-			bogusStaticMethodReturnValue = ReflectionTools.executeStaticMethod(java.lang.String.class, "bogusStaticMethod", parmTypes, parms);
-		} catch (RuntimeException ex) {
-			if (ex.getCause() instanceof NoSuchMethodException) {
-				exCaught = true;
-			}
-		}
-		assertTrue("NoSuchMethodException not thrown: " + bogusStaticMethodReturnValue, exCaught);
-
-		// test non-static method
-		exCaught = false;
-		try {
-			bogusStaticMethodReturnValue = ReflectionTools.executeStaticMethod(java.lang.String.class, "toString");
-		} catch (RuntimeException ex) {
-			if (ex.getCause() instanceof NoSuchMethodException) {
-				exCaught = true;
-			}
-		}
-		assertTrue("NoSuchMethodException not thrown: " + bogusStaticMethodReturnValue, exCaught);
-	}
-
-	public void testSetFieldValue() {
-		Vector<String> v = new Vector<String>();
-		Object[] newElementData = new Object[5];
-		newElementData[0] = "foo";
-		ReflectionTools.setFieldValue(v, "elementData", newElementData);
-		ReflectionTools.setFieldValue(v, "elementCount", new Integer(1));
-		// test inherited field
-		ReflectionTools.setFieldValue(v, "modCount", new Integer(1));
-		assertTrue(v.contains("foo"));
-
-		boolean exCaught = false;
-		try {
-			ReflectionTools.setFieldValue(v, "bogusField", "foo");
-		} catch (RuntimeException ex) {
-			if (ex.getCause() instanceof NoSuchFieldException) {
-				exCaught = true;
-			}
-		}
-		assertTrue("NoSuchFieldException not thrown", exCaught);
-	}
-
-	public void testSetStaticFieldValue() {
-		ReflectionTools.setStaticFieldValue(this.getClass(), "testStaticField", "new value");
-		assertEquals(testStaticField, "new value");
-
-		boolean exCaught = false;
-		try {
-			ReflectionTools.setStaticFieldValue(this.getClass(), "bogusStaticField", "new value");
-		} catch (RuntimeException ex) {
-			if (ex.getCause() instanceof NoSuchFieldException) {
-				exCaught = true;
-			}
-		}
-		assertTrue("NoSuchFieldException not thrown", exCaught);
-	}
-
-	public void testSimpleName() {
-		assertEquals("Vector", java.util.Vector.class.getSimpleName());
-		assertEquals("Entry", java.util.Map.Entry.class.getSimpleName());
-		assertEquals("int", int.class.getSimpleName());
-		assertEquals("int[]", int[].class.getSimpleName());
-		assertEquals("int[][]", int[][].class.getSimpleName());
-		assertEquals("void", void.class.getSimpleName());
-	}
-
-	public void testPackageName() {
-		assertEquals("java.util", java.util.Vector.class.getPackage().getName());
-		assertEquals("java.util", java.util.Map.Entry.class.getPackage().getName());
-	}
-
-	public void testArrayDepthFor() {
-		assertEquals(0, ReflectionTools.getArrayDepth(java.util.Vector.class));
-		assertEquals(0, ReflectionTools.getArrayDepth(int.class));
-		assertEquals(0, ReflectionTools.getArrayDepth(void.class));
-		assertEquals(1, ReflectionTools.getArrayDepth(java.util.Vector[].class));
-		assertEquals(1, ReflectionTools.getArrayDepth(int[].class));
-		assertEquals(3, ReflectionTools.getArrayDepth(java.util.Vector[][][].class));
-		assertEquals(3, ReflectionTools.getArrayDepth(int[][][].class));
-	}
-
-	public void testElementTypeFor() {
-		assertEquals(java.util.Vector.class, ReflectionTools.getElementType(java.util.Vector.class));
-		assertEquals(int.class, ReflectionTools.getElementType(int.class));
-		assertEquals(void.class, ReflectionTools.getElementType(void.class));
-		assertEquals(java.util.Vector.class, ReflectionTools.getElementType(java.util.Vector[].class));
-		assertEquals(int.class, ReflectionTools.getElementType(int[].class));
-		assertEquals(java.util.Vector.class, ReflectionTools.getElementType(java.util.Vector[][][].class));
-		assertEquals(int.class, ReflectionTools.getElementType(int[][][].class));
-	}
-
-	public void testClassIsPrimitiveWrapperClass() {
-		assertTrue(ReflectionTools.classIsPrimitiveWrapper(java.lang.Void.class));
-		assertTrue(ReflectionTools.classIsPrimitiveWrapper(java.lang.Boolean.class));
-		assertTrue(ReflectionTools.classIsPrimitiveWrapper(java.lang.Integer.class));
-		assertTrue(ReflectionTools.classIsPrimitiveWrapper(java.lang.Float.class));
-
-		assertFalse(ReflectionTools.classIsPrimitiveWrapper(java.lang.String.class));
-		assertFalse(ReflectionTools.classIsPrimitiveWrapper(void.class));
-		assertFalse(ReflectionTools.classIsPrimitiveWrapper(int.class));
-	}
-
-	public void testClassIsVariablePrimitiveWrapperClass() {
-		assertFalse(ReflectionTools.classIsVariablePrimitiveWrapper(java.lang.Void.class));
-
-		assertTrue(ReflectionTools.classIsVariablePrimitiveWrapper(java.lang.Boolean.class));
-		assertTrue(ReflectionTools.classIsVariablePrimitiveWrapper(java.lang.Integer.class));
-		assertTrue(ReflectionTools.classIsVariablePrimitiveWrapper(java.lang.Float.class));
-
-		assertFalse(ReflectionTools.classIsVariablePrimitiveWrapper(java.lang.String.class));
-		assertFalse(ReflectionTools.classIsVariablePrimitiveWrapper(void.class));
-		assertFalse(ReflectionTools.classIsVariablePrimitiveWrapper(int.class));
-	}
-
-	public void testWrapperClass() {
-		assertEquals(java.lang.Void.class, ReflectionTools.getWrapperClass(void.class));
-		assertEquals(java.lang.Integer.class, ReflectionTools.getWrapperClass(int.class));
-		assertEquals(java.lang.Float.class, ReflectionTools.getWrapperClass(float.class));
-		assertEquals(java.lang.Boolean.class, ReflectionTools.getWrapperClass(boolean.class));
-
-		assertNull(ReflectionTools.getWrapperClass(java.lang.String.class));
-	}
-
-	public void testClassForTypeDeclarationStringInt() throws Exception {
-		assertEquals(int.class, ReflectionTools.getClassForTypeDeclaration("int", 0));
-		assertEquals(int[].class, ReflectionTools.getClassForTypeDeclaration("int", 1));
-		assertEquals(int[][][].class, ReflectionTools.getClassForTypeDeclaration("int", 3));
-
-		assertEquals(Object.class, ReflectionTools.getClassForTypeDeclaration("java.lang.Object", 0));
-		assertEquals(Object[][][].class, ReflectionTools.getClassForTypeDeclaration("java.lang.Object", 3));
-
-		assertEquals(void.class, ReflectionTools.getClassForTypeDeclaration("void", 0));
-		try {
-			ReflectionTools.getClassForTypeDeclaration(void.class.getName(), 1);
-			fail("should not get here...");
-		} catch (RuntimeException ex) {
-			// expected
-		}
-	}
-
-	public void testCodeForClass() {
-		assertEquals('I', ReflectionTools.getCodeForClass(int.class));
-		assertEquals('B', ReflectionTools.getCodeForClass(byte.class));
-	}
-
-	public void testClassNameForTypeDeclarationString() throws Exception {
-		assertEquals("int", ReflectionTools.getClassNameForTypeDeclaration("int"));
-		assertEquals("[I", ReflectionTools.getClassNameForTypeDeclaration("int[]"));
-		assertEquals("[[I", ReflectionTools.getClassNameForTypeDeclaration("int [ ] [ ]"));
-
-		assertEquals("java.lang.Object", ReflectionTools.getClassNameForTypeDeclaration("java.lang.Object"));
-		assertEquals("[Ljava.lang.Object;", ReflectionTools.getClassNameForTypeDeclaration("java.lang.Object\t[]"));
-		assertEquals("[[Ljava.lang.Object;", ReflectionTools.getClassNameForTypeDeclaration("java.lang.Object\t[]\t[]"));
-	}
-
-	public void testArrayDepthForTypeDeclarationString() throws Exception {
-		assertEquals(0, ReflectionTools.getArrayDepthForTypeDeclaration("java.lang.Object"));
-		assertEquals(1, ReflectionTools.getArrayDepthForTypeDeclaration("java.lang.Object[]"));
-		assertEquals(3, ReflectionTools.getArrayDepthForTypeDeclaration("java.lang.Object[][][]"));
-
-		assertEquals(0, ReflectionTools.getArrayDepthForTypeDeclaration("int"));
-		assertEquals(1, ReflectionTools.getArrayDepthForTypeDeclaration("int[]"));
-		assertEquals(3, ReflectionTools.getArrayDepthForTypeDeclaration("int[][][]"));
-
-		assertEquals(0, ReflectionTools.getArrayDepthForTypeDeclaration("float"));
-		assertEquals(1, ReflectionTools.getArrayDepthForTypeDeclaration("float [ ]"));
-		assertEquals(3, ReflectionTools.getArrayDepthForTypeDeclaration("float[] [] []"));
-	}
-
-	public void testElementTypeNameForTypeDeclarationString() throws Exception {
-		assertEquals("java.lang.Object", ReflectionTools.getElementTypeNameForTypeDeclaration("java.lang.Object"));
-		assertEquals("java.lang.Object", ReflectionTools.getElementTypeNameForTypeDeclaration("java.lang.Object[]"));
-		assertEquals("java.lang.Object", ReflectionTools.getElementTypeNameForTypeDeclaration("java.lang.Object[][][]"));
-
-		assertEquals("int", ReflectionTools.getElementTypeNameForTypeDeclaration("int"));
-		assertEquals("int", ReflectionTools.getElementTypeNameForTypeDeclaration("int[]"));
-		assertEquals("int", ReflectionTools.getElementTypeNameForTypeDeclaration("int[][][]"));
-
-		assertEquals("float", ReflectionTools.getElementTypeNameForTypeDeclaration("float"));
-		assertEquals("float", ReflectionTools.getElementTypeNameForTypeDeclaration("float [ ]"));
-		assertEquals("float", ReflectionTools.getElementTypeNameForTypeDeclaration("float[] [] []"));
-	}
-
-	public void testClassNameForTypeDeclarationStringInt() throws Exception {
-		assertEquals(int.class.getName(), ReflectionTools.getClassNameForTypeDeclaration("int", 0));
-		assertEquals(int[].class.getName(), ReflectionTools.getClassNameForTypeDeclaration("int", 1));
-		assertEquals(int[][][].class.getName(), ReflectionTools.getClassNameForTypeDeclaration("int", 3));
-
-		assertEquals(Object.class.getName(), ReflectionTools.getClassNameForTypeDeclaration("java.lang.Object", 0));
-		assertEquals(Object[][][].class.getName(), ReflectionTools.getClassNameForTypeDeclaration("java.lang.Object", 3));
-
-		assertEquals(void.class.getName(), ReflectionTools.getClassNameForTypeDeclaration("void", 0));
-		try {
-			ReflectionTools.getClassNameForTypeDeclaration(void.class.getName(), 1);
-			fail("should not get here...");
-		} catch (IllegalArgumentException ex) {
-			// expected
-		}
-	}
-
-	private Iterable<String> fieldNames(Iterable<Field> fields) {
-		return new TransformationIterable<String, Field>(fields) {
-			@Override
-			protected String transform(Field field) {
-				return field.getName();
-			}
-		};
-	}
-
-	private Iterable<String> methodNames(Iterable<Method> methods) {
-		return new TransformationIterable<String, Method>(methods) {
-			@Override
-			protected String transform(Method method) {
-				return method.getName();
-			}
-		};
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ReverseComparatorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ReverseComparatorTests.java
deleted file mode 100644
index d2b216e..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ReverseComparatorTests.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.ReverseComparator;
-
-@SuppressWarnings("nls")
-public class ReverseComparatorTests extends TestCase {
-	private Comparator<String> naturalReverseComparator;
-	private Comparator<String> customComparator;
-	private Comparator<String> customReverseComparator;
-
-	public ReverseComparatorTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.naturalReverseComparator = new ReverseComparator<String>();
-		this.customComparator = this.buildCustomComparator();
-		this.customReverseComparator = new ReverseComparator<String>(this.customComparator);
-	}
-
-	private Comparator<String> buildCustomComparator() {
-		return new Comparator<String>() {
-			public int compare(String s1, String s2) {
-				String lower1 = s1.toLowerCase();
-				String lower2 = s2.toLowerCase();
-				int result = lower1.compareTo(lower2);
-				if (result == 0) {
-					return s1.compareTo(s2); // use case to differentiate "equal" strings
-				}
-				return result;
-			}
-		};
-	}
-
-	private List<String> buildUnsortedList() {
-		List<String> result = new ArrayList<String>();
-		result.add("T");
-		result.add("Z");
-		result.add("Y");
-		result.add("M");
-		result.add("m");
-		result.add("a");
-		result.add("B");
-		result.add("b");
-		result.add("A");
-		return result;
-	}
-
-	private List<String> buildNaturallySortedList() {
-		List<String> result = new ArrayList<String>(this.buildUnsortedList());
-		Collections.sort(result);
-		return result;
-	}
-
-	private List<String> buildCustomSortedList() {
-		List<String> result = new ArrayList<String>(this.buildUnsortedList());
-		Collections.sort(result, this.customComparator);
-		return result;
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		TestTools.clear(this);
-		super.tearDown();
-	}
-
-	public void testNatural() {
-		List<String> list = this.buildUnsortedList();
-		Collections.sort(list, this.naturalReverseComparator);
-		this.verifyList(this.buildNaturallySortedList(), list);
-	}
-
-	public void testCustom() {
-		List<String> list = this.buildUnsortedList();
-		Collections.sort(list, this.customReverseComparator);
-		this.verifyList(this.buildCustomSortedList(), list);
-	}
-
-	private void verifyList(List<String> normal, List<String> reverse) {
-		int size = normal.size();
-		int max = size - 1;
-		for (int i = 0; i < size; i++) {
-			assertEquals(normal.get(i), reverse.get(max - i));
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleAssociationTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleAssociationTests.java
deleted file mode 100644
index 0109655..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleAssociationTests.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import org.eclipse.persistence.tools.utility.Association;
-import org.eclipse.persistence.tools.utility.SimpleAssociation;
-
-@SuppressWarnings("nls")
-public class SimpleAssociationTests extends TestCase {
-	private SimpleAssociation<String, String> assoc;
-
-	public static Test suite() {
-		return new TestSuite(SimpleAssociationTests.class);
-	}
-
-	public SimpleAssociationTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.assoc = new SimpleAssociation<String, String>("foo", "bar");
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		TestTools.clear(this);
-		super.tearDown();
-	}
-
-	public void testGetKey() {
-		assertEquals("foo", this.assoc.getKey());
-	}
-
-	public void testGetValue() {
-		assertEquals("bar", this.assoc.getValue());
-	}
-
-	public void testSetValue() {
-		assertEquals("bar", this.assoc.getValue());
-		this.assoc.setValue("baz");
-		assertEquals("baz", this.assoc.getValue());
-	}
-
-	public void testEquals() {
-		assertFalse(this.assoc.equals("foo"));
-
-		assertEquals(this.assoc, this.copy(this.assoc));
-
-		SimpleAssociation<String, String> assoc2 = new SimpleAssociation<String, String>("foo", "baz");
-		assertFalse(this.assoc.equals(assoc2));
-
-		assoc2 = new SimpleAssociation<String, String>("fop", "bar");
-		assertFalse(this.assoc.equals(assoc2));
-
-		SimpleAssociation<String, String> assoc3 = new SimpleAssociation<String, String>(null, null);
-		SimpleAssociation<String, String> assoc4 = new SimpleAssociation<String, String>(null, null);
-		assertEquals(assoc3, assoc4);
-	}
-
-	public void testHashCode() {
-		assertEquals(this.assoc.hashCode(), this.copy(this.assoc).hashCode());
-
-		SimpleAssociation<String, String> assoc2 = new SimpleAssociation<String, String>(null, null);
-		assertEquals(assoc2.hashCode(), this.copy(assoc2).hashCode());
-	}
-
-	public void testToString() {
-		assertNotNull(this.assoc.toString());
-	}
-
-	public void testClone() {
-		this.verifyClone(this.assoc, this.assoc.clone());
-	}
-
-	private void verifyClone(Association<String, String> expected, Association<String, String> actual) {
-		assertEquals(expected, actual);
-		assertNotSame(expected, actual);
-		assertEquals(expected.getKey(), actual.getKey());
-		assertSame(expected.getKey(), actual.getKey());
-		assertEquals(expected.getValue(), actual.getValue());
-		assertSame(expected.getValue(), actual.getValue());
-	}
-
-	public void testSerialization() throws Exception {
-		@SuppressWarnings("cast")
-		Association<String, String> assoc2 = (Association<String, String>) TestTools.serialize(this.assoc);
-
-		assertEquals(this.assoc, assoc2);
-		assertNotSame(this.assoc, assoc2);
-		assertEquals(this.assoc.getKey(), assoc2.getKey());
-		assertNotSame(this.assoc.getKey(), assoc2.getKey());
-		assertEquals(this.assoc.getValue(), assoc2.getValue());
-		assertNotSame(this.assoc.getValue(), assoc2.getValue());
-	}
-
-	private SimpleAssociation<String, String> copy(SimpleAssociation<String, String> sa) {
-		return new SimpleAssociation<String, String>(sa.getKey(), sa.getValue());
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleBooleanReferenceTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleBooleanReferenceTests.java
deleted file mode 100644
index 695ac46..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleBooleanReferenceTests.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.SimpleBooleanReference;
-
-@SuppressWarnings("nls")
-public class SimpleBooleanReferenceTests extends TestCase {
-
-	public SimpleBooleanReferenceTests(String name) {
-		super(name);
-	}
-
-	public void testGetValue() {
-		SimpleBooleanReference br = new SimpleBooleanReference(true);
-		assertTrue(br.getValue());
-	}
-
-	public void testGetValueDefault() {
-		SimpleBooleanReference br = new SimpleBooleanReference();
-		assertFalse(br.getValue());
-	}
-
-	public void testIs() {
-		SimpleBooleanReference br = new SimpleBooleanReference(true);
-		assertTrue(br.is(true));
-		assertFalse(br.is(false));
-	}
-
-	public void testIsNot() {
-		SimpleBooleanReference br = new SimpleBooleanReference(true);
-		assertFalse(br.isNot(true));
-		assertTrue(br.isNot(false));
-	}
-
-	public void testIsTrue() {
-		SimpleBooleanReference br = new SimpleBooleanReference(true);
-		assertTrue(br.isTrue());
-	}
-
-	public void testIsFalse() {
-		SimpleBooleanReference br = new SimpleBooleanReference(true);
-		assertFalse(br.isFalse());
-		br.setFalse();
-		assertTrue(br.isFalse());
-	}
-
-	public void testSetValue() {
-		SimpleBooleanReference br = new SimpleBooleanReference(true);
-		assertTrue(br.getValue());
-		br.setValue(false);
-		assertFalse(br.getValue());
-	}
-
-	public void testFlip() {
-		SimpleBooleanReference br = new SimpleBooleanReference(true);
-		assertTrue(br.getValue());
-		assertFalse(br.flip());
-		assertFalse(br.getValue());
-		assertTrue(br.flip());
-		assertTrue(br.getValue());
-	}
-
-	public void testSetNotBoolean() {
-		SimpleBooleanReference br = new SimpleBooleanReference(false);
-		assertFalse(br.getValue());
-		br.setNot(true);
-		assertFalse(br.getValue());
-		br.setNot(true);
-		assertFalse(br.getValue());
-		br.setNot(false);
-		assertTrue(br.getValue());
-	}
-
-	public void testSetTrue() {
-		SimpleBooleanReference br = new SimpleBooleanReference(false);
-		assertFalse(br.getValue());
-		br.setTrue();
-		assertTrue(br.getValue());
-	}
-
-	public void testSetFalse() {
-		SimpleBooleanReference br = new SimpleBooleanReference(true);
-		assertTrue(br.getValue());
-		br.setFalse();
-		assertFalse(br.getValue());
-	}
-
-	public void testClone() {
-		SimpleBooleanReference br = new SimpleBooleanReference(true);
-		SimpleBooleanReference clone = br.clone();
-		assertTrue(clone.getValue());
-	}
-
-	public void testToString() {
-		SimpleBooleanReference br1 = new SimpleBooleanReference(true);
-		assertEquals("[true]", br1.toString());
-		br1.setFalse();
-		assertEquals("[false]", br1.toString());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleIntReferenceTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleIntReferenceTests.java
deleted file mode 100644
index bd40528..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleIntReferenceTests.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.SimpleIntReference;
-
-@SuppressWarnings("nls")
-public class SimpleIntReferenceTests extends TestCase {
-
-	public SimpleIntReferenceTests(String name) {
-		super(name);
-	}
-
-	public void testCtors() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference();
-		assertEquals(0, ir.getValue());
-		ir = new SimpleIntReference(7);
-		assertEquals(7, ir.getValue());
-		ir = new SimpleIntReference(-7);
-		assertEquals(-7, ir.getValue());
-	}
-
-	public void testEqualsInt() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference();
-		assertTrue(ir.equals(0));
-		assertFalse(ir.equals(7));
-
-		ir = new SimpleIntReference(7);
-		assertTrue(ir.equals(7));
-		assertFalse(ir.equals(0));
-	}
-
-	public void testNotEqualInt() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference();
-		assertFalse(ir.notEqual(0));
-		assertTrue(ir.notEqual(7));
-
-		ir = new SimpleIntReference(7);
-		assertFalse(ir.notEqual(7));
-		assertTrue(ir.notEqual(0));
-	}
-
-	public void testIsZero() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference();
-		assertTrue(ir.isZero());
-
-		ir = new SimpleIntReference(7);
-		assertFalse(ir.isZero());
-	}
-
-	public void testIsNotZero() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference();
-		assertFalse(ir.isNotZero());
-
-		ir = new SimpleIntReference(7);
-		assertTrue(ir.isNotZero());
-	}
-
-	public void testIsGreaterThanInt() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference();
-		assertTrue(ir.isGreaterThan(-1));
-		assertFalse(ir.isGreaterThan(0));
-		assertFalse(ir.isGreaterThan(7));
-	}
-
-	public void testIsGreaterThanOrEqualInt() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference();
-		assertTrue(ir.isGreaterThanOrEqual(-1));
-		assertTrue(ir.isGreaterThanOrEqual(0));
-		assertFalse(ir.isGreaterThanOrEqual(7));
-	}
-
-	public void testIsLessThanInt() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference();
-		assertFalse(ir.isLessThan(-1));
-		assertFalse(ir.isLessThan(0));
-		assertTrue(ir.isLessThan(7));
-	}
-
-	public void testIsLessThanOrEqualInt() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference();
-		assertFalse(ir.isLessThanOrEqual(-1));
-		assertTrue(ir.isLessThanOrEqual(0));
-		assertTrue(ir.isLessThanOrEqual(7));
-	}
-
-	public void testIsPositive() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(-3);
-		assertFalse(ir.isPositive());
-
-		ir = new SimpleIntReference();
-		assertFalse(ir.isPositive());
-
-		ir = new SimpleIntReference(7);
-		assertTrue(ir.isPositive());
-	}
-
-	public void testIsNotPositive() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(-3);
-		assertTrue(ir.isNotPositive());
-
-		ir = new SimpleIntReference();
-		assertTrue(ir.isNotPositive());
-
-		ir = new SimpleIntReference(7);
-		assertFalse(ir.isNotPositive());
-	}
-
-	public void testIsNegative() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(-3);
-		assertTrue(ir.isNegative());
-
-		ir = new SimpleIntReference();
-		assertFalse(ir.isNegative());
-
-		ir = new SimpleIntReference(7);
-		assertFalse(ir.isNegative());
-	}
-
-	public void testIsNotNegative() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(-3);
-		assertFalse(ir.isNotNegative());
-
-		ir = new SimpleIntReference();
-		assertTrue(ir.isNotNegative());
-
-		ir = new SimpleIntReference(7);
-		assertTrue(ir.isNotNegative());
-	}
-
-	public void testSetValueInt() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(-3);
-		assertEquals(-3, ir.getValue());
-		assertEquals(-3, ir.setValue(4));
-		assertEquals(4, ir.getValue());
-	}
-
-	public void testAbs() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(-3);
-		assertEquals(-3, ir.getValue());
-		assertEquals(3, ir.abs());
-
-		ir.setValue(3);
-		assertEquals(3, ir.getValue());
-		assertEquals(3, ir.abs());
-	}
-
-	public void testNeg() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(-3);
-		assertEquals(-3, ir.getValue());
-		assertEquals(3, ir.neg());
-
-		ir.setValue(3);
-		assertEquals(3, ir.getValue());
-		assertEquals(-3, ir.neg());
-	}
-
-	public void testSetZero() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(-3);
-		assertEquals(-3, ir.getValue());
-		assertEquals(-3, ir.setZero());
-		assertEquals(0, ir.getValue());
-	}
-
-	public void testAddInt() {
-		SimpleIntReference ir;
-		int value;
-		ir = new SimpleIntReference();
-		assertEquals(0, ir.getValue());
-
-		value = ir.add(3);
-		assertEquals(3, value);
-
-		ir.setValue(3);
-		value = ir.add(-7);
-		assertEquals(-4, value);
-	}
-
-	public void testIncrement() {
-		SimpleIntReference ir;
-		int value;
-		ir = new SimpleIntReference();
-		assertEquals(0, ir.getValue());
-
-		value = ir.increment();
-		assertEquals(1, value);
-		assertEquals(1, ir.getValue());
-	}
-
-	public void testSubtractInt() {
-		SimpleIntReference ir;
-		int count;
-		ir = new SimpleIntReference();
-		assertEquals(0, ir.getValue());
-
-		count = ir.subtract(3);
-		assertEquals(-3, count);
-
-		ir.setValue(-3);
-		count = ir.subtract(-7);
-		assertEquals(4, count);
-	}
-
-	public void testDecrement() {
-		SimpleIntReference ir;
-		int count;
-		ir = new SimpleIntReference();
-		assertEquals(0, ir.getValue());
-
-		count = ir.decrement();
-		assertEquals(-1, count);
-		assertEquals(-1, ir.getValue());
-	}
-
-	public void testMultiplyInt() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(3);
-		assertEquals(3, ir.getValue());
-		assertEquals(9, ir.multiply(3));
-	}
-
-	public void testDivideInt() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(24);
-		assertEquals(24, ir.getValue());
-		assertEquals(8, ir.divide(3));
-	}
-
-	public void testRemainderInt() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(25);
-		assertEquals(25, ir.getValue());
-		assertEquals(1, ir.remainder(3));
-	}
-
-	public void testMinInt() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(25);
-		assertEquals(25, ir.getValue());
-		assertEquals(3, ir.min(3));
-		assertEquals(25, ir.min(33));
-	}
-
-	public void testMaxInt() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(25);
-		assertEquals(25, ir.getValue());
-		assertEquals(25, ir.max(3));
-		assertEquals(30, ir.max(30));
-	}
-
-	public void testPowInt() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(5);
-		assertEquals(5, ir.getValue());
-		assertTrue(ir.pow(2) == 25L);
-	}
-
-	public void testCompareToIntReference() {
-		SimpleIntReference ir1 = new SimpleIntReference(44);
-		SimpleIntReference ir2 = new SimpleIntReference(44);
-		assertTrue(ir1.compareTo(ir2) == 0);
-		ir2 = new SimpleIntReference(55);
-		assertTrue(ir1.compareTo(ir2) < 0);
-		ir2 = new SimpleIntReference(33);
-		assertTrue(ir1.compareTo(ir2) > 0);
-	}
-
-	public void testClone() {
-		SimpleIntReference ir1 = new SimpleIntReference(44);
-		SimpleIntReference ir2 = ir1.clone();
-		assertEquals(44, ir2.getValue());
-		assertNotSame(ir1, ir2);
-	}
-
-	public void testSerialization() throws Exception {
-		SimpleIntReference ir1 = new SimpleIntReference(44);
-		SimpleIntReference ir2 = TestTools.serialize(ir1);
-		assertEquals(44, ir2.getValue());
-		assertNotSame(ir1, ir2);
-	}
-
-	public void testToString() {
-		SimpleIntReference ir;
-		ir = new SimpleIntReference(5);
-		assertEquals("[5]", ir.toString());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleObjectReferenceTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleObjectReferenceTests.java
deleted file mode 100644
index c309e4f..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleObjectReferenceTests.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.SimpleObjectReference;
-
-@SuppressWarnings("nls")
-public class SimpleObjectReferenceTests extends TestCase {
-
-	public SimpleObjectReferenceTests(String name) {
-		super(name);
-	}
-
-	public void testGetValue() {
-		SimpleObjectReference<String> or = new SimpleObjectReference<String>();
-		assertNull(or.getValue());
-		or.setValue("foo");
-		assertEquals("foo", or.getValue());
-	}
-
-	public void testValueEqualsObject() {
-		SimpleObjectReference<String> or = new SimpleObjectReference<String>();
-		assertTrue(or.valueEquals(null));
-		assertFalse(or.valueEquals("foo"));
-
-		or.setValue("foo");
-		assertFalse(or.valueEquals(null));
-		assertTrue(or.valueEquals("foo"));
-	}
-
-	public void testValueNotEqualObject() {
-		SimpleObjectReference<String> or = new SimpleObjectReference<String>();
-		assertFalse(or.valueNotEqual(null));
-		assertTrue(or.valueNotEqual("foo"));
-
-		or.setValue("foo");
-		assertTrue(or.valueNotEqual(null));
-		assertFalse(or.valueNotEqual("foo"));
-	}
-
-	public void testIsNull() {
-		SimpleObjectReference<String> or = new SimpleObjectReference<String>();
-		assertTrue(or.isNull());
-		or.setValue("foo");
-		assertFalse(or.isNull());
-	}
-
-	public void testIsNotNull() {
-		SimpleObjectReference<String> or = new SimpleObjectReference<String>();
-		assertFalse(or.isNotNull());
-		or.setValue("foo");
-		assertTrue(or.isNotNull());
-	}
-
-	public void testSetNull() {
-		SimpleObjectReference<String> or = new SimpleObjectReference<String>();
-		assertNull(or.getValue());
-		or.setValue("foo");
-		assertEquals("foo", or.getValue());
-		or.setNull();
-		assertNull(or.getValue());
-	}
-
-	public void testClone() {
-		SimpleObjectReference<String> or = new SimpleObjectReference<String>("foo");
-		@SuppressWarnings("cast")
-		SimpleObjectReference<String> clone = (SimpleObjectReference<String>) or.clone();
-		assertEquals("foo", clone.getValue());
-		assertNotSame(or, clone);
-	}
-
-	public void testToString() {
-		SimpleObjectReference<String> or = new SimpleObjectReference<String>();
-		assertEquals("[null]", or.toString());
-		or.setValue("foo");
-		assertEquals("[foo]", or.toString());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleQueueTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleQueueTests.java
deleted file mode 100644
index d454cc6..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleQueueTests.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.Queue;
-import org.eclipse.persistence.tools.utility.SimpleQueue;
-
-@SuppressWarnings("nls")
-public class SimpleQueueTests
-	extends MultiThreadedTestCase
-{
-
-	public SimpleQueueTests(String name) {
-		super(name);
-	}
-
-	Queue<String> buildQueue() {
-		return new SimpleQueue<String>();
-	}
-
-	public void testIsEmpty() {
-		Queue<String> queue = this.buildQueue();
-		assertTrue(queue.isEmpty());
-		queue.enqueue("first");
-		assertFalse(queue.isEmpty());
-		queue.enqueue("second");
-		assertFalse(queue.isEmpty());
-		queue.dequeue();
-		assertFalse(queue.isEmpty());
-		queue.dequeue();
-		assertTrue(queue.isEmpty());
-	}
-
-	public void testEnqueueAndDequeue() {
-		Queue<String> queue = this.buildQueue();
-		String first = "first";
-		String second = "second";
-
-		queue.enqueue(first);
-		queue.enqueue(second);
-		assertEquals(first, queue.dequeue());
-		assertEquals(second, queue.dequeue());
-	}
-
-	public void testEnqueueAndPeek() {
-		Queue<String> queue = this.buildQueue();
-		String first = "first";
-		String second = "second";
-
-		queue.enqueue(first);
-		queue.enqueue(second);
-		assertEquals(first, queue.peek());
-		assertEquals(first, queue.peek());
-		assertEquals(first, queue.dequeue());
-		assertEquals(second, queue.peek());
-		assertEquals(second, queue.peek());
-		assertEquals(second, queue.dequeue());
-	}
-
-	public void testEmptyQueueExceptionPeek() {
-		Queue<String> queue = this.buildQueue();
-		String first = "first";
-		String second = "second";
-
-		queue.enqueue(first);
-		queue.enqueue(second);
-		assertEquals(first, queue.peek());
-		assertEquals(first, queue.dequeue());
-		assertEquals(second, queue.peek());
-		assertEquals(second, queue.dequeue());
-
-		boolean exCaught = false;
-		try {
-			queue.peek();
-			fail();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testEmptyQueueExceptionDequeue() {
-		Queue<String> queue = this.buildQueue();
-		String first = "first";
-		String second = "second";
-
-		queue.enqueue(first);
-		queue.enqueue(second);
-		assertEquals(first, queue.peek());
-		assertEquals(first, queue.dequeue());
-		assertEquals(second, queue.peek());
-		assertEquals(second, queue.dequeue());
-
-		boolean exCaught = false;
-		try {
-			queue.dequeue();
-			fail();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testClone() {
-		SimpleQueue<String> queue = (SimpleQueue<String>) this.buildQueue();
-		queue.enqueue("first");
-		queue.enqueue("second");
-		queue.enqueue("third");
-
-		this.verifyClone(queue, queue.clone());
-	}
-
-	public void testSerialization() throws Exception {
-		Queue<String> queue = this.buildQueue();
-		queue.enqueue("first");
-		queue.enqueue("second");
-		queue.enqueue("third");
-
-		this.verifyClone(queue, TestTools.serialize(queue));
-	}
-
-	private void verifyClone(Queue<String> original, Queue<String> clone) {
-		assertNotSame(original, clone);
-		assertEquals(original.peek(), clone.peek());
-		assertEquals(original.dequeue(), clone.dequeue());
-		assertEquals(original.peek(), clone.peek());
-		assertEquals(original.dequeue(), clone.dequeue());
-		assertEquals(original.isEmpty(), clone.isEmpty());
-		assertEquals(original.peek(), clone.peek());
-		assertEquals(original.dequeue(), clone.dequeue());
-		assertTrue(original.isEmpty());
-		assertEquals(original.isEmpty(), clone.isEmpty());
-
-		original.enqueue("fourth");
-		assertFalse(original.isEmpty());
-		// clone should still be empty
-		assertTrue(clone.isEmpty());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleStackTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleStackTests.java
deleted file mode 100644
index 8733e1d..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SimpleStackTests.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.util.EmptyStackException;
-
-import org.eclipse.persistence.tools.utility.SimpleStack;
-import org.eclipse.persistence.tools.utility.Stack;
-
-@SuppressWarnings("nls")
-public class SimpleStackTests
-	extends MultiThreadedTestCase
-{
-	public SimpleStackTests(String name) {
-		super(name);
-	}
-
-	Stack<String> buildStack() {
-		return new SimpleStack<String>();
-	}
-
-	public void testIsEmpty() {
-		Stack<String> stack = this.buildStack();
-		assertTrue(stack.isEmpty());
-		stack.push("first");
-		assertFalse(stack.isEmpty());
-		stack.push("second");
-		assertFalse(stack.isEmpty());
-		stack.pop();
-		assertFalse(stack.isEmpty());
-		stack.pop();
-		assertTrue(stack.isEmpty());
-	}
-
-	public void testPushAndPop() {
-		Stack<String> stack = this.buildStack();
-		String first = "first";
-		String second = "second";
-
-		stack.push(first);
-		stack.push(second);
-		assertEquals(second, stack.pop());
-		assertEquals(first, stack.pop());
-	}
-
-	public void testPushAndPeek() {
-		Stack<String> stack = this.buildStack();
-		String first = "first";
-		String second = "second";
-
-		stack.push(first);
-		stack.push(second);
-		assertEquals(second, stack.peek());
-		assertEquals(second, stack.peek());
-		assertEquals(second, stack.pop());
-		assertEquals(first, stack.peek());
-		assertEquals(first, stack.peek());
-		assertEquals(first, stack.pop());
-	}
-
-	public void testEmptyStackExceptionPeek() {
-		Stack<String> stack = this.buildStack();
-		String first = "first";
-		String second = "second";
-
-		stack.push(first);
-		stack.push(second);
-		assertEquals(second, stack.peek());
-		assertEquals(second, stack.pop());
-		assertEquals(first, stack.peek());
-		assertEquals(first, stack.pop());
-
-		boolean exCaught = false;
-		try {
-			stack.peek();
-			fail();
-		} catch (EmptyStackException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testEmptyStackExceptionPop() {
-		Stack<String> stack = this.buildStack();
-		String first = "first";
-		String second = "second";
-
-		stack.push(first);
-		stack.push(second);
-		assertEquals(second, stack.peek());
-		assertEquals(second, stack.pop());
-		assertEquals(first, stack.peek());
-		assertEquals(first, stack.pop());
-
-		boolean exCaught = false;
-		try {
-			stack.pop();
-			fail();
-		} catch (EmptyStackException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testClone() {
-		SimpleStack<String> stack = (SimpleStack<String>) this.buildStack();
-		stack.push("first");
-		stack.push("second");
-		stack.push("third");
-
-		this.verifyClone(stack, stack.clone());
-	}
-
-	public void testSerialization() throws Exception {
-		Stack<String> stack = this.buildStack();
-		stack.push("first");
-		stack.push("second");
-		stack.push("third");
-
-		this.verifyClone(stack, TestTools.serialize(stack));
-	}
-
-	private void verifyClone(Stack<String> original, Stack<String> clone) {
-		assertNotSame(original, clone);
-		assertEquals(original.peek(), clone.peek());
-		assertEquals(original.pop(), clone.pop());
-		assertEquals(original.peek(), clone.peek());
-		assertEquals(original.pop(), clone.pop());
-		assertEquals(original.isEmpty(), clone.isEmpty());
-		assertEquals(original.peek(), clone.peek());
-		assertEquals(original.pop(), clone.pop());
-		assertTrue(original.isEmpty());
-		assertEquals(original.isEmpty(), clone.isEmpty());
-
-		original.push("fourth");
-		assertFalse(original.isEmpty());
-		// clone should still be empty
-		assertTrue(clone.isEmpty());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/StringToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/StringToolsTests.java
deleted file mode 100644
index ba352a3..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/StringToolsTests.java
+++ /dev/null
@@ -1,1875 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.io.StringWriter;
-import java.io.Writer;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-@SuppressWarnings("nls")
-public class StringToolsTests extends TestCase {
-
-	public StringToolsTests(String name) {
-		super(name);
-	}
-
-	private static void assertEquals(String expected, char[] actual) {
-		assertEquals(expected, new String(actual));
-	}
-
-	// ********** padding/truncating **********
-
-	public void testPad() {
-		assertEquals("fred", StringTools.pad("fred", 4));
-		assertEquals("fred  ", StringTools.pad("fred", 6));
-		boolean exThrown = false;
-		try {
-			assertEquals("fr", StringTools.pad("fred", 2));
-		} catch (IllegalArgumentException ex) {
-			exThrown = true;
-		}
-		assertTrue(exThrown);
-	}
-
-	public void testPadCharArray() {
-		assertEquals("fred", StringTools.pad(new char[] { 'f', 'r', 'e', 'd' }, 4));
-		assertEquals("fred  ", StringTools.pad(new char[] { 'f', 'r', 'e', 'd' }, 6));
-		boolean exThrown = false;
-		try {
-			assertEquals("fr", StringTools.pad(new char[] { 'f', 'r', 'e', 'd' }, 2));
-		} catch (IllegalArgumentException ex) {
-			exThrown = true;
-		}
-		assertTrue(exThrown);
-	}
-
-	public void testPadOnWriter() {
-		Writer writer;
-		writer = new StringWriter();
-		StringTools.padOn("fred", 4, writer);
-		assertEquals("fred", writer.toString());
-
-		writer = new StringWriter();
-		StringTools.padOn("fred", 6, writer);
-		assertEquals("fred  ", writer.toString());
-
-		writer = new StringWriter();
-		boolean exThrown = false;
-		try {
-			StringTools.padOn("fred", 2, writer);
-			fail();
-		} catch (IllegalArgumentException ex) {
-			exThrown = true;
-		}
-		assertTrue(exThrown);
-	}
-
-	public void testPadOnStringBuffer() {
-		StringBuffer sb;
-		sb = new StringBuffer();
-		StringTools.padOn("fred", 4, sb);
-		assertEquals("fred", sb.toString());
-
-		sb = new StringBuffer();
-		StringTools.padOn("fred", 6, sb);
-		assertEquals("fred  ", sb.toString());
-
-		sb = new StringBuffer();
-		boolean exThrown = false;
-		try {
-			StringTools.padOn("fred", 2, sb);
-			fail();
-		} catch (IllegalArgumentException ex) {
-			exThrown = true;
-		}
-		assertTrue(exThrown);
-	}
-
-	public void testPadOnStringBuilder() {
-		StringBuilder sb;
-		sb = new StringBuilder();
-		StringTools.padOn("fred", 4, sb);
-		assertEquals("fred", sb.toString());
-
-		sb = new StringBuilder();
-		StringTools.padOn("fred", 6, sb);
-		assertEquals("fred  ", sb.toString());
-
-		sb = new StringBuilder();
-		boolean exThrown = false;
-		try {
-			StringTools.padOn("fred", 2, sb);
-			fail();
-		} catch (IllegalArgumentException ex) {
-			exThrown = true;
-		}
-		assertTrue(exThrown);
-	}
-
-	public void testPadOrTruncate() {
-		assertEquals("fred", StringTools.padOrTruncate("fred", 4));
-		assertEquals("fred  ", StringTools.padOrTruncate("fred", 6));
-		assertEquals("fr", StringTools.padOrTruncate("fred", 2));
-	}
-
-	public void testPadOrTruncateCharArray() {
-		assertEquals("fred", StringTools.padOrTruncate(new char[] { 'f', 'r', 'e', 'd' }, 4));
-		assertEquals("fred  ", StringTools.padOrTruncate(new char[] { 'f', 'r', 'e', 'd' }, 6));
-		assertEquals("fr", StringTools.padOrTruncate(new char[] { 'f', 'r', 'e', 'd' }, 2));
-	}
-
-	public void testPadOrTruncateOnWriter() {
-		this.verifyPadOrTruncateOnWriter("fred", "fred", 4);
-		this.verifyPadOrTruncateOnWriter("fred  ", "fred", 6);
-		this.verifyPadOrTruncateOnWriter("fr", "fred", 2);
-	}
-
-	private void verifyPadOrTruncateOnWriter(String expected, String string, int length) {
-		Writer writer = new StringWriter();
-		StringTools.padOrTruncateOn(string, length, writer);
-		assertEquals(expected, writer.toString());
-	}
-
-	public void testPadOrTruncateOnStringBuffer() {
-		this.verifyPadOrTruncateOnStringBuffer("fred", "fred", 4);
-		this.verifyPadOrTruncateOnStringBuffer("fred  ", "fred", 6);
-		this.verifyPadOrTruncateOnStringBuffer("fr", "fred", 2);
-	}
-
-	private void verifyPadOrTruncateOnStringBuffer(String expected, String string, int length) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.padOrTruncateOn(string, length, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testPadOrTruncateOnStringBuilder() {
-		this.verifyPadOrTruncateOnStringBuilder("fred", "fred", 4);
-		this.verifyPadOrTruncateOnStringBuilder("fred  ", "fred", 6);
-		this.verifyPadOrTruncateOnStringBuilder("fr", "fred", 2);
-	}
-
-	private void verifyPadOrTruncateOnStringBuilder(String expected, String string, int length) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.padOrTruncateOn(string, length, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testZeroPad() {
-		assertEquals("1234", StringTools.zeroPad("1234", 4));
-		assertEquals("001234", StringTools.zeroPad("1234", 6));
-		boolean exThrown = false;
-		try {
-			assertEquals("12", StringTools.zeroPad("1234", 2));
-		} catch (IllegalArgumentException ex) {
-			exThrown = true;
-		}
-		assertTrue(exThrown);
-	}
-
-	public void testZeroPadCharArray() {
-		assertEquals("1234", StringTools.zeroPad(new char[] { '1', '2', '3', '4' }, 4));
-		assertEquals("001234", StringTools.zeroPad(new char[] { '1', '2', '3', '4' }, 6));
-		boolean exThrown = false;
-		try {
-			assertEquals("12", StringTools.zeroPad(new char[] { '1', '2', '3', '4' }, 2));
-		} catch (IllegalArgumentException ex) {
-			exThrown = true;
-		}
-		assertTrue(exThrown);
-	}
-
-	public void testZeroPadOnWriter() {
-		Writer writer;
-		writer = new StringWriter();
-		StringTools.zeroPadOn("1234", 4, writer);
-		assertEquals("1234", writer.toString());
-
-		writer = new StringWriter();
-		StringTools.zeroPadOn("1234", 6, writer);
-		assertEquals("001234", writer.toString());
-
-		writer = new StringWriter();
-		boolean exThrown = false;
-		try {
-			StringTools.zeroPadOn("1234", 2, writer);
-			fail();
-		} catch (IllegalArgumentException ex) {
-			exThrown = true;
-		}
-		assertTrue(exThrown);
-	}
-
-	public void testZeroPadOnStringBuffer() {
-		StringBuffer sb;
-		sb = new StringBuffer();
-		StringTools.zeroPadOn("1234", 4, sb);
-		assertEquals("1234", sb.toString());
-
-		sb = new StringBuffer();
-		StringTools.zeroPadOn("1234", 6, sb);
-		assertEquals("001234", sb.toString());
-
-		sb = new StringBuffer();
-		boolean exThrown = false;
-		try {
-			StringTools.zeroPadOn("1234", 2, sb);
-			fail();
-		} catch (IllegalArgumentException ex) {
-			exThrown = true;
-		}
-		assertTrue(exThrown);
-	}
-
-	public void testZeroPadOnStringBuilder() {
-		StringBuilder sb;
-		sb = new StringBuilder();
-		StringTools.zeroPadOn("1234", 4, sb);
-		assertEquals("1234", sb.toString());
-
-		sb = new StringBuilder();
-		StringTools.zeroPadOn("1234", 6, sb);
-		assertEquals("001234", sb.toString());
-
-		sb = new StringBuilder();
-		boolean exThrown = false;
-		try {
-			StringTools.zeroPadOn("1234", 2, sb);
-			fail();
-		} catch (IllegalArgumentException ex) {
-			exThrown = true;
-		}
-		assertTrue(exThrown);
-	}
-
-	public void testZeroPadOrTruncate() {
-		assertEquals("1234", StringTools.zeroPadOrTruncate("1234", 4));
-		assertEquals("001234", StringTools.zeroPadOrTruncate("1234", 6));
-		assertEquals("34", StringTools.zeroPadOrTruncate("1234", 2));
-	}
-
-	public void testZeroPadOrTruncateCharArray() {
-		assertEquals("1234", StringTools.zeroPadOrTruncate(new char[] { '1', '2', '3', '4' }, 4));
-		assertEquals("001234", StringTools.zeroPadOrTruncate(new char[] { '1', '2', '3', '4' }, 6));
-		assertEquals("34", StringTools.zeroPadOrTruncate(new char[] { '1', '2', '3', '4' }, 2));
-	}
-
-	public void testZeroPadOrTruncateOnWriter() {
-		this.verifyZeroPadOrTruncateOnWriter("1234", "1234", 4);
-		this.verifyZeroPadOrTruncateOnWriter("001234", "1234", 6);
-		this.verifyZeroPadOrTruncateOnWriter("34", "1234", 2);
-	}
-
-	private void verifyZeroPadOrTruncateOnWriter(String expected, String string, int length) {
-		Writer writer = new StringWriter();
-		StringTools.zeroPadOrTruncateOn(string, length, writer);
-		assertEquals(expected, writer.toString());
-	}
-
-	public void testZeroPadOrTruncateOnStringBuffer() {
-		this.verifyZeroPadOrTruncateOnStringBuffer("1234", "1234", 4);
-		this.verifyZeroPadOrTruncateOnStringBuffer("001234", "1234", 6);
-		this.verifyZeroPadOrTruncateOnStringBuffer("34", "1234", 2);
-	}
-
-	private void verifyZeroPadOrTruncateOnStringBuffer(String expected, String string, int length) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.zeroPadOrTruncateOn(string, length, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testZeroPadOrTruncateOnStringBuilder() {
-		this.verifyZeroPadOrTruncateOnStringBuilder("1234", "1234", 4);
-		this.verifyZeroPadOrTruncateOnStringBuilder("001234", "1234", 6);
-		this.verifyZeroPadOrTruncateOnStringBuilder("34", "1234", 2);
-	}
-
-	private void verifyZeroPadOrTruncateOnStringBuilder(String expected, String string, int length) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.zeroPadOrTruncateOn(string, length, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	// ********** separating **********
-
-	public void testSeparateStringCharInt() {
-		this.verifySeparate("012345", '-', 22, "012345");
-		this.verifySeparate("012345", '-',  6, "012345");
-		this.verifySeparate("012345", '-',  5, "01234-5");
-		this.verifySeparate("012345", '-',  4, "0123-45");
-		this.verifySeparate("012345", '-',  3, "012-345");
-		this.verifySeparate("012345", '-',  2, "01-23-45");
-		this.verifySeparate("012345", '-',  1, "0-1-2-3-4-5");
-	}
-
-	private void verifySeparate(String string, char separator, int segmentLength, String expected) {
-		assertEquals(expected, StringTools.separate(string, separator, segmentLength));
-	}
-
-	public void testSeparateOnStringCharIntWriter() {
-		this.verifySeparateOnWriter("012345", '-', 22, "012345");
-		this.verifySeparateOnWriter("012345", '-',  6, "012345");
-		this.verifySeparateOnWriter("012345", '-',  5, "01234-5");
-		this.verifySeparateOnWriter("012345", '-',  4, "0123-45");
-		this.verifySeparateOnWriter("012345", '-',  3, "012-345");
-		this.verifySeparateOnWriter("012345", '-',  2, "01-23-45");
-		this.verifySeparateOnWriter("012345", '-',  1, "0-1-2-3-4-5");
-	}
-
-	private void verifySeparateOnWriter(String string, char separator, int segmentLength, String expected) {
-		Writer writer = new StringWriter();
-		StringTools.separateOn(string, separator, segmentLength, writer);
-		assertEquals(expected, writer.toString());
-	}
-
-	public void testSeparateOnStringCharIntStringBuffer() {
-		this.verifySeparateOnStringBuffer("012345", '-', 22, "012345");
-		this.verifySeparateOnStringBuffer("012345", '-',  6, "012345");
-		this.verifySeparateOnStringBuffer("012345", '-',  5, "01234-5");
-		this.verifySeparateOnStringBuffer("012345", '-',  4, "0123-45");
-		this.verifySeparateOnStringBuffer("012345", '-',  3, "012-345");
-		this.verifySeparateOnStringBuffer("012345", '-',  2, "01-23-45");
-		this.verifySeparateOnStringBuffer("012345", '-',  1, "0-1-2-3-4-5");
-	}
-
-	private void verifySeparateOnStringBuffer(String string, char separator, int segmentLength, String expected) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.separateOn(string, separator, segmentLength, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testSeparateOnStringCharIntStringBuilder() {
-		this.verifySeparateOnStringBuilder("012345", '-', 22, "012345");
-		this.verifySeparateOnStringBuilder("012345", '-',  6, "012345");
-		this.verifySeparateOnStringBuilder("012345", '-',  5, "01234-5");
-		this.verifySeparateOnStringBuilder("012345", '-',  4, "0123-45");
-		this.verifySeparateOnStringBuilder("012345", '-',  3, "012-345");
-		this.verifySeparateOnStringBuilder("012345", '-',  2, "01-23-45");
-		this.verifySeparateOnStringBuilder("012345", '-',  1, "0-1-2-3-4-5");
-	}
-
-	private void verifySeparateOnStringBuilder(String string, char separator, int segmentLength, String expected) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.separateOn(string, separator, segmentLength, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testSeparateCharArrayCharInt() {
-		this.verifySeparateCharArray("012345", '-', 22, "012345");
-		this.verifySeparateCharArray("012345", '-',  6, "012345");
-		this.verifySeparateCharArray("012345", '-',  5, "01234-5");
-		this.verifySeparateCharArray("012345", '-',  4, "0123-45");
-		this.verifySeparateCharArray("012345", '-',  3, "012-345");
-		this.verifySeparateCharArray("012345", '-',  2, "01-23-45");
-		this.verifySeparateCharArray("012345", '-',  1, "0-1-2-3-4-5");
-	}
-
-	private void verifySeparateCharArray(String string, char separator, int segmentLength, String expected) {
-		assertEquals(expected, StringTools.separate(string.toCharArray(), separator, segmentLength));
-	}
-
-	public void testSeparateOnCharArrayCharIntWriter() {
-		this.verifySeparateCharArrayOnWriter("012345", '-', 22, "012345");
-		this.verifySeparateCharArrayOnWriter("012345", '-',  6, "012345");
-		this.verifySeparateCharArrayOnWriter("012345", '-',  5, "01234-5");
-		this.verifySeparateCharArrayOnWriter("012345", '-',  4, "0123-45");
-		this.verifySeparateCharArrayOnWriter("012345", '-',  3, "012-345");
-		this.verifySeparateCharArrayOnWriter("012345", '-',  2, "01-23-45");
-		this.verifySeparateCharArrayOnWriter("012345", '-',  1, "0-1-2-3-4-5");
-	}
-
-	private void verifySeparateCharArrayOnWriter(String string, char separator, int segmentLength, String expected) {
-		Writer writer = new StringWriter();
-		StringTools.separateOn(string.toCharArray(), separator, segmentLength, writer);
-		assertEquals(expected, writer.toString());
-	}
-
-	public void testSeparateOnCharArrayCharIntStringBuffer() {
-		this.verifySeparateCharArrayOnStringBuffer("012345", '-', 22, "012345");
-		this.verifySeparateCharArrayOnStringBuffer("012345", '-',  6, "012345");
-		this.verifySeparateCharArrayOnStringBuffer("012345", '-',  5, "01234-5");
-		this.verifySeparateCharArrayOnStringBuffer("012345", '-',  4, "0123-45");
-		this.verifySeparateCharArrayOnStringBuffer("012345", '-',  3, "012-345");
-		this.verifySeparateCharArrayOnStringBuffer("012345", '-',  2, "01-23-45");
-		this.verifySeparateCharArrayOnStringBuffer("012345", '-',  1, "0-1-2-3-4-5");
-	}
-
-	private void verifySeparateCharArrayOnStringBuffer(String string, char separator, int segmentLength, String expected) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.separateOn(string.toCharArray(), separator, segmentLength, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testSeparateOnCharArrayCharIntStringBuilder() {
-		this.verifySeparateCharArrayOnStringBuilder("012345", '-', 22, "012345");
-		this.verifySeparateCharArrayOnStringBuilder("012345", '-',  6, "012345");
-		this.verifySeparateCharArrayOnStringBuilder("012345", '-',  5, "01234-5");
-		this.verifySeparateCharArrayOnStringBuilder("012345", '-',  4, "0123-45");
-		this.verifySeparateCharArrayOnStringBuilder("012345", '-',  3, "012-345");
-		this.verifySeparateCharArrayOnStringBuilder("012345", '-',  2, "01-23-45");
-		this.verifySeparateCharArrayOnStringBuilder("012345", '-',  1, "0-1-2-3-4-5");
-	}
-
-	private void verifySeparateCharArrayOnStringBuilder(String string, char separator, int segmentLength, String expected) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.separateOn(string.toCharArray(), separator, segmentLength, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	// ********** delimiting **********
-
-	public void testDelimit() {
-		this.verifyDelimit("Employee", "123", "123Employee123");
-		this.verifyDelimit("123", "123", "123123123");
-		this.verifyDelimit("", "123", "123123");
-	}
-
-	private void verifyDelimit(String string, String delimiter, String expectedString) {
-		assertEquals(expectedString, StringTools.delimit(string, delimiter));
-	}
-
-	public void testDelimitOnWriter() {
-		this.verifyDelimitOnWriter("Employee", "123", "123Employee123");
-		this.verifyDelimitOnWriter("123", "123", "123123123");
-		this.verifyDelimitOnWriter("", "123", "123123");
-	}
-
-	private void verifyDelimitOnWriter(String string, String delimiter, String expectedString) {
-		Writer writer = new StringWriter();
-		StringTools.delimitOn(string, delimiter, writer);
-		assertEquals(expectedString, writer.toString());
-	}
-
-	public void testDelimitOnStringBuffer() {
-		this.verifyDelimitOnStringBuffer("Employee", "123", "123Employee123");
-		this.verifyDelimitOnStringBuffer("123", "123", "123123123");
-		this.verifyDelimitOnStringBuffer("", "123", "123123");
-	}
-
-	private void verifyDelimitOnStringBuffer(String string, String delimiter, String expectedString) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.delimitOn(string, delimiter, sb);
-		assertEquals(expectedString, sb.toString());
-	}
-
-	public void testDelimitOnStringBuilder() {
-		this.verifyDelimitOnStringBuilder("Employee", "123", "123Employee123");
-		this.verifyDelimitOnStringBuilder("123", "123", "123123123");
-		this.verifyDelimitOnStringBuilder("", "123", "123123");
-	}
-
-	private void verifyDelimitOnStringBuilder(String string, String delimiter, String expectedString) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.delimitOn(string, delimiter, sb);
-		assertEquals(expectedString, sb.toString());
-	}
-
-	public void testQuote() {
-		this.verifyQuote("Employee", "\"Employee\"");
-		this.verifyQuote("123", "\"123\"");
-		this.verifyQuote("", "\"\"");
-		this.verifyQuote("Emp\"loyee", "\"Emp\"\"loyee\"");
-	}
-
-	private void verifyQuote(String string, String expectedString) {
-		assertEquals(expectedString, StringTools.quote(string));
-	}
-
-	public void testQuoteOnWriter() {
-		this.verifyQuoteOnWriter("Employee", "\"Employee\"");
-		this.verifyQuoteOnWriter("123", "\"123\"");
-		this.verifyQuoteOnWriter("", "\"\"");
-		this.verifyQuoteOnWriter("Emp\"loyee", "\"Emp\"\"loyee\"");
-	}
-
-	private void verifyQuoteOnWriter(String string, String expectedString) {
-		Writer writer = new StringWriter();
-		StringTools.quoteOn(string, writer);
-		assertEquals(expectedString, writer.toString());
-	}
-
-	public void testQuoteOnStringBuffer() {
-		this.verifyQuoteOnStringBuffer("Employee", "\"Employee\"");
-		this.verifyQuoteOnStringBuffer("123", "\"123\"");
-		this.verifyQuoteOnStringBuffer("", "\"\"");
-		this.verifyQuoteOnStringBuffer("Emp\"loyee", "\"Emp\"\"loyee\"");
-	}
-
-	private void verifyQuoteOnStringBuffer(String string, String expectedString) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.quoteOn(string, sb);
-		assertEquals(expectedString, sb.toString());
-	}
-
-	public void testQuoteOnStringBuilder() {
-		this.verifyQuoteOnStringBuilder("Employee", "\"Employee\"");
-		this.verifyQuoteOnStringBuilder("123", "\"123\"");
-		this.verifyQuoteOnStringBuilder("", "\"\"");
-		this.verifyQuoteOnStringBuilder("Emp\"loyee", "\"Emp\"\"loyee\"");
-	}
-
-	private void verifyQuoteOnStringBuilder(String string, String expectedString) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.quoteOn(string, sb);
-		assertEquals(expectedString, sb.toString());
-	}
-
-	// ********** removing characters **********
-
-	public void testRemoveFirstOccurrence() {
-		this.verifyRemoveFirstOccurrence("Emplo&yee", '&', "Employee");
-		this.verifyRemoveFirstOccurrence("Emplo&yee&", '&', "Employee&");
-		this.verifyRemoveFirstOccurrence("Employee &Foo", '&', "Employee Foo");
-		this.verifyRemoveFirstOccurrence("Employee&", '&', "Employee");
-		this.verifyRemoveFirstOccurrence("&Employee", '&', "Employee");
-	}
-
-	private void verifyRemoveFirstOccurrence(String string, char charToRemove, String expectedString) {
-		assertEquals(expectedString, StringTools.removeFirstOccurrence(string, charToRemove));
-	}
-
-	public void testRemoveFirstOccurrenceCharArray() {
-		this.verifyRemoveFirstOccurrenceCharArray("Emplo&yee", '&', "Employee");
-		this.verifyRemoveFirstOccurrenceCharArray("Emplo&yee&", '&', "Employee&");
-		this.verifyRemoveFirstOccurrenceCharArray("Employee &Foo", '&', "Employee Foo");
-		this.verifyRemoveFirstOccurrenceCharArray("Employee&", '&', "Employee");
-		this.verifyRemoveFirstOccurrenceCharArray("&Employee", '&', "Employee");
-	}
-
-	private void verifyRemoveFirstOccurrenceCharArray(String string, char charToRemove, String expectedString) {
-		assertEquals(expectedString, StringTools.removeFirstOccurrence(string.toCharArray(), charToRemove));
-	}
-
-	public void testRemoveFirstOccurrenceOnWriter() {
-		this.verifyRemoveFirstOccurrenceOnWriter("Emplo&yee", '&', "Employee");
-		this.verifyRemoveFirstOccurrenceOnWriter("Emplo&yee&", '&', "Employee&");
-		this.verifyRemoveFirstOccurrenceOnWriter("Employee &Foo", '&', "Employee Foo");
-		this.verifyRemoveFirstOccurrenceOnWriter("Employee&", '&', "Employee");
-		this.verifyRemoveFirstOccurrenceOnWriter("&Employee", '&', "Employee");
-	}
-
-	private void verifyRemoveFirstOccurrenceOnWriter(String string, char charToRemove, String expectedString) {
-		Writer writer = new StringWriter();
-		StringTools.removeFirstOccurrenceOn(string, charToRemove, writer);
-		assertEquals(expectedString, writer.toString());
-	}
-
-	public void testRemoveFirstOccurrenceOnStringBuffer() {
-		this.verifyRemoveFirstOccurrenceOnStringBuffer("Emplo&yee", '&', "Employee");
-		this.verifyRemoveFirstOccurrenceOnStringBuffer("Emplo&yee&", '&', "Employee&");
-		this.verifyRemoveFirstOccurrenceOnStringBuffer("Employee &Foo", '&', "Employee Foo");
-		this.verifyRemoveFirstOccurrenceOnStringBuffer("Employee&", '&', "Employee");
-		this.verifyRemoveFirstOccurrenceOnStringBuffer("&Employee", '&', "Employee");
-	}
-
-	private void verifyRemoveFirstOccurrenceOnStringBuffer(String string, char charToRemove, String expectedString) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.removeFirstOccurrenceOn(string, charToRemove, sb);
-		assertEquals(expectedString, sb.toString());
-	}
-
-	public void testRemoveFirstOccurrenceOnStringBuilder() {
-		this.verifyRemoveFirstOccurrenceOnStringBuilder("Emplo&yee", '&', "Employee");
-		this.verifyRemoveFirstOccurrenceOnStringBuilder("Emplo&yee&", '&', "Employee&");
-		this.verifyRemoveFirstOccurrenceOnStringBuilder("Employee &Foo", '&', "Employee Foo");
-		this.verifyRemoveFirstOccurrenceOnStringBuilder("Employee&", '&', "Employee");
-		this.verifyRemoveFirstOccurrenceOnStringBuilder("&Employee", '&', "Employee");
-	}
-
-	private void verifyRemoveFirstOccurrenceOnStringBuilder(String string, char charToRemove, String expectedString) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.removeFirstOccurrenceOn(string, charToRemove, sb);
-		assertEquals(expectedString, sb.toString());
-	}
-
-	public void testRemoveAllOccurrences() {
-		this.verifyRemoveAllOccurrences("Employee Fred", ' ', "EmployeeFred");
-		this.verifyRemoveAllOccurrences(" Employee ", ' ', "Employee");
-		this.verifyRemoveAllOccurrences("Employee   Foo", ' ', "EmployeeFoo");
-		this.verifyRemoveAllOccurrences(" Emp loyee   Foo", ' ', "EmployeeFoo");
-	}
-
-	private void verifyRemoveAllOccurrences(String string, char charToRemove, String expectedString) {
-		assertEquals(expectedString, StringTools.removeAllOccurrences(string, charToRemove));
-	}
-
-	public void testRemoveAllOccurrencesCharArray() {
-		this.verifyRemoveAllOccurrencesCharArray("Employee Fred", ' ', "EmployeeFred");
-		this.verifyRemoveAllOccurrencesCharArray(" Employee ", ' ', "Employee");
-		this.verifyRemoveAllOccurrencesCharArray("Employee   Foo", ' ', "EmployeeFoo");
-		this.verifyRemoveAllOccurrencesCharArray(" Emp loyee   Foo", ' ', "EmployeeFoo");
-	}
-
-	private void verifyRemoveAllOccurrencesCharArray(String string, char charToRemove, String expectedString) {
-		assertEquals(expectedString, StringTools.removeAllOccurrences(string.toCharArray(), charToRemove));
-	}
-
-	public void testRemoveAllOccurrencesOnWriter() {
-		this.verifyRemoveAllOccurrencesOnWriter("Employee Fred", ' ', "EmployeeFred");
-		this.verifyRemoveAllOccurrencesOnWriter(" Employee ", ' ', "Employee");
-		this.verifyRemoveAllOccurrencesOnWriter("Employee   Foo", ' ', "EmployeeFoo");
-		this.verifyRemoveAllOccurrencesOnWriter(" Emp loyee   Foo", ' ', "EmployeeFoo");
-	}
-
-	private void verifyRemoveAllOccurrencesOnWriter(String string, char charToRemove, String expectedString) {
-		Writer writer = new StringWriter();
-		StringTools.removeAllOccurrencesOn(string, charToRemove, writer);
-		assertEquals(expectedString, writer.toString());
-	}
-
-	public void testRemoveAllOccurrencesOnStringBuffer() {
-		this.verifyRemoveAllOccurrencesOnStringBuffer("Employee Fred", ' ', "EmployeeFred");
-		this.verifyRemoveAllOccurrencesOnStringBuffer(" Employee ", ' ', "Employee");
-		this.verifyRemoveAllOccurrencesOnStringBuffer("Employee   Foo", ' ', "EmployeeFoo");
-		this.verifyRemoveAllOccurrencesOnStringBuffer(" Emp loyee   Foo", ' ', "EmployeeFoo");
-	}
-
-	private void verifyRemoveAllOccurrencesOnStringBuffer(String string, char charToRemove, String expectedString) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.removeAllOccurrencesOn(string, charToRemove, sb);
-		assertEquals(expectedString, sb.toString());
-	}
-
-	public void testRemoveAllOccurrencesOnStringBuilder() {
-		this.verifyRemoveAllOccurrencesOnStringBuilder("Employee Fred", ' ', "EmployeeFred");
-		this.verifyRemoveAllOccurrencesOnStringBuilder(" Employee ", ' ', "Employee");
-		this.verifyRemoveAllOccurrencesOnStringBuilder("Employee   Foo", ' ', "EmployeeFoo");
-		this.verifyRemoveAllOccurrencesOnStringBuilder(" Emp loyee   Foo", ' ', "EmployeeFoo");
-	}
-
-	private void verifyRemoveAllOccurrencesOnStringBuilder(String string, char charToRemove, String expectedString) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.removeAllOccurrencesOn(string, charToRemove, sb);
-		assertEquals(expectedString, sb.toString());
-	}
-
-	public void testRemoveAllWhitespace() {
-		this.verifyRemoveAllWhitespace("Employee Fred\t", "EmployeeFred");
-		this.verifyRemoveAllWhitespace("\tEmployee\n", "Employee");
-		this.verifyRemoveAllWhitespace("Employee \t Foo", "EmployeeFoo");
-		this.verifyRemoveAllWhitespace(" Emp\tloyee \n Foo", "EmployeeFoo");
-	}
-
-	private void verifyRemoveAllWhitespace(String string, String expectedString) {
-		assertEquals(expectedString, StringTools.removeAllWhitespace(string));
-	}
-
-	public void testRemoveAllWhitespaceCharArray() {
-		this.verifyRemoveAllWhitespaceCharArray("Employee Fred\t", "EmployeeFred");
-		this.verifyRemoveAllWhitespaceCharArray("\tEmployee\n", "Employee");
-		this.verifyRemoveAllWhitespaceCharArray("Employee \t Foo", "EmployeeFoo");
-		this.verifyRemoveAllWhitespaceCharArray(" Emp\tloyee \n Foo", "EmployeeFoo");
-	}
-
-	private void verifyRemoveAllWhitespaceCharArray(String string, String expectedString) {
-		assertEquals(expectedString, StringTools.removeAllWhitespace(string.toCharArray()));
-	}
-
-	public void testRemoveAllWhitespaceOnWriter() {
-		this.verifyRemoveAllWhitespaceOnWriter("Employee Fred\t", "EmployeeFred");
-		this.verifyRemoveAllWhitespaceOnWriter("\tEmployee\n", "Employee");
-		this.verifyRemoveAllWhitespaceOnWriter("Employee \t Foo", "EmployeeFoo");
-		this.verifyRemoveAllWhitespaceOnWriter(" Emp\tloyee \n Foo", "EmployeeFoo");
-	}
-
-	private void verifyRemoveAllWhitespaceOnWriter(String string, String expectedString) {
-		Writer writer = new StringWriter();
-		StringTools.removeAllWhitespaceOn(string, writer);
-		assertEquals(expectedString, writer.toString());
-	}
-
-	public void testRemoveAllWhitespaceOnStringBuffer() {
-		this.verifyRemoveAllWhitespaceOnStringBuffer("Employee Fred\t", "EmployeeFred");
-		this.verifyRemoveAllWhitespaceOnStringBuffer("\tEmployee\n", "Employee");
-		this.verifyRemoveAllWhitespaceOnStringBuffer("Employee \t Foo", "EmployeeFoo");
-		this.verifyRemoveAllWhitespaceOnStringBuffer(" Emp\tloyee \n Foo", "EmployeeFoo");
-	}
-
-	private void verifyRemoveAllWhitespaceOnStringBuffer(String string, String expectedString) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.removeAllWhitespaceOn(string, sb);
-		assertEquals(expectedString, sb.toString());
-	}
-
-	public void testRemoveAllWhitespaceOnStringBuilder() {
-		this.verifyRemoveAllWhitespaceOnStringBuilder("Employee Fred\t", "EmployeeFred");
-		this.verifyRemoveAllWhitespaceOnStringBuilder("\tEmployee\n", "Employee");
-		this.verifyRemoveAllWhitespaceOnStringBuilder("Employee \t Foo", "EmployeeFoo");
-		this.verifyRemoveAllWhitespaceOnStringBuilder(" Emp\tloyee \n Foo", "EmployeeFoo");
-	}
-
-	private void verifyRemoveAllWhitespaceOnStringBuilder(String string, String expectedString) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.removeAllWhitespaceOn(string, sb);
-		assertEquals(expectedString, sb.toString());
-	}
-//////////////////////////////
-	public void testCompressWhitespace() {
-		this.verifyCompressWhitespace("Employee      Fred\t", "Employee Fred ");
-		this.verifyCompressWhitespace("\tEmployee  \n", " Employee ");
-		this.verifyCompressWhitespace("Employee \t Foo", "Employee Foo");
-		this.verifyCompressWhitespace(" Emp\tloyee \n Foo ", " Emp loyee Foo ");
-	}
-
-	private void verifyCompressWhitespace(String string, String expectedString) {
-		assertEquals(expectedString, StringTools.compressWhitespace(string));
-	}
-
-	public void testCompressWhitespaceCharArray() {
-		this.verifyCompressWhitespaceCharArray("Employee      Fred\t", "Employee Fred ");
-		this.verifyCompressWhitespaceCharArray("\tEmployee  \n", " Employee ");
-		this.verifyCompressWhitespaceCharArray("Employee \t Foo", "Employee Foo");
-		this.verifyCompressWhitespaceCharArray(" Emp\tloyee \n Foo ", " Emp loyee Foo ");
-	}
-
-	private void verifyCompressWhitespaceCharArray(String string, String expectedString) {
-		assertEquals(expectedString, StringTools.compressWhitespace(string.toCharArray()));
-	}
-
-	public void testCompressWhitespaceOnWriter() {
-		this.verifyCompressWhitespaceOnWriter("Employee      Fred\t", "Employee Fred ");
-		this.verifyCompressWhitespaceOnWriter("\tEmployee  \n", " Employee ");
-		this.verifyCompressWhitespaceOnWriter("Employee \t Foo", "Employee Foo");
-		this.verifyCompressWhitespaceOnWriter(" Emp\tloyee \n Foo ", " Emp loyee Foo ");
-	}
-
-	private void verifyCompressWhitespaceOnWriter(String string, String expectedString) {
-		Writer writer = new StringWriter();
-		StringTools.compressWhitespaceOn(string, writer);
-		assertEquals(expectedString, writer.toString());
-	}
-
-	public void testCompressWhitespaceOnStringBuffer() {
-		this.verifyCompressWhitespaceOnStringBuffer("Employee      Fred\t", "Employee Fred ");
-		this.verifyCompressWhitespaceOnStringBuffer("\tEmployee  \n", " Employee ");
-		this.verifyCompressWhitespaceOnStringBuffer("Employee \t Foo", "Employee Foo");
-		this.verifyCompressWhitespaceOnStringBuffer(" Emp\tloyee \n Foo ", " Emp loyee Foo ");
-	}
-
-	private void verifyCompressWhitespaceOnStringBuffer(String string, String expectedString) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.compressWhitespaceOn(string, sb);
-		assertEquals(expectedString, sb.toString());
-	}
-
-	public void testCompressWhitespaceOnStringBuilder() {
-		this.verifyCompressWhitespaceOnStringBuilder("Employee      Fred\t", "Employee Fred ");
-		this.verifyCompressWhitespaceOnStringBuilder("\tEmployee  \n", " Employee ");
-		this.verifyCompressWhitespaceOnStringBuilder("Employee \t Foo", "Employee Foo");
-		this.verifyCompressWhitespaceOnStringBuilder(" Emp\tloyee \n Foo ", " Emp loyee Foo ");
-	}
-
-	private void verifyCompressWhitespaceOnStringBuilder(String string, String expectedString) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.compressWhitespaceOn(string, sb);
-		assertEquals(expectedString, sb.toString());
-	}
-
-	// ********** common prefix **********
-
-	public void testCommonPrefixLength() {
-		assertEquals(3, StringTools.commonPrefixLength("fooZZZ", "fooBBB"));
-		assertEquals(3, StringTools.commonPrefixLength("foo", "fooBBB"));
-		assertEquals(3, StringTools.commonPrefixLength("fooZZZ", "foo"));
-		assertEquals(3, StringTools.commonPrefixLength("foo", "foo"));
-	}
-
-	public void testCommonPrefixLengthMax() {
-		assertEquals(2, StringTools.commonPrefixLength("fooZZZ", "fooBBB", 2));
-		assertEquals(2, StringTools.commonPrefixLength("foo", "fooBBB", 2));
-		assertEquals(2, StringTools.commonPrefixLength("fooZZZ", "foo", 2));
-		assertEquals(2, StringTools.commonPrefixLength("foo", "foo", 2));
-	}
-
-	// ********** capitalization **********
-
-	public void testCapitalizeCharArray() {
-		this.verifyCapitalizeCharArray("Oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyCapitalizeCharArray("Oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyCapitalizeCharArray("   ", new char[] { ' ', ' ', ' ' });
-		this.verifyCapitalizeCharArray("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
-		this.verifyCapitalizeCharArray("", new char[0]);
-		this.verifyCapitalizeCharArray("A", new char[] { 'a' });
-		this.verifyCapitalizeCharArray("\u00C9cole", new char[] { '\u00E9', 'c', 'o', 'l', 'e' });
-	}
-
-	private void verifyCapitalizeCharArray(String expected, char[] string) {
-		assertEquals(expected, StringTools.capitalize(string));
-	}
-
-	public void testCapitalizeString() {
-		this.verifyCapitalizeString("Oracle", "Oracle");
-		this.verifyCapitalizeString("Oracle", "oracle");
-		this.verifyCapitalizeString("   ", "   ");
-		this.verifyCapitalizeString("ORACLE", "ORACLE");
-		this.verifyCapitalizeString("", "");
-		this.verifyCapitalizeString("A", "a");
-		this.verifyCapitalizeString("\u00C9cole", "\u00E9cole"); // �cole->�COLE
-	}
-
-	private void verifyCapitalizeString(String expected, String string) {
-		assertEquals(expected, StringTools.capitalize(string));
-	}
-
-	public void testCapitalizeOnCharArrayStringBuffer() {
-		this.verifyCapitalizeOnCharArrayStringBuffer("Oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyCapitalizeOnCharArrayStringBuffer("Oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyCapitalizeOnCharArrayStringBuffer("   ", new char[] { ' ', ' ', ' ' });
-		this.verifyCapitalizeOnCharArrayStringBuffer("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
-		this.verifyCapitalizeOnCharArrayStringBuffer("", new char[0]);
-		this.verifyCapitalizeOnCharArrayStringBuffer("A", new char[] { 'a' });
-		this.verifyCapitalizeOnCharArrayStringBuffer("\u00C9cole", new char[] { '\u00E9', 'c', 'o', 'l', 'e' });
-	}
-
-	private void verifyCapitalizeOnCharArrayStringBuffer(String expected, char[] string) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.capitalizeOn(string, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testCapitalizeOnCharArrayStringBuilder() {
-		this.verifyCapitalizeOnCharArrayStringBuilder("Oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyCapitalizeOnCharArrayStringBuilder("Oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyCapitalizeOnCharArrayStringBuilder("   ", new char[] { ' ', ' ', ' ' });
-		this.verifyCapitalizeOnCharArrayStringBuilder("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
-		this.verifyCapitalizeOnCharArrayStringBuilder("", new char[0]);
-		this.verifyCapitalizeOnCharArrayStringBuilder("A", new char[] { 'a' });
-		this.verifyCapitalizeOnCharArrayStringBuilder("\u00C9cole", new char[] { '\u00E9', 'c', 'o', 'l', 'e' });
-	}
-
-	private void verifyCapitalizeOnCharArrayStringBuilder(String expected, char[] string) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.capitalizeOn(string, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testCapitalizeOnStringStringBuffer() {
-		this.verifyCapitalizeOnStringStringBuffer("Oracle", "Oracle");
-		this.verifyCapitalizeOnStringStringBuffer("Oracle", "oracle");
-		this.verifyCapitalizeOnStringStringBuffer("   ", "   ");
-		this.verifyCapitalizeOnStringStringBuffer("ORACLE", "ORACLE");
-		this.verifyCapitalizeOnStringStringBuffer("", "");
-		this.verifyCapitalizeOnStringStringBuffer("A", "a");
-		this.verifyCapitalizeOnStringStringBuffer("\u00C9cole", "\u00E9cole"); // �cole->�COLE
-	}
-
-	private void verifyCapitalizeOnStringStringBuffer(String expected, String string) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.capitalizeOn(string, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testCapitalizeOnStringStringBuilder() {
-		this.verifyCapitalizeOnStringStringBuilder("Oracle", "Oracle");
-		this.verifyCapitalizeOnStringStringBuilder("Oracle", "oracle");
-		this.verifyCapitalizeOnStringStringBuilder("   ", "   ");
-		this.verifyCapitalizeOnStringStringBuilder("ORACLE", "ORACLE");
-		this.verifyCapitalizeOnStringStringBuilder("", "");
-		this.verifyCapitalizeOnStringStringBuilder("A", "a");
-		this.verifyCapitalizeOnStringStringBuilder("\u00C9cole", "\u00E9cole"); // �cole->�COLE
-	}
-
-	private void verifyCapitalizeOnStringStringBuilder(String expected, String string) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.capitalizeOn(string, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testCapitalizeOnCharArrayWriter() {
-		this.verifyCapitalizeOnCharArrayWriter("Oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyCapitalizeOnCharArrayWriter("Oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyCapitalizeOnCharArrayWriter("   ", new char[] { ' ', ' ', ' ' });
-		this.verifyCapitalizeOnCharArrayWriter("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
-		this.verifyCapitalizeOnCharArrayWriter("", new char[0]);
-		this.verifyCapitalizeOnCharArrayWriter("A", new char[] { 'a' });
-		this.verifyCapitalizeOnCharArrayWriter("\u00C9cole", new char[] { '\u00E9', 'c', 'o', 'l', 'e' });
-	}
-
-	private void verifyCapitalizeOnCharArrayWriter(String expected, char[] string) {
-		Writer writer = new StringWriter();
-		StringTools.capitalizeOn(string, writer);
-		assertEquals(expected, writer.toString());
-	}
-
-	public void testCapitalizeOnStringWriter() {
-		this.verifyCapitalizeOnStringWriter("Oracle", "Oracle");
-		this.verifyCapitalizeOnStringWriter("Oracle", "oracle");
-		this.verifyCapitalizeOnStringWriter("   ", "   ");
-		this.verifyCapitalizeOnStringWriter("ORACLE", "ORACLE");
-		this.verifyCapitalizeOnStringWriter("", "");
-		this.verifyCapitalizeOnStringWriter("A", "a");
-		this.verifyCapitalizeOnStringWriter("\u00C9cole", "\u00E9cole"); // �cole->�COLE
-	}
-
-	private void verifyCapitalizeOnStringWriter(String expected, String string) {
-		Writer writer = new StringWriter();
-		StringTools.capitalizeOn(string, writer);
-		assertEquals(expected, writer.toString());
-	}
-
-	public void testUnapitalizeCharArray() {
-		this.verifyUncapitalizeCharArray("oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyUncapitalizeCharArray("oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyUncapitalizeCharArray("   ", new char[] { ' ', ' ', ' ' });
-		this.verifyUncapitalizeCharArray("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
-		this.verifyUncapitalizeCharArray("", new char[0]);
-		this.verifyUncapitalizeCharArray("a", new char[] { 'A' });
-		this.verifyUncapitalizeCharArray("\u00E9cole", new char[] { '\u00C9', 'c', 'o', 'l', 'e' });
-	}
-
-	private void verifyUncapitalizeCharArray(String expected, char[] string) {
-		assertEquals(expected, StringTools.uncapitalize(string));
-	}
-
-	public void testUncapitalizeString() {
-		this.verifyUncapitalizeString("oracle", "Oracle");
-		this.verifyUncapitalizeString("oracle", "oracle");
-		this.verifyUncapitalizeString("   ", "   ");
-		this.verifyUncapitalizeString("ORACLE", "ORACLE");
-		this.verifyUncapitalizeString("", "");
-		this.verifyUncapitalizeString("a", "A");
-		this.verifyUncapitalizeString("\u00E9cole", "\u00C9cole"); // �cole->�COLE
-	}
-
-	private void verifyUncapitalizeString(String expected, String string) {
-		assertEquals(expected, StringTools.uncapitalize(string));
-	}
-
-	public void testUncapitalizeOnCharArrayStringBuffer() {
-		this.verifyUncapitalizeOnCharArrayStringBuffer("oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyUncapitalizeOnCharArrayStringBuffer("oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyUncapitalizeOnCharArrayStringBuffer("   ", new char[] { ' ', ' ', ' ' });
-		this.verifyUncapitalizeOnCharArrayStringBuffer("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
-		this.verifyUncapitalizeOnCharArrayStringBuffer("", new char[0]);
-		this.verifyUncapitalizeOnCharArrayStringBuffer("a", new char[] { 'A' });
-		this.verifyUncapitalizeOnCharArrayStringBuffer("\u00E9cole", new char[] { '\u00C9', 'c', 'o', 'l', 'e' });
-	}
-
-	private void verifyUncapitalizeOnCharArrayStringBuffer(String expected, char[] string) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.uncapitalizeOn(string, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testUncapitalizeOnCharArrayStringBuilder() {
-		this.verifyUncapitalizeOnCharArrayStringBuilder("oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyUncapitalizeOnCharArrayStringBuilder("oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyUncapitalizeOnCharArrayStringBuilder("   ", new char[] { ' ', ' ', ' ' });
-		this.verifyUncapitalizeOnCharArrayStringBuilder("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
-		this.verifyUncapitalizeOnCharArrayStringBuilder("", new char[0]);
-		this.verifyUncapitalizeOnCharArrayStringBuilder("a", new char[] { 'A' });
-		this.verifyUncapitalizeOnCharArrayStringBuilder("\u00E9cole", new char[] { '\u00C9', 'c', 'o', 'l', 'e' });
-	}
-
-	private void verifyUncapitalizeOnCharArrayStringBuilder(String expected, char[] string) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.uncapitalizeOn(string, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testUncapitalizeOnStringStringBuffer() {
-		this.verifyUncapitalizeOnStringStringBuffer("oracle", "Oracle");
-		this.verifyUncapitalizeOnStringStringBuffer("oracle", "oracle");
-		this.verifyUncapitalizeOnStringStringBuffer("   ", "   ");
-		this.verifyUncapitalizeOnStringStringBuffer("ORACLE", "ORACLE");
-		this.verifyUncapitalizeOnStringStringBuffer("", "");
-		this.verifyUncapitalizeOnStringStringBuffer("a", "A");
-		this.verifyUncapitalizeOnStringStringBuffer("\u00E9cole", "\u00C9cole"); // �cole->�COLE
-	}
-
-	private void verifyUncapitalizeOnStringStringBuffer(String expected, String string) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.uncapitalizeOn(string, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testUncapitalizeOnStringStringBuilder() {
-		this.verifyUncapitalizeOnStringStringBuilder("oracle", "Oracle");
-		this.verifyUncapitalizeOnStringStringBuilder("oracle", "oracle");
-		this.verifyUncapitalizeOnStringStringBuilder("   ", "   ");
-		this.verifyUncapitalizeOnStringStringBuilder("ORACLE", "ORACLE");
-		this.verifyUncapitalizeOnStringStringBuilder("", "");
-		this.verifyUncapitalizeOnStringStringBuilder("a", "A");
-		this.verifyUncapitalizeOnStringStringBuilder("\u00E9cole", "\u00C9cole"); // �cole->�COLE
-	}
-
-	private void verifyUncapitalizeOnStringStringBuilder(String expected, String string) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.uncapitalizeOn(string, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testUncapitalizeOnCharArrayWriter() {
-		this.verifyUncapitalizeOnCharArrayWriter("oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyUncapitalizeOnCharArrayWriter("oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
-		this.verifyUncapitalizeOnCharArrayWriter("   ", new char[] { ' ', ' ', ' ' });
-		this.verifyUncapitalizeOnCharArrayWriter("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
-		this.verifyUncapitalizeOnCharArrayWriter("", new char[0]);
-		this.verifyUncapitalizeOnCharArrayWriter("a", new char[] { 'A' });
-		this.verifyUncapitalizeOnCharArrayWriter("\u00E9cole", new char[] { '\u00C9', 'c', 'o', 'l', 'e' });
-	}
-
-	private void verifyUncapitalizeOnCharArrayWriter(String expected, char[] string) {
-		Writer writer = new StringWriter();
-		StringTools.uncapitalizeOn(string, writer);
-		assertEquals(expected, writer.toString());
-	}
-
-	public void testUncapitalizeOnStringWriter() {
-		this.verifyUncapitalizeOnStringWriter("oracle", "Oracle");
-		this.verifyUncapitalizeOnStringWriter("oracle", "oracle");
-		this.verifyUncapitalizeOnStringWriter("   ", "   ");
-		this.verifyUncapitalizeOnStringWriter("ORACLE", "ORACLE");
-		this.verifyUncapitalizeOnStringWriter("", "");
-		this.verifyUncapitalizeOnStringWriter("a", "A");
-		this.verifyUncapitalizeOnStringWriter("\u00E9cole", "\u00C9cole"); // �cole->�COLE
-	}
-
-	private void verifyUncapitalizeOnStringWriter(String expected, String string) {
-		Writer writer = new StringWriter();
-		StringTools.uncapitalizeOn(string, writer);
-		assertEquals(expected, writer.toString());
-	}
-
-	// ********** #toString() **********
-
-	public void testBuildToStringClassName_anonymous() {
-		Object o = new Object(){/*anonymous subclass of Object*/};
-		assertEquals("Object", StringTools.buildToStringClassName(o.getClass()));
-	}
-
-	public void testBuildToStringClassName_member() {
-		assertEquals("Map.Entry", StringTools.buildToStringClassName(java.util.Map.Entry.class));
-	}
-
-	public void testBuildToStringClassName_local() {
-		class Foo {
-			Bar bar = new Bar();
-			class Bar {
-				Bar() {
-					super();
-				}
-			}
-			Foo() {
-				super();
-			}
-		}
-		Foo foo = new Foo();
-		assertEquals("StringToolsTests.Foo", StringTools.buildToStringClassName(foo.getClass()));
-		assertEquals("StringToolsTests.Foo.Bar", StringTools.buildToStringClassName(foo.bar.getClass()));
-	}
-
-	// ********** queries **********
-
-	public void testStringIsEmptyString() {
-		assertTrue(StringTools.stringIsEmpty((String) null));
-		assertTrue(StringTools.stringIsEmpty(""));
-		assertTrue(StringTools.stringIsEmpty("      "));
-		assertTrue(StringTools.stringIsEmpty("      \t\t   "));
-		assertTrue(StringTools.stringIsEmpty("      \t\t   " + StringTools.CR));
-	}
-
-	public void testStringIsEmptyCharArray() {
-		assertTrue(StringTools.stringIsEmpty((char[]) null));
-		this.verifyStringIsEmptyCharArray("");
-		this.verifyStringIsEmptyCharArray("      \t\t   ");
-		this.verifyStringIsEmptyCharArray("      ");
-		this.verifyStringIsEmptyCharArray("      \t\t   " + StringTools.CR);
-	}
-
-	private void verifyStringIsEmptyCharArray(String string) {
-		assertTrue(StringTools.stringIsEmpty(string.toCharArray()));
-	}
-
-	public void testStringsAreEqualStringString() {
-		assertTrue(StringTools.stringsAreEqual((String) null, (String) null));
-		assertFalse(StringTools.stringsAreEqual(null, "asdf"));
-		assertFalse(StringTools.stringsAreEqual("asdf", null));
-		assertTrue(StringTools.stringsAreEqual("asdf", "asdf"));
-		assertFalse(StringTools.stringsAreEqual("asdf", "ASDF"));
-	}
-
-	public void testStringsAreEqualCharArrayCharArray() {
-		assertTrue(StringTools.stringsAreEqual((char[]) null, (char[]) null));
-		assertFalse(StringTools.stringsAreEqual((char[]) null, "asdf".toCharArray()));
-		assertFalse(StringTools.stringsAreEqual("asdf".toCharArray(), (char[]) null));
-		assertTrue(StringTools.stringsAreEqual("asdf".toCharArray(), "asdf".toCharArray()));
-		assertFalse(StringTools.stringsAreEqual("asdf".toCharArray(), "ASDF".toCharArray()));
-	}
-
-	public void testStringsAreEqualIgnoreCaseStringString() {
-		assertTrue(StringTools.stringsAreEqualIgnoreCase((String) null, (String) null));
-		assertFalse(StringTools.stringsAreEqualIgnoreCase(null, "asdf"));
-		assertFalse(StringTools.stringsAreEqualIgnoreCase("asdf", null));
-		assertTrue(StringTools.stringsAreEqualIgnoreCase("asdf", "asdf"));
-		assertTrue(StringTools.stringsAreEqualIgnoreCase("asdf", "ASDF"));
-	}
-
-	public void testStringsAreEqualIgnoreCaseCharArrayCharArray() {
-		assertTrue(StringTools.stringsAreEqualIgnoreCase((char[]) null, (char[]) null));
-		assertFalse(StringTools.stringsAreEqualIgnoreCase((char[]) null, "asdf".toCharArray()));
-		assertFalse(StringTools.stringsAreEqualIgnoreCase("asdf".toCharArray(), (char[]) null));
-		assertTrue(StringTools.stringsAreEqualIgnoreCase("asdf".toCharArray(), "asdf".toCharArray()));
-		assertTrue(StringTools.stringsAreEqualIgnoreCase("asdf".toCharArray(), "ASDF".toCharArray()));
-	}
-
-	public void testStringStartsWithIgnoreCaseStringString() {
-		assertTrue(StringTools.stringStartsWithIgnoreCase("asdf", "as"));
-		assertTrue(StringTools.stringStartsWithIgnoreCase("asdf", "aS"));
-		assertTrue(StringTools.stringStartsWithIgnoreCase("asdf", ""));
-		assertTrue(StringTools.stringStartsWithIgnoreCase("asdf", "A"));
-
-		assertFalse(StringTools.stringStartsWithIgnoreCase("asdf", "bsdf"));
-		assertFalse(StringTools.stringStartsWithIgnoreCase("asdf", "g"));
-		assertFalse(StringTools.stringStartsWithIgnoreCase("asdf", "asdg"));
-		assertFalse(StringTools.stringStartsWithIgnoreCase("asdf", "asdfg"));
-		assertFalse(StringTools.stringStartsWithIgnoreCase("asdf", "asdfgggggg"));
-	}
-
-	public void testStringStartsWithIgnoreCaseCharArrayCharArray() {
-		assertTrue(StringTools.stringStartsWithIgnoreCase("asdf".toCharArray(), "as".toCharArray()));
-		assertTrue(StringTools.stringStartsWithIgnoreCase("asdf".toCharArray(), "aS".toCharArray()));
-		assertTrue(StringTools.stringStartsWithIgnoreCase("asdf".toCharArray(), "".toCharArray()));
-		assertTrue(StringTools.stringStartsWithIgnoreCase("asdf".toCharArray(), "A".toCharArray()));
-		assertTrue(StringTools.stringStartsWithIgnoreCase("asdf".toCharArray(), "ASDF".toCharArray()));
-		assertTrue(StringTools.stringStartsWithIgnoreCase("asdf".toCharArray(), "asdf".toCharArray()));
-
-		assertFalse(StringTools.stringStartsWithIgnoreCase("asdf".toCharArray(), "bsdf".toCharArray()));
-		assertFalse(StringTools.stringStartsWithIgnoreCase("asdf".toCharArray(), "g".toCharArray()));
-		assertFalse(StringTools.stringStartsWithIgnoreCase("asdf".toCharArray(), "asdg".toCharArray()));
-		assertFalse(StringTools.stringStartsWithIgnoreCase("asdf".toCharArray(), "asdfg".toCharArray()));
-		assertFalse(StringTools.stringStartsWithIgnoreCase("asdf".toCharArray(), "asdfgggggg".toCharArray()));
-	}
-
-	public void testCharactersAreEqualIgnoreCase() {
-		assertTrue(StringTools.charactersAreEqualIgnoreCase('a', 'a'));
-		assertTrue(StringTools.charactersAreEqualIgnoreCase('a', 'A'));
-		assertTrue(StringTools.charactersAreEqualIgnoreCase('A', 'a'));
-		assertTrue(StringTools.charactersAreEqualIgnoreCase('A', 'A'));
-
-		assertFalse(StringTools.charactersAreEqualIgnoreCase('a', 'b'));
-		assertFalse(StringTools.charactersAreEqualIgnoreCase('A', 'b'));
-	}
-
-	public void testStringIsUppercase() {
-		this.verifyStringIsUppercase("FOO");
-		this.verifyStringIsUppercase("FOO2");
-		this.verifyStringIsUppercase("F O O");
-		this.denyStringIsUppercase("Foo");
-		this.denyStringIsUppercase("");
-	}
-
-	private void verifyStringIsUppercase(String s) {
-		assertTrue(StringTools.stringIsUppercase(s));
-		assertTrue(StringTools.stringIsUppercase(s.toCharArray()));
-	}
-
-	private void denyStringIsUppercase(String s) {
-		assertFalse(StringTools.stringIsUppercase(s));
-		assertFalse(StringTools.stringIsUppercase(s.toCharArray()));
-	}
-
-	public void testStringIsLowercase() {
-		this.verifyStringIsLowercase("foo");
-		this.verifyStringIsLowercase("foo2");
-		this.verifyStringIsLowercase("f o o");
-		this.denyStringIsLowercase("Foo");
-		this.denyStringIsLowercase("");
-	}
-
-	private void verifyStringIsLowercase(String s) {
-		assertTrue(StringTools.stringIsLowercase(s));
-		assertTrue(StringTools.stringIsLowercase(s.toCharArray()));
-	}
-
-	private void denyStringIsLowercase(String s) {
-		assertFalse(StringTools.stringIsLowercase(s));
-		assertFalse(StringTools.stringIsLowercase(s.toCharArray()));
-	}
-
-	// ********** convert camel-case to all-caps **********
-
-	public void testConvertCamelCaseToAllCaps() {
-		assertEquals("TEST", StringTools.convertCamelCaseToAllCaps("test"));
-		assertEquals("TEST", StringTools.convertCamelCaseToAllCaps("TEST"));
-		assertEquals("TEST_TEST", StringTools.convertCamelCaseToAllCaps("testTest"));
-		assertEquals("TEST_TEST", StringTools.convertCamelCaseToAllCaps("TestTest"));
-		assertEquals("TEST_TEST_TEST", StringTools.convertCamelCaseToAllCaps("testTESTTest"));
-		assertEquals("TEST_TEST_TEST", StringTools.convertCamelCaseToAllCaps("TestTESTTest"));
-		assertEquals("TEST_TEST_TEST_T", StringTools.convertCamelCaseToAllCaps("TestTESTTestT"));
-	}
-
-	public void testConvertCamelCaseToAllCapsOnWriter() {
-		this.verifyConvertCamelCaseToAllCapsOnWriter("TEST", "test");
-		this.verifyConvertCamelCaseToAllCapsOnWriter("TEST", "TEST");
-		this.verifyConvertCamelCaseToAllCapsOnWriter("TEST_TEST", "testTest");
-		this.verifyConvertCamelCaseToAllCapsOnWriter("TEST_TEST", "TestTest");
-		this.verifyConvertCamelCaseToAllCapsOnWriter("TEST_TEST_TEST", "testTESTTest");
-		this.verifyConvertCamelCaseToAllCapsOnWriter("TEST_TEST_TEST", "TestTESTTest");
-		this.verifyConvertCamelCaseToAllCapsOnWriter("TEST_TEST_TEST_T", "TestTESTTestT");
-	}
-
-	private void verifyConvertCamelCaseToAllCapsOnWriter(String expected, String string) {
-		Writer writer = new StringWriter();
-		StringTools.convertCamelCaseToAllCapsOn(string, writer);
-		assertEquals(expected, writer.toString());
-	}
-
-	public void testConvertCamelCaseToAllCapsOnStringBuffer() {
-		this.verifyConvertCamelCaseToAllCapsOnStringBuffer("TEST", "test");
-		this.verifyConvertCamelCaseToAllCapsOnStringBuffer("TEST", "TEST");
-		this.verifyConvertCamelCaseToAllCapsOnStringBuffer("TEST_TEST", "testTest");
-		this.verifyConvertCamelCaseToAllCapsOnStringBuffer("TEST_TEST", "TestTest");
-		this.verifyConvertCamelCaseToAllCapsOnStringBuffer("TEST_TEST_TEST", "testTESTTest");
-		this.verifyConvertCamelCaseToAllCapsOnStringBuffer("TEST_TEST_TEST", "TestTESTTest");
-		this.verifyConvertCamelCaseToAllCapsOnStringBuffer("TEST_TEST_TEST_T", "TestTESTTestT");
-	}
-
-	private void verifyConvertCamelCaseToAllCapsOnStringBuffer(String expected, String string) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.convertCamelCaseToAllCapsOn(string, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testConvertCamelCaseToAllCapsOnStringBuilder() {
-		this.verifyConvertCamelCaseToAllCapsOnStringBuilder("TEST", "test");
-		this.verifyConvertCamelCaseToAllCapsOnStringBuilder("TEST", "TEST");
-		this.verifyConvertCamelCaseToAllCapsOnStringBuilder("TEST_TEST", "testTest");
-		this.verifyConvertCamelCaseToAllCapsOnStringBuilder("TEST_TEST", "TestTest");
-		this.verifyConvertCamelCaseToAllCapsOnStringBuilder("TEST_TEST_TEST", "testTESTTest");
-		this.verifyConvertCamelCaseToAllCapsOnStringBuilder("TEST_TEST_TEST", "TestTESTTest");
-		this.verifyConvertCamelCaseToAllCapsOnStringBuilder("TEST_TEST_TEST_T", "TestTESTTestT");
-	}
-
-	private void verifyConvertCamelCaseToAllCapsOnStringBuilder(String expected, String string) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.convertCamelCaseToAllCapsOn(string, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testConvertCamelCaseToAllCapsMaxLength() {
-		assertEquals("TEST", StringTools.convertCamelCaseToAllCaps("test", 44));
-		assertEquals("TEST", StringTools.convertCamelCaseToAllCaps("test", 4));
-		assertEquals("TES", StringTools.convertCamelCaseToAllCaps("test", 3));
-		assertEquals("TEST", StringTools.convertCamelCaseToAllCaps("TEST", 5));
-		assertEquals("TE", StringTools.convertCamelCaseToAllCaps("TEST", 2));
-		assertEquals("TEST_TEST", StringTools.convertCamelCaseToAllCaps("testTest", 9));
-		assertEquals("TEST_TES", StringTools.convertCamelCaseToAllCaps("testTest", 8));
-		assertEquals("TEST_T", StringTools.convertCamelCaseToAllCaps("testTest", 6));
-		assertEquals("TEST_", StringTools.convertCamelCaseToAllCaps("testTest", 5));
-		assertEquals("TEST", StringTools.convertCamelCaseToAllCaps("testTest", 4));
-		assertEquals("TEST_TEST", StringTools.convertCamelCaseToAllCaps("TestTest", 9));
-		assertEquals("TEST_TEST", StringTools.convertCamelCaseToAllCaps("TestTest", 1100));
-		assertEquals("TEST_TEST_", StringTools.convertCamelCaseToAllCaps("testTESTTest", 10));
-		assertEquals("TEST_TEST_TEST", StringTools.convertCamelCaseToAllCaps("TestTESTTest", 14));
-		assertEquals("TEST_TEST_TEST_T", StringTools.convertCamelCaseToAllCaps("TestTESTTestT", 16));
-		assertEquals("TEST_TEST_TEST_", StringTools.convertCamelCaseToAllCaps("TestTESTTestT", 15));
-	}
-
-	public void testConvertCamelCaseToAllCapsMaxLengthOnWriter() {
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TEST", "test", 44);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TEST", "test", 4);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TES", "test", 3);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TEST", "TEST", 5);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TE", "TEST", 2);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TEST_TEST", "testTest", 9);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TEST_TES", "testTest", 8);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TEST_T", "testTest", 6);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TEST_", "testTest", 5);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TEST", "testTest", 4);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TEST_TEST", "TestTest", 9);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TEST_TEST", "TestTest", 1100);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TEST_TEST_", "testTESTTest", 10);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TEST_TEST_TEST", "TestTESTTest", 14);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TEST_TEST_TEST_T", "TestTESTTestT", 16);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnWriter("TEST_TEST_TEST_", "TestTESTTestT", 15);
-	}
-
-	private void verifyConvertCamelCaseToAllCapsMaxLengthOnWriter(String expected, String string, int max) {
-		Writer writer = new StringWriter();
-		StringTools.convertCamelCaseToAllCapsOn(string, max, writer);
-		assertEquals(expected, writer.toString());
-	}
-
-	public void testConvertCamelCaseToAllCapsMaxLengthOnStringBuffer() {
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TEST", "test", 44);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TEST", "test", 4);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TES", "test", 3);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TEST", "TEST", 5);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TE", "TEST", 2);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TEST_TEST", "testTest", 9);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TEST_TES", "testTest", 8);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TEST_T", "testTest", 6);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TEST_", "testTest", 5);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TEST", "testTest", 4);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TEST_TEST", "TestTest", 9);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TEST_TEST", "TestTest", 1100);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TEST_TEST_", "testTESTTest", 10);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TEST_TEST_TEST", "TestTESTTest", 14);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TEST_TEST_TEST_T", "TestTESTTestT", 16);
-		this.verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer("TEST_TEST_TEST_", "TestTESTTestT", 15);
-	}
-
-	private void verifyConvertCamelCaseToAllCapsMaxLengthOnStringBuffer(String expected, String string, int max) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.convertCamelCaseToAllCapsOn(string, max, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	// ********** convert underscores to all-caps **********
-
-	public void testConvertUnderscoresToCamelCase() {
-		assertEquals("test", StringTools.convertUnderscoresToCamelCase("TEST", false));
-		assertEquals("test", StringTools.convertUnderscoresToCamelCase("TEST_", false));
-		assertEquals("test", StringTools.convertUnderscoresToCamelCase("TEST____", false));
-		assertEquals("Test", StringTools.convertUnderscoresToCamelCase("TEST", true));
-		assertEquals("test", StringTools.convertUnderscoresToCamelCase("TeST", false));
-		assertEquals("testTest", StringTools.convertUnderscoresToCamelCase("TEST_TEST", false));
-		assertEquals("testTest", StringTools.convertUnderscoresToCamelCase("TEST___TEST", false));
-		assertEquals("TestTest", StringTools.convertUnderscoresToCamelCase("TEST_TEST", true));
-		assertEquals("testTestTest", StringTools.convertUnderscoresToCamelCase("TEST_TEST_TEST", false));
-		assertEquals("TestTestTest", StringTools.convertUnderscoresToCamelCase("TEST_TEST_TEST", true));
-		assertEquals("testTestTestT", StringTools.convertUnderscoresToCamelCase("TEST_TEST_TEST_T", false));
-		assertEquals("testTestTestT", StringTools.convertUnderscoresToCamelCase("_TEST_TEST_TEST_T", false));
-		assertEquals("testTestTestT", StringTools.convertUnderscoresToCamelCase("__TEST_TEST_TEST_T", false));
-		assertEquals("TestTestTestT", StringTools.convertUnderscoresToCamelCase("TEST_TEST_TEST_T", true));
-		assertEquals("TestTestTestT", StringTools.convertUnderscoresToCamelCase("_TEST_TEST_TEST_T", true));
-		assertEquals("TestTestTestT", StringTools.convertUnderscoresToCamelCase("__TEST_TEST_TEST_T", true));
-	}
-
-	public void testConvertUnderscoresToCamelCaseLowercase() {
-		assertEquals("test", StringTools.convertUnderscoresToCamelCase("test", false));
-		assertEquals("test", StringTools.convertUnderscoresToCamelCase("test_", false));
-		assertEquals("test", StringTools.convertUnderscoresToCamelCase("test____", false));
-		assertEquals("Test", StringTools.convertUnderscoresToCamelCase("test", true));
-		assertEquals("test", StringTools.convertUnderscoresToCamelCase("test", false));
-		assertEquals("testTest", StringTools.convertUnderscoresToCamelCase("test_test", false));
-		assertEquals("testTest", StringTools.convertUnderscoresToCamelCase("test___test", false));
-		assertEquals("TestTest", StringTools.convertUnderscoresToCamelCase("test_test", true));
-		assertEquals("testTestTest", StringTools.convertUnderscoresToCamelCase("test_test_test", false));
-		assertEquals("TestTestTest", StringTools.convertUnderscoresToCamelCase("test_test_test", true));
-		assertEquals("testTestTestT", StringTools.convertUnderscoresToCamelCase("test_test_test_t", false));
-		assertEquals("testTestTestT", StringTools.convertUnderscoresToCamelCase("_test_test_test_t", false));
-		assertEquals("testTestTestT", StringTools.convertUnderscoresToCamelCase("__test_test_test_t", false));
-		assertEquals("TestTestTestT", StringTools.convertUnderscoresToCamelCase("test_test_test_t", true));
-		assertEquals("TestTestTestT", StringTools.convertUnderscoresToCamelCase("_test_test_test_t", true));
-		assertEquals("TestTestTestT", StringTools.convertUnderscoresToCamelCase("__test_test_test_t", true));
-	}
-
-	public void testConvertUnderscoresToCamelCaseOnWriter() {
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("test", "TEST", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("test", "TEST_", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("test", "TEST____", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("Test", "TEST", true);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("test", "TeST", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("testTest", "TEST_TEST", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("testTest", "TEST___TEST", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("TestTest", "TEST_TEST", true);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("testTestTest", "TEST_TEST_TEST", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("TestTestTest", "TEST_TEST_TEST", true);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("testTestTestT", "TEST_TEST_TEST_T", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("testTestTestT", "_TEST_TEST_TEST_T", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("testTestTestT", "__TEST_TEST_TEST_T", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("TestTestTestT", "TEST_TEST_TEST_T", true);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("TestTestTestT", "_TEST_TEST_TEST_T", true);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("TestTestTestT", "__TEST_TEST_TEST_T", true);
-	}
-
-	public void testConvertUnderscoresToCamelCaseOnWriterLowercase() {
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("test", "test", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("test", "test_", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("test", "test____", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("Test", "test", true);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("test", "test", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("testTest", "test_test", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("testTest", "test___test", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("TestTest", "test_test", true);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("testTestTest", "test_test_test", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("TestTestTest", "test_test_test", true);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("testTestTestT", "test_test_test_t", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("testTestTestT", "_test_test_test_t", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("testTestTestT", "__test_test_test_t", false);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("TestTestTestT", "test_test_test_t", true);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("TestTestTestT", "_test_test_test_t", true);
-		this.verifyConvertUnderscoresToCamelCaseOnWriter("TestTestTestT", "__test_test_test_t", true);
-	}
-
-	private void verifyConvertUnderscoresToCamelCaseOnWriter(String expected, String string, boolean capitalizeFirstLetter) {
-		Writer writer = new StringWriter();
-		StringTools.convertUnderscoresToCamelCaseOn(string, capitalizeFirstLetter, writer);
-		assertEquals(expected, writer.toString());
-	}
-
-	public void testConvertUnderscoresToCamelCaseOnStringBuffer() {
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("test", "TEST", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("test", "TEST_", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("test", "TEST____", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("Test", "TEST", true);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("test", "TeST", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("testTest", "TEST_TEST", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("testTest", "TEST___TEST", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("TestTest", "TEST_TEST", true);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("testTestTest", "TEST_TEST_TEST", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("TestTestTest", "TEST_TEST_TEST", true);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("testTestTestT", "TEST_TEST_TEST_T", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("testTestTestT", "_TEST_TEST_TEST_T", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("testTestTestT", "__TEST_TEST_TEST_T", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("TestTestTestT", "TEST_TEST_TEST_T", true);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("TestTestTestT", "_TEST_TEST_TEST_T", true);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("TestTestTestT", "__TEST_TEST_TEST_T", true);
-	}
-
-	public void testConvertUnderscoresToCamelCaseOnStringBufferLowercase() {
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("test", "test", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("test", "test_", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("test", "test____", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("Test", "test", true);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("test", "test", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("testTest", "test_test", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("testTest", "test___test", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("TestTest", "test_test", true);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("testTestTest", "test_test_test", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("TestTestTest", "test_test_test", true);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("testTestTestT", "test_test_test_t", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("testTestTestT", "_test_test_test_t", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("testTestTestT", "__test_test_test_t", false);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("TestTestTestT", "test_test_test_t", true);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("TestTestTestT", "_test_test_test_t", true);
-		this.verifyConvertUnderscoresToCamelCaseOnStringBuffer("TestTestTestT", "__test_test_test_t", true);
-	}
-
-	private void verifyConvertUnderscoresToCamelCaseOnStringBuffer(String expected, String string, boolean capitalizeFirstLetter) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.convertUnderscoresToCamelCaseOn(string, capitalizeFirstLetter, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	// ********** delimiting **********
-
-	public void testStringIsQuoted() {
-		this.denyStringIsQuoted("foo");
-		this.verifyStringIsQuoted("\"foo\"");
-
-		this.denyStringIsQuoted("");
-		this.verifyStringIsQuoted("\"\"");
-
-		this.denyStringIsQuoted("\"");
-		this.denyStringIsQuoted(" ");
-		this.denyStringIsQuoted("''");
-		this.denyStringIsQuoted("'foo'");
-	}
-
-	private void verifyStringIsQuoted(String s) {
-		assertTrue(StringTools.stringIsQuoted(s));
-		assertTrue(StringTools.stringIsQuoted(s.toCharArray()));
-	}
-
-	private void denyStringIsQuoted(String s) {
-		assertFalse(StringTools.stringIsQuoted(s));
-		assertFalse(StringTools.stringIsQuoted(s.toCharArray()));
-	}
-
-	public void testStringIsParenthetical() {
-		this.denyStringIsParenthetical("foo");
-		this.verifyStringIsParenthetical("(foo)");
-
-		this.denyStringIsParenthetical("");
-		this.verifyStringIsParenthetical("()");
-
-		this.denyStringIsParenthetical("(");
-		this.denyStringIsParenthetical(" ");
-		this.denyStringIsParenthetical("''");
-		this.denyStringIsParenthetical("'foo'");
-	}
-
-	private void verifyStringIsParenthetical(String s) {
-		assertTrue(StringTools.stringIsParenthetical(s));
-		assertTrue(StringTools.stringIsParenthetical(s.toCharArray()));
-	}
-
-	private void denyStringIsParenthetical(String s) {
-		assertFalse(StringTools.stringIsParenthetical(s));
-		assertFalse(StringTools.stringIsParenthetical(s.toCharArray()));
-	}
-
-	public void testStringIsBracketed() {
-		this.denyStringIsBracketed("foo");
-		this.verifyStringIsBracketed("[foo]");
-
-		this.denyStringIsBracketed("");
-		this.verifyStringIsBracketed("[]");
-
-		this.denyStringIsBracketed("[");
-		this.denyStringIsBracketed(" ");
-		this.denyStringIsBracketed("''");
-		this.denyStringIsBracketed("'foo'");
-	}
-
-	private void verifyStringIsBracketed(String s) {
-		assertTrue(StringTools.stringIsBracketed(s));
-		assertTrue(StringTools.stringIsBracketed(s.toCharArray()));
-	}
-
-	private void denyStringIsBracketed(String s) {
-		assertFalse(StringTools.stringIsBracketed(s));
-		assertFalse(StringTools.stringIsBracketed(s.toCharArray()));
-	}
-
-	public void testStringIsBraced() {
-		this.denyStringIsBraced("foo");
-		this.verifyStringIsBraced("{foo}");
-
-		this.denyStringIsBraced("");
-		this.verifyStringIsBraced("{}");
-
-		this.denyStringIsBraced("{");
-		this.denyStringIsBraced(" ");
-		this.denyStringIsBraced("''");
-		this.denyStringIsBraced("'foo'");
-	}
-
-	private void verifyStringIsBraced(String s) {
-		assertTrue(StringTools.stringIsBraced(s));
-		assertTrue(StringTools.stringIsBraced(s.toCharArray()));
-	}
-
-	private void denyStringIsBraced(String s) {
-		assertFalse(StringTools.stringIsBraced(s));
-		assertFalse(StringTools.stringIsBraced(s.toCharArray()));
-	}
-
-	public void testStringIsChevroned() {
-		this.denyStringIsChevroned("foo");
-		this.verifyStringIsChevroned("<foo>");
-
-		this.denyStringIsChevroned("");
-		this.verifyStringIsChevroned("<>");
-
-		this.denyStringIsChevroned("{");
-		this.denyStringIsChevroned(" ");
-		this.denyStringIsChevroned("''");
-		this.denyStringIsChevroned("'foo'");
-	}
-
-	private void verifyStringIsChevroned(String s) {
-		assertTrue(StringTools.stringIsChevroned(s));
-		assertTrue(StringTools.stringIsChevroned(s.toCharArray()));
-	}
-
-	private void denyStringIsChevroned(String s) {
-		assertFalse(StringTools.stringIsChevroned(s));
-		assertFalse(StringTools.stringIsChevroned(s.toCharArray()));
-	}
-
-	public void testStringIsDelimited() {
-		this.denyStringIsDelimited("foo", '?');
-		this.verifyStringIsDelimited("?foo?", '?');
-
-		this.denyStringIsDelimited("", '?');
-		this.verifyStringIsDelimited("\"\"", '"');
-		this.verifyStringIsDelimited("?xx?", '?');
-		this.denyStringIsDelimited("?xx]", '?');
-
-		this.denyStringIsDelimited("\"", '"');
-		this.denyStringIsDelimited(" ", ' ');
-		this.denyStringIsDelimited("''", '"');
-		this.denyStringIsDelimited("'foo'", '?');
-	}
-
-	private void verifyStringIsDelimited(String s, char c) {
-		assertTrue(StringTools.stringIsDelimited(s, c));
-		assertTrue(StringTools.stringIsDelimited(s.toCharArray(), c));
-	}
-
-	private void denyStringIsDelimited(String s, char c) {
-		assertFalse(StringTools.stringIsDelimited(s, c));
-		assertFalse(StringTools.stringIsDelimited(s.toCharArray(), c));
-	}
-
-	public void testStringIsDelimited2() {
-		this.denyStringIsDelimited2("foo", '[', ']');
-		this.verifyStringIsDelimited2("{foo}", '{', '}');
-
-		this.denyStringIsDelimited2("", '[', ']');
-		this.verifyStringIsDelimited2("[]", '[', ']');
-		this.verifyStringIsDelimited2("[xx]", '[', ']');
-		this.denyStringIsDelimited2("?xx]", '[', ']');
-
-		this.denyStringIsDelimited2("\"", '[', ']');
-		this.denyStringIsDelimited2(" ", '[', ']');
-		this.denyStringIsDelimited2("''", '[', ']');
-		this.denyStringIsDelimited2("'foo'", '[', ']');
-	}
-
-	private void verifyStringIsDelimited2(String s, char start, char end) {
-		assertTrue(StringTools.stringIsDelimited(s, start, end));
-		assertTrue(StringTools.stringIsDelimited(s.toCharArray(), start, end));
-	}
-
-	private void denyStringIsDelimited2(String s, char start, char end) {
-		assertFalse(StringTools.stringIsDelimited(s, start, end));
-		assertFalse(StringTools.stringIsDelimited(s.toCharArray(), start, end));
-	}
-
-	// ********** undelimiting **********
-
-	public void testUndelimit() {
-		this.verifyUndelimit("\"foo\"", "foo");
-		this.verifyUndelimit("\"\"", "");
-		this.verifyUndelimit("'foo'", "foo");
-		this.verifyUndelimit("\"fo\"\"o\"", "fo\"o");
-		this.verifyUndelimit("\"foo\"\"\"", "foo\"");
-		this.verifyUndelimit("\"\"\"foo\"", "\"foo");
-		this.verifyUndelimit("[foo]", "foo");
-		this.verifyUndelimit("\"\"\"", "\"");
-		this.verifyUndelimit("\"foo\"bar\"", "foo\"");
-		this.verifyUndelimit("\"foo\"\"", "foo\"");
-	}
-
-	private void verifyUndelimit(String s, String expected) {
-		assertEquals(expected, StringTools.undelimit(s));
-		assertEquals(expected, StringTools.undelimit(s.toCharArray()));
-	}
-
-	public void testUndelimitInt() {
-		this.verifyUndelimitInt("\"foo\"", 2, "o");
-		this.verifyUndelimitInt("\"\"foo\"\"", 2, "foo");
-		this.verifyUndelimitInt("'foo'", 2, "o");
-	}
-
-	private void verifyUndelimitInt(String s, int count, String expected) {
-		assertEquals(expected, StringTools.undelimit(s, count));
-		assertEquals(expected, StringTools.undelimit(s.toCharArray(), count));
-	}
-
-	public void testUndelimitIntException() {
-		this.denyUndelimitInt("\"\"", 2);
-		this.denyUndelimitInt("'o'", 2);
-	}
-
-	private void denyUndelimitInt(String s, int count) {
-		boolean exCaught = false;
-		try {
-			String bogus = StringTools.undelimit(s, count);
-			fail("invalid string: " + bogus);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		exCaught = false;
-		try {
-			char[] bogus = StringTools.undelimit(s.toCharArray(), count);
-			fail("invalid string: " + new String(bogus));
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testUndelimitOnWriter() {
-		this.verifyUndelimitOnWriter("\"foo\"", "foo");
-		this.verifyUndelimitOnWriter("\"\"", "");
-		this.verifyUndelimitOnWriter("'foo'", "foo");
-		this.verifyUndelimitOnWriter("\"fo\"\"o\"", "fo\"o");
-		this.verifyUndelimitOnWriter("\"foo\"\"\"", "foo\"");
-		this.verifyUndelimitOnWriter("\"\"\"foo\"", "\"foo");
-		this.verifyUndelimitOnWriter("[foo]", "foo");
-		this.verifyUndelimitOnWriter("\"\"\"", "\"");
-		this.verifyUndelimitOnWriter("\"foo\"bar\"", "foo\"");
-		this.verifyUndelimitOnWriter("\"foo\"\"", "foo\"");
-	}
-
-	private void verifyUndelimitOnWriter(String s, String expected) {
-		Writer writer = new StringWriter();
-		StringTools.undelimitOn(s, writer);
-		assertEquals(expected, writer.toString());
-
-		writer = new StringWriter();
-		StringTools.undelimitOn(s.toCharArray(), writer);
-		assertEquals(expected, writer.toString());
-	}
-
-	public void testUndelimitOnStringBuffer() {
-		this.verifyUndelimitOnStringBuffer("\"foo\"", "foo");
-		this.verifyUndelimitOnStringBuffer("\"\"", "");
-		this.verifyUndelimitOnStringBuffer("'foo'", "foo");
-		this.verifyUndelimitOnStringBuffer("\"fo\"\"o\"", "fo\"o");
-		this.verifyUndelimitOnStringBuffer("\"foo\"\"\"", "foo\"");
-		this.verifyUndelimitOnStringBuffer("\"\"\"foo\"", "\"foo");
-		this.verifyUndelimitOnStringBuffer("[foo]", "foo");
-		this.verifyUndelimitOnStringBuffer("\"\"\"", "\"");
-		this.verifyUndelimitOnStringBuffer("\"foo\"bar\"", "foo\"");
-		this.verifyUndelimitOnStringBuffer("\"foo\"\"", "foo\"");
-	}
-
-	private void verifyUndelimitOnStringBuffer(String s, String expected) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.undelimitOn(s, sb);
-		assertEquals(expected, sb.toString());
-
-		sb = new StringBuffer();
-		StringTools.undelimitOn(s.toCharArray(), sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testUndelimitOnStringBuilder() {
-		this.verifyUndelimitOnStringBuilder("\"foo\"", "foo");
-		this.verifyUndelimitOnStringBuilder("\"\"", "");
-		this.verifyUndelimitOnStringBuilder("'foo'", "foo");
-		this.verifyUndelimitOnStringBuilder("\"fo\"\"o\"", "fo\"o");
-		this.verifyUndelimitOnStringBuilder("\"foo\"\"\"", "foo\"");
-		this.verifyUndelimitOnStringBuilder("\"\"\"foo\"", "\"foo");
-		this.verifyUndelimitOnStringBuilder("[foo]", "foo");
-		this.verifyUndelimitOnStringBuilder("\"\"\"", "\"");
-		this.verifyUndelimitOnStringBuilder("\"foo\"bar\"", "foo\"");
-		this.verifyUndelimitOnStringBuilder("\"foo\"\"", "foo\"");
-	}
-
-	private void verifyUndelimitOnStringBuilder(String s, String expected) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.undelimitOn(s, sb);
-		assertEquals(expected, sb.toString());
-
-		sb = new StringBuilder();
-		StringTools.undelimitOn(s.toCharArray(), sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testUndelimitOnWriterCount() {
-		this.verifyUndelimitOnWriterCount("\"foo\"", 2, "o");
-		this.verifyUndelimitOnWriterCount("\"\"\"\"", 2, "");
-		this.verifyUndelimitOnWriterCount("XXfooXX", 2, "foo");
-	}
-
-	private void verifyUndelimitOnWriterCount(String s, int count, String expected) {
-		Writer writer = new StringWriter();
-		StringTools.undelimitOn(s, count, writer);
-		assertEquals(expected, writer.toString());
-
-		writer = new StringWriter();
-		StringTools.undelimitOn(s.toCharArray(), count, writer);
-		assertEquals(expected, writer.toString());
-	}
-
-	public void testUndelimitOnStringBufferCount() {
-		this.verifyUndelimitOnStringBufferCount("\"foo\"", 2, "o");
-		this.verifyUndelimitOnStringBufferCount("\"\"\"\"", 2, "");
-		this.verifyUndelimitOnStringBufferCount("XXfooXX", 2, "foo");
-	}
-
-	private void verifyUndelimitOnStringBufferCount(String s, int count, String expected) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.undelimitOn(s, count, sb);
-		assertEquals(expected, sb.toString());
-
-		sb = new StringBuffer();
-		StringTools.undelimitOn(s.toCharArray(), count, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testUndelimitOnStringBuilderCount() {
-		this.verifyUndelimitOnStringBuilderCount("\"foo\"", 2, "o");
-		this.verifyUndelimitOnStringBuilderCount("\"\"\"\"", 2, "");
-		this.verifyUndelimitOnStringBuilderCount("XXfooXX", 2, "foo");
-	}
-
-	private void verifyUndelimitOnStringBuilderCount(String s, int count, String expected) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.undelimitOn(s, count, sb);
-		assertEquals(expected, sb.toString());
-
-		sb = new StringBuilder();
-		StringTools.undelimitOn(s.toCharArray(), count, sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	// ********** converting to Java string literal **********
-
-	public void testConvertToJavaStringLiteral() {
-		this.verifyConvertToJavaStringLiteral("", "\"\"");
-		this.verifyConvertToJavaStringLiteral("\"\"", "\"\\\"\\\"\"");
-		this.verifyConvertToJavaStringLiteral("'foo'", "\"'foo'\"");
-		this.verifyConvertToJavaStringLiteral("foo\bbar", "\"foo\\bbar\"");
-		this.verifyConvertToJavaStringLiteral("foo\n\tbar", "\"foo\\n\\tbar\"");
-		this.verifyConvertToJavaStringLiteral("foo\"bar", "\"foo\\\"bar\"");
-		this.verifyConvertToJavaStringLiteral("foo\\bar", "\"foo\\\\bar\"");
-	}
-
-	private void verifyConvertToJavaStringLiteral(String s, String expected) {
-		assertEquals(expected, StringTools.convertToJavaStringLiteral(s));
-		assertEquals(expected, StringTools.convertToJavaStringLiteral(s.toCharArray()));
-	}
-
-	public void testConvertToJavaStringLiteralOnStringBuffer() {
-		this.verifyConvertToJavaStringLiteralOnStringBuffer("", "\"\"");
-		this.verifyConvertToJavaStringLiteralOnStringBuffer("\"\"", "\"\\\"\\\"\"");
-		this.verifyConvertToJavaStringLiteralOnStringBuffer("'foo'", "\"'foo'\"");
-		this.verifyConvertToJavaStringLiteralOnStringBuffer("foo\bbar", "\"foo\\bbar\"");
-		this.verifyConvertToJavaStringLiteralOnStringBuffer("foo\n\tbar", "\"foo\\n\\tbar\"");
-		this.verifyConvertToJavaStringLiteralOnStringBuffer("foo\"bar", "\"foo\\\"bar\"");
-		this.verifyConvertToJavaStringLiteralOnStringBuffer("foo\\bar", "\"foo\\\\bar\"");
-	}
-
-	private void verifyConvertToJavaStringLiteralOnStringBuffer(String s, String expected) {
-		StringBuffer sb = new StringBuffer();
-		StringTools.convertToJavaStringLiteralOn(s, sb);
-		assertEquals(expected, sb.toString());
-
-		sb = new StringBuffer();
-		StringTools.convertToJavaStringLiteralOn(s.toCharArray(), sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testConvertToJavaStringLiteralOnStringBuilder() {
-		this.verifyConvertToJavaStringLiteralOnStringBuilder("", "\"\"");
-		this.verifyConvertToJavaStringLiteralOnStringBuilder("\"\"", "\"\\\"\\\"\"");
-		this.verifyConvertToJavaStringLiteralOnStringBuilder("'foo'", "\"'foo'\"");
-		this.verifyConvertToJavaStringLiteralOnStringBuilder("foo\bbar", "\"foo\\bbar\"");
-		this.verifyConvertToJavaStringLiteralOnStringBuilder("foo\n\tbar", "\"foo\\n\\tbar\"");
-		this.verifyConvertToJavaStringLiteralOnStringBuilder("foo\"bar", "\"foo\\\"bar\"");
-		this.verifyConvertToJavaStringLiteralOnStringBuilder("foo\\bar", "\"foo\\\\bar\"");
-	}
-
-	private void verifyConvertToJavaStringLiteralOnStringBuilder(String s, String expected) {
-		StringBuilder sb = new StringBuilder();
-		StringTools.convertToJavaStringLiteralOn(s, sb);
-		assertEquals(expected, sb.toString());
-
-		sb = new StringBuilder();
-		StringTools.convertToJavaStringLiteralOn(s.toCharArray(), sb);
-		assertEquals(expected, sb.toString());
-	}
-
-	public void testConvertToJavaStringLiteralOnWriter() {
-		this.verifyConvertToJavaStringLiteralOnWriter("", "\"\"");
-		this.verifyConvertToJavaStringLiteralOnWriter("\"\"", "\"\\\"\\\"\"");
-		this.verifyConvertToJavaStringLiteralOnWriter("'foo'", "\"'foo'\"");
-		this.verifyConvertToJavaStringLiteralOnWriter("foo\bbar", "\"foo\\bbar\"");
-		this.verifyConvertToJavaStringLiteralOnWriter("foo\n\tbar", "\"foo\\n\\tbar\"");
-		this.verifyConvertToJavaStringLiteralOnWriter("foo\"bar", "\"foo\\\"bar\"");
-		this.verifyConvertToJavaStringLiteralOnWriter("foo\\bar", "\"foo\\\\bar\"");
-	}
-
-	private void verifyConvertToJavaStringLiteralOnWriter(String s, String expected) {
-		Writer writer = new StringWriter();
-		StringTools.convertToJavaStringLiteralOn(s, writer);
-		assertEquals(expected, writer.toString());
-
-		writer = new StringWriter();
-		StringTools.convertToJavaStringLiteralOn(s.toCharArray(), writer);
-		assertEquals(expected, writer.toString());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedBooleanTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedBooleanTests.java
deleted file mode 100644
index 684cda1..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedBooleanTests.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import org.eclipse.persistence.tools.utility.SynchronizedBoolean;
-
-
-public class SynchronizedBooleanTests
-	extends MultiThreadedTestCase
-{
-	private volatile SynchronizedBoolean sb;
-	volatile boolean timeoutOccurred;
-	volatile long startTime;
-	volatile long endTime;
-
-
-	public SynchronizedBooleanTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.sb = new SynchronizedBoolean();
-		this.timeoutOccurred = false;
-		this.startTime = 0;
-		this.endTime = 0;
-	}
-
-	public void testGetValue() throws Exception {
-		assertFalse(this.sb.getValue());
-	}
-
-	public void testIs() throws Exception {
-		assertTrue(this.sb.is(false));
-	}
-
-	public void testIsNot() throws Exception {
-		assertTrue(this.sb.isNot(true));
-	}
-
-	public void testIsTrue() throws Exception {
-		assertFalse(this.sb.isTrue());
-	}
-
-	public void testIsFalse() throws Exception {
-		assertTrue(this.sb.isFalse());
-	}
-
-	public void testSetValueFalse() throws Exception {
-		this.sb.setValue(false);
-		assertFalse(this.sb.getValue());
-		assertFalse(this.sb.isTrue());
-		assertTrue(this.sb.isFalse());
-	}
-
-	public void testSetValueTrue() throws Exception {
-		this.sb.setValue(true);
-		assertTrue(this.sb.getValue());
-		assertTrue(this.sb.isTrue());
-		assertFalse(this.sb.isFalse());
-	}
-
-	public void testFlip() throws Exception {
-		assertTrue(this.sb.flip());
-		assertFalse(this.sb.flip());
-	}
-
-	public void testFalseAndTrue() throws Exception {
-		assertFalse(this.sb.and(true));
-		assertFalse(this.sb.getValue());
-	}
-
-	public void testTrueAndTrue() throws Exception {
-		this.sb.setValue(true);
-		assertTrue(this.sb.and(true));
-		assertTrue(this.sb.getValue());
-	}
-
-	public void testFalseAndFalse() throws Exception {
-		assertFalse(this.sb.and(false));
-		assertFalse(this.sb.getValue());
-	}
-
-	public void testTrueAndFalse() throws Exception {
-		this.sb.setValue(true);
-		assertFalse(this.sb.and(false));
-		assertFalse(this.sb.getValue());
-	}
-
-	public void testFalseOrTrue() throws Exception {
-		assertTrue(this.sb.or(true));
-		assertTrue(this.sb.getValue());
-	}
-
-	public void testTrueOrTrue() throws Exception {
-		this.sb.setValue(true);
-		assertTrue(this.sb.or(true));
-		assertTrue(this.sb.getValue());
-	}
-
-	public void testFalseOrFalse() throws Exception {
-		assertFalse(this.sb.or(false));
-		assertFalse(this.sb.getValue());
-	}
-
-	public void testTrueOrFalse() throws Exception {
-		this.sb.setValue(true);
-		assertTrue(this.sb.or(false));
-		assertTrue(this.sb.getValue());
-	}
-
-	public void testFalseXorTrue() throws Exception {
-		assertTrue(this.sb.xor(true));
-		assertTrue(this.sb.getValue());
-	}
-
-	public void testTrueXorTrue() throws Exception {
-		this.sb.setValue(true);
-		assertFalse(this.sb.xor(true));
-		assertFalse(this.sb.getValue());
-	}
-
-	public void testFalseXorFalse() throws Exception {
-		assertFalse(this.sb.xor(false));
-		assertFalse(this.sb.getValue());
-	}
-
-	public void testTrueXorFalse() throws Exception {
-		this.sb.setValue(true);
-		assertTrue(this.sb.xor(false));
-		assertTrue(this.sb.getValue());
-	}
-
-	public void testSetNotTrue() throws Exception {
-		this.sb.setNot(true);
-		assertFalse(this.sb.getValue());
-		assertFalse(this.sb.isTrue());
-		assertTrue(this.sb.isFalse());
-	}
-
-	public void testSetNotFalse() throws Exception {
-		this.sb.setNot(false);
-		assertTrue(this.sb.getValue());
-		assertTrue(this.sb.isTrue());
-		assertFalse(this.sb.isFalse());
-	}
-
-	public void testSetFalse() throws Exception {
-		this.sb.setFalse();
-		assertFalse(this.sb.getValue());
-		assertFalse(this.sb.isTrue());
-		assertTrue(this.sb.isFalse());
-	}
-
-	public void testSetTrue() throws Exception {
-		this.sb.setTrue();
-		assertTrue(this.sb.getValue());
-		assertTrue(this.sb.isTrue());
-		assertFalse(this.sb.isFalse());
-	}
-
-	public void testCommitFalseSuccess() throws Exception {
-		assertTrue(this.sb.commit(false, false));
-		assertFalse(this.sb.getValue());
-	}
-
-	public void testCommitTrueSuccess() throws Exception {
-		assertTrue(this.sb.commit(false, true));
-		assertTrue(this.sb.getValue());
-	}
-
-	public void testCommitFalseFailure() throws Exception {
-		assertFalse(this.sb.commit(true, false));
-		assertFalse(this.sb.getValue());
-	}
-
-	public void testCommitTrueFailure() throws Exception {
-		assertFalse(this.sb.commit(true, true));
-		assertFalse(this.sb.getValue());
-	}
-
-	public void testSwapSame() throws Exception {
-		assertFalse(this.sb.swap(this.sb));
-		assertFalse(this.sb.getValue());
-	}
-
-	public void testSwapSameValue() throws Exception {
-		SynchronizedBoolean sb2 = new SynchronizedBoolean();
-		assertFalse(this.sb.swap(sb2));
-		assertFalse(this.sb.getValue());
-		assertFalse(sb2.getValue());
-	}
-
-	public void testSwapDifferentValue() throws Exception {
-		SynchronizedBoolean sb2 = new SynchronizedBoolean(true);
-		assertTrue(this.sb.swap(sb2));
-		assertTrue(this.sb.getValue());
-		assertFalse(sb2.getValue());
-	}
-
-	public void testGetMutexThis() throws Exception {
-		assertSame(this.sb, this.sb.getMutex());
-	}
-
-	public void testGetMutexObject() throws Exception {
-		Object mutex = new Object();
-		SynchronizedBoolean syncBool = new SynchronizedBoolean(mutex);
-		assertSame(mutex, syncBool.getMutex());
-	}
-
-	/**
-	 * t2 will wait indefinitely until t1 sets the value to true
-	 */
-	public void testWaitUntilTrue() throws Exception {
-		this.verifyWaitUntilTrue(0);  // 0 = indefinite wait
-		// no timeout occurs...
-		assertFalse(this.timeoutOccurred);
-		// ...and the value should be set to true by t2
-		assertTrue(this.sb.getValue());
-		// make a reasonable guess about how long t2 took
-		assertTrue(this.calculateElapsedTime() > TICK);
-	}
-
-	/**
-	 * t2 will time out waiting for t1 to set the value to true
-	 */
-	public void testWaitUntilTrueTimeout() throws Exception {
-		this.verifyWaitUntilTrue(TICK);
-		// timeout occurs...
-		assertTrue(this.timeoutOccurred);
-		// ...and the value will eventually be set to true by t1
-		assertTrue(this.sb.getValue());
-		// make a reasonable guess about how long t2 took
-		assertTrue(this.calculateElapsedTime() < THREE_TICKS);
-	}
-
-	private void verifyWaitUntilTrue(long t2Timeout) throws Exception {
-		this.executeThreads(this.buildSetTrueCommand(), this.buildWaitUntilTrueCommand(t2Timeout));
-	}
-
-	/**
-	 * t2 will wait indefinitely until t1 sets the value to false
-	 */
-	public void testWaitToSetFalse() throws Exception {
-		this.verifyWaitToSetFalse(0);  // 0 = indefinite wait
-		// no timeout occurs...
-		assertFalse(this.timeoutOccurred);
-		// ...and the value should be set to false by t2
-		assertFalse(this.sb.getValue());
-		// make a reasonable guess about how long t2 took
-		assertTrue(this.calculateElapsedTime() > TICK);
-	}
-
-	/**
-	 * t2 will time out waiting for t1 to set the value to false
-	 */
-	public void testWaitToSetFalseTimeout() throws Exception {
-		this.verifyWaitToSetFalse(TICK);
-		// timeout occurs...
-		assertTrue(this.timeoutOccurred);
-		// ...and the value will eventually be set to true by t1
-		assertTrue(this.sb.getValue());
-		// make a reasonable guess about how long t2 took
-		assertTrue(this.calculateElapsedTime() < THREE_TICKS);
-	}
-
-	private void verifyWaitToSetFalse(long t2Timeout) throws Exception {
-		this.executeThreads(this.buildSetTrueCommand(), this.buildWaitToSetFalseCommand(t2Timeout));
-	}
-
-	private void executeThreads(Command t1Command, Command t2Command) throws Exception {
-		this.sb.setFalse();
-		Runnable r1 = this.buildRunnable(t1Command, this.sb, TWO_TICKS);
-		Runnable r2 = this.buildRunnable(t2Command, this.sb, 0);
-		Thread t1 = this.buildThread(r1);
-		Thread t2 = this.buildThread(r2);
-		t1.start();
-		t2.start();
-		t1.join();
-		t2.join();
-	}
-
-	private Command buildSetTrueCommand() {
-		return new Command() {
-			public void execute(SynchronizedBoolean syncBool) {
-				syncBool.setTrue();
-			}
-		};
-	}
-
-	private Command buildWaitUntilTrueCommand(final long timeout) {
-		return new Command() {
-			public void execute(SynchronizedBoolean syncBool) throws InterruptedException {
-				SynchronizedBooleanTests.this.startTime = System.currentTimeMillis();
-				SynchronizedBooleanTests.this.timeoutOccurred = ! syncBool.waitUntilTrue(timeout);
-				SynchronizedBooleanTests.this.endTime = System.currentTimeMillis();
-			}
-		};
-	}
-
-	private Command buildWaitToSetFalseCommand(final long timeout) {
-		return new Command() {
-			public void execute(SynchronizedBoolean syncBool) throws InterruptedException {
-				SynchronizedBooleanTests.this.startTime = System.currentTimeMillis();
-				SynchronizedBooleanTests.this.timeoutOccurred =  ! syncBool.waitToSetFalse(timeout);
-				SynchronizedBooleanTests.this.endTime = System.currentTimeMillis();
-			}
-		};
-	}
-
-	private Runnable buildRunnable(final Command command, final SynchronizedBoolean syncBool, final long delay) {
-		return new TestRunnable() {
-			@Override
-			public void run_() throws InterruptedException {
-				if (delay != 0) {
-					Thread.sleep(delay);
-				}
-				command.execute(syncBool);
-			}
-		};
-	}
-
-	long calculateElapsedTime() {
-		return this.endTime - this.startTime;
-	}
-
-
-	// ********** Command interface **********
-
-	private interface Command {
-		void execute(SynchronizedBoolean syncBool) throws InterruptedException;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedIntTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedIntTests.java
deleted file mode 100644
index ddab6a0..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedIntTests.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import org.eclipse.persistence.tools.utility.SynchronizedInt;
-
-
-@SuppressWarnings("nls")
-public class SynchronizedIntTests
-	extends MultiThreadedTestCase
-{
-	private volatile SynchronizedInt si;
-	volatile boolean timeoutOccurred;
-	volatile int value = 7;
-	volatile long startTime;
-	volatile long endTime;
-	volatile int sIntValue;
-
-
-	public SynchronizedIntTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.si = new SynchronizedInt();
-		this.timeoutOccurred = false;
-		this.startTime = 0;
-		this.endTime = 0;
-		this.sIntValue = 0;
-	}
-
-	public void testGetValue() throws Exception {
-		assertEquals(0, this.si.getValue());
-	}
-
-	public void testEqualsInt() throws Exception {
-		assertTrue(this.si.equals(0));
-		this.si.setValue(this.value);
-		assertTrue(this.si.equals(7));
-	}
-
-	public void testNotEqualInt() throws Exception {
-		assertTrue(this.si.notEqual(7));
-		this.si.setValue(this.value);
-		assertTrue(this.si.notEqual(0));
-	}
-
-	public void testIsZero() throws Exception {
-		assertTrue(this.si.isZero());
-		this.si.setValue(this.value);
-		assertFalse(this.si.isZero());
-	}
-
-	public void testIsNotZero() throws Exception {
-		assertFalse(this.si.isNotZero());
-		this.si.setValue(this.value);
-		assertTrue(this.si.isNotZero());
-	}
-
-	public void testIsGreaterThan() throws Exception {
-		assertTrue(this.si.isGreaterThan(-1));
-		assertFalse(this.si.isGreaterThan(0));
-		assertFalse(this.si.isGreaterThan(1));
-		this.si.setValue(this.value);
-		assertTrue(this.si.isGreaterThan(-1));
-		assertFalse(this.si.isGreaterThan(7));
-		assertFalse(this.si.isGreaterThan(8));
-	}
-
-	public void testIsGreaterThanOrEqual() throws Exception {
-		assertTrue(this.si.isGreaterThanOrEqual(-1));
-		assertTrue(this.si.isGreaterThanOrEqual(0));
-		assertFalse(this.si.isGreaterThanOrEqual(1));
-		this.si.setValue(this.value);
-		assertTrue(this.si.isGreaterThanOrEqual(-1));
-		assertTrue(this.si.isGreaterThanOrEqual(7));
-		assertFalse(this.si.isGreaterThanOrEqual(8));
-	}
-
-	public void testIsLessThan() throws Exception {
-		assertFalse(this.si.isLessThan(-1));
-		assertFalse(this.si.isLessThan(0));
-		assertTrue(this.si.isLessThan(1));
-		this.si.setValue(this.value);
-		assertFalse(this.si.isLessThan(-1));
-		assertFalse(this.si.isLessThan(7));
-		assertTrue(this.si.isLessThan(8));
-	}
-
-	public void testIsLessThanOrEqual() throws Exception {
-		assertFalse(this.si.isLessThanOrEqual(-1));
-		assertTrue(this.si.isLessThanOrEqual(0));
-		assertTrue(this.si.isLessThanOrEqual(1));
-		this.si.setValue(this.value);
-		assertFalse(this.si.isLessThanOrEqual(-1));
-		assertTrue(this.si.isLessThanOrEqual(7));
-		assertTrue(this.si.isLessThanOrEqual(8));
-	}
-
-	public void testIsPositive() throws Exception {
-		assertFalse(this.si.isPositive());
-		this.si.setValue(this.value);
-		assertTrue(this.si.isPositive());
-		this.si.setValue(-3);
-		assertFalse(this.si.isPositive());
-	}
-
-	public void testIsNotPositive() throws Exception {
-		assertTrue(this.si.isNotPositive());
-		this.si.setValue(this.value);
-		assertFalse(this.si.isNotPositive());
-		this.si.setValue(-3);
-		assertTrue(this.si.isNotPositive());
-	}
-
-	public void testIsNegative() throws Exception {
-		assertFalse(this.si.isNegative());
-		this.si.setValue(this.value);
-		assertFalse(this.si.isNegative());
-		this.si.setValue(-3);
-		assertTrue(this.si.isNegative());
-	}
-
-	public void testIsNotNegative() throws Exception {
-		assertTrue(this.si.isNotNegative());
-		this.si.setValue(this.value);
-		assertTrue(this.si.isNotNegative());
-		this.si.setValue(-3);
-		assertFalse(this.si.isNotNegative());
-	}
-
-	public void testSetValue() throws Exception {
-		this.si.setValue(0);
-		assertEquals(0, this.si.getValue());
-		assertFalse(this.si.isNotZero());
-		assertTrue(this.si.isZero());
-
-		this.si.setValue(this.value);
-		assertEquals(this.value, this.si.getValue());
-		assertTrue(this.si.isNotZero());
-		assertFalse(this.si.isZero());
-	}
-
-	public void testAbs() throws Exception {
-		assertEquals(0, this.si.abs());
-		assertEquals(0, this.si.getValue());
-		this.si.setValue(this.value);
-		assertEquals(this.value, this.si.abs());
-		assertEquals(this.value, this.si.getValue());
-		this.si.setValue(-this.value);
-		assertEquals(this.value, this.si.abs());
-	}
-
-	public void testNeg() throws Exception {
-		assertEquals(0, this.si.neg());
-		assertEquals(0, this.si.getValue());
-		this.si.setValue(this.value);
-		assertEquals(-this.value, this.si.neg());
-		this.si.setValue(-this.value);
-		assertEquals(this.value, this.si.neg());
-	}
-
-	public void testSetZero() throws Exception {
-		this.si.setZero();
-		assertEquals(0, this.si.getValue());
-		assertFalse(this.si.isNotZero());
-		assertTrue(this.si.isZero());
-	}
-
-	public void testGetMutexThis() throws Exception {
-		assertSame(this.si, this.si.getMutex());
-	}
-
-	/**
-	 * t2 will wait indefinitely until t1 sets the value to 0
-	 */
-	public void testWaitUntilZero() throws Exception {
-		this.verifyWaitUntilZero(0);  // 0 = indefinite wait
-		// no timeout occurs...
-		assertFalse(this.timeoutOccurred);
-		// ...and the value should be set to 0 by t2
-		assertEquals(0, this.si.getValue());
-		// make a reasonable guess about how long t2 took
-		long time = this.calculateElapsedTime();
-		assertTrue("t2 finished a bit early (expected value should be > " + TICK + "): " + time, time > TICK);
-	}
-
-	/**
-	 * t2 will time out waiting for t1 to set the value to 0
-	 */
-	public void testWaitUntilZeroTimeout() throws Exception {
-		this.verifyWaitUntilZero(TICK);
-		// timeout occurs...
-		assertTrue(this.timeoutOccurred);
-		// ...and the value will eventually be set to 0 by t1
-		assertEquals(0, this.si.getValue());
-		// make a reasonable guess about how long t2 took
-		long time = this.calculateElapsedTime();
-		assertTrue("t2 finished a bit late (expected value should be < " + THREE_TICKS + "): " + time, time < THREE_TICKS);
-	}
-
-	private void verifyWaitUntilZero(long t2Timeout) throws Exception {
-		this.executeThreads(this.buildSetZeroCommand(), this.buildWaitUntilZeroCommand(t2Timeout));
-	}
-
-	/**
-	 * t2 will wait indefinitely until t1 sets the value to 0;
-	 * then t2 will set the value to 7
-	 */
-	public void testWaitToSetValue() throws Exception {
-		this.verifyWaitToSetValue(0);  // 0 = indefinite wait
-		// no timeout occurs...
-		assertFalse(this.timeoutOccurred);
-		// ...and the value should be set to an object by t2
-		assertTrue(this.si.isNotZero());
-		// make a reasonable guess about how long t2 took
-		long time = this.calculateElapsedTime();
-		assertTrue("t2 finished a bit early (expected value should be > " + TICK + "): " + time, time > TICK);
-	}
-
-	/**
-	 * t2 will time out waiting for t1 to set the value to 0
-	 */
-	public void testWaitToSetValueTimeout() throws Exception {
-		this.verifyWaitToSetValue(TICK);
-		// timeout occurs...
-		assertTrue(this.timeoutOccurred);
-		// ...and the value will eventually be set to zero by t1
-		assertTrue(this.si.isZero());
-		// make a reasonable guess about how long t2 took
-		long time = this.calculateElapsedTime();
-		assertTrue("t2 finished a bit late (expected value should be < " + THREE_TICKS + "): " + time, time < THREE_TICKS);
-	}
-
-	private void verifyWaitToSetValue(long t2Timeout) throws Exception {
-		this.executeThreads(this.buildSetZeroCommand(), this.buildWaitToSetValueCommand(t2Timeout));
-	}
-
-	/**
-	 * t2 will wait until t1 is finished "initializing" the value;
-	 * then t2 will get the newly-initialized value (42)
-	 */
-	public void testExecute() throws Exception {
-		this.si.setValue(0);
-		Runnable r1 = this.buildRunnable(this.buildInitializeValueCommand(), this.si, 0);
-		// give t1 a head start
-		Runnable r2 = this.buildRunnable(this.buildGetValueCommand(), this.si, TICK);
-		Thread t1 = this.buildThread(r1);
-		Thread t2 = this.buildThread(r2);
-		t1.start();
-		t2.start();
-		t1.join();
-		t2.join();
-		assertEquals(42, this.si.getValue());
-		assertEquals(42, this.sIntValue);
-		// make a reasonable guess about how long t2 took
-		long time = this.calculateElapsedTime();
-		assertTrue("t2 finished a bit early (expected value should be > " + TWO_TICKS + "): " + time, time > TWO_TICKS);
-	}
-
-	private void executeThreads(Command t1Command, Command t2Command) throws Exception {
-		this.si.setValue(this.value);
-		Runnable r1 = this.buildRunnable(t1Command, this.si, TWO_TICKS);
-		Runnable r2 = this.buildRunnable(t2Command, this.si, 0);
-		Thread t1 = this.buildThread(r1);
-		Thread t2 = this.buildThread(r2);
-		t1.start();
-		t2.start();
-		t1.join();
-		t2.join();
-	}
-
-	private Command buildSetZeroCommand() {
-		return new Command() {
-			public void execute(SynchronizedInt sInt) {
-				sInt.setZero();
-			}
-		};
-	}
-
-	private Command buildWaitUntilZeroCommand(final long timeout) {
-		return new Command() {
-			public void execute(SynchronizedInt sInt) throws InterruptedException {
-				SynchronizedIntTests.this.startTime = System.currentTimeMillis();
-				SynchronizedIntTests.this.timeoutOccurred = ! sInt.waitUntilZero(timeout);
-				SynchronizedIntTests.this.endTime = System.currentTimeMillis();
-			}
-		};
-	}
-
-	private Command buildWaitToSetValueCommand(final long timeout) {
-		return new Command() {
-			public void execute(SynchronizedInt sInt) throws InterruptedException {
-				SynchronizedIntTests.this.startTime = System.currentTimeMillis();
-				SynchronizedIntTests.this.timeoutOccurred = ! sInt.waitToSetValue(SynchronizedIntTests.this.value, timeout);
-				SynchronizedIntTests.this.endTime = System.currentTimeMillis();
-			}
-		};
-	}
-
-	private Command buildInitializeValueCommand() {
-		return new Command() {
-			public void execute(final SynchronizedInt sInt) throws InterruptedException {
-				sInt.execute(
-					new org.eclipse.persistence.tools.utility.command.Command() {
-						public void execute() {
-							// pretend to perform some long initialization process
-							try {
-								Thread.sleep(5 * TICK);
-							} catch (InterruptedException ex) {
-								throw new RuntimeException(ex);
-							}
-							sInt.setValue(42);
-						}
-					}
-				);
-			}
-		};
-	}
-
-	private Command buildGetValueCommand() {
-		return new Command() {
-			public void execute(SynchronizedInt sInt) throws InterruptedException {
-				SynchronizedIntTests.this.startTime = System.currentTimeMillis();
-				SynchronizedIntTests.this.sIntValue = sInt.getValue();
-				SynchronizedIntTests.this.endTime = System.currentTimeMillis();
-			}
-		};
-	}
-
-	private Runnable buildRunnable(final Command command, final SynchronizedInt sInt, final long sleep) {
-		return new TestRunnable() {
-			@Override
-			protected void run_() throws InterruptedException {
-				if (sleep != 0) {
-					Thread.sleep(sleep);
-				}
-				command.execute(sInt);
-			}
-		};
-	}
-
-	private long calculateElapsedTime() {
-		return this.endTime - this.startTime;
-	}
-
-
-	// ********** Command interface **********
-
-	private interface Command {
-		void execute(SynchronizedInt sInt) throws InterruptedException;
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedObjectTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedObjectTests.java
deleted file mode 100644
index ba7cd46..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedObjectTests.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import org.eclipse.persistence.tools.utility.SynchronizedObject;
-
-
-@SuppressWarnings("nls")
-public class SynchronizedObjectTests
-	extends MultiThreadedTestCase
-{
-	private volatile SynchronizedObject<Object> so;
-	volatile boolean timeoutOccurred;
-	volatile Object value = new Object();
-	volatile long startTime;
-	volatile long endTime;
-	volatile Object soValue;
-
-
-	public SynchronizedObjectTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.so = new SynchronizedObject<Object>();
-		this.timeoutOccurred = false;
-		this.startTime = 0;
-		this.endTime = 0;
-		this.soValue = null;
-	}
-
-	public void testAccessors() throws Exception {
-		this.so.setValue(null);
-		assertNull(this.so.getValue());
-		assertFalse(this.so.isNotNull());
-		assertTrue(this.so.isNull());
-
-		this.so.setValue(this.value);
-		assertEquals(this.value, this.so.getValue());
-		assertTrue(this.so.isNotNull());
-		assertFalse(this.so.isNull());
-
-		this.so.setNull();
-		assertNull(this.so.getValue());
-		assertFalse(this.so.isNotNull());
-		assertTrue(this.so.isNull());
-
-		assertSame(this.so, this.so.getMutex());
-	}
-
-	/**
-	 * t2 will wait indefinitely until t1 sets the value to null
-	 */
-	public void testWaitUntilNull() throws Exception {
-		this.verifyWaitUntilNull(0);
-		// no timeout occurs...
-		assertFalse(this.timeoutOccurred);
-		// ...and the value should be set to null by t2
-		assertNull(this.so.getValue());
-		// make a reasonable guess about how long t2 took
-		long time = this.calculateElapsedTime();
-		assertTrue("t2 finished a bit early (expected value should be > " + TICK + "): " + time, time > TICK);
-	}
-
-	/**
-	 * t2 will time out waiting for t1 to set the value to null
-	 */
-	public void testWaitUntilNullTimeout() throws Exception {
-		this.verifyWaitUntilNull(TICK);
-		// timeout occurs...
-		assertTrue(this.timeoutOccurred);
-		// ...and the value will eventually be set to null by t1
-		assertNull(this.so.getValue());
-		// make a reasonable guess about how long t2 took
-		long time = this.calculateElapsedTime();
-		assertTrue("t2 finished a bit late (expected value should be < " + THREE_TICKS + "): " + time, time < THREE_TICKS);
-	}
-
-	private void verifyWaitUntilNull(long t2Timeout) throws Exception {
-		this.executeThreads(this.buildSetNullCommand(), this.buildWaitUntilNullCommand(t2Timeout));
-	}
-
-	/**
-	 * t2 will wait indefinitely until t1 sets the value to null;
-	 * then t2 will set the value to an object
-	 */
-	public void testWaitToSetValue() throws Exception {
-		this.verifyWaitToSetValue(0);
-		// no timeout occurs...
-		assertFalse(this.timeoutOccurred);
-		// ...and the value should be set to an object by t2
-		assertTrue(this.so.isNotNull());
-		// make a reasonable guess about how long t2 took
-		long time = this.calculateElapsedTime();
-		assertTrue("t2 finished a bit early (expected value should be > " + TICK + "): " + time, time > TICK);
-	}
-
-	/**
-	 * t2 will time out waiting for t1 to set the value to null
-	 */
-	public void testWaitToSetValueTimeout() throws Exception {
-		this.verifyWaitToSetValue(TICK);
-		// timeout occurs...
-		assertTrue(this.timeoutOccurred);
-		// ...and the value will eventually be set to null by t1
-		assertTrue(this.so.isNull());
-		// make a reasonable guess about how long t2 took
-		long time = this.calculateElapsedTime();
-		assertTrue("t2 finished a bit late (expected value should be < " + THREE_TICKS + "): " + time, time < THREE_TICKS);
-	}
-
-	private void verifyWaitToSetValue(long t2Timeout) throws Exception {
-		this.executeThreads(this.buildSetNullCommand(), this.buildWaitToSetValueCommand(t2Timeout));
-	}
-
-	/**
-	 * t2 will wait until t1 is finished "initializing" the value;
-	 * then t2 will get the newly-initialized value ("foo")
-	 */
-	public void testExecute() throws Exception {
-		this.so.setValue(null);
-		Runnable r1 = this.buildRunnable(this.buildInitializeValueCommand(), this.so, 0);
-		// give t1 a head start of 100 ms
-		Runnable r2 = this.buildRunnable(this.buildGetValueCommand(), this.so, TICK);
-		Thread t1 = this.buildThread(r1);
-		Thread t2 = this.buildThread(r2);
-		t1.start();
-		t2.start();
-		t1.join();
-		t2.join();
-		assertEquals("foo", this.so.getValue());
-		assertEquals("foo", this.soValue);
-		// make a reasonable guess about how long t2 took
-		long time = this.calculateElapsedTime();
-		assertTrue("t2 finished a bit early (expected value should be > " + TWO_TICKS + "): " + time, time > TWO_TICKS);
-	}
-
-	private void executeThreads(Command t1Command, Command t2Command) throws Exception {
-		this.so.setValue(this.value);
-		Runnable r1 = this.buildRunnable(t1Command, this.so, TWO_TICKS);
-		Runnable r2 = this.buildRunnable(t2Command, this.so, 0);
-		Thread t1 = this.buildThread(r1);
-		Thread t2 = this.buildThread(r2);
-		t1.start();
-		t2.start();
-		t1.join();
-		t2.join();
-	}
-
-	private Command buildSetNullCommand() {
-		return new Command() {
-			public void execute(SynchronizedObject<Object> sObject) {
-				sObject.setNull();
-			}
-		};
-	}
-
-	private Command buildWaitUntilNullCommand(final long timeout) {
-		return new Command() {
-			public void execute(SynchronizedObject<Object> sObject) throws InterruptedException {
-				SynchronizedObjectTests.this.startTime = System.currentTimeMillis();
-				SynchronizedObjectTests.this.timeoutOccurred = ! sObject.waitUntilNull(timeout);
-				SynchronizedObjectTests.this.endTime = System.currentTimeMillis();
-			}
-		};
-	}
-
-	private Command buildWaitToSetValueCommand(final long timeout) {
-		return new Command() {
-			public void execute(SynchronizedObject<Object> sObject) throws InterruptedException {
-				SynchronizedObjectTests.this.startTime = System.currentTimeMillis();
-				SynchronizedObjectTests.this.timeoutOccurred = ! sObject.waitToSetValue(SynchronizedObjectTests.this.value, timeout);
-				SynchronizedObjectTests.this.endTime = System.currentTimeMillis();
-			}
-		};
-	}
-
-	private Command buildInitializeValueCommand() {
-		return new Command() {
-			public void execute(final SynchronizedObject<Object> sObject) throws InterruptedException {
-				sObject.execute(
-					new org.eclipse.persistence.tools.utility.command.Command() {
-						public void execute() {
-							// pretend to perform some long initialization process
-							try {
-								Thread.sleep(5 * TICK);
-							} catch (Exception ex) {
-								throw new RuntimeException(ex);
-							}
-							sObject.setValue("foo");
-						}
-					}
-				);
-			}
-		};
-	}
-
-	private Command buildGetValueCommand() {
-		return new Command() {
-			public void execute(SynchronizedObject<Object> sObject) throws InterruptedException {
-				SynchronizedObjectTests.this.startTime = System.currentTimeMillis();
-				SynchronizedObjectTests.this.soValue = sObject.getValue();
-				SynchronizedObjectTests.this.endTime = System.currentTimeMillis();
-			}
-		};
-	}
-
-	private Runnable buildRunnable(final Command command, final SynchronizedObject<Object> sObject, final long sleep) {
-		return new TestRunnable() {
-			@Override
-			protected void run_() throws InterruptedException {
-				if (sleep != 0) {
-					Thread.sleep(sleep);
-				}
-				command.execute(sObject);
-			}
-		};
-	}
-
-	private long calculateElapsedTime() {
-		return this.endTime - this.startTime;
-	}
-
-
-	// ********** Command interface **********
-
-	private interface Command {
-		void execute(SynchronizedObject<Object> so) throws InterruptedException;
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedQueueTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedQueueTests.java
deleted file mode 100644
index d8a811e..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedQueueTests.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.Queue;
-import org.eclipse.persistence.tools.utility.SimpleQueue;
-import org.eclipse.persistence.tools.utility.SynchronizedQueue;
-
-@SuppressWarnings("nls")
-public class SynchronizedQueueTests extends SimpleQueueTests {
-	private volatile SynchronizedQueue<String> sq;
-	volatile boolean timeoutOccurred;
-	volatile long startTime;
-	volatile long endTime;
-	volatile Object dequeuedObject;
-
-	static final String ITEM_1 = new String();
-	static final String ITEM_2 = new String();
-
-	public SynchronizedQueueTests(String name) {
-		super(name);
-	}
-
-	@Override
-	Queue<String> buildQueue() {
-		return new SynchronizedQueue<String>();
-	}
-
-	@Override
-	public void testClone() {
-		// synchronized queue is not cloneable
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.sq = new SynchronizedQueue<String>();
-		this.timeoutOccurred = false;
-		this.startTime = 0;
-		this.endTime = 0;
-		this.dequeuedObject = null;
-	}
-
-	/**
-	 * test first with an unsynchronized queue,
-	 * then with a synchronized queue
-	 */
-	public void testConcurrentAccess() throws Exception {
-		this.verifyConcurrentAccess(new SlowSimpleQueue<String>(), "first");
-		this.verifyConcurrentAccess(new SlowSynchronizedQueue<String>(), "second");
-	}
-
-	private void verifyConcurrentAccess(SlowQueue<String> slowQueue, String expected) throws Exception {
-		slowQueue.enqueue("first");
-		slowQueue.enqueue("second");
-
-		Thread thread = this.buildThread(this.buildRunnable(slowQueue));
-		thread.start();
-		Thread.sleep(TWO_TICKS);
-
-		assertEquals(expected, slowQueue.dequeue());
-		thread.join();
-		assertTrue(slowQueue.isEmpty());
-	}
-
-	private Runnable buildRunnable(final SlowQueue<String> slowQueue) {
-		return new Runnable() {
-			public void run() {
-				slowQueue.slowDequeue();
-			}
-		};
-	}
-
-
-	private interface SlowQueue<E> extends Queue<E> {
-		Object slowDequeue();
-	}
-
-	private class SlowSimpleQueue<E> extends SimpleQueue<E> implements SlowQueue<E> {
-		SlowSimpleQueue() {
-			super();
-		}
-		public Object slowDequeue() {
-			try {
-				Thread.sleep(5 * TICK);
-			} catch (InterruptedException ex) {
-				throw new RuntimeException(ex);
-			}
-			return this.dequeue();
-		}
-
-	}
-
-	private class SlowSynchronizedQueue<E> extends SynchronizedQueue<E> implements SlowQueue<E> {
-		SlowSynchronizedQueue() {
-			super();
-		}
-		public synchronized Object slowDequeue() {
-			try {
-				Thread.sleep(5 * TICK);
-			} catch (InterruptedException ex) {
-				throw new RuntimeException(ex);
-			}
-			return this.dequeue();
-		}
-
-	}
-
-
-	// ********** waits **********
-
-	public void testWaitToDequeue() throws Exception {
-		this.verifyWaitToDequeue(0);
-		// no timeout occurs...
-		assertFalse(this.timeoutOccurred);
-		// ...and an item should have been dequeued by t2...
-		assertSame(ITEM_1, this.dequeuedObject);
-		// ...and the queue should be empty
-		assertTrue(this.sq.isEmpty());
-		// make a reasonable guess about how long t2 took
-		assertTrue(this.calculateElapsedTime() > TICK);
-	}
-
-	public void testWaitToDequeueTimeout() throws Exception {
-		this.verifyWaitToDequeue(TICK);
-		// timeout occurs...
-		assertTrue(this.timeoutOccurred);
-		// ...and the queue was never dequeued...
-		assertNull(this.dequeuedObject);
-		// ...and it still holds the item
-		assertSame(ITEM_1, this.sq.peek());
-		// make a reasonable guess about how long t2 took
-		assertTrue(this.calculateElapsedTime() < THREE_TICKS);
-	}
-
-	private void verifyWaitToDequeue(long timeout) throws Exception {
-		Runnable r1 = this.buildRunnable(this.buildEnqueueCommand(), this.sq, TWO_TICKS);
-		Runnable r2 = this.buildRunnable(this.buildWaitToDequeueCommand(timeout), this.sq, 0);
-		Thread t1 = this.buildThread(r1);
-		Thread t2 = this.buildThread(r2);
-		t1.start();
-		t2.start();
-		t1.join();
-		t2.join();
-	}
-
-	public void testWaitToEnqueue() throws Exception {
-		this.verifyWaitToEnqueue(0);
-		// no timeout occurs...
-		assertFalse(this.timeoutOccurred);
-		// ...and the queue gets dequeued by t1...
-		assertSame(ITEM_1, this.dequeuedObject);
-		// ...and an item is enqueued on to the queue by t2
-		assertFalse(this.sq.isEmpty());
-		assertSame(ITEM_2, this.sq.peek());
-		// make a reasonable guess about how long t2 took
-		assertTrue(this.calculateElapsedTime() > TICK);
-	}
-
-	public void testWaitToEnqueueTimeout() throws Exception {
-		this.verifyWaitToEnqueue(TICK);
-		// timeout occurs...
-		assertTrue(this.timeoutOccurred);
-		// ...and the queue is eventually dequeued by t1...
-		assertSame(ITEM_1, this.dequeuedObject);
-		// ...but nothing is enqueued on to the queue by t2
-		assertTrue(this.sq.isEmpty());
-		// make a reasonable guess about how long t2 took
-		assertTrue(this.calculateElapsedTime() < THREE_TICKS);
-	}
-
-	private void verifyWaitToEnqueue(long timeout) throws Exception {
-		this.sq.enqueue(ITEM_1);
-		Runnable r1 = this.buildRunnable(this.buildDequeueCommand(), this.sq, TWO_TICKS);
-		Runnable r2 = this.buildRunnable(this.buildWaitToEnqueueCommand(timeout), this.sq, 0);
-		Thread t1 = this.buildThread(r1);
-		Thread t2 = this.buildThread(r2);
-		t1.start();
-		t2.start();
-		t1.join();
-		t2.join();
-	}
-
-	private Command buildEnqueueCommand() {
-		return new Command() {
-			public void execute(SynchronizedQueue<String> synchronizedQueue) {
-				synchronizedQueue.enqueue(ITEM_1);
-			}
-		};
-	}
-
-	private Command buildWaitToDequeueCommand(final long timeout) {
-		return new Command() {
-			public void execute(SynchronizedQueue<String> synchronizedQueue) throws InterruptedException {
-				SynchronizedQueueTests.this.startTime = System.currentTimeMillis();
-				try {
-					SynchronizedQueueTests.this.dequeuedObject = synchronizedQueue.waitToDequeue(timeout);
-				} catch (NoSuchElementException ex) {
-					SynchronizedQueueTests.this.timeoutOccurred = true;
-				}
-				SynchronizedQueueTests.this.endTime = System.currentTimeMillis();
-			}
-		};
-	}
-
-	private Command buildDequeueCommand() {
-		return new Command() {
-			public void execute(SynchronizedQueue<String> synchronizedQueue) {
-				SynchronizedQueueTests.this.dequeuedObject = synchronizedQueue.dequeue();
-			}
-		};
-	}
-
-	private Command buildWaitToEnqueueCommand(final long timeout) {
-		return new Command() {
-			public void execute(SynchronizedQueue<String> synchronizedQueue) throws InterruptedException {
-				SynchronizedQueueTests.this.startTime = System.currentTimeMillis();
-				SynchronizedQueueTests.this.timeoutOccurred = ! synchronizedQueue.waitToEnqueue(ITEM_2, timeout);
-				SynchronizedQueueTests.this.endTime = System.currentTimeMillis();
-			}
-		};
-	}
-
-	private Runnable buildRunnable(final Command command, final SynchronizedQueue<String> synchronizedQueue, final long sleep) {
-		return new TestRunnable() {
-			@Override
-			protected void run_() throws Throwable {
-				if (sleep != 0) {
-					Thread.sleep(sleep);
-				}
-				command.execute(synchronizedQueue);
-			}
-		};
-	}
-
-	long calculateElapsedTime() {
-		return this.endTime - this.startTime;
-	}
-
-
-	// ********** Command interface **********
-
-	private interface Command {
-		void execute(SynchronizedQueue<String> synchronizedQueue) throws InterruptedException;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedStackTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedStackTests.java
deleted file mode 100644
index a09cb7a..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/SynchronizedStackTests.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.util.EmptyStackException;
-
-import org.eclipse.persistence.tools.utility.SimpleStack;
-import org.eclipse.persistence.tools.utility.Stack;
-import org.eclipse.persistence.tools.utility.SynchronizedStack;
-
-@SuppressWarnings("nls")
-public class SynchronizedStackTests
-	extends SimpleStackTests
-{
-	private volatile SynchronizedStack<String> ss;
-	volatile boolean timeoutOccurred;
-	volatile long startTime;
-	volatile long endTime;
-	volatile Object poppedObject;
-
-	static final String ITEM_1 = new String();
-	static final String ITEM_2 = new String();
-
-	public SynchronizedStackTests(String name) {
-		super(name);
-	}
-
-	@Override
-	Stack<String> buildStack() {
-		return new SynchronizedStack<String>();
-	}
-
-	@Override
-	public void testClone() {
-		// synchronized stack is not cloneable
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.ss = new SynchronizedStack<String>();
-		this.timeoutOccurred = false;
-		this.startTime = 0;
-		this.endTime = 0;
-		this.poppedObject = null;
-	}
-
-	/**
-	 * test first with an unsynchronized stack,
-	 * then with a synchronized stack
-	 */
-	public void testConcurrentAccess() throws Exception {
-		this.verifyConcurrentAccess(new SlowSimpleStack<String>(), "second");
-		this.verifyConcurrentAccess(new SlowSynchronizedStack<String>(), "first");
-	}
-
-	private void verifyConcurrentAccess(SlowStack<String> slowStack, String expected) throws Exception {
-		slowStack.push("first");
-		slowStack.push("second");
-
-		Thread thread = this.buildThread(this.buildRunnable(slowStack));
-		thread.start();
-		Thread.sleep(TWO_TICKS);
-
-		assertEquals(expected, slowStack.pop());
-		thread.join();
-		assertTrue(slowStack.isEmpty());
-	}
-
-	private Runnable buildRunnable(final SlowStack<String> slowStack) {
-		return new Runnable() {
-			public void run() {
-				slowStack.slowPop();
-			}
-		};
-	}
-
-
-	private interface SlowStack<E> extends Stack<E> {
-		Object slowPop();
-	}
-
-	private class SlowSimpleStack<E> extends SimpleStack<E> implements SlowStack<E> {
-		SlowSimpleStack() {
-			super();
-		}
-		public Object slowPop() {
-			try {
-				Thread.sleep(5 * TICK);
-			} catch (InterruptedException ex) {
-				throw new RuntimeException(ex);
-			}
-			return this.pop();
-		}
-
-	}
-
-	private class SlowSynchronizedStack<E> extends SynchronizedStack<E> implements SlowStack<E> {
-		SlowSynchronizedStack() {
-			super();
-		}
-		public synchronized Object slowPop() {
-			try {
-				Thread.sleep(5 * TICK);
-			} catch (InterruptedException ex) {
-				throw new RuntimeException(ex);
-			}
-			return this.pop();
-		}
-
-	}
-
-
-	// ********** waits **********
-
-	public void testWaitToPop() throws Exception {
-		this.verifyWaitToPop(0);
-		// no timeout occurs...
-		assertFalse(this.timeoutOccurred);
-		// ...and an item should have been popped by t2...
-		assertSame(ITEM_1, this.poppedObject);
-		// ...and the stack should be empty
-		assertTrue(this.ss.isEmpty());
-		// make a reasonable guess about how long t2 took
-		assertTrue(this.calculateElapsedTime() > TICK);
-	}
-
-	public void testWaitToPopTimeout() throws Exception {
-		this.verifyWaitToPop(TICK);
-		// timeout occurs...
-		assertTrue(this.timeoutOccurred);
-		// ...and the stack was never popped...
-		assertNull(this.poppedObject);
-		// ...and it still holds the item
-		assertSame(ITEM_1, this.ss.peek());
-		// make a reasonable guess about how long t2 took
-		assertTrue(this.calculateElapsedTime() < THREE_TICKS);
-	}
-
-	private void verifyWaitToPop(long timeout) throws Exception {
-		Runnable r1 = this.buildRunnable(this.buildPushCommand(), this.ss, TWO_TICKS);
-		Runnable r2 = this.buildRunnable(this.buildWaitToPopCommand(timeout), this.ss, 0);
-		Thread t1 = this.buildThread(r1);
-		Thread t2 = this.buildThread(r2);
-		t1.start();
-		t2.start();
-		t1.join();
-		t2.join();
-	}
-
-	public void testWaitToPush() throws Exception {
-		this.verifyWaitToPush(0);
-		// no timeout occurs...
-		assertFalse(this.timeoutOccurred);
-		// ...and the stack gets popped by t1...
-		assertSame(ITEM_1, this.poppedObject);
-		// ...and an item is pushed on to the stack by t2
-		assertFalse(this.ss.isEmpty());
-		assertSame(ITEM_2, this.ss.peek());
-		// make a reasonable guess about how long t2 took
-		assertTrue(this.calculateElapsedTime() > TICK);
-	}
-
-	public void testWaitToPushTimeout() throws Exception {
-		this.verifyWaitToPush(TICK);
-		// timeout occurs...
-		assertTrue(this.timeoutOccurred);
-		// ...and the stack is eventually popped by t1...
-		assertSame(ITEM_1, this.poppedObject);
-		// ...but nothing is pushed on to the stack by t2
-		assertTrue(this.ss.isEmpty());
-		// make a reasonable guess about how long t2 took
-		assertTrue(this.calculateElapsedTime() < THREE_TICKS);
-	}
-
-	private void verifyWaitToPush(long timeout) throws Exception {
-		this.ss.push(ITEM_1);
-		Runnable r1 = this.buildRunnable(this.buildPopCommand(), this.ss, TWO_TICKS);
-		Runnable r2 = this.buildRunnable(this.buildWaitToPushCommand(timeout), this.ss, 0);
-		Thread t1 = this.buildThread(r1);
-		Thread t2 = this.buildThread(r2);
-		t1.start();
-		t2.start();
-		t1.join();
-		t2.join();
-	}
-
-	private Command buildPushCommand() {
-		return new Command() {
-			public void execute(SynchronizedStack<String> synchronizedStack) {
-				synchronizedStack.push(ITEM_1);
-			}
-		};
-	}
-
-	private Command buildWaitToPopCommand(final long timeout) {
-		return new Command() {
-			public void execute(SynchronizedStack<String> synchronizedStack) throws InterruptedException {
-				SynchronizedStackTests.this.startTime = System.currentTimeMillis();
-				try {
-					SynchronizedStackTests.this.poppedObject = synchronizedStack.waitToPop(timeout);
-				} catch (EmptyStackException ex) {
-					SynchronizedStackTests.this.timeoutOccurred = true;
-				}
-				SynchronizedStackTests.this.endTime = System.currentTimeMillis();
-			}
-		};
-	}
-
-	private Command buildPopCommand() {
-		return new Command() {
-			public void execute(SynchronizedStack<String> synchronizedStack) {
-				SynchronizedStackTests.this.poppedObject = synchronizedStack.pop();
-			}
-		};
-	}
-
-	private Command buildWaitToPushCommand(final long timeout) {
-		return new Command() {
-			public void execute(SynchronizedStack<String> synchronizedStack) throws InterruptedException {
-				SynchronizedStackTests.this.startTime = System.currentTimeMillis();
-				SynchronizedStackTests.this.timeoutOccurred = ! synchronizedStack.waitToPush(ITEM_2, timeout);
-				SynchronizedStackTests.this.endTime = System.currentTimeMillis();
-			}
-		};
-	}
-
-	private Runnable buildRunnable(final Command command, final SynchronizedStack<String> synchronizedStack, final long sleep) {
-		return new TestRunnable() {
-			@Override
-			protected void run_() throws Throwable {
-				if (sleep != 0) {
-					Thread.sleep(sleep);
-				}
-				command.execute(synchronizedStack);
-			}
-		};
-	}
-
-	long calculateElapsedTime() {
-		return this.endTime - this.startTime;
-	}
-
-
-	// ********** Command interface **********
-
-	private interface Command {
-		void execute(SynchronizedStack<String> synchronizedStack) throws InterruptedException;
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/TestCommand.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/TestCommand.java
deleted file mode 100644
index 3a10b66..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/TestCommand.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-/**
- * Command that can be used to execute tests; i.e. a command that allows its
- * implementation to throw exceptions.
- */
-public interface TestCommand {
-	void execute() throws Exception;
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/TestTools.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/TestTools.java
deleted file mode 100644
index 28b039b..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/TestTools.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import junit.framework.Assert;
-import junit.framework.TestCase;
-import junit.framework.TestFailure;
-import junit.framework.TestResult;
-
-import org.eclipse.persistence.tools.utility.ReflectionTools;
-
-/**
- * Various tools that can be used by test cases.
- */
-@SuppressWarnings("nls")
-public final class TestTools {
-
-	/**
-	 * Convenience method that handles {@link InterruptedException}.
-	 */
-	public static void sleep(long millis) {
-		try {
-			Thread.sleep(millis);
-		} catch (InterruptedException ex) {
-			throw new RuntimeException(ex);
-		}
-	}
-
-	/**
-	 * Execute the specified command. If it throws an exception, re-execute it
-	 * repeatedly until it executes without an exception.
-	 * There will be a one-second delay between each execution.
-	 * This is useful when calling third-party code that intermittently throws
-	 * exceptions but will <em>eventually</em> execute successfully (e.g. when
-	 * there are problems deleting files).
-	 */
-	public static void execute(TestCommand command) {
-		execute(command, -1);
-	}
-
-	/**
-	 * Execute the specified command. If it throws an exception, re-execute it
-	 * repeatedly until it executes without an exception. Execute the command
-	 * up to the specified number of attempts.
-	 * There will be a one-second delay between each execution.
-	 * This is useful when calling third-party code that intermittently throws
-	 * exceptions but will <em>eventually</em> execute successfully (e.g. when
-	 * there are problems deleting files).
-	 */
-	public static void execute(TestCommand command, int attempts) {
-		execute(command, attempts, 1000);
-	}
-
-	/**
-	 * Execute the specified command. If it throws an exception, re-execute it
-	 * repeatedly until it executes without an exception. Execute the command
-	 * up to the specified number of attemptsl with specified delay between
-	 * each execution.
-	 * This is useful when calling third-party code that intermittently throws
-	 * exceptions but will <em>eventually</em> execute successfully (e.g. when
-	 * there are problems deleting files).
-	 */
-	public static void execute(TestCommand command, int attempts, long delay) {
-		for (int i = 1; i <= attempts; i++) {  // NB: start with 1
-			try {
-				command.execute();
-				return;
-			} catch (Exception ex) {
-				if ((attempts != -1) && (i == attempts)) {
-					throw new RuntimeException("attempts: " + i, ex);
-				}
-				sleep(delay);
-			}
-		}
-	}
-
-	/**
-	 * Test an object's implementation of {@link Serializable} by serializing the
-	 * specified object to a byte array; then de-serializing the byte array and
-	 * returning the resultant object.
-	 */
-	public static <T> T serialize(T o) throws IOException, ClassNotFoundException {
-		ByteArrayOutputStream baOutStream = new ByteArrayOutputStream(2000);
-		ObjectOutputStream outStream = new ObjectOutputStream(baOutStream);
-		outStream.writeObject(o);
-		outStream.close();
-
-		ByteArrayInputStream baInStream = new ByteArrayInputStream(baOutStream.toByteArray());
-		ObjectInputStream inStream = new ObjectInputStream(baInStream);
-		T o2 = readObject(inStream);
-		inStream.close();
-
-		return o2;
-	}
-
-	@SuppressWarnings("unchecked")
-	private static <T> T readObject(ObjectInput objectInput) throws IOException, ClassNotFoundException {
-		return (T) objectInput.readObject();
-	}
-
-	/**
-	 * Redirect std out and std err to the specified stream.
-	 */
-	public static void redirectSystemStreamsTo(OutputStream outputStream) {
-		redirectSystemStreamsTo(new PrintStream(outputStream));
-	}
-
-	/**
-	 * Redirect std out and std err to the specified stream.
-	 */
-	public static void redirectSystemStreamsTo(PrintStream printStream) {
-		System.setOut(printStream);
-		System.setErr(printStream);
-	}
-
-	/**
-	 * Sort and print out all the current Java System properties on the
-	 * console.
-	 */
-	public static void printSystemProperties() {
-		synchronized (System.out) {
-			printSystemPropertiesOn(System.out);
-		}
-	}
-
-	/**
-	 * Sort and print out all the current Java System properties on the
-	 * specified print stream.
-	 */
-	public static void printSystemPropertiesOn(PrintStream stream) {
-		SortedSet<String> sortedKeys = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
-		for (Object key : System.getProperties().keySet()) {
-			sortedKeys.add((String) key);
-		}
-		for (String key : sortedKeys) {
-			stream.print(key);
-			stream.print(" => ");
-			stream.print(System.getProperty(key));
-			stream.println();
-		}
-	}
-
-	/**
-	 * Execute the specified test and return a text output of its results.
-	 */
-	public static String execute(TestCase testCase) {
-		long start = System.currentTimeMillis();
-		TestResult result = testCase.run();
-		long end = System.currentTimeMillis();
-
-		StringWriter stringWriter = new StringWriter();
-		PrintWriter writer = new PrintWriter(stringWriter);
-		writer.print(testCase.getName());
-		writer.print(": ");
-		if (result.wasSuccessful()) {
-			writer.println("OK");
-		} else {
-			TestFailure failure = null;
-			if (result.failures().hasMoreElements()) {
-				failure = result.failures().nextElement();
-			} else {
-				failure = result.errors().nextElement();
-			}
-			failure.thrownException().printStackTrace(writer);
-		}
-		writer.print("elapsed time: ");
-		long elapsed = end - start;
-		writer.print(elapsed / 1000L);
-		writer.println(" sec.");
-		return stringWriter.toString();
-	}
-
-	/**
-	 * Clear out all the instance variable of the specified test case, allowing
-	 * the various test fixtures to be garbage-collected. Typically this is
-	 * called in the test case's implementation of {@link TestCase#tearDown()}.
-	 */
-	public static void clear(TestCase testCase) throws IllegalAccessException {
-		for (Class<?> clazz = testCase.getClass(); clazz != TestCase_class; clazz = clazz.getSuperclass()) {
-			for (Field field : clazz.getDeclaredFields()) {
-				// leave primitives alone - they don't get garbage-collected, and we can't set them to null...
-				if (field.getType().isPrimitive()) {
-					continue;
-				}
-				// leave static fields alone (?)
-				if (Modifier.isStatic(field.getModifiers())) {
-					continue;
-				}
-				field.setAccessible(true);
-				field.set(testCase, null);
-			}
-		}
-	}
-
-	/**
-	 * Return the value of the specified class's <code>DEBUG</code> constant.
-	 */
-	public static boolean debug(Class<?> clazz) {
-		Boolean debug = (Boolean) ReflectionTools.getStaticFieldValue(clazz, "DEBUG");
-		return debug.booleanValue();
-	}
-
-	/**
-	 * Verify the specified class's <code>DEBUG</code> constant is set to
-	 * <code>false</code>.
-	 */
-	public static void assertFalseDEBUG(Class<?> clazz) {
-		Assert.assertFalse("Recompile with \"DEBUG = false\": " + clazz.getName(), debug(clazz));
-	}
-	
-	private static final Class<TestCase> TestCase_class = TestCase.class;
-
-	/**
-	 * Workaround for a JUnit bug: JUnit does not configure the testing {@link Thread}
-	 * with a context class loader. This should probably happen in
-	 * {@link TestRunner#doRun(Test)}, just before starting the thread.
-	 */
-	public static void setUpJUnitThreadContextClassLoader() {
-		Thread.currentThread().setContextClassLoader(TestTools.class.getClassLoader());
-	}
-
-	/**
-	 * suppressed constructor
-	 */
-	private TestTools() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ToolsTests.java
deleted file mode 100644
index db8d946..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/ToolsTests.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.Tools;
-
-@SuppressWarnings("nls")
-public class ToolsTests extends TestCase {
-
-	public ToolsTests(String name) {
-		super(name);
-	}
-
-	public void testValuesAreEqual1() {
-		assertTrue(Tools.valuesAreEqual(null, null));
-	}
-
-	public void testValuesAreEqual2() {
-		assertFalse(Tools.valuesAreEqual(null, "foo"));
-	}
-
-	public void testValuesAreEqual3() {
-		assertFalse(Tools.valuesAreEqual("foo", null));
-	}
-
-	public void testValuesAreEqual4() {
-		assertTrue(Tools.valuesAreEqual("foo", "foo"));
-	}
-
-	public void testValuesAreEqual5() {
-		assertFalse(Tools.valuesAreEqual("foo", "bar"));
-	}
-
-	public void testValuesAreDifferent1() {
-		assertFalse(Tools.valuesAreDifferent(null, null));
-	}
-
-	public void testValuesAreDifferent2() {
-		assertTrue(Tools.valuesAreDifferent(null, "foo"));
-	}
-
-	public void testValuesAreDifferent3() {
-		assertTrue(Tools.valuesAreDifferent("foo", null));
-	}
-
-	public void testValuesAreDifferent4() {
-		assertFalse(Tools.valuesAreDifferent("foo", "foo"));
-	}
-
-	public void testValuesAreDifferent5() {
-		assertTrue(Tools.valuesAreDifferent("foo", "bar"));
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/VersionComparatorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/VersionComparatorTests.java
deleted file mode 100644
index c101d7d..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/VersionComparatorTests.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.util.Comparator;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.VersionComparator;
-import org.eclipse.persistence.tools.utility.VersionComparator.SegmentParser;
-
-@SuppressWarnings("nls")
-public class VersionComparatorTests
-	extends TestCase
-{
-	public VersionComparatorTests(String name) {
-		super(name);
-	}
-
-	public void testVersionIsEqual_integer() {
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.0", "2.0.0") == 0);
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.0", "2.0.0.0") == 0);
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.0.0.0.0.0000", "2.0") == 0);
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.-1", "2.0.-1") == 0);
-	}
-
-	public void testVersionIsLess_integer() {
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.0", "2.0.1") < 0);
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.5.0", "2.14") < 0);
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.5.0", "2.5.0.0.1.0") < 0);
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.5.0.0.0.-1", "2.5") < 0);
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.-1", "2.0.0") < 0);
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.-1", "2") < 0);
-	}
-
-	public void testVersionIsGreater_integer() {
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.2", "2.0.1") > 0);
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.2", "2.0.1") > 0);
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.5.0.0.1.0", "2.5.0") > 0);
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.5", "2.5.0.0.0.-1") > 0);
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.0", "2.0.-1") > 0);
-		assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2", "2.0.-1") > 0);
-	}
-
-	public void testVersionIsEqual_integer_comma() {
-		Comparator<String> versionComparator = new VersionComparator<BigDecimal>(",", DecimalSegmentParser.instance());
-		assertTrue(versionComparator.compare("2,0,0", "2,0,0") == 0);
-		assertTrue(versionComparator.compare("2,0.0,0", "2,0,0") == 0);
-		assertTrue(versionComparator.compare("2,0.0,0", "2,0,0.0") == 0);
-		assertTrue(versionComparator.compare("2.0,0.0,0", "2,0,0.0") == 0);
-	}
-
-	public void testVersionIsLess_integer_comma() {
-		Comparator<String> versionComparator = new VersionComparator<BigDecimal>(",", DecimalSegmentParser.instance());
-		assertTrue(versionComparator.compare("2,0,0", "2,0,1") < 0);
-		assertTrue(versionComparator.compare("2,0.0,0", "2,0,1") < 0);
-		assertTrue(versionComparator.compare("2,0,0", "2,0,1.0") < 0);
-		assertTrue(versionComparator.compare("2.0,0,0", "2,0,1") < 0);
-	}
-
-	public void testVersionIsGreater_integer_comma() {
-		Comparator<String> versionComparator = new VersionComparator<BigDecimal>(",", DecimalSegmentParser.instance());
-		assertTrue(versionComparator.compare("2,0,2", "2,0,1") > 0);
-		assertTrue(versionComparator.compare("2,0,2.1", "2,0,1") > 0);
-		assertTrue(versionComparator.compare("2,0,2", "2,0,1.9") > 0);
-		assertTrue(versionComparator.compare("2.000,0,2", "2,0,1") > 0);
-	}
-
-	public void testVersionIsEqual_subclass() {
-		Comparator<String> versionComparator = new VersionComparator<Integer>() {
-				@Override
-				protected Integer parseSegment(int index, String s) {
-					return Integer.valueOf(s);
-				}
-				@Override
-				protected Integer getZero() {
-					return Integer.valueOf(0);
-				}
-			};
-		assertTrue(versionComparator.compare("2.0.0", "2.0.0") == 0);
-		assertTrue(versionComparator.compare("2.0.0", "2.0.0.0") == 0);
-		assertTrue(versionComparator.compare("2.0.0.0", "2.0") == 0);
-		assertTrue(versionComparator.compare("2.0.-1", "2.0.-1") == 0);
-	}
-
-	public void testVersionIsLess_subclass() {
-		Comparator<String> versionComparator = new VersionComparator<Integer>() {
-				@Override
-				protected Integer parseSegment(int index, String s) {
-					return Integer.valueOf(s);
-				}
-				@Override
-				protected Integer getZero() {
-					return Integer.valueOf(0);
-				}
-			};
-		assertTrue(versionComparator.compare("2.0.0", "2.0.1") < 0);
-		assertTrue(versionComparator.compare("2.5.0", "2.14") < 0);
-		assertTrue(versionComparator.compare("2.5.0", "2.5.0.0.1.0") < 0);
-		assertTrue(versionComparator.compare("2.0.-1", "2.0.0") < 0);
-		assertTrue(versionComparator.compare("2.0.-1", "2") < 0);
-	}
-
-	public void testVersionIsGreater_subclass() {
-		Comparator<String> versionComparator = new VersionComparator<Integer>() {
-				@Override
-				protected Integer parseSegment(int index, String s) {
-					return Integer.valueOf(s);
-				}
-				@Override
-				protected Integer getZero() {
-					return Integer.valueOf(0);
-				}
-			};
-		assertTrue(versionComparator.compare("2.0.2", "2.0.1") > 0);
-		assertTrue(versionComparator.compare("2.0.2", "2.0.1") > 0);
-		assertTrue(versionComparator.compare("2.5.0.0.1.0", "2.5.0") > 0);
-		assertTrue(versionComparator.compare("2.0.0", "2.0.-1") > 0);
-		assertTrue(versionComparator.compare("2", "2.0.-1") > 0);
-	}
-
-	public void testBadString() {
-		boolean exCaught = false;
-		try {
-			// note the letter 'O' instead of the numeral '0'
-			assertTrue(VersionComparator.INTEGER_VERSION_COMPARATOR.compare("2.0.0", "2.O.O") == 0);
-		} catch (NumberFormatException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testBogusSubclass1() {
-		Comparator<String> versionComparator = new VersionComparator<Integer>() {
-				// bogus - must override parseSegment(...)
-				@Override
-				protected Integer getZero() {
-					return Integer.valueOf(0);
-				}
-			};
-		boolean exCaught = false;
-		try {
-			assertTrue(versionComparator.compare("2.0.0", "2.0.0") == 0);
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testBogusSubclass2() {
-		Comparator<String> versionComparator = new VersionComparator<Integer>() {
-				@Override
-				protected Integer parseSegment(int index, String s) {
-					return Integer.valueOf(s);
-				}
-				// bogus - must getZero()
-			};
-		boolean exCaught = false;
-		try {
-			assertTrue(versionComparator.compare("2.0.0", "2.0.0.0.0") == 0);
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-
-	static final class DecimalSegmentParser
-		implements SegmentParser<BigDecimal>, Serializable
-	{
-		public static final SegmentParser<BigDecimal> INSTANCE = new DecimalSegmentParser();
-		public static SegmentParser<BigDecimal> instance() {
-			return INSTANCE;
-		}
-		// ensure single instance
-		private DecimalSegmentParser() {
-			super();
-		}
-		// simply parse the segment as an integer
-		public BigDecimal parse(int segmentIndex, String segment) {
-			return new BigDecimal(segment);
-		}
-		public BigDecimal getZero() {
-			return ZERO;
-		}
-		private static final BigDecimal ZERO = new BigDecimal(0);
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-		private static final long serialVersionUID = 1L;
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/XMLStringEncoderTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/XMLStringEncoderTests.java
deleted file mode 100644
index 7c1569b..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/XMLStringEncoderTests.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.FileTools;
-import org.eclipse.persistence.tools.utility.XMLStringEncoder;
-
-@SuppressWarnings("nls")
-public class XMLStringEncoderTests extends TestCase {
-
-	public XMLStringEncoderTests(String name) {
-		super(name);
-	}
-
-	public void testEncodeNoCharacterSequences() {
-		XMLStringEncoder encoder = new XMLStringEncoder(FileTools.INVALID_FILENAME_CHARACTERS);
-
-		String s = "foo";
-		assertEquals(s, encoder.encode(s));
-
-		s = "123foo123";
-		assertEquals(s, encoder.encode(s));
-	}
-
-	public void testEncodeCharacterSequences() {
-		XMLStringEncoder encoder = new XMLStringEncoder(FileTools.INVALID_FILENAME_CHARACTERS);
-
-		String s = "?foo?";
-		String expected = "&#x3f;foo&#x3f;";
-		assertEquals(expected, encoder.encode(s));
-
-		s = "?foo&123";
-		expected = "&#x3f;foo&#x26;123";
-		assertEquals(expected, encoder.encode(s));
-	}
-
-	public void testDenormalizeValidFileName() {
-		XMLStringEncoder encoder = new XMLStringEncoder(FileTools.INVALID_FILENAME_CHARACTERS);
-
-		String s = "foo";
-		assertEquals(s, encoder.decode(s));
-
-		s = "123foo123";
-		assertEquals(s, encoder.decode(s));
-	}
-
-	public void testDenormalizeInvalidFileName() {
-		XMLStringEncoder encoder = new XMLStringEncoder(FileTools.INVALID_FILENAME_CHARACTERS);
-
-		String s = "&#x3f;foo&#x3f;";
-		String expected = "?foo?";
-		assertEquals(expected, encoder.decode(s));
-
-		s = "&#x3f;foo&#x26;123";
-		expected = "?foo&123";
-		assertEquals(expected, encoder.decode(s));
-	}
-
-	public void testRoundTripNoCharacterSequences() {
-		this.verifyRoundTrip("foo");
-		this.verifyRoundTrip("123foo456");
-	}
-
-	public void testRoundTripCharacterSequences() {
-		this.verifyRoundTrip("?foo?");
-		this.verifyRoundTrip("?foo&123&&&&&&>>>>");
-	}
-
-	private void verifyRoundTrip(String s) {
-		XMLStringEncoder encoder = new XMLStringEncoder(FileTools.INVALID_FILENAME_CHARACTERS);
-		String actual = encoder.encode(s);
-		assertEquals(s, encoder.decode(actual));
-	}
-
-	public void testInvalidCharacterSequence1() {
-		this.verifyIllegalStateException("foo&");
-	}
-
-	public void testInvalidCharacterSequence2() {
-		this.verifyIllegalStateException("foo&#");
-	}
-
-	public void testInvalidCharacterSequence3() {
-		this.verifyIllegalStateException("foo&#x");
-	}
-
-	public void testInvalidCharacterSequence4() {
-		this.verifyIllegalStateException("foo&#x3");
-	}
-
-	public void testInvalidCharacterSequence5() {
-		this.verifyIllegalStateException("foo&#x;");
-	}
-
-	public void testInvalidCharacterSequence6() {
-		this.verifyIllegalStateException("foo&A");
-	}
-
-	public void testInvalidCharacterSequence7() {
-		this.verifyIllegalStateException("foo&#A");
-	}
-
-	private void verifyIllegalStateException(String s) {
-		XMLStringEncoder encoder = new XMLStringEncoder(FileTools.INVALID_FILENAME_CHARACTERS);
-		boolean exCaught = false;
-		try {
-			s = encoder.decode(s);
-			fail(s);
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testInvalidCharacterSequence8() {
-		String s = "foo&#xZZZZ;";
-		XMLStringEncoder encoder = new XMLStringEncoder(FileTools.INVALID_FILENAME_CHARACTERS);
-		boolean exCaught = false;
-		try {
-			s = encoder.decode(s);
-			fail(s);
-		} catch (NumberFormatException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/AsynchronousCommandExecutorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/AsynchronousCommandExecutorTests.java
deleted file mode 100644
index d7101f4..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/AsynchronousCommandExecutorTests.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.command;
-
-import org.eclipse.persistence.tools.utility.ExceptionHandler;
-import org.eclipse.persistence.tools.utility.command.AsynchronousExtendedCommandExecutor;
-import org.eclipse.persistence.tools.utility.command.Command;
-import org.eclipse.persistence.tools.utility.command.StatefulCommandExecutor;
-import org.eclipse.persistence.tools.utility.tests.internal.MultiThreadedTestCase;
-
-public class AsynchronousCommandExecutorTests
-	extends MultiThreadedTestCase
-{
-	public AsynchronousCommandExecutorTests(String name) {
-		super(name);
-	}
-
-	public void testExecution() throws Exception {
-		TestCommand command = new TestCommand();
-		AsynchronousExtendedCommandExecutor.SimpleConfig config = new AsynchronousExtendedCommandExecutor.SimpleConfig();
-		config.setThreadFactory(this.buildThreadFactory());
-		config.setExceptionHandler(ExceptionHandler.Runtime.instance());
-		StatefulCommandExecutor commandExecutor = new AsynchronousExtendedCommandExecutor(config);
-		commandExecutor.start();
-		commandExecutor.execute(command);
-		commandExecutor.execute(command);
-		commandExecutor.execute(command);
-		Thread.sleep(TWO_TICKS);  // wait for the command to execute
-		commandExecutor.stop();
-		assertEquals(3, command.count);
-	}
-
-	static class TestCommand implements Command {
-		int count = 0;
-		public void execute() {
-			this.count++;
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/AsynchronousRepeatingCommandWrapperTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/AsynchronousRepeatingCommandWrapperTests.java
deleted file mode 100644
index 4698734..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/AsynchronousRepeatingCommandWrapperTests.java
+++ /dev/null
@@ -1,457 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.command;
-
-import org.eclipse.persistence.tools.utility.CollectingExceptionHandler;
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.ConsumerThreadCoordinator;
-import org.eclipse.persistence.tools.utility.ExceptionHandler;
-import org.eclipse.persistence.tools.utility.ReflectionTools;
-import org.eclipse.persistence.tools.utility.command.AsynchronousRepeatingCommandWrapper;
-import org.eclipse.persistence.tools.utility.command.Command;
-import org.eclipse.persistence.tools.utility.command.RepeatingCommand;
-import org.eclipse.persistence.tools.utility.tests.internal.MultiThreadedTestCase;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-
-@SuppressWarnings("nls")
-public class AsynchronousRepeatingCommandWrapperTests
-	extends MultiThreadedTestCase
-{
-	PrimaryModel1 primaryModel1;
-	SecondaryModel1 secondaryModel1;
-	Command command1;
-	RepeatingCommand repeatingCommand1;
-
-	PrimaryModel2 primaryModel2;
-	SecondaryModel2 secondaryModel2;
-	Command command2;
-	RepeatingCommand repeatingCommand2;
-
-	public AsynchronousRepeatingCommandWrapperTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.primaryModel1 = new PrimaryModel1();
-		this.secondaryModel1 = new SecondaryModel1(this.primaryModel1);
-		this.command1 = new SynchronizeSecondaryModelCommand1(this.secondaryModel1);
-		this.repeatingCommand1 = new AsynchronousRepeatingCommandWrapper(this.command1, this.buildThreadFactory(), null, ExceptionHandler.Runtime.instance());
-		this.primaryModel1.setSynchronizer(this.repeatingCommand1);
-
-		this.primaryModel2 = new PrimaryModel2();
-		this.secondaryModel2 = new SecondaryModel2(this.primaryModel2);
-		this.command2 = new SynchronizeSecondaryModelCommand2(this.primaryModel2, this.secondaryModel2);
-		this.repeatingCommand2 = new AsynchronousRepeatingCommandWrapper(this.command2, this.buildThreadFactory(), null, ExceptionHandler.Runtime.instance());
-		this.primaryModel2.setSynchronizer(this.repeatingCommand2);
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		this.repeatingCommand1.stop();
-		this.repeatingCommand2.stop();
-		super.tearDown();
-	}
-
-	public void testInitialization() {
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-	}
-
-	public void testToString() {
-		assertNotNull(this.repeatingCommand1.toString());
-	}
-
-	public void testChange() throws Exception {
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-		this.primaryModel1.setCount(7);
-
-		this.sleep(TICK);
-		this.repeatingCommand1.stop();
-		this.sleep(TICK);
-
-		assertEquals(14, this.secondaryModel1.getDoubleCount());
-
-		// re-start so tear-down works
-		this.repeatingCommand1.start();
-	}
-
-	public void testStart() throws Exception {
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-		this.primaryModel1.setSynchronizer(RepeatingCommand.Null.instance());
-		this.primaryModel1.setCount(7);
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-		this.primaryModel1.setSynchronizer(this.repeatingCommand1);
-		// the async synchronizer does not synchronize at start-up
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-
-		this.primaryModel1.setCount(8);
-
-		this.sleep(TICK);
-		this.repeatingCommand1.stop();
-		this.sleep(TICK);
-
-		assertEquals(16, this.secondaryModel1.getDoubleCount());
-
-		// re-start so tear-down works
-		this.repeatingCommand1.start();
-	}
-
-	public void testStop() throws Exception {
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-		this.primaryModel1.dispose();
-		this.primaryModel1.setCount(7);
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-
-		// re-start so tear-down works
-		this.repeatingCommand1.start();
-	}
-
-	public void testDoubleStart() throws Exception {
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-		boolean exCaught = false;
-		try {
-			this.primaryModel1.startSynchronizer();
-			fail();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-		this.primaryModel1.setCount(7);
-
-		this.sleep(TICK);
-		this.repeatingCommand1.stop();
-		this.sleep(TICK);
-
-		assertEquals(14, this.secondaryModel1.getDoubleCount());
-
-		// re-start so tear-down works
-		this.repeatingCommand1.start();
-	}
-
-	public void testDoubleStop() throws Exception {
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-		this.primaryModel1.dispose();
-		boolean exCaught = false;
-		try {
-			this.primaryModel1.dispose();
-			fail();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-		this.primaryModel1.setCount(7);
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-
-		// re-start so tear-down works
-		this.repeatingCommand1.start();
-	}
-
-	public void testRecursiveChange() throws Exception {
-		assertEquals(4, this.secondaryModel2.getDoubleCount());
-		this.primaryModel2.setCount(7);
-
-		this.sleep(TICK);
-		assertEquals(10, this.primaryModel2.getCountPlus3());
-		assertEquals(14, this.secondaryModel2.getDoubleCount());
-
-		this.sleep(TICK);
-		assertEquals(20, this.secondaryModel2.getDoubleCountPlus3());
-	}
-
-	public void testNullCommand() {
-		boolean exCaught = false;
-		try {
-			RepeatingCommand s = new AsynchronousRepeatingCommandWrapper(null, this.buildThreadFactory(), null, ExceptionHandler.Runtime.instance());
-			fail("bogus: " + s);
-		} catch (NullPointerException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testThreadName() throws Exception {
-		RepeatingCommand s = new AsynchronousRepeatingCommandWrapper(this.command1, this.buildThreadFactory(), "sync", ExceptionHandler.Runtime.instance());
-		s.start();
-		ConsumerThreadCoordinator ctc = (ConsumerThreadCoordinator) ReflectionTools.getFieldValue(s, "consumerThreadCoordinator");
-		Thread t = (Thread) ReflectionTools.getFieldValue(ctc, "thread");
-		assertEquals("sync", t.getName());
-		s.stop();
-	}
-
-	public void testExecuteCalledBeforeStart() throws Exception {
-		SimpleCommand command = new SimpleCommand();
-		RepeatingCommand synchronizer = new AsynchronousRepeatingCommandWrapper(command, this.buildThreadFactory(), null, ExceptionHandler.Runtime.instance());
-
-		synchronizer.execute();
-		synchronizer.start();
-		this.sleep(TICK);
-		synchronizer.stop();
-		assertEquals(1, command.count);
-	}
-
-	public class SimpleCommand implements Command {
-		int count = 0;
-		public void execute() {
-			this.count++;
-		}
-	}
-
-	public void testException() throws Exception {
-		BogusCommand command = new BogusCommand();
-		CollectingExceptionHandler exHandler = new CollectingExceptionHandler();
-		RepeatingCommand synchronizer = new AsynchronousRepeatingCommandWrapper(command, this.buildThreadFactory(), null, exHandler);
-		synchronizer.start();
-
-		synchronizer.execute();
-		this.sleep(TICK);
-
-		synchronizer.execute();
-		this.sleep(TICK);
-
-		synchronizer.stop();
-		assertEquals(2, CollectionTools.size(exHandler.getExceptions()));
-		assertEquals(2, command.count);
-	}
-
-	public class BogusCommand implements Command {
-		int count = 0;
-		public void execute() {
-			this.count++;
-			throw new NullPointerException();
-		}
-	}
-
-	/**
-	 * Make sure the <code>DEBUG</code> constant is <code>false</code>
-	 * before checking in the code.
-	 */
-	public void testDEBUG() {
-		TestTools.assertFalseDEBUG(AsynchronousRepeatingCommandWrapper.class);
-	}
-
-
-	// ********** synchronize commands **********
-
-	public static class SynchronizeSecondaryModelCommand1
-		implements Command
-	{
-		private final SecondaryModel1 secondaryModel;
-
-		public SynchronizeSecondaryModelCommand1(SecondaryModel1 secondaryModel) {
-			super();
-			this.secondaryModel = secondaryModel;
-		}
-
-		public void execute() {
-			this.secondaryModel.synchronize();
-		}
-	}
-
-	/**
-	 * the primary model (subclass) has to synchronize with itself (superclass)
-	 */
-	public static class SynchronizeSecondaryModelCommand2
-		extends SynchronizeSecondaryModelCommand1
-	{
-		private final PrimaryModel2 primaryModel;
-
-		public SynchronizeSecondaryModelCommand2(PrimaryModel2 primaryModel, SecondaryModel2 secondaryModel) {
-			super(secondaryModel);
-			this.primaryModel = primaryModel;
-		}
-
-		@Override
-		public void execute() {
-			super.execute();
-			this.primaryModel.synchronize();
-		}
-	}
-
-
-	// ********** primary models **********
-
-	/**
-	 * this object will call the synchronizer whenever its count changes,
-	 * allowing interested parties to synchronize with the change
-	 */
-	public static class PrimaryModel1 {
-		protected RepeatingCommand synchronizer;
-		protected int count = 2;
-
-		public PrimaryModel1() {
-			super();
-			this.setSynchronizer_(RepeatingCommand.Null.instance());
-		}
-
-		public int getCount() {
-			return this.count;
-		}
-		public void setCount(int count) {
-			if (count != this.count) {
-				this.count = count;
-				this.stateChanged();
-			}
-		}
-
-		protected void stateChanged() {
-			this.synchronizer.execute();
-		}
-
-		public void setSynchronizer(RepeatingCommand synchronizer) throws InterruptedException {
-			if (synchronizer == null) {
-				throw new NullPointerException();
-			}
-			this.synchronizer.stop();
-			this.setSynchronizer_(synchronizer);
-		}
-			
-		protected void setSynchronizer_(RepeatingCommand synchronizer) {
-			this.synchronizer = synchronizer;
-			this.synchronizer.start();
-		}
-
-		public void startSynchronizer() {
-			this.synchronizer.start();  // this should cause an exception
-		}
-		public void dispose() throws InterruptedException {
-			this.synchronizer.stop();
-		}
-
-		@Override
-		public String toString() {
-			StringBuilder sb = new StringBuilder();
-			sb.append(this.getClass().getSimpleName());
-			sb.append('(');
-			this.toString(sb);
-			sb.append(')');
-			return sb.toString();
-		}
-		public void toString(StringBuilder sb) {
-			sb.append("count=");
-			sb.append(this.count);
-		}
-	}
-
-	/**
-	 * This model synchronizes with itself, triggering a recursive synchronization
-	 * with the change. Whenever the [inherited] 'count' changes, 'countPlus3'
-	 * is updated appropriately and another synchronize is initiated if appropriate.
-	 */
-	public static class PrimaryModel2
-		extends PrimaryModel1
-	{
-		private int countPlus3 = 0;
-
-		public PrimaryModel2() {
-			super();
-			this.countPlus3 = this.count + 3;
-		}
-
-		public int getCountPlus3() {
-			return this.countPlus3;
-		}
-		protected void setCountPlus3(int countPlus3) {
-			if (countPlus3 != this.countPlus3) {
-				this.countPlus3 = countPlus3;
-				this.stateChanged();
-			}
-		}
-
-		// synchronize with itself, so to speak
-		public void synchronize() {
-			this.setCountPlus3(this.count + 3);
-		}
-
-		@Override
-		public void toString(StringBuilder sb) {
-			super.toString(sb);
-			sb.append(", countPlus3=");
-			sb.append(this.countPlus3);
-		}
-	}
-
-
-	// ********** secondary models **********
-
-	/**
-	 * This dependent object updates its 'doubleCount' whenever the
-	 * PrimaryModel1's 'count' changes, via the 'synchronizer'.
-	 */
-	public static class SecondaryModel1 {
-		protected final PrimaryModel1 primaryModel;
-		protected int doubleCount = 0;
-
-		public SecondaryModel1(PrimaryModel1 primaryModel) {
-			super();
-			this.primaryModel = primaryModel;
-			this.synchronize();
-		}
-
-		public void synchronize() {
-			this.doubleCount = this.primaryModel.getCount() * 2;
-		}
-
-		public int getDoubleCount() {
-			return this.doubleCount;
-		}
-
-		@Override
-		public String toString() {
-			StringBuilder sb = new StringBuilder();
-			sb.append(this.getClass().getSimpleName());
-			sb.append('(');
-			this.toString(sb);
-			sb.append(')');
-			return sb.toString();
-		}
-		public void toString(StringBuilder sb) {
-			sb.append("doubleCount=");
-			sb.append(this.doubleCount);
-		}
-	}
-
-	public static class SecondaryModel2
-		extends SecondaryModel1
-	{
-		private int doubleCountPlus3 = 0;
-
-		public SecondaryModel2(PrimaryModel2 extendedPrimaryModel) {
-			super(extendedPrimaryModel);
-		}
-
-		protected PrimaryModel2 getExtendedPrimaryModel() {
-			return (PrimaryModel2) this.primaryModel;
-		}
-
-		@Override
-		public void synchronize() {
-			super.synchronize();
-			int temp = this.getExtendedPrimaryModel().getCountPlus3() * 2;
-			if (this.doubleCountPlus3 != temp) {
-				this.doubleCountPlus3 = temp;
-			}
-		}
-
-		public int getDoubleCountPlus3() {
-			return this.doubleCountPlus3;
-		}
-
-		@Override
-		public void toString(StringBuilder sb) {
-			super.toString(sb);
-			sb.append(", doubleCountPlus3=");
-			sb.append(this.doubleCountPlus3);
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/CommandExecutorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/CommandExecutorTests.java
deleted file mode 100644
index 75a6e80..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/CommandExecutorTests.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.command;
-
-import org.eclipse.persistence.tools.utility.command.Command;
-import org.eclipse.persistence.tools.utility.command.CommandExecutor;
-import org.eclipse.persistence.tools.utility.command.ExtendedCommandExecutor;
-import org.eclipse.persistence.tools.utility.command.ThreadLocalExtendedCommandExecutor;
-import org.eclipse.persistence.tools.utility.tests.internal.MultiThreadedTestCase;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-
-public class CommandExecutorTests
-	extends MultiThreadedTestCase
-{
-
-	public CommandExecutorTests(String name) {
-		super(name);
-	}
-
-	public void testDefaultCommandExecutor_toString() throws Exception {
-		CommandExecutor commandExecutor = CommandExecutor.Default.instance();
-		assertNotNull(commandExecutor.toString());
-	}
-
-	public void testDefaultCommandExecutor_serialization() throws Exception {
-		CommandExecutor commandExecutor1 = CommandExecutor.Default.instance();
-		CommandExecutor commandExecutor2 = TestTools.serialize(commandExecutor1);
-		assertSame(commandExecutor1, commandExecutor2);
-	}
-
-	public void testDefaultCommandExecutor() {
-		TestCommand testCommand = new TestCommand();
-		assertEquals(0, testCommand.count);
-		CommandExecutor commandExecutor = CommandExecutor.Default.instance();
-		commandExecutor.execute(testCommand);
-		assertEquals(1, testCommand.count);
-	}
-
-	static class TestCommand implements Command {
-		int count = 0;
-		public void execute() {
-			this.count++;
-		}
-	}
-
-	public void testThreadLocalCommandExecutor_toString() throws Exception {
-		CommandExecutor commandExecutor = new ThreadLocalExtendedCommandExecutor();
-		assertNotNull(commandExecutor.toString());
-	}
-
-	public void testThreadLocalCommandExecutor() throws Exception {
-		ThreadLocalExtendedCommandExecutor threadLocalCommandExecutor = new ThreadLocalExtendedCommandExecutor();
-		TestRunnable testRunnable1 = new TestRunnable(threadLocalCommandExecutor, 1);
-		Thread thread1 = this.buildThread(testRunnable1);
-		thread1.run();
-
-		TestRunnable testRunnable2 = new TestRunnable(threadLocalCommandExecutor, 2);
-		Thread thread2 = this.buildThread(testRunnable2);
-		thread2.run();
-
-		TestRunnable testRunnable3 = new TestRunnable(threadLocalCommandExecutor, 3, null);
-		Thread thread3 = this.buildThread(testRunnable3);
-		thread3.run();
-
-		thread1.join();
-		thread2.join();
-		thread3.join();
-
-		assertEquals(1, testRunnable1.testCommand.count);
-		assertEquals(1, testRunnable1.testCommandExecutor.count);
-
-		assertEquals(2, testRunnable2.testCommand.count);
-		assertEquals(2, testRunnable2.testCommandExecutor.count);
-
-		assertEquals(3, testRunnable3.testCommand.count);
-		assertNull(testRunnable3.testCommandExecutor);
-	}
-
-	static class TestCommandExecutor implements ExtendedCommandExecutor {
-		int count = 0;
-		public void execute(Command command) {
-			this.count++;
-			command.execute();
-		}
-		public void waitToExecute(Command command) {
-			this.execute(command);
-		}
-		public boolean waitToExecute(Command command, long timeout) {
-			this.execute(command);
-			return true;
-		}
-	}
-
-	static class TestRunnable implements Runnable {
-		final ThreadLocalExtendedCommandExecutor threadLocalCommandExecutor;
-		final int executionCount;
-		final TestCommand testCommand = new TestCommand();
-		final TestCommandExecutor testCommandExecutor;
-		TestRunnable(ThreadLocalExtendedCommandExecutor threadLocalCommandExecutor, int executionCount) {
-			this(threadLocalCommandExecutor, executionCount, new TestCommandExecutor());
-		}
-		TestRunnable(ThreadLocalExtendedCommandExecutor threadLocalCommandExecutor, int executionCount, TestCommandExecutor testCommandExecutor) {
-			super();
-			this.threadLocalCommandExecutor = threadLocalCommandExecutor;
-			this.executionCount = executionCount;
-			this.testCommandExecutor = testCommandExecutor;
-		}
-		public void run() {
-			this.threadLocalCommandExecutor.set(this.testCommandExecutor);
-			for (int i = 0; i < this.executionCount; i++) {
-				this.threadLocalCommandExecutor.execute(this.testCommand);
-			}
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/CommandRunnableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/CommandRunnableTests.java
deleted file mode 100644
index 793d57d..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/CommandRunnableTests.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.command;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.command.Command;
-import org.eclipse.persistence.tools.utility.command.CommandRunnable;
-
-@SuppressWarnings("nls")
-public class CommandRunnableTests extends TestCase {
-	boolean commandExecuted = false;
-
-	public CommandRunnableTests(String name) {
-		super(name);
-	}
-
-	public void testNullCommand() {
-		boolean exCaught = false;
-		try {
-			Runnable runnable = new CommandRunnable(null);
-			fail("bogus: " + runnable);
-		} catch (NullPointerException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testRun() {
-		Runnable runnable = new CommandRunnable(this.buildCommand());
-		runnable.run();
-		assertTrue(this.commandExecuted);
-	}
-
-	public void testToString() {
-		Runnable runnable = new CommandRunnable(this.buildCommand());
-		assertNotNull(runnable.toString());
-	}
-
-	private Command buildCommand() {
-		return new Command() {
-			public void execute() {
-				CommandRunnableTests.this.commandExecuted = true;
-			}
-		};
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/CommandTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/CommandTests.java
deleted file mode 100644
index d62ed2d..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/CommandTests.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.command;
-
-import org.eclipse.persistence.tools.utility.command.Command;
-import org.eclipse.persistence.tools.utility.command.CommandExecutor;
-import org.eclipse.persistence.tools.utility.command.CommandRunnable;
-import org.eclipse.persistence.tools.utility.command.RunnableCommand;
-import org.eclipse.persistence.tools.utility.command.ThreadLocalCommand;
-import org.eclipse.persistence.tools.utility.tests.internal.MultiThreadedTestCase;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-
-public class CommandTests
-	extends MultiThreadedTestCase
-{
-	public CommandTests(String name) {
-		super(name);
-	}
-
-	public void testNullCommand() {
-		Command command = Command.Null.instance();
-		command.execute();  // just make sure it doesn't blow up?
-	}
-
-	public void testNullCommand_toString() {
-		Command command = Command.Null.instance();
-		assertNotNull(command.toString());
-	}
-
-	public void testNullCommand_serialization() throws Exception {
-		Command command1 = Command.Null.instance();
-		Command command2 = TestTools.serialize(command1);
-		assertSame(command1, command2);
-	}
-
-	public void testDisabledCommand() {
-		Command command = Command.Disabled.instance();
-		boolean exCaught = false;
-		try {
-			command.execute();
-			fail();
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testDisabledCommand_toString() {
-		Command command = Command.Disabled.instance();
-		assertNotNull(command.toString());
-	}
-
-	public void testDisabledCommand_serialization() throws Exception {
-		Command command1 = Command.Disabled.instance();
-		Command command2 = TestTools.serialize(command1);
-		assertSame(command1, command2);
-	}
-
-	public void testRunnableCommand() {
-		SimpleTestRunnable testRunnable = new SimpleTestRunnable();
-		assertFalse(testRunnable.ran);
-		Command command = new RunnableCommand(testRunnable);
-		command.execute();
-		assertTrue(testRunnable.ran);
-	}
-
-	static class SimpleTestRunnable implements Runnable {
-		boolean ran = false;
-		public void run() {
-			this.ran = true;
-		}
-	}
-
-	public void testCommandRunnable() {
-		TestCommand testCommand = new TestCommand();
-		assertEquals(0, testCommand.count);
-		Runnable runnable = new CommandRunnable(testCommand);
-		runnable.run();
-		assertEquals(1, testCommand.count);
-	}
-
-	static class TestCommand implements Command {
-		int count = 0;
-		public void execute() {
-			this.count++;
-		}
-	}
-
-	public void testThreadLocalCommand() throws Exception {
-		ThreadLocalCommand threadLocalCommand = new ThreadLocalCommand();
-		TestRunnable testRunnable1 = new TestRunnable(threadLocalCommand, 1);
-		Thread thread1 = this.buildThread(testRunnable1);
-		thread1.run();
-
-		TestRunnable testRunnable2 = new TestRunnable(threadLocalCommand, 2);
-		Thread thread2 = this.buildThread(testRunnable2);
-		thread2.run();
-
-		thread1.join();
-		thread2.join();
-
-		assertEquals(1, testRunnable1.testCommand.count);
-
-		assertEquals(2, testRunnable2.testCommand.count);
-	}
-
-	static class TestCommandExecutor implements CommandExecutor {
-		int count = 0;
-		public void execute(Command command) {
-			this.count++;
-			command.execute();
-		}
-	}
-
-	static class TestRunnable implements Runnable {
-		final ThreadLocalCommand threadLocalCommand;
-		final int executionCount;
-		final TestCommand testCommand = new TestCommand();
-		TestRunnable(ThreadLocalCommand threadLocalCommand, int executionCount) {
-			super();
-			this.threadLocalCommand = threadLocalCommand;
-			this.executionCount = executionCount;
-		}
-		public void run() {
-			this.threadLocalCommand.set(this.testCommand);
-			for (int i = 0; i < this.executionCount; i++) {
-				this.threadLocalCommand.execute();
-			}
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/CompositeCommandTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/CompositeCommandTests.java
deleted file mode 100644
index 839524b..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/CompositeCommandTests.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.command;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.command.Command;
-import org.eclipse.persistence.tools.utility.command.CommandRunnable;
-import org.eclipse.persistence.tools.utility.command.CompositeCommand;
-
-public class CompositeCommandTests extends TestCase {
-	boolean command1Executed = false;
-	boolean command2Executed = false;
-
-	public CompositeCommandTests(String name) {
-		super(name);
-	}
-
-	public void testRun() {
-		Runnable runnable = new CommandRunnable(this.buildCompositeCommand());
-		runnable.run();
-		assertTrue(this.command1Executed);
-		assertTrue(this.command2Executed);
-	}
-
-	public void testToString() {
-		Runnable runnable = new CommandRunnable(this.buildCompositeCommand());
-		assertNotNull(runnable.toString());
-	}
-
-	private Command buildCompositeCommand() {
-		return new CompositeCommand(
-					this.buildCommand1(),
-					this.buildCommand2()
-				);
-	}
-
-	private Command buildCommand1() {
-		return new Command() {
-			public void execute() {
-				CompositeCommandTests.this.command1Executed = true;
-			}
-		};
-	}
-
-	private Command buildCommand2() {
-		return new Command() {
-			public void execute() {
-				CompositeCommandTests.this.command2Executed = true;
-			}
-		};
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/UtilityCommandTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/UtilityCommandTests.java
deleted file mode 100644
index 99917a0..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/command/UtilityCommandTests.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.command;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * decentralize test creation code
- */
-public class UtilityCommandTests {
-
-	public static Test suite() {
-		TestSuite suite = new TestSuite(UtilityCommandTests.class.getPackage().getName());
-
-		suite.addTestSuite(AsynchronousCommandExecutorTests.class);
-		suite.addTestSuite(AsynchronousRepeatingCommandWrapperTests.class);
-		suite.addTestSuite(CommandExecutorTests.class);
-		suite.addTestSuite(CommandRunnableTests.class);
-		suite.addTestSuite(CommandTests.class);
-		suite.addTestSuite(CompositeCommandTests.class);
-
-		return suite;
-	}
-
-	private UtilityCommandTests() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/enumerations/EmptyEnumerationTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/enumerations/EmptyEnumerationTests.java
deleted file mode 100644
index 5364e9b..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/enumerations/EmptyEnumerationTests.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.enumerations;
-
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.enumerations.EmptyEnumeration;
-
-@SuppressWarnings("nls")
-public class EmptyEnumerationTests extends TestCase {
-
-	public EmptyEnumerationTests(String name) {
-		super(name);
-	}
-
-	public void testHasMoreElements() {
-		int i = 0;
-		for (Enumeration<Object> stream = EmptyEnumeration.instance(); stream.hasMoreElements();) {
-			stream.nextElement();
-			i++;
-		}
-		assertEquals(0, i);
-	}
-
-	public void testNextElement() {
-		for (Enumeration<Object> stream = EmptyEnumeration.instance(); stream.hasMoreElements();) {
-			fail("bogus element: " + stream.nextElement());
-		}
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		Enumeration<Object> stream = EmptyEnumeration.instance();
-		Object element = null;
-		while (stream.hasMoreElements()) {
-			element = stream.nextElement();
-		}
-		try {
-			element = stream.nextElement();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + element, exCaught);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/enumerations/IteratorEnumerationTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/enumerations/IteratorEnumerationTests.java
deleted file mode 100644
index f3c5297..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/enumerations/IteratorEnumerationTests.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.enumerations;
-
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import java.util.Vector;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.enumerations.IteratorEnumeration;
-
-@SuppressWarnings("nls")
-public class IteratorEnumerationTests extends TestCase {
-
-	public IteratorEnumerationTests(String name) {
-		super(name);
-	}
-
-	public void testHasMoreElements() {
-		int i = 0;
-		for (Enumeration<String> stream = this.buildEnumeration(); stream.hasMoreElements();) {
-			stream.nextElement();
-			i++;
-		}
-		assertEquals(this.buildVector().size(), i);
-	}
-
-	public void testHasMoreElementsUpcast() {
-		int i = 0;
-		for (Enumeration<Object> stream = this.buildEnumerationUpcast(); stream.hasMoreElements();) {
-			stream.nextElement();
-			i++;
-		}
-		assertEquals(this.buildVector().size(), i);
-	}
-
-	public void testNextElement() {
-		Iterator<String> iterator = this.buildIterator();
-		for (Enumeration<String> stream = this.buildEnumeration(); stream.hasMoreElements();) {
-			assertEquals("bogus element", iterator.next(), stream.nextElement());
-		}
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		Enumeration<String> stream = this.buildEnumeration();
-		String string = null;
-		while (stream.hasMoreElements()) {
-			string = stream.nextElement();
-		}
-		try {
-			string = stream.nextElement();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
-	}
-
-	private Enumeration<String> buildEnumeration() {
-		return this.buildEnumeration(this.buildIterator());
-	}
-
-	private Enumeration<Object> buildEnumerationUpcast() {
-		return this.buildEnumerationUpcast(this.buildIterator());
-	}
-
-	private Enumeration<String> buildEnumeration(Iterator<String> iterator) {
-		return new IteratorEnumeration<String>(iterator);
-	}
-
-	private Enumeration<Object> buildEnumerationUpcast(Iterator<String> iterator) {
-		return new IteratorEnumeration<Object>(iterator);
-	}
-
-	private Iterator<String> buildIterator() {
-		return this.buildVector().iterator();
-	}
-
-	private Vector<String> buildVector() {
-		Vector<String> v = new Vector<String>();
-		v.addElement("one");
-		v.addElement("two");
-		v.addElement("three");
-		v.addElement("four");
-		v.addElement("five");
-		v.addElement("six");
-		v.addElement("seven");
-		v.addElement("eight");
-		return v;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/enumerations/UtilityEnumerationsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/enumerations/UtilityEnumerationsTests.java
deleted file mode 100644
index b140bcd..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/enumerations/UtilityEnumerationsTests.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.enumerations;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * decentralize test creation code
- */
-public class UtilityEnumerationsTests {
-
-	public static Test suite() {
-		TestSuite suite = new TestSuite(UtilityEnumerationsTests.class.getPackage().getName());
-
-		suite.addTestSuite(EmptyEnumerationTests.class);
-		suite.addTestSuite(IteratorEnumerationTests.class);
-
-		return suite;
-	}
-
-	private UtilityEnumerationsTests() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ArrayIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ArrayIterableTests.java
deleted file mode 100644
index 8ad2527..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ArrayIterableTests.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
-
-@SuppressWarnings("nls")
-public class ArrayIterableTests extends TestCase {
-
-	public ArrayIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		int i = 1;
-		for (String string : this.buildIterable()) {
-			assertEquals(i++, Integer.parseInt(string));
-		}
-	}
-
-	public void testSubIterator() {
-		int i = 3;
-		for (String string : this.buildIterable(2)) {
-			assertEquals(i++, Integer.parseInt(string));
-		}
-	}
-
-	public void testIllegalArgumentException() {
-		this.triggerIllegalArgumentException(-1, 1);
-		this.triggerIllegalArgumentException(8, 1);
-		this.triggerIllegalArgumentException(0, -1);
-		this.triggerIllegalArgumentException(0, 9);
-	}
-
-	private void triggerIllegalArgumentException(int start, int length) {
-		boolean exCaught = false;
-		try {
-			Iterable<String> iterable = this.buildIterable(start, length);
-			fail("bogus iterable: " + iterable);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	private Iterable<String> buildIterable() {
-		return this.buildIterable(0);
-	}
-
-	private Iterable<String> buildIterable(int start) {
-		return this.buildIterable(this.buildArray(), start);
-	}
-
-	private Iterable<String> buildIterable(String[] array, int start) {
-		return new ArrayIterable<String>(array, start);
-	}
-
-	private Iterable<String> buildIterable(int start, int length) {
-		return this.buildIterable(this.buildArray(), start, length);
-	}
-
-	private Iterable<String> buildIterable(String[] array, int start, int length) {
-		return new ArrayIterable<String>(array, start, length);
-	}
-
-	private String[] buildArray() {
-		return new String[] { "1", "2", "3", "4", "5", "6", "7", "8" };
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ArrayListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ArrayListIterableTests.java
deleted file mode 100644
index 05054cb..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ArrayListIterableTests.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.ListIterator;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterables.ArrayListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-
-@SuppressWarnings("nls")
-public class ArrayListIterableTests extends TestCase {
-
-	public ArrayListIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		int i = 1;
-		ListIterable<String> iterable = this.buildIterable();
-		for (String string : iterable) {
-			assertEquals(i++, Integer.parseInt(string));
-		}
-		ListIterator<String> stream = iterable.iterator();
-		while (stream.hasNext()) {
-			stream.next();
-		}
-		while (stream.hasPrevious()) {
-			assertEquals(--i, Integer.parseInt(stream.previous()));
-		}
-	}
-
-	public void testSubIterator() {
-		int i = 3;
-		for (String string : this.buildIterable(2)) {
-			assertEquals(i++, Integer.parseInt(string));
-		}
-	}
-
-	public void testIllegalArgumentException() {
-		this.triggerIllegalArgumentException(-1, 1);
-		this.triggerIllegalArgumentException(8, 1);
-		this.triggerIllegalArgumentException(0, -1);
-		this.triggerIllegalArgumentException(0, 9);
-	}
-
-	private void triggerIllegalArgumentException(int start, int length) {
-		boolean exCaught = false;
-		try {
-			Iterable<String> iterable = this.buildIterable(start, length);
-			fail("bogus iterable: " + iterable);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	private ListIterable<String> buildIterable() {
-		return this.buildIterable(0);
-	}
-
-	private ListIterable<String> buildIterable(int start) {
-		return this.buildIterable(this.buildArray(), start);
-	}
-
-	private ListIterable<String> buildIterable(String[] array, int start) {
-		return (start == 0) ?
-				new ArrayListIterable<String>(array) :
-				new ArrayListIterable<String>(array, start);
-	}
-
-	private ListIterable<String> buildIterable(int start, int length) {
-		return this.buildIterable(this.buildArray(), start, length);
-	}
-
-	private ListIterable<String> buildIterable(String[] array, int start, int length) {
-		return new ArrayListIterable<String>(array, start, length);
-	}
-
-	private String[] buildArray() {
-		return new String[] { "1", "2", "3", "4", "5", "6", "7", "8" };
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ChainIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ChainIterableTests.java
deleted file mode 100644
index 097fd84..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ChainIterableTests.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.AbstractCollection;
-import java.util.AbstractList;
-import java.util.Iterator;
-import java.util.Vector;
-import junit.framework.TestCase;
-import org.eclipse.persistence.tools.utility.iterables.ChainIterable;
-import org.eclipse.persistence.tools.utility.iterators.ChainIterator;
-
-@SuppressWarnings("nls")
-public class ChainIterableTests extends TestCase {
-	private final static Class<?>[] VECTOR_HIERARCHY = { Vector.class, AbstractList.class, AbstractCollection.class, Object.class };
-
-	public ChainIterableTests(String name) {
-		super(name);
-	}
-
-
-	public void testNextLink() {
-		int i = 0;
-		for (Class<?> clazz : this.buildIterable()) {
-			assertEquals(VECTOR_HIERARCHY[i++], clazz);
-		}
-	}
-
-	public void testLinker() {
-		int i = 0;
-		for (Class<?> clazz : new ChainIterable<Class<?>>(Vector.class, this.buildLinker())) {
-			assertEquals(VECTOR_HIERARCHY[i++], clazz);
-		}
-	}
-
-	public void testException() {
-		Iterable<Class<?>> iterable = new ChainIterable<Class<?>>(Vector.class);
-		Iterator<Class<?>> iterator = iterable.iterator();
-		boolean exCaught = false;
-		try {
-			Class<?> clazz = iterator.next();
-			fail("bogus class: " + clazz);
-		} catch (RuntimeException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testToString() {
-		assertNotNull(this.buildIterable().toString());
-	}
-
-	private Iterable<Class<?>> buildIterable() {
-		return this.buildChainIterable(Vector.class);
-	}
-
-	private Iterable<Class<?>> buildChainIterable(Class<?> startLink) {
-		// chain up the class's hierarchy
-		return new ChainIterable<Class<?>>(startLink) {
-			@Override
-			protected Class<?> nextLink(Class<?> currentLink) {
-				return currentLink.getSuperclass();
-			}
-		};
-	}
-
-	private ChainIterator.Linker<Class<?>> buildLinker() {
-		return new ChainIterator.Linker<Class<?>>() {
-			public Class<?> nextLink(Class<?> currentLink) {
-				return currentLink.getSuperclass();
-			}
-		};
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/CloneIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/CloneIterableTests.java
deleted file mode 100644
index 848d3a1..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/CloneIterableTests.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.iterators.CloneListIterator;
-
-@SuppressWarnings("nls")
-public abstract class CloneIterableTests extends TestCase {
-	Iterable<String> iterable;
-
-	public CloneIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		List<String> c = new ArrayList<String>();
-		c.add("0");
-		c.add("1");
-		c.add("2");
-		c.add("3");
-		assertEquals(4, c.size());
-		this.iterable = this.buildIterable(c);
-		int i = 0;
-		for (String s : this.iterable) {
-			assertEquals(String.valueOf(i++), s);
-			c.remove("3");
-		}
-		assertEquals(4, i);
-		assertEquals(3, c.size());
-	}
-
-	public void testRemove() {
-		final List<String> collection = this.buildCollection();
-		this.iterable = this.buildRemovingIterable(collection);
-
-		Object removed = "three";
-		assertTrue(CollectionTools.contains(this.iterable, removed));
-		for (Iterator<String> iterator = this.iterable.iterator(); iterator.hasNext(); ) {
-			if (iterator.next().equals(removed)) {
-				iterator.remove();
-			}
-		}
-		assertFalse(collection.contains(removed));
-	}
-
-	public void testRemover() {
-		final List<String> collection = this.buildCollection();
-		this.iterable = this.buildIterableWithRemover(collection);
-
-		Object removed = "three";
-		assertTrue(CollectionTools.contains(this.iterable, removed));
-		for (Iterator<String> iterator = this.iterable.iterator(); iterator.hasNext(); ) {
-			if (iterator.next().equals(removed)) {
-				iterator.remove();
-			}
-		}
-		assertFalse(collection.contains(removed));
-	}
-
-	public void testMissingRemover() {
-		final List<String> collection = this.buildCollection();
-		this.iterable = this.buildIterable(collection);
-		assertNotNull(this.iterable.toString());
-
-		Object removed = "three";
-		assertTrue(CollectionTools.contains(this.iterable, removed));
-		boolean exCaught = false;
-		for (Iterator<String> iterator = this.iterable.iterator(); iterator.hasNext(); ) {
-			if (iterator.next().equals(removed)) {
-				try {
-					iterator.remove();
-					fail();
-				} catch (RuntimeException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testToString() {
-		final List<String> collection = this.buildCollection();
-		this.iterable = this.buildIterable(collection);
-		assertNotNull(iterable.toString());
-	}
-
-	abstract Iterable<String> buildIterable(List<String> c);
-
-	abstract Iterable<String> buildRemovingIterable(List<String> c);
-
-	abstract Iterable<String> buildIterableWithRemover(List<String> c);
-
-	CloneIterator.Remover<String> buildRemover(final Collection<String> c) {
-		return new CloneIterator.Remover<String>() {
-			public void remove(String current) {
-				c.remove(current);
-			}
-		};
-	}
-
-	CloneListIterator.Mutator<String> buildMutator(final List<String> list) {
-		return new CloneListIterator.Mutator<String>() {
-			public void add(int index, String string) {
-				list.add(index, string);
-			}
-			public void set(int index, String string) {
-				list.set(index, string);
-			}
-			public void remove(int index) {
-				list.remove(index);
-			}
-		};
-	}
-
-	List<String> buildCollection() {
-		List<String> c = new ArrayList<String>();
-		c.add("one");
-		c.add("two");
-		c.add("three");
-		c.add("four");
-		c.add("five");
-		c.add("six");
-		c.add("seven");
-		c.add("eight");
-		return c;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/CompositeIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/CompositeIterableTests.java
deleted file mode 100644
index 0232750..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/CompositeIterableTests.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterables.CompositeIterable;
-
-@SuppressWarnings("nls")
-public class CompositeIterableTests extends TestCase {
-
-	public CompositeIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		Collection<String> c1 = new ArrayList<String>();
-		c1.add("0");
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-
-		Collection<String> c2 = new ArrayList<String>();
-		c2.add("4");
-		c2.add("5");
-		c2.add("6");
-		c2.add("7");
-
-		@SuppressWarnings("unchecked")
-		Iterable<String> composite = new CompositeIterable<String>(c1, c2);
-		int i = 0;
-		for (String s : composite) {
-			assertEquals(String.valueOf(i++), s);
-		}
-	}
-
-	public void testExtraElement1() {
-		Collection<String> c1 = new ArrayList<String>();
-		c1.add("0");
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-
-		Iterable<String> composite = new CompositeIterable<String>(c1, "4");
-		int i = 0;
-		for (String s : composite) {
-			assertEquals(String.valueOf(i++), s);
-		}
-	}
-
-	public void testExtraElement2() {
-		Collection<String> c1 = new ArrayList<String>();
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-
-		Iterable<String> composite = new CompositeIterable<String>("0", c1);
-		int i = 0;
-		for (String s : composite) {
-			assertEquals(String.valueOf(i++), s);
-		}
-	}
-
-	public void testCollectionOfIterables() {
-		Collection<String> c1 = new ArrayList<String>();
-		c1.add("0");
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-
-		Collection<String> c2 = new ArrayList<String>();
-		c2.add("4");
-		c2.add("5");
-		c2.add("6");
-		c2.add("7");
-
-		Collection<Iterable<String>> collection = new ArrayList<Iterable<String>>();
-		collection.add(c1);
-		collection.add(c2);
-		Iterable<String> composite = new CompositeIterable<String>(collection);
-		int i = 0;
-		for (String s : composite) {
-			assertEquals(String.valueOf(i++), s);
-		}
-	}
-
-	public void testToString() {
-		Collection<String> c1 = new ArrayList<String>();
-		c1.add("0");
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-
-		Collection<String> c2 = new ArrayList<String>();
-		c2.add("4");
-		c2.add("5");
-		c2.add("6");
-		c2.add("7");
-
-		@SuppressWarnings("unchecked")
-		Iterable<String> composite = new CompositeIterable<String>(c1, c2);
-		assertNotNull(composite.toString());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/CompositeListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/CompositeListIterableTests.java
deleted file mode 100644
index 18c62ab..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/CompositeListIterableTests.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.ArrayList;
-import java.util.List;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterables.CompositeListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
-
-@SuppressWarnings("nls")
-public class CompositeListIterableTests extends TestCase {
-
-	public CompositeListIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		List<String> c1 = new ArrayList<String>();
-		c1.add("0");
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-
-		List<String> c2 = new ArrayList<String>();
-		c2.add("4");
-		c2.add("5");
-		c2.add("6");
-		c2.add("7");
-
-		@SuppressWarnings("unchecked")
-		Iterable<String> composite = new CompositeListIterable<String>(c1, c2);
-		int i = 0;
-		for (String s : composite) {
-			assertEquals(String.valueOf(i++), s);
-		}
-	}
-
-	public void testExtraElement1() {
-		List<String> c1 = new ArrayList<String>();
-		c1.add("0");
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-
-		Iterable<String> composite = new CompositeListIterable<String>(c1, "4");
-		int i = 0;
-		for (String s : composite) {
-			assertEquals(String.valueOf(i++), s);
-		}
-	}
-
-	public void testExtraElement2() {
-		List<String> c1 = new ArrayList<String>();
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-
-		Iterable<String> composite = new CompositeListIterable<String>("0", c1);
-		int i = 0;
-		for (String s : composite) {
-			assertEquals(String.valueOf(i++), s);
-		}
-	}
-
-	public void testCollectionOfIterables() {
-		List<String> c1 = new ArrayList<String>();
-		c1.add("0");
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-
-		List<String> c2 = new ArrayList<String>();
-		c2.add("4");
-		c2.add("5");
-		c2.add("6");
-		c2.add("7");
-
-		List<ListIterable<String>> collection = new ArrayList<ListIterable<String>>();
-		collection.add(new ListListIterable<String>(c1));
-		collection.add(new ListListIterable<String>(c2));
-		Iterable<String> composite = new CompositeListIterable<String>(collection);
-		int i = 0;
-		for (String s : composite) {
-			assertEquals(String.valueOf(i++), s);
-		}
-	}
-
-	public void testToString() {
-		List<String> c1 = new ArrayList<String>();
-		c1.add("0");
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-
-		List<String> c2 = new ArrayList<String>();
-		c2.add("4");
-		c2.add("5");
-		c2.add("6");
-		c2.add("7");
-
-		@SuppressWarnings("unchecked")
-		Iterable<String> composite = new CompositeListIterable<String>(c1, c2);
-		assertNotNull(composite.toString());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/EmptyIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/EmptyIterableTests.java
deleted file mode 100644
index c890c24..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/EmptyIterableTests.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterables.EmptyIterable;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-
-@SuppressWarnings("nls")
-public class EmptyIterableTests extends TestCase {
-
-	public EmptyIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		for (String s : EmptyIterable.<String>instance()) {
-			fail("bogus element: " + s);
-		}
-	}
-
-	public void testToString() {
-		assertNotNull(EmptyIterable.instance().toString());
-	}
-
-	public void testSerialization() throws Exception {
-		Iterable<String> iterable = EmptyIterable.instance();
-		assertSame(iterable, TestTools.serialize(iterable));
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/EmptyListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/EmptyListIterableTests.java
deleted file mode 100644
index 30c9477..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/EmptyListIterableTests.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterables.EmptyListIterable;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-
-@SuppressWarnings("nls")
-public class EmptyListIterableTests extends TestCase {
-
-	public EmptyListIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		for (String s : EmptyListIterable.<String>instance()) {
-			fail("bogus element: " + s);
-		}
-	}
-
-	public void testToString() {
-		assertNotNull(EmptyListIterable.instance().toString());
-	}
-
-	public void testSerialization() throws Exception {
-		Iterable<String> iterable = EmptyListIterable.instance();
-		assertSame(iterable, TestTools.serialize(iterable));
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/FilteringIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/FilteringIterableTests.java
deleted file mode 100644
index 0d53482..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/FilteringIterableTests.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import junit.framework.TestCase;
-import org.eclipse.persistence.tools.utility.Filter;
-import org.eclipse.persistence.tools.utility.iterables.FilteringIterable;
-
-@SuppressWarnings("nls")
-public class FilteringIterableTests extends TestCase {
-	private static final String PREFIX = "prefix";
-
-	public FilteringIterableTests(String name) {
-		super(name);
-	}
-
-	public void testAccept() {
-		int i = 0;
-		for (String s : this.buildIterable()) {
-			assertTrue(s.contains(PREFIX));
-			i++;
-		}
-		assertEquals(6, i);
-	}
-
-	public void testFilter() {
-		Filter<String> filter = this.buildFilter();
-		int i = 0;
-		for (String s : new FilteringIterable<String>(this.buildNestedIterable(), filter)) {
-			assertTrue(s.contains(PREFIX));
-			i++;
-		}
-		assertEquals(6, i);
-	}
-
-	public void testToString() {
-		assertNotNull(this.buildIterable().toString());
-	}
-
-	public void testMissingFilter() {
-		boolean exCaught = false;
-		Iterable<String> iterable = new FilteringIterable<String>(this.buildNestedIterable());
-		try {
-			Iterator<String> iterator = iterable.iterator();
-			fail("bogus iterator: " + iterator);
-		} catch (RuntimeException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	private Iterable<String> buildIterable() {
-		return this.buildFilteringIterable(this.buildNestedIterable());
-	}
-
-	private Iterable<String> buildFilteringIterable(Iterable<String> nestedIterable) {
-		return new FilteringIterable<String>(nestedIterable) {
-			@Override
-			protected boolean accept(String s) {
-				return s.startsWith(PREFIX);
-			}
-		};
-	}
-
-	private Filter<String> buildFilter() {
-		return new Filter<String>() {
-			public boolean accept(String s) {
-				return s.startsWith(PREFIX);
-			}
-		};
-	}
-
-	private Iterable<String> buildNestedIterable() {
-		Collection<String> c = new ArrayList<String>();
-		c.add(PREFIX + "1");
-		c.add(PREFIX + "2");
-		c.add(PREFIX + "3");
-		c.add("4");
-		c.add(PREFIX + "5");
-		c.add(PREFIX + "6");
-		c.add(PREFIX + "7");
-		c.add("8");
-		return c;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/GraphIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/GraphIterableTests.java
deleted file mode 100644
index 1d48f44..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/GraphIterableTests.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.iterables.GraphIterable;
-import org.eclipse.persistence.tools.utility.iterators.GraphIterator;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-
-@SuppressWarnings("nls")
-public class GraphIterableTests extends TestCase {
-	/** this will be populated with all the nodes created for the test */
-	Collection<GraphNode> nodes = new ArrayList<GraphNode>();
-
-	public GraphIterableTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		TestTools.clear(this);
-		super.tearDown();
-	}
-
-	public void testNeighbors1() {
-		for (GraphNode gn : this.buildGraphIterable1()) {
-			assertTrue(this.nodes.contains(gn));
-		}
-	}
-
-	private Iterable<GraphNode> buildGraphIterable1() {
-		return new GraphIterable<GraphNode>(this.buildGraphRoot()) {
-			@Override
-			public Iterator<GraphNode> neighbors(GraphNode next) {
-				return next.neighbors();
-			}
-		};
-	}
-
-	public void testNeighbors2() {
-		for (GraphNode gn : this.buildGraphIterable2()) {
-			assertTrue(this.nodes.contains(gn));
-		}
-	}
-
-	private Iterable<GraphNode> buildGraphIterable2() {
-		return new GraphIterable<GraphNode>(this.buildGraphRoot(), this.buildMisterRogers());
-	}
-
-	public void testNeighbors3() {
-		for (GraphNode gn : this.buildGraphIterable3()) {
-			assertTrue(this.nodes.contains(gn));
-		}
-	}
-
-	private Iterable<GraphNode> buildGraphIterable3() {
-		return new GraphIterable<GraphNode>(new GraphNode[] { this.buildGraphRoot() }) {
-			@Override
-			public Iterator<GraphNode> neighbors(GraphNode next) {
-				return next.neighbors();
-			}
-		};
-	}
-
-	public void testNeighbors4() {
-		for (GraphNode gn : this.buildGraphIterable4()) {
-			assertTrue(this.nodes.contains(gn));
-		}
-	}
-
-	private Iterable<GraphNode> buildGraphIterable4() {
-		return new GraphIterable<GraphNode>(new GraphNode[] { this.buildGraphRoot() }, this.buildMisterRogers());
-	}
-
-	public void testToString() {
-		assertNotNull(this.buildGraphIterable1().toString());
-	}
-
-	public void testMissingMisterRogers() {
-		boolean exCaught = false;
-		try {
-			for (GraphNode gn : new GraphIterable<GraphNode>(this.buildGraphRoot())) {
-				assertTrue(this.nodes.contains(gn));
-			}
-			fail();
-		} catch (RuntimeException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	private GraphIterator.MisterRogers<GraphNode> buildMisterRogers() {
-		return new GraphIterator.MisterRogers<GraphNode>() {
-			public Iterator<GraphNode> neighbors(GraphNode next) {
-				return next.neighbors();
-			}
-		};
-	}
-
-	private GraphNode buildGraphRoot() {
-		GraphNode ncNode = new GraphNode("North Carolina");
-		GraphNode vaNode = new GraphNode("Virginia");
-		GraphNode scNode = new GraphNode("South Carolina");
-		GraphNode gaNode = new GraphNode("Georgia");
-		GraphNode flNode = new GraphNode("Florida");
-		GraphNode alNode = new GraphNode("Alabama");
-		GraphNode msNode = new GraphNode("Mississippi");
-		GraphNode tnNode = new GraphNode("Tennessee");
-
-		ncNode.setNeighbors(new GraphNode[] { vaNode, scNode, gaNode, tnNode });
-		vaNode.setNeighbors(new GraphNode[] { ncNode, tnNode });
-		scNode.setNeighbors(new GraphNode[] { ncNode, gaNode });
-		gaNode.setNeighbors(new GraphNode[] { ncNode, scNode, flNode, alNode, tnNode });
-		flNode.setNeighbors(new GraphNode[] { gaNode });
-		alNode.setNeighbors(new GraphNode[] { gaNode, msNode, tnNode });
-		msNode.setNeighbors(new GraphNode[] { alNode, tnNode });
-		tnNode.setNeighbors(new GraphNode[] { vaNode, ncNode, gaNode, alNode, msNode });
-
-		return ncNode;
-	}
-
-	public class GraphNode {
-		private String name;
-
-		private Collection<GraphNode> neighbors = new ArrayList<GraphNode>();
-
-		public GraphNode(String name) {
-			super();
-			GraphIterableTests.this.nodes.add(this); // log node
-			this.name = name;
-		}
-
-		public String getName() {
-			return this.name;
-		}
-
-		void setNeighbors(GraphNode[] neighbors) {
-			this.neighbors = CollectionTools.list(neighbors);
-		}
-
-		public Iterator<GraphNode> neighbors() {
-			return this.neighbors.iterator();
-		}
-
-		public int neighborsSize() {
-			return this.neighbors.size();
-		}
-
-		@Override
-		public String toString() {
-			return "GraphNode(" + this.name + ")";
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/LiveCloneIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/LiveCloneIterableTests.java
deleted file mode 100644
index 18e82d6..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/LiveCloneIterableTests.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.List;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.iterables.LiveCloneIterable;
-
-@SuppressWarnings("nls")
-public class LiveCloneIterableTests extends CloneIterableTests {
-
-	public LiveCloneIterableTests(String name) {
-		super(name);
-	}
-
-	@Override
-	public void testIterator() {
-		super.testIterator();
-		// iterable should now return only 3 strings (since it's "live")
-		int i = 0;
-		for (String s : this.iterable) {
-			assertEquals(String.valueOf(i++), s);
-		}
-		assertEquals(3, i);
-	}
-
-	@Override
-	public void testRemove() {
-		super.testRemove();
-		// "live" clone iterable will no longer contain the element removed from the
-		// original collection
-		assertFalse(CollectionTools.contains(this.iterable, "three"));
-	}
-
-	@Override
-	public void testRemover() {
-		super.testRemover();
-		// "live" clone iterable will no longer contain the element removed from the
-		// original collection
-		assertFalse(CollectionTools.contains(this.iterable, "three"));
-	}
-
-	@Override
-	Iterable<String> buildIterable(List<String> c) {
-		return new LiveCloneIterable<String>(c);
-	}
-
-	@Override
-	Iterable<String> buildRemovingIterable(final List<String> c) {
-		return new LiveCloneIterable<String>(c) {
-				@Override
-				protected void remove(String current) {
-					c.remove(current);
-				}
-			};
-	}
-
-	@Override
-	Iterable<String> buildIterableWithRemover(List<String> c) {
-		return new LiveCloneIterable<String>(c, this.buildRemover(c));
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/LiveCloneListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/LiveCloneListIterableTests.java
deleted file mode 100644
index 29a0dce..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/LiveCloneListIterableTests.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.iterables.LiveCloneListIterable;
-
-@SuppressWarnings("nls")
-public class LiveCloneListIterableTests extends LiveCloneIterableTests {
-
-	public LiveCloneListIterableTests(String name) {
-		super(name);
-	}
-
-	public void testAdd() {
-		final List<String> collection = this.buildCollection();
-		this.iterable = this.buildRemovingIterable(collection);
-
-		String added = "xxxx";
-		assertFalse(CollectionTools.contains(this.iterable, added));
-		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
-			if (iterator.next().equals("two")) {
-				iterator.add(added);
-			}
-		}
-		assertTrue(collection.contains(added));
-		// "live" clone iterable will contain the element added to the
-		// original collection
-		assertTrue(CollectionTools.contains(this.iterable, added));
-	}
-
-	public void testMissingMutatorAdd() {
-		final List<String> collection = this.buildCollection();
-		this.iterable = this.buildIterable(collection);
-		assertNotNull(this.iterable.toString());
-
-		String added = "xxxx";
-		assertFalse(CollectionTools.contains(this.iterable, added));
-		boolean exCaught = false;
-		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
-			if (iterator.next().equals("three")) {
-				try {
-					iterator.add(added);
-					fail();
-				} catch (RuntimeException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testSet() {
-		final List<String> collection = this.buildCollection();
-		this.iterable = this.buildRemovingIterable(collection);
-
-		String added = "xxxx";
-		assertFalse(CollectionTools.contains(this.iterable, added));
-		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
-			if (iterator.next().equals("two")) {
-				iterator.set(added);
-			}
-		}
-		assertTrue(collection.contains(added));
-		assertFalse(collection.contains("two"));
-		// "live" clone iterable will contain the element added to the
-		// original collection
-		assertTrue(CollectionTools.contains(this.iterable, added));
-		assertFalse(CollectionTools.contains(this.iterable, "two"));
-	}
-
-	public void testMissingMutatorSet() {
-		final List<String> collection = this.buildCollection();
-		this.iterable = this.buildIterable(collection);
-		assertNotNull(this.iterable.toString());
-
-		String added = "xxxx";
-		assertFalse(CollectionTools.contains(this.iterable, added));
-		boolean exCaught = false;
-		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
-			if (iterator.next().equals("three")) {
-				try {
-					iterator.set(added);
-					fail();
-				} catch (RuntimeException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-	@Override
-	Iterable<String> buildIterable(List<String> c) {
-		return new LiveCloneListIterable<String>(c);
-	}
-
-	@Override
-	Iterable<String> buildRemovingIterable(final List<String> c) {
-		return new LiveCloneListIterable<String>(c) {
-				@Override
-				protected void add(int index, String element) {
-					c.add(index, element);
-				}
-				@Override
-				protected void remove(int index) {
-					c.remove(index);
-				}
-				@Override
-				protected void set(int index, String element) {
-					c.set(index, element);
-				}
-			};
-	}
-
-	@Override
-	Iterable<String> buildIterableWithRemover(List<String> c) {
-		return new LiveCloneListIterable<String>(c, this.buildMutator(c));
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/PeekableIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/PeekableIterableTests.java
deleted file mode 100644
index 3976bad..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/PeekableIterableTests.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import junit.framework.TestCase;
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
-import org.eclipse.persistence.tools.utility.iterables.PeekableIterable;
-import org.eclipse.persistence.tools.utility.iterators.PeekableIterator;
-
-@SuppressWarnings("nls")
-public class PeekableIterableTests extends TestCase {
-
-	public PeekableIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		PeekableIterable<String> iterable = this.buildIterable();
-		PeekableIterator<String> iterator = iterable.iterator();
-		assertEquals("one", iterator.peek());
-	}
-
-	public void testToString() {
-		assertNotNull(this.buildIterable().toString());
-	}
-
-	private PeekableIterable<String> buildIterable() {
-		return new PeekableIterable<String>(this.buildNestedIterable());
-	}
-
-	private Iterable<String> buildNestedIterable() {
-		return new ArrayIterable<String>(this.buildArray());
-	}
-
-	private String[] buildArray() {
-		return new String[] {"one", "two", "three"};
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/QueueIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/QueueIterableTests.java
deleted file mode 100644
index f119c9b..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/QueueIterableTests.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.Queue;
-import org.eclipse.persistence.tools.utility.SimpleQueue;
-import org.eclipse.persistence.tools.utility.iterables.QueueIterable;
-
-@SuppressWarnings("nls")
-public class QueueIterableTests extends TestCase {
-
-	public QueueIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		Iterable<String> iterable = this.buildIterable();
-		for (String s : iterable) {
-			assertNotNull(s);
-		}
-	}
-
-	public void testToString() {
-		assertNotNull(this.buildIterable().toString());
-	}
-
-	private Iterable<String> buildIterable() {
-		return new QueueIterable<String>(this.buildQueue());
-	}
-
-	private Queue<String> buildQueue() {
-		Queue<String> q = new SimpleQueue<String>();
-		q.enqueue("foo");
-		q.enqueue("bar");
-		q.enqueue("baz");
-		return q;
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ReadOnlyCompositeListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ReadOnlyCompositeListIterableTests.java
deleted file mode 100644
index e661705..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ReadOnlyCompositeListIterableTests.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.ArrayList;
-import java.util.List;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ReadOnlyCompositeListIterable;
-
-@SuppressWarnings("nls")
-public class ReadOnlyCompositeListIterableTests extends TestCase {
-
-	public ReadOnlyCompositeListIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		List<String> c1 = new ArrayList<String>();
-		c1.add("0");
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-		ListIterable<String> li1 = new ListListIterable<String>(c1);
-
-		List<String> c2 = new ArrayList<String>();
-		c2.add("4");
-		c2.add("5");
-		c2.add("6");
-		c2.add("7");
-		ListIterable<String> li2 = new ListListIterable<String>(c2);
-
-		@SuppressWarnings("unchecked")
-		Iterable<String> composite = new ReadOnlyCompositeListIterable<String>(li1, li2);
-		int i = 0;
-		for (String s : composite) {
-			assertEquals(String.valueOf(i++), s);
-		}
-	}
-
-	public void testExtraElement1() {
-		List<String> c1 = new ArrayList<String>();
-		c1.add("0");
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-		ListIterable<String> li1 = new ListListIterable<String>(c1);
-
-		Iterable<String> composite = new ReadOnlyCompositeListIterable<String>(li1, "4");
-		int i = 0;
-		for (String s : composite) {
-			assertEquals(String.valueOf(i++), s);
-		}
-	}
-
-	public void testExtraElement2() {
-		List<String> c1 = new ArrayList<String>();
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-		ListIterable<String> li1 = new ListListIterable<String>(c1);
-
-		Iterable<String> composite = new ReadOnlyCompositeListIterable<String>("0", li1);
-		int i = 0;
-		for (String s : composite) {
-			assertEquals(String.valueOf(i++), s);
-		}
-	}
-
-	public void testCollectionOfIterables() {
-		List<String> c1 = new ArrayList<String>();
-		c1.add("0");
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-		ListIterable<String> li1 = new ListListIterable<String>(c1);
-
-		List<String> c2 = new ArrayList<String>();
-		c2.add("4");
-		c2.add("5");
-		c2.add("6");
-		c2.add("7");
-		ListIterable<String> li2 = new ListListIterable<String>(c2);
-
-		List<ListIterable<String>> collection = new ArrayList<ListIterable<String>>();
-		collection.add(li1);
-		collection.add(li2);
-		ListIterable<ListIterable<String>> li = new ListListIterable<ListIterable<String>>(collection);
-		
-		Iterable<String> composite = new ReadOnlyCompositeListIterable<String>(li);
-		int i = 0;
-		for (String s : composite) {
-			assertEquals(String.valueOf(i++), s);
-		}
-	}
-
-	public void testToString() {
-		List<String> c1 = new ArrayList<String>();
-		c1.add("0");
-		c1.add("1");
-		c1.add("2");
-		c1.add("3");
-		ListIterable<String> li1 = new ListListIterable<String>(c1);
-
-		List<String> c2 = new ArrayList<String>();
-		c2.add("4");
-		c2.add("5");
-		c2.add("6");
-		c2.add("7");
-		ListIterable<String> li2 = new ListListIterable<String>(c2);
-
-		@SuppressWarnings("unchecked")
-		Iterable<String> composite = new ReadOnlyCompositeListIterable<String>(li1, li2);
-		assertNotNull(composite.toString());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ReadOnlyIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ReadOnlyIterableTests.java
deleted file mode 100644
index a3b5eb2..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ReadOnlyIterableTests.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.Iterator;
-import java.util.Vector;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterables.ReadOnlyIterable;
-
-@SuppressWarnings("nls")
-public class ReadOnlyIterableTests extends TestCase {
-
-	public ReadOnlyIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		Iterator<String> nestedIterator = this.buildVector().iterator();
-		for (String s : this.buildReadOnlyIterable()) {
-			assertEquals(nestedIterator.next(), s);
-		}
-	}
-
-	public void testRemove() {
-		boolean exCaught = false;
-		for (Iterator<String> stream = this.buildReadOnlyIterable().iterator(); stream.hasNext();) {
-			if (stream.next().equals("three")) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testToString() {
-		assertNotNull(this.buildReadOnlyIterable().toString());
-	}
-
-	private Iterable<String> buildReadOnlyIterable() {
-		return new ReadOnlyIterable<String>(this.buildVector());
-	}
-
-	private Vector<String> buildVector() {
-		Vector<String> v = new Vector<String>();
-		v.addElement("one");
-		v.addElement("two");
-		v.addElement("three");
-		v.addElement("four");
-		v.addElement("five");
-		v.addElement("six");
-		v.addElement("seven");
-		v.addElement("eight");
-		return v;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ReadOnlyListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ReadOnlyListIterableTests.java
deleted file mode 100644
index 5576bd8..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/ReadOnlyListIterableTests.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.Iterator;
-import java.util.Vector;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ReadOnlyListIterable;
-
-@SuppressWarnings("nls")
-public class ReadOnlyListIterableTests extends TestCase {
-
-	public ReadOnlyListIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		Iterator<String> nestedIterator = this.buildVector().iterator();
-		for (String s : this.buildReadOnlyListIterable()) {
-			assertEquals(nestedIterator.next(), s);
-		}
-	}
-
-	public void testRemove() {
-		boolean exCaught = false;
-		for (Iterator<String> stream = this.buildReadOnlyListIterable().iterator(); stream.hasNext();) {
-			if (stream.next().equals("three")) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testToString() {
-		assertNotNull(this.buildReadOnlyListIterable().toString());
-	}
-
-	private Iterable<String> buildReadOnlyListIterable() {
-		return new ReadOnlyListIterable<String>(this.buildNestedListIterable());
-	}
-
-	private ListIterable<String> buildNestedListIterable() {
-		return new ListListIterable<String>(this.buildVector());
-	}
-
-	private Vector<String> buildVector() {
-		Vector<String> v = new Vector<String>();
-		v.addElement("one");
-		v.addElement("two");
-		v.addElement("three");
-		v.addElement("four");
-		v.addElement("five");
-		v.addElement("six");
-		v.addElement("seven");
-		v.addElement("eight");
-		return v;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SingleElementIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SingleElementIterableTests.java
deleted file mode 100644
index 61c1918..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SingleElementIterableTests.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterables.SingleElementIterable;
-
-@SuppressWarnings("nls")
-public class SingleElementIterableTests extends TestCase {
-
-	public SingleElementIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		for (String s : this.buildSingleElementIterable()) {
-			assertEquals(this.singleElement(), s);
-		}
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		Iterator<String> stream = this.buildSingleElementIterable().iterator();
-		String string = stream.next();
-		try {
-			string = stream.next();
-			fail("bogus element: " + string);
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testRemove() {
-		boolean exCaught = false;
-		for (Iterator<String> stream = this.buildSingleElementIterable().iterator(); stream.hasNext(); ) {
-			if (stream.next().equals(this.singleElement())) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	protected Iterable<String> buildSingleElementIterable() {
-		return new SingleElementIterable<String>(this.singleElement());
-	}
-
-	protected String singleElement() {
-		return "single element";
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SingleElementListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SingleElementListIterableTests.java
deleted file mode 100644
index d15d2a7..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SingleElementListIterableTests.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterables.SingleElementListIterable;
-
-@SuppressWarnings("nls")
-public class SingleElementListIterableTests extends TestCase {
-
-	public SingleElementListIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		for (String s : this.buildSingleElementListIterable()) {
-			assertEquals(this.singleElement(), s);
-		}
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		Iterator<String> stream = this.buildSingleElementListIterable().iterator();
-		String string = stream.next();
-		try {
-			string = stream.next();
-			fail("bogus element: " + string);
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testRemove() {
-		boolean exCaught = false;
-		for (Iterator<String> stream = this.buildSingleElementListIterable().iterator(); stream.hasNext(); ) {
-			if (stream.next().equals(this.singleElement())) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	public void testToString() {
-		assertNotNull(this.buildSingleElementListIterable().toString());
-	}
-
-	protected Iterable<String> buildSingleElementListIterable() {
-		return new SingleElementListIterable<String>(this.singleElement());
-	}
-
-	protected String singleElement() {
-		return "single element";
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SnapshotCloneIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SnapshotCloneIterableTests.java
deleted file mode 100644
index d120fa3..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SnapshotCloneIterableTests.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.List;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.iterables.SnapshotCloneIterable;
-
-@SuppressWarnings("nls")
-public class SnapshotCloneIterableTests extends CloneIterableTests {
-
-	public SnapshotCloneIterableTests(String name) {
-		super(name);
-	}
-
-	@Override
-	public void testIterator() {
-		super.testIterator();
-		// "snapshot" iterable should still return 4 strings (since the original collection was cloned)
-		int i = 0;
-		for (String s : this.iterable) {
-			assertEquals(String.valueOf(i++), s);
-		}
-		assertEquals(4, i);
-	}
-
-	@Override
-	public void testRemove() {
-		super.testRemove();
-		// "snapshot" clone iterable will still contain the element removed from the
-		// original collection
-		assertTrue(CollectionTools.contains(this.iterable, "three"));
-	}
-
-	@Override
-	public void testRemover() {
-		super.testRemover();
-		// "snapshot" clone iterable will still contain the element removed from the
-		// original collection
-		assertTrue(CollectionTools.contains(this.iterable, "three"));
-	}
-
-	@Override
-	Iterable<String> buildIterable(List<String> c) {
-		return new SnapshotCloneIterable<String>(c);
-	}
-
-	@Override
-	Iterable<String> buildRemovingIterable(final List<String> c) {
-		return new SnapshotCloneIterable<String>(c) {
-				@Override
-				protected void remove(String current) {
-					c.remove(current);
-				}
-			};
-	}
-
-	@Override
-	Iterable<String> buildIterableWithRemover(List<String> c) {
-		return new SnapshotCloneIterable<String>(c, this.buildRemover(c));
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SnapshotCloneListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SnapshotCloneListIterableTests.java
deleted file mode 100644
index 00c31de..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SnapshotCloneListIterableTests.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.iterables.SnapshotCloneListIterable;
-
-@SuppressWarnings("nls")
-public class SnapshotCloneListIterableTests extends SnapshotCloneIterableTests {
-
-	public SnapshotCloneListIterableTests(String name) {
-		super(name);
-	}
-
-	public void testAdd() {
-		final List<String> collection = this.buildCollection();
-		this.iterable = this.buildRemovingIterable(collection);
-
-		String added = "xxxx";
-		assertFalse(CollectionTools.contains(this.iterable, added));
-		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
-			if (iterator.next().equals("two")) {
-				iterator.add(added);
-			}
-		}
-		assertTrue(collection.contains(added));
-		// "snapshot" clone iterable not will contain the element added to the
-		// original collection
-		assertFalse(CollectionTools.contains(this.iterable, added));
-	}
-
-	public void testMissingMutatorAdd() {
-		final List<String> collection = this.buildCollection();
-		this.iterable = this.buildIterable(collection);
-		assertNotNull(this.iterable.toString());
-
-		String added = "xxxx";
-		assertFalse(CollectionTools.contains(this.iterable, added));
-		boolean exCaught = false;
-		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
-			if (iterator.next().equals("three")) {
-				try {
-					iterator.add(added);
-					fail();
-				} catch (RuntimeException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testSet() {
-		final List<String> collection = this.buildCollection();
-		this.iterable = this.buildRemovingIterable(collection);
-
-		String added = "xxxx";
-		assertFalse(CollectionTools.contains(this.iterable, added));
-		assertTrue(CollectionTools.contains(this.iterable, "two"));
-		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
-			if (iterator.next().equals("two")) {
-				iterator.set(added);
-			}
-		}
-		assertTrue(collection.contains(added));
-		assertFalse(collection.contains("two"));
-		// "snapshot" clone iterable will not be changed
-		assertFalse(CollectionTools.contains(this.iterable, added));
-		assertTrue(CollectionTools.contains(this.iterable, "two"));
-	}
-
-	public void testMissingMutatorSet() {
-		final List<String> collection = this.buildCollection();
-		this.iterable = this.buildIterable(collection);
-		assertNotNull(this.iterable.toString());
-
-		String added = "xxxx";
-		assertFalse(CollectionTools.contains(this.iterable, added));
-		boolean exCaught = false;
-		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
-			if (iterator.next().equals("three")) {
-				try {
-					iterator.set(added);
-					fail();
-				} catch (RuntimeException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-	@Override
-	Iterable<String> buildIterable(List<String> c) {
-		return new SnapshotCloneListIterable<String>(c);
-	}
-
-	@Override
-	Iterable<String> buildRemovingIterable(final List<String> c) {
-		return new SnapshotCloneListIterable<String>(c) {
-				@Override
-				protected void add(int index, String element) {
-					c.add(index, element);
-				}
-				@Override
-				protected void remove(int index) {
-					c.remove(index);
-				}
-				@Override
-				protected void set(int index, String element) {
-					c.set(index, element);
-				}
-			};
-	}
-
-	@Override
-	Iterable<String> buildIterableWithRemover(List<String> c) {
-		return new SnapshotCloneListIterable<String>(c, this.buildMutator(c));
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/StackIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/StackIterableTests.java
deleted file mode 100644
index c72f0d5..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/StackIterableTests.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.Iterator;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.SimpleStack;
-import org.eclipse.persistence.tools.utility.Stack;
-import org.eclipse.persistence.tools.utility.iterables.StackIterable;
-
-@SuppressWarnings("nls")
-public class StackIterableTests extends TestCase {
-
-	public StackIterableTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		Iterator<String> iterator = this.buildIterable().iterator();
-		assertEquals("three", iterator.next());
-		assertEquals("two", iterator.next());
-		assertEquals("one", iterator.next());
-	}
-
-	public void testToString() {
-		assertNotNull(this.buildIterable().toString());
-	}
-
-	private Iterable<String> buildIterable() {
-		return new StackIterable<String>(this.buildStack());
-	}
-
-	private Stack<String> buildStack() {
-		Stack<String> stack = new SimpleStack<String>();
-		stack.push("one");
-		stack.push("two");
-		stack.push("three");
-		return stack;
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SuperIterableWrapperTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SuperIterableWrapperTests.java
deleted file mode 100644
index 7c0b377..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/SuperIterableWrapperTests.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterables.SuperIterableWrapper;
-
-@SuppressWarnings("nls")
-public class SuperIterableWrapperTests extends TestCase {
-
-	public SuperIterableWrapperTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("foo");
-		list.add("bar");
-		list.add("baz");
-		String concat = "";
-		for (String s : list) {
-			concat += s;
-		}
-		assertEquals("foobarbaz", concat);
-
-		Iterable<Object> iterable = new SuperIterableWrapper<Object>(list);
-		concat = "";
-		for (Object s : iterable) {
-			concat += s;
-		}
-		assertEquals("foobarbaz", concat);
-	}
-
-	public void testToString() {
-		Iterable<Object> iterable = new SuperIterableWrapper<Object>(Collections.emptyList());
-		assertNotNull(iterable.toString());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/TransformationIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/TransformationIterableTests.java
deleted file mode 100644
index 965df8c..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/TransformationIterableTests.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.Transformer;
-import org.eclipse.persistence.tools.utility.iterables.TransformationIterable;
-
-@SuppressWarnings("nls")
-public class TransformationIterableTests extends TestCase {
-
-	public TransformationIterableTests(String name) {
-		super(name);
-	}
-
-	public void testTransform1() {
-		int i = 1;
-		for (Integer integer : this.buildIterable1()) {
-			assertEquals(i++, integer.intValue());
-		}
-	}
-
-	private Iterable<Integer> buildIterable1() {
-		return this.buildTransformationIterable1(this.buildNestedIterable());
-	}
-
-	private Iterable<Integer> buildTransformationIterable1(Iterable<String> nestedIterable) {
-		// transform each string into an integer with a value of the string's length
-		return new TransformationIterable<Integer, String>(nestedIterable) {
-			@Override
-			protected Integer transform(String next) {
-				return new Integer(next.length());
-			}
-		};
-	}
-
-	public void testTransform2() {
-		int i = 1;
-		for (Integer integer : this.buildIterable2()) {
-			assertEquals(i++, integer.intValue());
-		}
-	}
-
-	private Iterable<Integer> buildIterable2() {
-		return this.buildTransformationIterable2(this.buildNestedIterable());
-	}
-
-	private Iterable<Integer> buildTransformationIterable2(Iterable<String> nestedIterable) {
-		// transform each string into an integer with a value of the string's length
-		return new TransformationIterable<Integer, String>(nestedIterable, this.buildTransformer());
-	}
-
-	private Transformer<Integer, String> buildTransformer() {
-		// transform each string into an integer with a value of the string's length
-		return new Transformer<Integer, String>() {
-			public Integer transform(String next) {
-				return new Integer(next.length());
-			}
-		};
-	}
-
-	private Iterable<String> buildNestedIterable() {
-		Collection<String> c = new ArrayList<String>();
-		c.add("1");
-		c.add("22");
-		c.add("333");
-		c.add("4444");
-		c.add("55555");
-		c.add("666666");
-		c.add("7777777");
-		c.add("88888888");
-		return c;
-	}
-
-	public void testToString() {
-		assertNotNull(this.buildIterable1().toString());
-	}
-
-	public void testMissingTransformer() {
-		Iterable<Integer> iterable = new TransformationIterable<Integer, String>(this.buildNestedIterable());
-		boolean exCaught = false;
-		try {
-			int i = 1;
-			for (Integer integer : iterable) {
-				assertEquals(i++, integer.intValue());
-			}
-		} catch (RuntimeException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/TransformationListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/TransformationListIterableTests.java
deleted file mode 100644
index 73a007b..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/TransformationListIterableTests.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.ArrayList;
-import java.util.List;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.Transformer;
-import org.eclipse.persistence.tools.utility.iterables.TransformationListIterable;
-
-@SuppressWarnings("nls")
-public class TransformationListIterableTests extends TestCase {
-
-	public TransformationListIterableTests(String name) {
-		super(name);
-	}
-
-	public void testTransform1() {
-		int i = 1;
-		for (Integer integer : this.buildIterable1()) {
-			assertEquals(i++, integer.intValue());
-		}
-	}
-
-	private Iterable<Integer> buildIterable1() {
-		return this.buildTransformationListIterable1(this.buildNestedList());
-	}
-
-	private Iterable<Integer> buildTransformationListIterable1(List<String> nestedList) {
-		// transform each string into an integer with a value of the string's length
-		return new TransformationListIterable<Integer, String>(nestedList) {
-			@Override
-			protected Integer transform(String next) {
-				return new Integer(next.length());
-			}
-		};
-	}
-
-	public void testTransform2() {
-		int i = 1;
-		for (Integer integer : this.buildIterable2()) {
-			assertEquals(i++, integer.intValue());
-		}
-	}
-
-	private Iterable<Integer> buildIterable2() {
-		return this.buildTransformationListIterable2(this.buildNestedList());
-	}
-
-	private Iterable<Integer> buildTransformationListIterable2(List<String> nestedList) {
-		// transform each string into an integer with a value of the string's length
-		return new TransformationListIterable<Integer, String>(nestedList, this.buildTransformer());
-	}
-
-	private Transformer<Integer, String> buildTransformer() {
-		// transform each string into an integer with a value of the string's length
-		return new Transformer<Integer, String>() {
-			public Integer transform(String next) {
-				return new Integer(next.length());
-			}
-		};
-	}
-
-	private List<String> buildNestedList() {
-		List<String> c = new ArrayList<String>();
-		c.add("1");
-		c.add("22");
-		c.add("333");
-		c.add("4444");
-		c.add("55555");
-		c.add("666666");
-		c.add("7777777");
-		c.add("88888888");
-		return c;
-	}
-
-	public void testToString() {
-		assertNotNull(this.buildIterable1().toString());
-	}
-
-	public void testMissingTransformer() {
-		Iterable<Integer> iterable = new TransformationListIterable<Integer, String>(this.buildNestedList());
-		boolean exCaught = false;
-		try {
-			int i = 1;
-			for (Integer integer : iterable) {
-				assertEquals(i++, integer.intValue());
-			}
-		} catch (RuntimeException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/TreeIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/TreeIterableTests.java
deleted file mode 100644
index f74bb26..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/TreeIterableTests.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import junit.framework.TestCase;
-import org.eclipse.persistence.tools.utility.iterables.TreeIterable;
-import org.eclipse.persistence.tools.utility.iterators.TreeIterator;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-import org.eclipse.persistence.tools.utility.tests.internal.iterables.TreeIterableTests.TreeNode;
-
-@SuppressWarnings("nls")
-public class TreeIterableTests extends TestCase {
-	/** this will be populated with all the nodes created for the test */
-	Collection<TreeNode> nodes = new ArrayList<TreeNode>();
-
-	public TreeIterableTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		TestTools.clear(this);
-		super.tearDown();
-	}
-
-	public void testIterator1() {
-		for (TreeNode tn : this.buildTreeIterable1()) {
-			assertTrue(this.nodes.contains(tn));
-		}
-	}
-
-	public void testIterator2() {
-		for (TreeNode tn : this.buildTreeIterable2()) {
-			assertTrue(this.nodes.contains(tn));
-		}
-	}
-
-	public void testMidwife1() {
-		for (TreeNode tn : new TreeIterable<TreeNode>(this.buildTree(), this.buildMidwife())) {
-			assertTrue(this.nodes.contains(tn));
-		}
-	}
-
-	public void testMidwife2() {
-		for (TreeNode tn : new TreeIterable<TreeNode>(new TreeNode[] { this.buildTree() }, this.buildMidwife())) {
-			assertTrue(this.nodes.contains(tn));
-		}
-	}
-
-	public void testToString() {
-		assertNotNull(this.buildTreeIterable1().toString());
-	}
-
-	public void testMissingMidwife() {
-		boolean exCaught = false;
-		try {
-			for (TreeNode tn : new TreeIterable<TreeNode>(this.buildTree())) {
-				assertTrue(this.nodes.contains(tn));
-			}
-		} catch (RuntimeException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	private Iterable<TreeNode> buildTreeIterable1() {
-		return new TreeIterable<TreeNode>(this.buildTree()) {
-			@Override
-			public Iterator<TreeNode> children(TreeNode next) {
-				return next.children();
-			}
-		};
-	}
-
-	private Iterable<TreeNode> buildTreeIterable2() {
-		return new TreeIterable<TreeNode>(new TreeNode[] { this.buildTree() }) {
-			@Override
-			public Iterator<TreeNode> children(TreeNode next) {
-				return next.children();
-			}
-		};
-	}
-
-	private TreeIterator.Midwife<TreeNode> buildMidwife() {
-		return new TreeIterator.Midwife<TreeNode>() {
-			public Iterator<TreeNode> children(TreeNode next) {
-				return next.children();
-			}
-		};
-	}
-
-	private TreeNode buildTree() {
-		TreeNode root = new TreeNode("root");
-		TreeNode child1 = new TreeNode(root, "child 1");
-		new TreeNode(child1, "grandchild 1A");
-		TreeNode child2 = new TreeNode(root, "child 2");
-		new TreeNode(child2, "grandchild 2A");
-		TreeNode grandchild2B = new TreeNode(child2, "grandchild 2B");
-		new TreeNode(grandchild2B, "great-grandchild 2B1");
-		new TreeNode(grandchild2B, "great-grandchild 2B2");
-		TreeNode grandchild2C = new TreeNode(child2, "grandchild 2C");
-		new TreeNode(grandchild2C, "great-grandchild 2C1");
-		new TreeNode(root, "child 3");
-		return root;
-	}
-
-	public class TreeNode {
-		private String name;
-		private Collection<TreeNode> children = new ArrayList<TreeNode>();
-
-		public TreeNode(String name) {
-			super();
-			TreeIterableTests.this.nodes.add(this); // log node
-			this.name = name;
-		}
-
-		public TreeNode(TreeNode parent, String name) {
-			this(name);
-			parent.addChild(this);
-		}
-
-		public String getName() {
-			return this.name;
-		}
-
-		private void addChild(TreeNode child) {
-			this.children.add(child);
-		}
-
-		public Iterator<TreeNode> children() {
-			return this.children.iterator();
-		}
-
-		public int childrenSize() {
-			return this.children.size();
-		}
-
-		@Override
-		public String toString() {
-			return "TreeNode(" + this.name + ")";
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/UtilityIterablesTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/UtilityIterablesTests.java
deleted file mode 100644
index 9975546..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterables/UtilityIterablesTests.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterables;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * decentralize test creation code
- */
-public class UtilityIterablesTests {
-
-	public static Test suite() {
-		TestSuite suite = new TestSuite(UtilityIterablesTests.class.getPackage().getName());
-
-		suite.addTestSuite(ArrayIterableTests.class);
-		suite.addTestSuite(ArrayListIterableTests.class);
-		suite.addTestSuite(ChainIterableTests.class);
-		suite.addTestSuite(CompositeIterableTests.class);
-		suite.addTestSuite(CompositeListIterableTests.class);
-		suite.addTestSuite(EmptyIterableTests.class);
-		suite.addTestSuite(EmptyListIterableTests.class);
-		suite.addTestSuite(FilteringIterableTests.class);
-		suite.addTestSuite(SuperIterableWrapperTests.class);
-		suite.addTestSuite(GraphIterableTests.class);
-		suite.addTestSuite(LiveCloneIterableTests.class);
-		suite.addTestSuite(LiveCloneListIterableTests.class);
-		suite.addTestSuite(PeekableIterableTests.class);
-		suite.addTestSuite(QueueIterableTests.class);
-		suite.addTestSuite(ReadOnlyCompositeListIterableTests.class);
-		suite.addTestSuite(ReadOnlyIterableTests.class);
-		suite.addTestSuite(ReadOnlyListIterableTests.class);
-		suite.addTestSuite(SingleElementIterableTests.class);
-		suite.addTestSuite(SingleElementListIterableTests.class);
-		suite.addTestSuite(SnapshotCloneIterableTests.class);
-		suite.addTestSuite(SnapshotCloneListIterableTests.class);
-		suite.addTestSuite(StackIterableTests.class);
-		suite.addTestSuite(TransformationIterableTests.class);
-		suite.addTestSuite(TransformationListIterableTests.class);
-		suite.addTestSuite(TreeIterableTests.class);
-
-		return suite;
-	}
-
-	private UtilityIterablesTests() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ArrayIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ArrayIteratorTests.java
deleted file mode 100644
index 7b50a06..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ArrayIteratorTests.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
-
-@SuppressWarnings("nls")
-public class ArrayIteratorTests extends TestCase {
-
-	public ArrayIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testHasNext() {
-		int i = 0;
-		for (Iterator<String> stream = this.buildIterator(); stream.hasNext(); ) {
-			stream.next();
-			i++;
-		}
-		assertEquals(this.buildArray().length, i);
-	}
-
-	public void testNext() {
-		int i = 1;
-		for (Iterator<String> stream = this.buildIterator(); stream.hasNext(); ) {
-			assertEquals("bogus element", i++, Integer.parseInt(stream.next()));
-		}
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		Iterator<String> stream = this.buildIterator();
-		String string = null;
-		while (stream.hasNext()) {
-			string = stream.next();
-		}
-		try {
-			string = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
-	}
-
-	public void testUnsupportedOperationException() {
-		boolean exCaught = false;
-		for (Iterator<String> stream = this.buildIterator(); stream.hasNext(); ) {
-			if (stream.next().equals("3")) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	public void testIllegalArgumentException() {
-		this.triggerIllegalArgumentException(-1, 1);
-		this.triggerIllegalArgumentException(8, 1);
-		this.triggerIllegalArgumentException(0, -1);
-		this.triggerIllegalArgumentException(0, 9);
-	}
-
-	public void testGenerics() {
-		Integer[] integers = new Integer[3];
-		integers[0] = new Integer(0);
-		integers[1] = new Integer(1);
-		integers[2] = new Integer(2);
-		int i = 0;
-		for (Iterator<Number> stream = this.buildGenericIterator(integers); stream.hasNext();) {
-			assertEquals(i++, stream.next().intValue());
-		}
-		assertEquals(integers.length, i);
-	}
-
-	Iterator<Number> buildGenericIterator(Integer[] integers) {
-		return new ArrayIterator<Number>(integers);
-	}
-
-	public void testVarargs() {
-		int i = 0;
-		for (Iterator<Number> stream = this.buildVarArgIterator(); stream.hasNext();) {
-			assertEquals(i++, stream.next().intValue());
-		}
-		assertEquals(3, i);
-	}
-
-	Iterator<Number> buildVarArgIterator() {
-		return new ArrayIterator<Number>(new Integer(0), new Integer(1), new Integer(2));
-	}
-
-	void triggerIllegalArgumentException(int start, int length) {
-		boolean exCaught = false;
-		Iterator<String> stream = null;
-		try {
-			stream = this.buildIterator(start, length);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue("IllegalArgumentException not thrown: " + stream, exCaught);
-	}
-
-	Iterator<String> buildIterator() {
-		return this.buildIterator(this.buildArray());
-	}
-
-	Iterator<String> buildIterator(String[] array) {
-		return new ArrayIterator<String>(array);
-	}
-
-	Iterator<String> buildIterator(int start, int length) {
-		return this.buildIterator(this.buildArray(), start, length);
-	}
-
-	Iterator<String> buildIterator(String[] array, int start, int length) {
-		return new ArrayIterator<String>(array, start, length);
-	}
-
-	String[] buildArray() {
-		return new String[] { "1", "2", "3", "4", "5", "6", "7", "8" };
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ArrayListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ArrayListIteratorTests.java
deleted file mode 100644
index 7d1b906..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ArrayListIteratorTests.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.Iterator;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.iterators.ArrayListIterator;
-
-@SuppressWarnings("nls")
-public class ArrayListIteratorTests extends ArrayIteratorTests {
-
-	public ArrayListIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testHasPrevious() {
-		ListIterator<String> stream = this.buildListIterator();
-		while (stream.hasNext()) {
-			stream.next();
-		}
-		int i = 0;
-		while (stream.hasPrevious()) {
-			stream.previous();
-			i++;
-		}
-		assertEquals(this.buildArray().length, i);
-	}
-
-	public void testPrevious() {
-		ListIterator<String> stream = this.buildListIterator();
-		while (stream.hasNext()) {
-			stream.next();
-		}
-		int i = this.buildArray().length;
-		while (stream.hasPrevious()) {
-			assertEquals("bogus element", i--, Integer.parseInt(stream.previous()));
-		}
-	}
-
-	public void testNextIndex() {
-		int i = 0;
-		ListIterator<String> stream = this.buildListIterator();
-		while (stream.hasNext()) {
-			assertEquals(i, stream.nextIndex());
-			stream.next();
-			i++;
-		}
-		assertEquals(i, stream.nextIndex());
-	}
-
-	public void testPreviousIndex() {
-		int i = 0;
-		ListIterator<String> stream = this.buildListIterator();
-		while (stream.hasNext()) {
-			assertEquals(i - 1, stream.previousIndex());
-			stream.next();
-			i++;
-		}
-		assertEquals(i - 1, stream.previousIndex());
-	}
-
-	@Override
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		ListIterator<String> stream = this.buildListIterator();
-		String string = null;
-		try {
-			string = stream.previous();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
-	}
-
-	public void testUnsupportedOperationExceptionAdd() {
-		boolean exCaught = false;
-		for (ListIterator<String> stream = this.buildListIterator(); stream.hasNext();) {
-			if (stream.next().equals("3")) {
-				try {
-					stream.add("3.5");
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	public void testUnsupportedOperationExceptionSet() {
-		boolean exCaught = false;
-		for (ListIterator<String> stream = this.buildListIterator(); stream.hasNext();) {
-			if (stream.next().equals("3")) {
-				try {
-					stream.set("three");
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	@Override
-	Iterator<Number> buildGenericIterator(Integer[] integers) {
-		return new ArrayListIterator<Number>(integers);
-	}
-
-	@Override
-	Iterator<Number> buildVarArgIterator() {
-		return new ArrayListIterator<Number>(new Integer(0), new Integer(1), new Integer(2));
-	}
-
-	private ListIterator<String> buildListIterator() {
-		return this.buildListIterator(this.buildArray());
-	}
-
-	private ListIterator<String> buildListIterator(String[] array) {
-		return new ArrayListIterator<String>(array);
-	}
-
-	@Override
-	Iterator<String> buildIterator(String[] array) {
-		return new ArrayListIterator<String>(array);
-	}
-
-	@Override
-	Iterator<String> buildIterator(String[] array, int start, int length) {
-		return new ArrayListIterator<String>(array, start, length);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ChainIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ChainIteratorTests.java
deleted file mode 100644
index e899416..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ChainIteratorTests.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.AbstractCollection;
-import java.util.AbstractList;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import java.util.Vector;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterators.ChainIterator;
-
-@SuppressWarnings("nls")
-public class ChainIteratorTests extends TestCase {
-	private final static Class<?>[] VECTOR_HIERARCHY = { Vector.class, AbstractList.class, AbstractCollection.class, Object.class };
-
-	public ChainIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testHasNext() {
-		int i = 0;
-		for (Iterator<Class<?>> stream = this.buildIterator(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(VECTOR_HIERARCHY.length, i);
-	}
-
-	public void testInnerHasNext() {
-		int i = 0;
-		for (Iterator<Class<?>> stream = this.buildInnerIterator(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(VECTOR_HIERARCHY.length, i);
-	}
-
-	public void testNext() {
-		int i = 0;
-		for (Iterator<Class<?>> stream = this.buildIterator(); stream.hasNext(); i++) {
-			assertEquals("bogus link", VECTOR_HIERARCHY[i], stream.next());
-		}
-	}
-
-	public void testInnerNext() {
-		int i = 0;
-		for (Iterator<Class<?>> stream = this.buildInnerIterator(); stream.hasNext(); i++) {
-			assertEquals("bogus link", VECTOR_HIERARCHY[i], stream.next());
-		}
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		Iterator<Class<?>> stream = this.buildIterator();
-		Class<?> javaClass = null;
-		while (stream.hasNext()) {
-			javaClass = stream.next();
-		}
-		try {
-			javaClass = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + javaClass, exCaught);
-	}
-
-	public void testUnsupportedOperationException() {
-		boolean exCaught = false;
-		for (Iterator<Class<?>> stream = this.buildIterator(); stream.hasNext();) {
-			if (stream.next() == AbstractCollection.class) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	private Iterator<Class<?>> buildIterator() {
-		return this.buildChainIterator(Vector.class, this.buildLinker());
-	}
-
-	private Iterator<Class<?>> buildInnerIterator() {
-		return this.buildInnerChainIterator(Vector.class);
-	}
-
-	private Iterator<Class<?>> buildChainIterator(Class<?> startLink, ChainIterator.Linker<Class<?>> linker) {
-		return new ChainIterator<Class<?>>(startLink, linker);
-	}
-
-	private ChainIterator.Linker<Class<?>> buildLinker() {
-		// chain up the class's hierarchy
-		return new ChainIterator.Linker<Class<?>>() {
-			public Class<?> nextLink(Class<?> currentLink) {
-				return currentLink.getSuperclass();
-			}
-		};
-	}
-
-	private Iterator<Class<?>> buildInnerChainIterator(Class<?> startLink) {
-		// chain up the class's hierarchy
-		return new ChainIterator<Class<?>>(startLink) {
-			@Override
-			protected Class<?> nextLink(Class<?> currentLink) {
-				return currentLink.getSuperclass();
-			}
-		};
-	}
-
-	public void testInvalidChainIterator() {
-		// missing method override
-		Iterator<Class<?>> iterator = new ChainIterator<Class<?>>(Vector.class);
-		boolean exCaught = false;
-		try {
-			Class<?> c = iterator.next();
-			fail("invalid class: " + c.getName());
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown", exCaught);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/CloneIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/CloneIteratorTests.java
deleted file mode 100644
index 254d05c..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/CloneIteratorTests.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.tests.internal.MultiThreadedTestCase;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-
-@SuppressWarnings("nls")
-public class CloneIteratorTests
-	extends MultiThreadedTestCase
-{
-	Collection<String> originalCollection;
-
-	private Collection<String> concurrentCollection;
-
-	public CloneIteratorTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.originalCollection = this.buildCollection();
-	}
-
-	public void testHasNext() {
-		int originalSize = this.originalCollection.size();
-		int i = 0;
-		for (Iterator<String> stream = this.buildCloneIterator(); stream.hasNext();) {
-			stream.next();
-			// should allow concurrent modification
-			this.originalCollection.add("foo");
-			i++;
-		}
-		assertTrue(originalSize != this.originalCollection.size());
-		assertEquals(originalSize, i);
-	}
-
-	public void testNext() {
-		Iterator<String> nestedIterator = this.originalCollection.iterator();
-		for (Iterator<String> stream = this.buildCloneIterator(); stream.hasNext();) {
-			assertEquals("bogus element", nestedIterator.next(), stream.next());
-		}
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		Iterator<String> stream = this.buildCloneIterator();
-		String string = null;
-		while (stream.hasNext()) {
-			string = stream.next();
-		}
-		try {
-			string = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
-	}
-
-	public void testRemoveDefault() {
-		boolean exCaught = false;
-		for (Iterator<String> stream = this.buildCloneIterator(); stream.hasNext();) {
-			if (stream.next().equals("three")) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	public void testRemoveEliminator() {
-		CloneIterator.Remover<String> eliminator = new CloneIterator.Remover<String>() {
-			public void remove(String element) {
-				CloneIteratorTests.this.originalCollection.remove(element);
-			}
-		};
-		this.verifyRemove(new CloneIterator<String>(this.originalCollection, eliminator));
-	}
-
-	public void testRemoveSubclass() {
-		this.verifyRemove(new CloneIterator<String>(this.originalCollection) {
-			@Override
-			protected void remove(String current) {
-				CloneIteratorTests.this.originalCollection.remove(current);
-			}
-		});
-	}
-
-	/**
-	 * Test concurrent access: First build a clone iterator in a separate thread
-	 * that hangs momentarily during its construction; then modify the shared
-	 * collection in this thread. This would cause a
-	 * ConcurrentModificationException in the other thread if the clone iterator
-	 * were not synchronized on the original collection.
-	 */
-	public void testConcurrentAccess() throws Exception {
-		SlowCollection<String> slow = new SlowCollection<String>();
-		this.populateCollection(slow);
-		// using the unsynchronized collection will cause the test to fail
-		//		this.originalCollection = slow;
-		this.originalCollection = Collections.synchronizedCollection(slow);
-
-		this.concurrentCollection = new ArrayList<String>();
-		Thread thread = this.buildThread(this.buildRunnable());
-		thread.start();
-		while ( ! slow.hasStartedClone()) {
-			// wait for the other thread to start the clone...
-			Thread.yield();
-		}
-		// ...then sneak in an extra element
-		this.originalCollection.add("seventeen");
-		thread.join();
-		Collection<String> expected = new ArrayList<String>();
-		this.populateCollection(expected);
-		assertEquals(expected, this.concurrentCollection);
-	}
-
-	private Runnable buildRunnable() {
-		return new TestRunnable() {
-			@Override
-			protected void run_() throws Throwable {
-				CloneIteratorTests.this.loopWithCloneIterator();
-			}
-		};
-	}
-
-	/**
-	 * use a clone iterator to loop over the "slow" collection and copy its
-	 * contents to the concurrent collection
-	 */
-	void loopWithCloneIterator() {
-		for (Iterator<String> stream = this.buildCloneIterator(); stream.hasNext();) {
-			this.concurrentCollection.add(stream.next());
-		}
-	}
-
-	private void verifyRemove(Iterator<String> iterator) {
-		Object removed = "three";
-		assertTrue(this.originalCollection.contains(removed));
-		// try to remove before calling #next()
-		boolean exCaught = false;
-		try {
-			iterator.remove();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue("IllegalStateException not thrown", exCaught);
-		while (iterator.hasNext()) {
-			if (iterator.next().equals(removed)) {
-				iterator.remove();
-				// try to remove twice
-				exCaught = false;
-				try {
-					iterator.remove();
-				} catch (IllegalStateException ex) {
-					exCaught = true;
-				}
-				assertTrue("IllegalStateException not thrown", exCaught);
-			}
-		}
-		assertFalse(this.originalCollection.contains(removed));
-	}
-
-	private Iterator<String> buildCloneIterator() {
-		return this.buildCloneIterator(this.originalCollection);
-	}
-
-	private Iterator<String> buildCloneIterator(Collection<String> c) {
-		return new CloneIterator<String>(c);
-	}
-
-	private Collection<String> buildCollection() {
-		Collection<String> c = this.buildEmptyCollection();
-		this.populateCollection(c);
-		return c;
-	}
-
-	protected Collection<String> buildEmptyCollection() {
-		return new ArrayList<String>();
-	}
-
-	private void populateCollection(Collection<String> c) {
-		c.add("one");
-		c.add("two");
-		c.add("three");
-		c.add("four");
-		c.add("five");
-		c.add("six");
-		c.add("seven");
-		c.add("eight");
-	}
-
-	// ********** custom collection **********
-	static class SlowCollection<E> extends ArrayList<E> {
-		private static final long serialVersionUID = 1L;
-		private boolean hasStartedClone = false;
-
-		public SlowCollection() {
-			super();
-		}
-
-		@Override
-		public Object[] toArray() {
-			this.setHasStartedClone(true);
-			// take a little snooze before returning the array
-			TestTools.sleep(100);
-			return super.toArray();
-		}
-
-		synchronized void setHasStartedClone(boolean hasStartedClone) {
-			this.hasStartedClone = hasStartedClone;
-		}
-
-		synchronized boolean hasStartedClone() {
-			return this.hasStartedClone;
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/CloneListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/CloneListIteratorTests.java
deleted file mode 100644
index 37a5f13..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/CloneListIteratorTests.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.iterators.CloneListIterator;
-import org.eclipse.persistence.tools.utility.tests.internal.MultiThreadedTestCase;
-
-@SuppressWarnings("nls")
-public class CloneListIteratorTests
-	extends MultiThreadedTestCase
-{
-	List<String> originalList;
-
-	private List<String> concurrentList;
-
-	public CloneListIteratorTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.originalList = this.buildList();
-	}
-
-	public void testHasNext() {
-		int originalSize = this.originalList.size();
-		int i = 0;
-		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
-			stream.next();
-			// should allow concurrent modification
-			this.originalList.add("foo");
-			i++;
-		}
-		assertTrue(originalSize != this.originalList.size());
-		assertEquals(originalSize, i);
-	}
-
-	public void testNext() {
-		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
-		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
-			assertEquals("bogus element", nestedListIterator.next(), stream.next());
-		}
-	}
-
-	public void testIndex() {
-		ListIterator<String> cloneListIterator = this.buildCloneListIterator();
-		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
-		for (int i = 0; i < 7; i++) {
-			nestedListIterator.next();
-			cloneListIterator.next();
-			assertEquals("bogus index", nestedListIterator.nextIndex(), cloneListIterator.nextIndex());
-			assertEquals("bogus index", nestedListIterator.previousIndex(), cloneListIterator.previousIndex());
-		}
-
-		for (int i = 0; i < 3; i++) {
-			nestedListIterator.previous();
-			cloneListIterator.previous();
-			assertEquals("bogus index", nestedListIterator.nextIndex(), cloneListIterator.nextIndex());
-			assertEquals("bogus index", nestedListIterator.previousIndex(), cloneListIterator.previousIndex());
-		}
-
-		while (nestedListIterator.hasNext()) {
-			nestedListIterator.next();
-			cloneListIterator.next();
-			assertEquals("bogus index", nestedListIterator.nextIndex(), cloneListIterator.nextIndex());
-			assertEquals("bogus index", nestedListIterator.previousIndex(), cloneListIterator.previousIndex());
-		}
-	}
-
-	public void testHasPrevious() {
-		int originalSize = this.originalList.size();
-		int i = 0;
-		ListIterator<String> stream = this.buildCloneListIterator();
-		while (stream.hasNext()) {
-			stream.next();
-			this.originalList.add("foo");
-			i++;
-		}
-		assertTrue(originalSize != this.originalList.size());
-		originalSize = this.originalList.size();
-		while (stream.hasPrevious()) {
-			stream.previous();
-			// should allow concurrent modification
-			this.originalList.add("bar");
-			i--;
-		}
-		assertTrue(originalSize != this.originalList.size());
-		assertEquals(0, i);
-	}
-
-	public void testPrevious() {
-		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
-		ListIterator<String> stream = this.buildCloneListIterator();
-		while (stream.hasNext()) {
-			nestedListIterator.next();
-			stream.next();
-		}
-		while (stream.hasPrevious()) {
-			assertEquals("bogus element", nestedListIterator.previous(), stream.previous());
-		}
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		ListIterator<String> stream = this.buildCloneListIterator();
-		String string = null;
-		while (stream.hasNext()) {
-			string = stream.next();
-		}
-		try {
-			string = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
-
-		exCaught = false;
-		while (stream.hasPrevious()) {
-			string = stream.previous();
-		}
-		try {
-			string = stream.previous();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
-	}
-
-	public void testModifyDefault() {
-		boolean exCaught = false;
-		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
-			if (stream.next().equals("three")) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-
-		exCaught = false;
-		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
-			if (stream.next().equals("three")) {
-				try {
-					stream.add("three and a half");
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-
-		exCaught = false;
-		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
-			if (stream.next().equals("three")) {
-				try {
-					stream.set("another three");
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	public void testModifyMutatorNext() {
-		this.verifyModifyNext(new CloneListIterator<String>(this.originalList, this.buildMutator()));
-	}
-
-	public void testModifyMutatorPrevious() {
-		this.verifyModifyPrevious(new CloneListIterator<String>(this.originalList, this.buildMutator()));
-	}
-
-	private CloneListIterator.Mutator<String> buildMutator() {
-		return new CloneListIterator.Mutator<String>() {
-			public void add(int index, String o) {
-				CloneListIteratorTests.this.originalList.add(index, o);
-			}
-
-			public void remove(int index) {
-				CloneListIteratorTests.this.originalList.remove(index);
-			}
-
-			public void set(int index, String o) {
-				CloneListIteratorTests.this.originalList.set(index, o);
-			}
-		};
-	}
-
-	public void testModifySubclassNext() {
-		this.verifyModifyNext(this.buildSubclass());
-	}
-
-	public void testModifySubclassPrevious() {
-		this.verifyModifyPrevious(this.buildSubclass());
-	}
-
-	private ListIterator<String> buildSubclass() {
-		return new CloneListIterator<String>(this.originalList) {
-			@Override
-			protected void add(int currentIndex, String o) {
-				CloneListIteratorTests.this.originalList.add(currentIndex, o);
-			}
-
-			@Override
-			protected void remove(int currentIndex) {
-				CloneListIteratorTests.this.originalList.remove(currentIndex);
-			}
-
-			@Override
-			protected void set(int currentIndex, String o) {
-				CloneListIteratorTests.this.originalList.set(currentIndex, o);
-			}
-		};
-	}
-
-	private void verifyModifyNext(ListIterator<String> iterator) {
-		String removed = "three";
-		String addedAfter = "five";
-		String added = "five and a half";
-		String replaced = "seven";
-		String replacement = "another seven";
-		assertTrue(this.originalList.contains(removed));
-		assertTrue(this.originalList.contains(addedAfter));
-		assertTrue(this.originalList.contains(replaced));
-		// try to remove before calling #next()
-		boolean exCaught = false;
-		try {
-			iterator.remove();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-		while (iterator.hasNext()) {
-			String next = iterator.next();
-			if (next.equals(addedAfter)) {
-				iterator.add(added);
-			}
-			if (next.equals(removed)) {
-				iterator.remove();
-				// try to remove twice
-				exCaught = false;
-				try {
-					iterator.remove();
-				} catch (IllegalStateException ex) {
-					exCaught = true;
-				}
-				assertTrue(exCaught);
-			}
-			if (next.equals(replaced)) {
-				iterator.set(replacement);
-			}
-		}
-		assertTrue(this.originalList.contains(added));
-		assertFalse(this.originalList.contains(removed));
-		assertFalse(this.originalList.contains(replaced));
-		assertTrue(this.originalList.contains(replacement));
-	}
-
-	private void verifyModifyPrevious(ListIterator<String> iterator) {
-		String removed = "three";
-		String addedBefore = "five";
-		String added = "four and a half";
-		String replaced = "seven";
-		String replacement = "another seven";
-		assertTrue(this.originalList.contains(removed));
-		assertTrue(this.originalList.contains(addedBefore));
-		assertTrue(this.originalList.contains(replaced));
-		while (iterator.hasNext()) {
-			iterator.next();
-		}
-		while (iterator.hasPrevious()) {
-			Object previous = iterator.previous();
-			if (previous.equals(addedBefore)) {
-				iterator.add(added);
-			}
-			if (previous.equals(removed)) {
-				iterator.remove();
-				// try to remove twice
-				boolean exCaught = false;
-				try {
-					iterator.remove();
-				} catch (IllegalStateException ex) {
-					exCaught = true;
-				}
-				assertTrue("IllegalStateException not thrown", exCaught);
-			}
-			if (previous.equals(replaced)) {
-				iterator.set(replacement);
-			}
-		}
-		assertTrue(this.originalList.contains(added));
-		assertFalse(this.originalList.contains(removed));
-		assertFalse(this.originalList.contains(replaced));
-		assertTrue(this.originalList.contains(replacement));
-	}
-
-	private ListIterator<String> buildCloneListIterator() {
-		return this.buildCloneListIterator(this.originalList);
-	}
-
-	private ListIterator<String> buildCloneListIterator(List<String> list) {
-		return new CloneListIterator<String>(list);
-	}
-
-	private ListIterator<String> buildNestedListIterator() {
-		return this.originalList.listIterator();
-	}
-
-	private List<String> buildList() {
-		List<String> list = this.buildEmptyList();
-		this.populateList(list);
-		return list;
-	}
-
-	private void populateList(List<String> list) {
-		list.add("zero");
-		list.add("one");
-		list.add("two");
-		list.add("three");
-		list.add("four");
-		list.add("five");
-		list.add("six");
-		list.add("seven");
-		list.add("eight");
-		list.add("nine");
-	}
-
-	protected List<String> buildEmptyList() {
-		return new ArrayList<String>();
-	}
-
-	/**
-	 * Test concurrent access: First build a clone iterator in a separate thread
-	 * that hangs momentarily during its construction; then modify the shared
-	 * collection in this thread. This would cause a
-	 * ConcurrentModificationException in the other thread if the clone iterator
-	 * were not synchronized on the original collection.
-	 */
-	public void testConcurrentAccess() throws Exception {
-		CloneIteratorTests.SlowCollection<String> slow = new CloneIteratorTests.SlowCollection<String>();
-		this.populateList(slow);
-		// using the unsynchronized list will cause the test to fail
-		// this.originalList = slow;
-		this.originalList = Collections.synchronizedList(slow);
-
-		this.concurrentList = new ArrayList<String>();
-		Thread thread = this.buildThread(this.buildRunnable());
-		thread.start();
-		while ( ! slow.hasStartedClone()) {
-			// wait for the other thread to start the clone...
-			Thread.yield();
-		}
-		// ...then sneak in an extra element
-		this.originalList.add("seventeen");
-		thread.join();
-		List<String> expected = new ArrayList<String>();
-		this.populateList(expected);
-		assertEquals(expected, this.concurrentList);
-	}
-
-	private Runnable buildRunnable() {
-		return new TestRunnable() {
-			@Override
-			protected void run_() throws Throwable {
-				CloneListIteratorTests.this.loopWithCloneListIterator();
-			}
-		};
-	}
-
-	/**
-	 * use a clone iterator to loop over the "slow" collection and copy its
-	 * contents to the concurrent collection
-	 */
-	void loopWithCloneListIterator() {
-		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
-			this.concurrentList.add(stream.next());
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/CompositeIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/CompositeIteratorTests.java
deleted file mode 100644
index 1648806..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/CompositeIteratorTests.java
+++ /dev/null
@@ -1,355 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterators.CompositeIterator;
-
-@SuppressWarnings("nls")
-public class CompositeIteratorTests extends TestCase {
-
-	public CompositeIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testHasAnother() {
-		this.verifyHasAnother(this.buildCompositeIterator());
-	}
-
-	public void testHasAnother2() {
-		this.verifyHasAnother(this.buildCompositeIterator2());
-	}
-
-	public void testHasAnother3() {
-		this.verifyHasAnother(this.buildCompositeIterator3());
-	}
-
-	void verifyHasAnother(Iterator<String> stream) {
-		this.verifyHasAnother(8, stream);
-	}
-
-	void verifyHasAnother(int expected, Iterator<String> stream) {
-		int i = 0;
-		while (stream.hasNext()) {
-			stream.next();
-			i++;
-		}
-		assertEquals(expected, i);
-	}
-
-	public void testAnother() {
-		this.verifyAnother(this.buildCompositeIterator());
-	}
-
-	public void testAnother2() {
-		this.verifyAnother(this.buildCompositeIterator2());
-	}
-
-	public void testAnother3() {
-		this.verifyAnother(this.buildCompositeIterator3());
-	}
-
-	void verifyAnother(Iterator<String> stream) {
-		this.verifyAnother(1, stream);
-	}
-
-	void verifyAnother(int start, Iterator<String> stream) {
-		int index = start;
-		while (stream.hasNext()) {
-			assertEquals("bogus element", String.valueOf(index++), stream.next().substring(0, 1));
-		}
-	}
-
-	public void testRemove() {
-		this.verifyRemove();
-	}
-
-	protected void verifyRemove() {
-		List<String> list1 = this.buildList1();
-		Object lastElement1 = list1.get(list1.size() - 1);
-		List<String> list2 = this.buildList2();
-		List<String> list3 = this.buildList3();
-
-		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
-		list.add(list1.listIterator());
-		list.add(list2.listIterator());
-		list.add(list3.listIterator());
-
-		Iterator<String> stream = this.buildCompositeIterator(list.listIterator());
-		while (stream.hasNext()) {
-			Object next = stream.next();
-			if (next.equals("333")) {
-				stream.remove();
-			}
-			// test special case - where we are between iterators
-			if (next.equals(lastElement1)) {
-				// this will trigger the next iterator to be loaded
-				stream.hasNext();
-				// now try to remove from the previous iterator
-				stream.remove();
-			}
-		}
-		stream.remove();
-
-		assertEquals("nothing removed from collection 1", this.buildList1().size() - 2, list1.size());
-		assertFalse("element still in collection 1", list1.contains("333"));
-		assertFalse("last element still in collection 1", list1.contains(lastElement1));
-		assertTrue("wrong element removed from collection 1", list1.contains("22"));
-
-		assertEquals("nothing removed from collection 3", this.buildList3().size() - 1, list3.size());
-		assertFalse("element still in collection 3", list3.contains("88888888"));
-		assertTrue("wrong element removed from collection 3", list3.contains("666666"));
-	}
-
-	public void testSingleElement() {
-		String item = "0";
-		this.verifyHasAnother(9, this.buildCompositeIterator(item, this.buildCompositeIterator()));
-		this.verifyAnother(0, this.buildCompositeIterator(item, this.buildCompositeIterator()));
-	}
-
-	public void testNoSuchElementException() {
-		this.verifyNoSuchElementException(this.buildCompositeIterator());
-	}
-
-	void verifyNoSuchElementException(Iterator<String> stream) {
-		boolean exCaught = false;
-		String string = null;
-		while (stream.hasNext()) {
-			string = stream.next();
-		}
-		try {
-			string = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
-	}
-
-	public void testUnsupportedOperationException() {
-		this.verifyUnsupportedOperationException(this.buildUnmodifiableCompositeIterator());
-	}
-
-	void verifyUnsupportedOperationException(Iterator<String> stream) {
-		boolean exCaught = false;
-		while (stream.hasNext()) {
-			Object string = stream.next();
-			if (string.equals("333")) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	public void testIllegalStateException() {
-		this.verifyIllegalStateException();
-	}
-
-	void verifyIllegalStateException() {
-		this.verifyIllegalStateException(this.buildCompositeIterator());
-	}
-
-	void verifyIllegalStateException(Iterator<String> stream) {
-		boolean exCaught = false;
-		try {
-			stream.remove();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue("IllegalStateException not thrown", exCaught);
-	}
-
-	public void testEmptyHasAnother1() {
-		this.verifyEmptyHasAnother(this.buildEmptyCompositeIterator1());
-	}
-
-	void verifyEmptyHasAnother(Iterator<String> stream) {
-		int i = 0;
-		while (stream.hasNext()) {
-			stream.next();
-			i++;
-		}
-		assertEquals(0, i);
-	}
-
-	public void testEmptyNoSuchElementException1() {
-		this.verifyNoSuchElementException(this.buildEmptyCompositeIterator1());
-	}
-
-	public void testEmptyIllegalStateException1() {
-		this.verifyEmptyIllegalStateException1();
-	}
-
-	void verifyEmptyIllegalStateException1() {
-		this.verifyIllegalStateException(this.buildEmptyCompositeIterator1());
-	}
-
-	public void testEmptyHasAnother2() {
-		this.verifyEmptyHasAnother(this.buildEmptyCompositeIterator2());
-	}
-
-	public void testEmptyNoSuchElementException2() {
-		this.verifyNoSuchElementException(this.buildEmptyCompositeIterator2());
-	}
-
-	public void testEmptyIllegalStateException2() {
-		this.verifyEmptyIllegalStateException2();
-	}
-
-	void verifyEmptyIllegalStateException2() {
-		this.verifyIllegalStateException(this.buildEmptyCompositeIterator2());
-	}
-
-	Iterator<String> buildCompositeIterator() {
-		return this.buildCompositeIterator(this.buildIterators());
-	}
-
-	Iterator<String> buildEmptyCompositeIterator1() {
-		return this.buildCompositeIterator(this.buildEmptyIterators1());
-	}
-
-	Iterator<String> buildEmptyCompositeIterator2() {
-		return this.buildCompositeIterator(this.buildEmptyIterators2());
-	}
-
-	Iterator<String> buildUnmodifiableCompositeIterator() {
-		return this.buildCompositeIterator(this.buildUnmodifiableIterators());
-	}
-
-	// leave unchecked so we can override in subclass
-	@SuppressWarnings({"unchecked", "rawtypes"})
-	Iterator<String> buildCompositeIterator(Iterator iterators) {
-		return new CompositeIterator<String>(iterators);
-	}
-
-	// use vararg constructor
-	@SuppressWarnings("unchecked")
-	Iterator<String> buildCompositeIterator2() {
-		return new CompositeIterator<String>(this.buildIterator1(), this.buildIterator2(), this.buildIterator3());
-	}
-
-	// use vararg constructor
-	@SuppressWarnings("unchecked")
-	Iterator<String> buildCompositeIterator3() {
-		return new CompositeIterator<String>(new Iterator[] { this.buildIterator1(), this.buildIterator2(), this.buildIterator3() });
-	}
-
-	Iterator<String> buildCompositeIterator(String string, Iterator<String> iterator) {
-		return new CompositeIterator<String>(string, iterator);
-	}
-
-	ListIterator<Iterator<String>> buildIterators() {
-		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
-		list.add(this.buildIterator1());
-		list.add(this.buildIterator2());
-		list.add(this.buildIterator3());
-		return list.listIterator();
-	}
-
-	ListIterator<Iterator<String>> buildEmptyIterators1() {
-		return this.buildEmptyIteratorIterator();
-	}
-
-	ListIterator<Iterator<String>> buildEmptyIterators2() {
-		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
-		list.add(this.buildEmptyStringIterator());
-		list.add(this.buildEmptyStringIterator());
-		list.add(this.buildEmptyStringIterator());
-		return list.listIterator();
-	}
-
-	ListIterator<Iterator<String>> buildUnmodifiableIterators() {
-		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
-		list.add(this.buildUnmodifiableIterator1());
-		list.add(this.buildUnmodifiableIterator2());
-		list.add(this.buildUnmodifiableIterator3());
-		return list.listIterator();
-	}
-
-	ListIterator<String> buildIterator1() {
-		return this.buildList1().listIterator();
-	}
-
-	ListIterator<String> buildIterator2() {
-		return this.buildList2().listIterator();
-	}
-
-	ListIterator<String> buildIterator3() {
-		return this.buildList3().listIterator();
-	}
-
-	ListIterator<String> buildUnmodifiableIterator1() {
-		return this.buildUnmodifiableList1().listIterator();
-	}
-
-	ListIterator<String> buildUnmodifiableIterator2() {
-		return this.buildUnmodifiableList2().listIterator();
-	}
-
-	ListIterator<String> buildUnmodifiableIterator3() {
-		return this.buildUnmodifiableList3().listIterator();
-	}
-
-	ListIterator<Iterator<String>> buildEmptyIteratorIterator() {
-		return (new ArrayList<Iterator<String>>()).listIterator();
-	}
-
-	ListIterator<String> buildEmptyStringIterator() {
-		return (new ArrayList<String>()).listIterator();
-	}
-
-	List<String> buildList1() {
-		List<String> list = new ArrayList<String>();
-		list.add("1");
-		list.add("22");
-		list.add("333");
-		list.add("4444");
-		return list;
-	}
-
-	List<String> buildList2() {
-		return new ArrayList<String>();
-	}
-
-	List<String> buildList3() {
-		List<String> list = new ArrayList<String>();
-		list.add("55555");
-		list.add("666666");
-		list.add("7777777");
-		list.add("88888888");
-		return list;
-	}
-
-	List<String> buildUnmodifiableList1() {
-		return Collections.unmodifiableList(this.buildList1());
-	}
-
-	List<String> buildUnmodifiableList2() {
-		return Collections.unmodifiableList(this.buildList2());
-	}
-
-	List<String> buildUnmodifiableList3() {
-		return Collections.unmodifiableList(this.buildList3());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/CompositeListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/CompositeListIteratorTests.java
deleted file mode 100644
index 81e1e87..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/CompositeListIteratorTests.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.iterators.CompositeListIterator;
-
-@SuppressWarnings("nls")
-public class CompositeListIteratorTests extends ReadOnlyCompositeListIteratorTests {
-
-	public CompositeListIteratorTests(String name) {
-		super(name);
-	}
-
-	@Override
-	public void testRemove() {
-		super.testRemove();
-		List<String> list1 = this.buildList1();
-		List<String> list2 = this.buildList2();
-		List<String> list3 = this.buildList3();
-		Object firstElement3 = list3.get(0);
-
-		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
-		list.add(list1.listIterator());
-		list.add(list2.listIterator());
-		list.add(list3.listIterator());
-
-		ListIterator<String> stream = (ListIterator<String>) this.buildCompositeIterator(list.listIterator());
-		// position to end of stream
-		while (stream.hasNext()) {
-			stream.next();
-		}
-		while (stream.hasPrevious()) {
-			Object previous = stream.previous();
-			if (previous.equals("333")) {
-				stream.remove();
-			}
-			// test special case - where we are between iterators
-			if (previous.equals(firstElement3)) {
-				// this will trigger the next iterator to be loaded
-				stream.hasPrevious();
-				// now try to remove from the previous iterator
-				stream.remove();
-			}
-		}
-		stream.remove();
-
-		assertEquals("nothing removed from collection 1", this.buildList1().size() - 2, list1.size());
-		assertFalse("element still in collection 1", list1.contains("1"));
-		assertFalse("element still in collection 1", list1.contains("333"));
-
-		assertEquals("nothing removed from collection 3", this.buildList3().size() - 1, list3.size());
-		assertFalse("first element still in collection 3", list3.contains(firstElement3));
-		assertTrue("wrong element removed from collection 3", list3.contains("666666"));
-	}
-
-	public void testAdd() {
-		List<String> list1 = this.buildList1();
-		Object lastElement1 = list1.get(list1.size() - 1);
-		List<String> list2 = this.buildList2();
-		List<String> list3 = this.buildList3();
-		Object firstElement3 = list3.get(0);
-
-		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
-		list.add(list1.listIterator());
-		list.add(list2.listIterator());
-		list.add(list3.listIterator());
-
-		ListIterator<String> stream = (ListIterator<String>) this.buildCompositeIterator(list.listIterator());
-		while (stream.hasNext()) {
-			Object next = stream.next();
-			if (next.equals("333")) {
-				stream.add("3.5");
-			}
-			// test special case - where we are between iterators
-			if (next.equals(lastElement1)) {
-				// this will trigger the next iterator to be loaded
-				stream.hasNext();
-				// now try to add to the iterator
-				stream.add("something in 3");
-			}
-		}
-		stream.add("finale");
-		boolean checkForFinale = true;
-		while (stream.hasPrevious()) {
-			Object previous = stream.previous();
-			if (checkForFinale) {
-				checkForFinale = false;
-				assertEquals("added element dropped", "finale", previous);
-			}
-			if (previous.equals("333")) {
-				stream.add("2.5");
-			}
-			// test special case - where we are between iterators
-			if (previous.equals(firstElement3)) {
-				// this will trigger the next iterator to be loaded
-				stream.hasPrevious();
-				// now try to remove from the previous iterator
-				stream.add("old start of 3");
-			}
-		}
-		stream.add("prelude");
-		assertEquals("added element dropped", "prelude", stream.previous());
-
-		assertEquals("elements not added to collection 1", this.buildList1().size() + 3, list1.size());
-		assertEquals("element not added to collection 1", "prelude", list1.get(0));
-		assertEquals("element not added to collection 1", "2.5", list1.get(3));
-		assertEquals("element not added to collection 1", "3.5", list1.get(5));
-
-		assertEquals("elements not added to collection 3", this.buildList3().size() + 3, list3.size());
-		assertEquals("element not added to collection 3", "something in 3", list3.get(0));
-		assertEquals("element not added to collection 3", "old start of 3", list3.get(1));
-		assertEquals("element not added to collection 3", "finale", list3.get(list3.size() - 1));
-
-		// add to the front
-		stream = (ListIterator<String>) this.buildCompositeIterator();
-		stream.add("blah");
-		assertFalse("added element should be placed BEFORE the \"cursor\"", stream.next().equals("blah"));
-
-		stream = (ListIterator<String>) this.buildCompositeIterator();
-		stream.add("blah");
-		assertTrue("added element should be placed BEFORE the \"cursor\"", stream.previous().equals("blah"));
-
-		stream = (ListIterator<String>) this.buildCompositeIterator();
-		while (stream.hasNext()) {
-			stream.next();
-		}
-		while (stream.hasPrevious()) {
-			stream.previous();
-		}
-		stream.add("blah");
-		assertFalse("added element should be placed BEFORE the \"cursor\"", stream.next().equals("blah"));
-
-		stream = (ListIterator<String>) this.buildCompositeIterator();
-		while (stream.hasNext()) {
-			stream.next();
-		}
-		while (stream.hasPrevious()) {
-			stream.previous();
-		}
-		stream.add("blah");
-		assertTrue("added element should be placed BEFORE the \"cursor\"", stream.previous().equals("blah"));
-
-		// add to the middle
-		stream = (ListIterator<String>) this.buildCompositeIterator();
-		stream.next();
-		stream.add("blah");
-		assertFalse("added element should be placed BEFORE the \"cursor\"", stream.next().equals("blah"));
-
-		stream = (ListIterator<String>) this.buildCompositeIterator();
-		stream.next();
-		stream.add("blah");
-		assertTrue("added element should be placed BEFORE the \"cursor\"", stream.previous().equals("blah"));
-
-		stream = (ListIterator<String>) this.buildCompositeIterator();
-		while (stream.hasNext()) {
-			stream.next();
-		}
-		stream.previous();
-		stream.add("blah");
-		assertFalse("added element should be placed BEFORE the \"cursor\"", stream.next().equals("blah"));
-
-		stream = (ListIterator<String>) this.buildCompositeIterator();
-		while (stream.hasNext()) {
-			stream.next();
-		}
-		stream.previous();
-		stream.add("blah");
-		assertTrue("added element should be placed BEFORE the \"cursor\"", stream.previous().equals("blah"));
-
-		// add to the end
-		stream = (ListIterator<String>) this.buildCompositeIterator();
-		while (stream.hasNext()) {
-			stream.next();
-		}
-		stream.add("blah");
-		assertFalse("added element should be placed BEFORE the \"cursor\"", stream.hasNext());
-
-		stream = (ListIterator<String>) this.buildCompositeIterator();
-		while (stream.hasNext()) {
-			stream.next();
-		}
-		stream.add("blah");
-		assertTrue("added element should be placed BEFORE the \"cursor\"", stream.previous().equals("blah"));
-	}
-
-	public void testSet() {
-		List<String> list1 = this.buildList1();
-		Object lastElement1 = list1.get(list1.size() - 1);
-		List<String> list2 = this.buildList2();
-		List<String> list3 = this.buildList3();
-		Object firstElement3 = list3.get(0);
-
-		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
-		list.add(list1.listIterator());
-		list.add(list2.listIterator());
-		list.add(list3.listIterator());
-
-		ListIterator<String> stream = (ListIterator<String>) this.buildCompositeIterator(list.listIterator());
-		// position to end of stream
-		while (stream.hasNext()) {
-			Object next = stream.next();
-			if (next.equals("333")) {
-				stream.set("333a");
-			}
-			// test special case - where we are between iterators
-			if (next.equals(lastElement1)) {
-				// this will trigger the next iterator to be loaded
-				stream.hasNext();
-				// now try to remove from the previous iterator
-				stream.set("end of 1");
-			}
-		}
-		while (stream.hasPrevious()) {
-			Object previous = stream.previous();
-			if (previous.equals("22")) {
-				stream.set("22a");
-			}
-			// test special case - where we are between iterators
-			if (previous.equals(firstElement3)) {
-				// this will trigger the next iterator to be loaded
-				stream.hasPrevious();
-				// now try to remove from the previous iterator
-				stream.set("start of 3");
-			}
-		}
-
-		assertEquals("element(s) added to collection 1", this.buildList1().size(), list1.size());
-		assertEquals("element not set in collection 1", "22a", list1.get(1));
-		assertFalse("element not set in collection 1", list1.contains("22"));
-		assertEquals("element not set in collection 1", "333a", list1.get(2));
-		assertFalse("element not set in collection 1", list1.contains("333"));
-		assertEquals("element not set in collection 1", "end of 1", list1.get(list1.size() - 1));
-		assertFalse("element not set in collection 1", list1.contains(lastElement1));
-
-		assertEquals("element(s) added to collection 3", this.buildList3().size(), list3.size());
-		assertEquals("element not set in collection 3", "start of 3", list3.get(0));
-		assertFalse("element not set in collection 3", list3.contains(firstElement3));
-	}
-
-	@Override
-	public void testNextIndexPreviousIndex() {
-		int i = 0;
-		ListIterator<String> stream = (ListIterator<String>) this.buildCompositeIterator();
-		assertEquals(i, stream.nextIndex());
-		assertEquals(i - 1, stream.previousIndex());
-		while (stream.hasNext()) {
-			Object next = stream.next();
-			i++;
-			if (next.equals("333")) {
-				stream.remove();
-				i--;
-			}
-			if (next.equals("7777777")) {
-				stream.add("7.5");
-				i++;
-			}
-			assertEquals(i, stream.nextIndex());
-			assertEquals(i - 1, stream.previousIndex());
-		}
-		assertEquals("index is corrupt", 8, i);
-
-		assertEquals(i, stream.nextIndex());
-		assertEquals(i - 1, stream.previousIndex());
-		while (stream.hasPrevious()) {
-			Object previous = stream.previous();
-			i--;
-			if (previous.equals("666666")) {
-				stream.remove();
-				// removing a previous element, does not change the cursor
-			}
-			if (previous.equals("22")) {
-				stream.add("1.5");
-				i++;
-			}
-			assertEquals(i, stream.nextIndex());
-			assertEquals(i - 1, stream.previousIndex());
-		}
-		assertEquals("index is corrupt", 0, i);
-	}
-
-	@Override
-	public void testIllegalStateException() {
-		this.verifyIllegalStateException();
-	}
-
-	@Override
-	public void testEmptyIllegalStateException1() {
-		this.verifyEmptyIllegalStateException1();
-	}
-
-	@Override
-	public void testEmptyIllegalStateException2() {
-		this.verifyEmptyIllegalStateException2();
-	}
-
-	// unchecked so we can override the unchecked method in superclass
-	@Override
-	@SuppressWarnings({"unchecked", "rawtypes"})
-	Iterator<String> buildCompositeIterator(Iterator iterators) {
-		return new CompositeListIterator<String>((ListIterator<ListIterator<String>>) iterators);
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	Iterator<String> buildCompositeIterator2() {
-		return new CompositeListIterator<String>(this.buildIterator1(), this.buildIterator2(), this.buildIterator3());
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	Iterator<String> buildCompositeIterator3() {
-		return new CompositeListIterator<String>(new ListIterator[] { this.buildIterator1(), this.buildIterator2(), this.buildIterator3() });
-	}
-
-	@Override
-	ListIterator<String> buildCompositeListIterator(String string, ListIterator<String> iterator) {
-		return new CompositeListIterator<String>(string, iterator);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/EmptyIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/EmptyIteratorTests.java
deleted file mode 100644
index b57ae8d..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/EmptyIteratorTests.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterators.EmptyIterator;
-
-@SuppressWarnings("nls")
-public class EmptyIteratorTests extends TestCase {
-
-	public EmptyIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testHasNext() {
-		int i = 0;
-		for (Iterator<Object> stream = EmptyIterator.instance(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(0, i);
-	}
-
-	public void testNext() {
-		for (Iterator<String> stream = EmptyIterator.instance(); stream.hasNext();) {
-			fail("bogus element: " + stream.next());
-		}
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		Iterator<Number> stream = EmptyIterator.instance();
-		Object element = null;
-		while (stream.hasNext()) {
-			element = stream.next();
-		}
-		try {
-			element = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + element, exCaught);
-	}
-
-	public void testUnsupportedOperationException() {
-		boolean exCaught = false;
-		try {
-			EmptyIterator.instance().remove();
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/EmptyListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/EmptyListIteratorTests.java
deleted file mode 100644
index 44b873e..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/EmptyListIteratorTests.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterators.EmptyListIterator;
-
-@SuppressWarnings("nls")
-public class EmptyListIteratorTests extends TestCase {
-
-	public EmptyListIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testHasNext() {
-		int i = 0;
-		for (ListIterator<Object> stream = EmptyListIterator.instance(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(0, i);
-	}
-
-	public void testNext() {
-		for (ListIterator<Object> stream = EmptyListIterator.instance(); stream.hasNext();) {
-			fail("bogus element: " + stream.next());
-		}
-	}
-
-	public void testNextIndex() {
-		ListIterator<Object> stream = EmptyListIterator.instance();
-		assertEquals(0, stream.nextIndex());
-	}
-
-	public void testHasPrevious() {
-		ListIterator<Object> stream = EmptyListIterator.instance();
-		int i = 0;
-		while (stream.hasPrevious()) {
-			stream.previous();
-			i++;
-		}
-		assertEquals(0, i);
-
-		while (stream.hasNext()) {
-			stream.next();
-		}
-		i = 0;
-		while (stream.hasPrevious()) {
-			stream.previous();
-			i++;
-		}
-		assertEquals(0, i);
-	}
-
-	public void testPrevious() {
-		ListIterator<Object> stream = EmptyListIterator.instance();
-		while (stream.hasPrevious()) {
-			fail("bogus element: " + stream.previous());
-		}
-		while (stream.hasNext()) {
-			stream.next();
-		}
-		while (stream.hasPrevious()) {
-			fail("bogus element: " + stream.previous());
-		}
-	}
-
-	public void testPreviousIndex() {
-		ListIterator<Object> stream = EmptyListIterator.instance();
-		assertEquals(-1, stream.previousIndex());
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		ListIterator<Object> stream = EmptyListIterator.instance();
-		Object element = null;
-		while (stream.hasNext()) {
-			element = stream.next();
-		}
-		try {
-			element = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown (next): " + element, exCaught);
-		while (stream.hasPrevious()) {
-			element = stream.previous();
-		}
-		try {
-			element = stream.previous();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown (previous): " + element, exCaught);
-	}
-
-	public void testUnsupportedOperationException() {
-		boolean exCaught = false;
-		try {
-			EmptyListIterator.instance().remove();
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue("UnsupportedOperationException not thrown (remove)", exCaught);
-		try {
-			EmptyListIterator.instance().set(new Object());
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue("UnsupportedOperationException not thrown (set)", exCaught);
-		try {
-			EmptyListIterator.instance().add(new Object());
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue("UnsupportedOperationException not thrown (add)", exCaught);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/EnumerationIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/EnumerationIteratorTests.java
deleted file mode 100644
index a3eeaef..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/EnumerationIteratorTests.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import java.util.Vector;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterators.EnumerationIterator;
-
-@SuppressWarnings("nls")
-public class EnumerationIteratorTests extends TestCase {
-
-	public EnumerationIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testHasNext() {
-		int i = 0;
-		for (Iterator<String> stream = this.buildIterator(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(this.buildVector().size(), i);
-	}
-
-	public void testHasNextUpcast() {
-		int i = 0;
-		for (Iterator<Object> stream = this.buildIteratorUpcast(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(this.buildVector().size(), i);
-	}
-
-	public void testNext() {
-		Enumeration<String> enumeration = this.buildEnumeration();
-		for (Iterator<String> stream = this.buildIterator(); stream.hasNext();) {
-			assertEquals("bogus element", enumeration.nextElement(), stream.next());
-		}
-	}
-
-	public void testNextUpcast() {
-		Enumeration<String> enumeration = this.buildEnumeration();
-		for (Iterator<Object> stream = this.buildIteratorUpcast(); stream.hasNext();) {
-			assertEquals("bogus element", enumeration.nextElement(), stream.next());
-		}
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		Iterator<String> stream = this.buildIterator();
-		String string = null;
-		while (stream.hasNext()) {
-			string = stream.next();
-		}
-		try {
-			string = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
-	}
-
-	public void testUnsupportedOperationException() {
-		boolean exCaught = false;
-		for (Iterator<String> stream = this.buildIterator(); stream.hasNext();) {
-			if (stream.next().equals("three")) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	private Iterator<String> buildIterator() {
-		return this.buildIterator(this.buildEnumeration());
-	}
-
-	private Iterator<String> buildIterator(Enumeration<String> enumeration) {
-		return new EnumerationIterator<String>(enumeration);
-	}
-
-	private Enumeration<String> buildEnumeration() {
-		return this.buildVector().elements();
-	}
-
-	private Vector<String> buildVector() {
-		Vector<String> v = new Vector<String>();
-		v.addElement("one");
-		v.addElement("two");
-		v.addElement("three");
-		v.addElement("four");
-		v.addElement("five");
-		v.addElement("six");
-		v.addElement("seven");
-		v.addElement("eight");
-		return v;
-	}
-
-	private Iterator<Object> buildIteratorUpcast() {
-		return this.buildIteratorUpcast(this.buildEnumeration());
-	}
-
-	private Iterator<Object> buildIteratorUpcast(Enumeration<String> enumeration) {
-		return new EnumerationIterator<Object>(enumeration);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/FilteringIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/FilteringIteratorTests.java
deleted file mode 100644
index 83b91d3..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/FilteringIteratorTests.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-import org.eclipse.persistence.tools.utility.Filter;
-import org.eclipse.persistence.tools.utility.SimpleFilter;
-import org.eclipse.persistence.tools.utility.iterators.FilteringIterator;
-
-@SuppressWarnings("nls")
-public class FilteringIteratorTests extends TestCase {
-
-	private static final String PREFIX = "prefix";
-
-	public FilteringIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testUnsupportedOperationException() {
-		boolean exCaught = false;
-		for (Iterator<String> stream = this.buildAcceptIterator(); stream.hasNext();) {
-			String string = stream.next();
-			if (string.equals(PREFIX + "3")) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		Iterator<String> stream = this.buildAcceptIterator();
-		String string = null;
-		while (stream.hasNext()) {
-			string = stream.next();
-		}
-		try {
-			string = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
-	}
-
-	public void testAcceptHasNext() {
-		int i = 0;
-		for (Iterator<String> stream = this.buildAcceptIterator(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(6, i);
-	}
-
-	public void testAcceptNext() {
-		for (Iterator<String> stream = this.buildAcceptIterator(); stream.hasNext();) {
-			assertTrue("bogus accept", stream.next().startsWith(PREFIX));
-		}
-	}
-
-	public void testInnerHasNext() {
-		int i = 0;
-		for (Iterator<String> stream = this.buildInnerIterator(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(6, i);
-	}
-
-	public void testInnerNext() {
-		for (Iterator<String> stream = this.buildInnerIterator(); stream.hasNext();) {
-			assertTrue("bogus accept", stream.next().startsWith(PREFIX));
-		}
-	}
-
-	public void testRejectHasNext() {
-		int i = 0;
-		for (Iterator<String> stream = this.buildRejectIterator(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(2, i);
-	}
-
-	public void testRejectNext() {
-		for (Iterator<String> stream = this.buildRejectIterator(); stream.hasNext();) {
-			assertFalse("bogus reject", stream.next().startsWith(PREFIX));
-		}
-	}
-
-	public void testBothHasNext() {
-		// if both accept() and reject() are overridden, accept() is used
-		int i = 0;
-		for (Iterator<String> stream = this.buildBothIterator(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(6, i);
-	}
-
-	public void testLoadNext() {
-		// loadNext() used to cause a NPE when executing during the
-		// constructor because the "outer" class is not bound until completion
-		// of the constructor
-		for (Iterator<String> stream = this.buildInnerIterator2(); stream.hasNext();) {
-			assertTrue("bogus accept", stream.next().startsWith(PREFIX));
-		}
-	}
-
-	public void testFilterHasNext() {
-		int i = 0;
-		for (Iterator<String> stream = this.buildFilterIterator(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(6, i);
-	}
-
-	public void testFilterNext() {
-		for (Iterator<String> stream = this.buildFilterIterator(); stream.hasNext();) {
-			assertTrue("bogus accept", stream.next().startsWith(PREFIX));
-		}
-	}
-
-	private Iterator<String> buildFilteredIterator(Iterator<String> nestedIterator, Filter<String> filter) {
-		return new FilteringIterator<String>(nestedIterator, filter);
-	}
-
-	private Iterator<String> buildInnerFilteredIterator(Iterator<String> nestedIterator) {
-		return new FilteringIterator<String>(nestedIterator) {
-			@Override
-			protected boolean accept(String s) {
-				return s.startsWith(PREFIX);
-			}
-		};
-	}
-
-	String getPrefix() {
-		return PREFIX;
-	}
-
-	// this inner iterator will call the "outer" object
-	private Iterator<String> buildInnerFilteredIterator2(Iterator<String> nestedIterator) {
-		return new FilteringIterator<String>(nestedIterator) {
-			@Override
-			protected boolean accept(String s) {
-				return s.startsWith(FilteringIteratorTests.this.getPrefix());
-			}
-		};
-	}
-
-	private Iterator<String> buildNestedIterator() {
-		Collection<String> c = new ArrayList<String>();
-		c.add(PREFIX + "1");
-		c.add(PREFIX + "2");
-		c.add(PREFIX + "3");
-		c.add("4");
-		c.add(PREFIX + "5");
-		c.add(PREFIX + "6");
-		c.add(PREFIX + "7");
-		c.add("8");
-		return c.iterator();
-	}
-
-	private Iterator<String> buildAcceptIterator() {
-		return this.buildFilteredIterator(this.buildNestedIterator(), this.buildAcceptFilter(PREFIX));
-	}
-
-	private Iterator<String> buildInnerIterator() {
-		return this.buildInnerFilteredIterator(this.buildNestedIterator());
-	}
-
-	// this inner iterator will call the "outer" object
-	private Iterator<String> buildInnerIterator2() {
-		return this.buildInnerFilteredIterator2(this.buildNestedIterator());
-	}
-
-	private Iterator<String> buildFilterIterator() {
-		return this.buildFilteredIterator(this.buildNestedIterator(), this.buildFilterFilter(PREFIX));
-	}
-
-	private Filter<String> buildAcceptFilter(String prefix) {
-		return new SimpleFilter<String, String>(prefix) {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public boolean accept(String s) {
-				return s.startsWith(this.criterion);
-			}
-		};
-	}
-
-	private Iterator<String> buildRejectIterator() {
-		return this.buildFilteredIterator(this.buildNestedIterator(), this.buildRejectFilter(PREFIX));
-	}
-
-	private Filter<String> buildRejectFilter(String prefix) {
-		return new SimpleFilter<String, String>(prefix) {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public boolean reject(String s) {
-				return s.startsWith(this.criterion);
-			}
-		};
-	}
-
-	// use anonymous inner Filter
-	private Filter<String> buildFilterFilter(final String prefix) {
-		return new Filter<String>() {
-			public boolean accept(String s) {
-				return s.startsWith(prefix);
-			}
-		};
-	}
-
-	private Iterator<String> buildBothIterator() {
-		return this.buildFilteredIterator(this.buildNestedIterator(), this.buildBothFilter(PREFIX));
-	}
-
-	private Filter<String> buildBothFilter(String prefix) {
-		return new SimpleFilter<String, String>(prefix) {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public boolean reject(String s) {
-				return s.startsWith(this.criterion);
-			}
-
-			@Override
-			public boolean accept(String s) {
-				return s.startsWith(this.criterion);
-			}
-		};
-	}
-
-	public void testInvalidFilteringIterator() {
-		boolean exCaught = false;
-		try {
-			// missing method override
-			Iterator<String> iterator = new FilteringIterator<String>(this.buildNestedIterator());
-			String s = iterator.next();
-			fail("invalid string: " + s);
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown", exCaught);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/GraphIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/GraphIteratorTests.java
deleted file mode 100644
index fedd815..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/GraphIteratorTests.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.iterators.GraphIterator;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-
-@SuppressWarnings("nls")
-public class GraphIteratorTests extends TestCase {
-	/** this will be populated with all the nodes created for the test */
-	Collection<GraphNode> nodes = new ArrayList<GraphNode>();
-
-	public GraphIteratorTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		TestTools.clear(this);
-		super.tearDown();
-	}
-
-	public void testHasNext1() {
-		this.verifyHasNext(this.buildGraphIterator1());
-	}
-
-	public void testHasNext2() {
-		this.verifyHasNext(this.buildGraphIterator2());
-	}
-
-	private void verifyHasNext(Iterator<GraphNode> iterator) {
-		int i = 0;
-		while (iterator.hasNext()) {
-			iterator.next();
-			i++;
-		}
-		assertEquals(this.nodes.size(), i);
-	}
-
-	public void testNext1() {
-		this.verifyNext(this.buildGraphIterator1());
-	}
-
-	public void testNext2() {
-		this.verifyNext(this.buildGraphIterator2());
-	}
-
-	private void verifyNext(Iterator<GraphNode> iterator) {
-		while (iterator.hasNext()) {
-			assertTrue("bogus element", this.nodes.contains(iterator.next()));
-		}
-	}
-
-	public void testNoSuchElementException1() {
-		this.verifyNoSuchElementException(this.buildGraphIterator1());
-	}
-
-	public void testNoSuchElementException2() {
-		this.verifyNoSuchElementException(this.buildGraphIterator2());
-	}
-
-	private void verifyNoSuchElementException(Iterator<GraphNode> iterator) {
-		boolean exCaught = false;
-		while (iterator.hasNext()) {
-			iterator.next();
-		}
-		try {
-			iterator.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown", exCaught);
-	}
-
-	public void testSize1() {
-		this.verifySize(this.buildGraphIterator1());
-	}
-
-	public void testSize2() {
-		this.verifySize(this.buildGraphIterator2());
-	}
-
-	private void verifySize(Iterator<GraphNode> iterator) {
-		int iteratorSize = CollectionTools.size(iterator);
-		int actualSize = this.nodes.size();
-		assertTrue("Too few items in iterator.", iteratorSize >= actualSize);
-		assertTrue("Too many items in iterator.", iteratorSize <= actualSize);
-	}
-
-	public void testInvalidGraphIterator() {
-		boolean exCaught = false;
-		try {
-			// missing method override
-			Iterator<GraphNode> iterator = new GraphIterator<GraphNode>(this.buildGraphRoot());
-			GraphNode gn = iterator.next();
-			fail("invalid graph node: " + gn);
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown", exCaught);
-	}
-
-	/**
-	 * build a graph iterator with an explicit misterRogers
-	 */
-	private Iterator<GraphNode> buildGraphIterator1() {
-		return new GraphIterator<GraphNode>(this.buildGraphRoot(), this.buildMisterRogers());
-	}
-
-	private GraphIterator.MisterRogers<GraphNode> buildMisterRogers() {
-		return new GraphIterator.MisterRogers<GraphNode>() {
-			public Iterator<GraphNode> neighbors(GraphNode next) {
-				return next.neighbors();
-			}
-		};
-	}
-
-	/**
-	 * build a graph iterator with an override
-	 */
-	private Iterator<GraphNode> buildGraphIterator2() {
-		return new GraphIterator<GraphNode>(this.buildGraphRoot()) {
-			@Override
-			public Iterator<GraphNode> neighbors(GraphNode next) {
-				return next.neighbors();
-			}
-		};
-	}
-
-	private GraphNode buildGraphRoot() {
-		GraphNode ncNode = new GraphNode("North Carolina");
-		GraphNode vaNode = new GraphNode("Virginia");
-		GraphNode scNode = new GraphNode("South Carolina");
-		GraphNode gaNode = new GraphNode("Georgia");
-		GraphNode flNode = new GraphNode("Florida");
-		GraphNode alNode = new GraphNode("Alabama");
-		GraphNode msNode = new GraphNode("Mississippi");
-		GraphNode tnNode = new GraphNode("Tennessee");
-
-		ncNode.setNeighbors(new GraphNode[] { vaNode, scNode, gaNode, tnNode });
-		vaNode.setNeighbors(new GraphNode[] { ncNode, tnNode });
-		scNode.setNeighbors(new GraphNode[] { ncNode, gaNode });
-		gaNode.setNeighbors(new GraphNode[] { ncNode, scNode, flNode, alNode, tnNode });
-		flNode.setNeighbors(new GraphNode[] { gaNode });
-		alNode.setNeighbors(new GraphNode[] { gaNode, msNode, tnNode });
-		msNode.setNeighbors(new GraphNode[] { alNode, tnNode });
-		tnNode.setNeighbors(new GraphNode[] { vaNode, ncNode, gaNode, alNode, msNode });
-
-		return ncNode;
-	}
-
-	public class GraphNode {
-		private String name;
-
-		private Collection<GraphNode> neighbors = new ArrayList<GraphNode>();
-
-		public GraphNode(String name) {
-			super();
-			GraphIteratorTests.this.nodes.add(this); // log node
-			this.name = name;
-		}
-
-		public String getName() {
-			return this.name;
-		}
-
-		void setNeighbors(GraphNode[] neighbors) {
-			this.neighbors = CollectionTools.list(neighbors);
-		}
-
-		public Iterator<GraphNode> neighbors() {
-			return this.neighbors.iterator();
-		}
-
-		public int neighborsSize() {
-			return this.neighbors.size();
-		}
-
-		@Override
-		public String toString() {
-			return "GraphNode(" + this.name + ")";
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/PeekableIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/PeekableIteratorTests.java
deleted file mode 100644
index 25b83ac..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/PeekableIteratorTests.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterators.PeekableIterator;
-
-@SuppressWarnings("nls")
-public class PeekableIteratorTests extends TestCase {
-
-	public PeekableIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testUnsupportedOperationException() {
-		boolean exCaught = false;
-		for (Iterator<String> stream = this.buildPeekableIterator(); stream.hasNext();) {
-			String string = stream.next();
-			if (string.equals("three")) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		Iterator<String> stream = this.buildPeekableIterator();
-		String string = null;
-		while (stream.hasNext()) {
-			string = stream.next();
-		}
-		try {
-			string = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
-	}
-
-	public void testHasNext() {
-		int i = 0;
-		for (Iterator<String> stream = this.buildPeekableIterator(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(6, i);
-	}
-
-	public void testHasNextUpcast() {
-		int i = 0;
-		for (Iterator<Object> stream = this.buildPeekableIteratorUpcast(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(6, i);
-	}
-
-	public void testNext() {
-		Iterator<String> stream = this.buildPeekableIterator();
-		assertEquals("zero", stream.next());
-		assertEquals("one", stream.next());
-		assertEquals("two", stream.next());
-		assertEquals("three", stream.next());
-		assertEquals("four", stream.next());
-		assertEquals("five", stream.next());
-	}
-
-	public void testNextUpcast() {
-		Iterator<Object> stream = this.buildPeekableIteratorUpcast();
-		assertEquals("zero", stream.next());
-		assertEquals("one", stream.next());
-		assertEquals("two", stream.next());
-		assertEquals("three", stream.next());
-		assertEquals("four", stream.next());
-		assertEquals("five", stream.next());
-	}
-
-	public void testPeek() {
-		Object next = null;
-		for (PeekableIterator<String> stream = this.buildPeekableIterator(); stream.hasNext();) {
-			Object peek = stream.peek();
-			assertTrue("peek and next are prematurely identical", peek != next);
-			next = stream.next();
-			assertTrue("peek and next are not identical", peek == next);
-		}
-	}
-
-	public void testPeekUpcast() {
-		Object next = null;
-		for (PeekableIterator<Object> stream = this.buildPeekableIteratorUpcast(); stream.hasNext();) {
-			Object peek = stream.peek();
-			assertTrue("peek and next are prematurely identical", peek != next);
-			next = stream.next();
-			assertTrue("peek and next are not identical", peek == next);
-		}
-	}
-
-	private PeekableIterator<String> buildPeekableIterator() {
-		return this.buildPeekableIterator(this.buildNestedIterator());
-	}
-
-	private PeekableIterator<Object> buildPeekableIteratorUpcast() {
-		return this.buildPeekableIteratorUpcast(this.buildNestedIterator());
-	}
-
-	private PeekableIterator<String> buildPeekableIterator(Iterator<String> nestedIterator) {
-		return new PeekableIterator<String>(nestedIterator);
-	}
-
-	private PeekableIterator<Object> buildPeekableIteratorUpcast(Iterator<String> nestedIterator) {
-		return new PeekableIterator<Object>(nestedIterator);
-	}
-
-	private Iterator<String> buildNestedIterator() {
-		Collection<String> c = new ArrayList<String>();
-		c.add("zero");
-		c.add("one");
-		c.add("two");
-		c.add("three");
-		c.add("four");
-		c.add("five");
-		return c.iterator();
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ReadOnlyCompositeListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ReadOnlyCompositeListIteratorTests.java
deleted file mode 100644
index 4e2a3de..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ReadOnlyCompositeListIteratorTests.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.iterators.ReadOnlyCompositeListIterator;
-
-@SuppressWarnings("nls")
-public class ReadOnlyCompositeListIteratorTests extends CompositeIteratorTests {
-
-	public ReadOnlyCompositeListIteratorTests(String name) {
-		super(name);
-	}
-
-	@Override
-	void verifyHasAnother(Iterator<String> stream) {
-		super.verifyHasAnother(stream);
-		ListIterator<String> stream2 = (ListIterator<String>) stream;
-		int i = 0;
-		while (stream2.hasPrevious()) {
-			stream2.previous();
-			i++;
-		}
-		assertEquals(8, i);
-	}
-
-	@Override
-	void verifyAnother(Iterator<String> stream) {
-		super.verifyAnother(stream);
-		int i = 8;
-		ListIterator<String> stream2 = (ListIterator<String>) stream;
-		while (stream2.hasPrevious()) {
-			assertEquals("bogus element", String.valueOf(i--), stream2.previous().substring(0, 1));
-		}
-	}
-
-	public void testNextIndexPreviousIndex() {
-		int i = 0;
-		ListIterator<String> stream = (ListIterator<String>) this.buildCompositeIterator();
-		assertEquals(i, stream.nextIndex());
-		assertEquals(i - 1, stream.previousIndex());
-		while (stream.hasNext()) {
-			stream.next();
-			i++;
-			assertEquals(i, stream.nextIndex());
-			assertEquals(i - 1, stream.previousIndex());
-		}
-		assertEquals("index is corrupt", 8, i);
-
-		assertEquals(i, stream.nextIndex());
-		assertEquals(i - 1, stream.previousIndex());
-		while (stream.hasPrevious()) {
-			stream.previous();
-			i--;
-			assertEquals(i, stream.nextIndex());
-			assertEquals(i - 1, stream.previousIndex());
-		}
-		assertEquals("index is corrupt", 0, i);
-	}
-
-	public void testPreviousIndex() {
-		// TODO
-	}
-
-	@Override
-	public void testRemove() {
-		// #remove() is not supported
-	}
-
-	@Override
-	public void testIllegalStateException() {
-		// #remove() is not supported
-	}
-
-	@Override
-	public void testEmptyIllegalStateException1() {
-		// #remove() is not supported
-	}
-
-	@Override
-	public void testEmptyIllegalStateException2() {
-		// #remove() is not supported
-	}
-
-	@Override
-	void verifyNoSuchElementException(Iterator<String> stream) {
-		super.verifyNoSuchElementException(stream);
-		ListIterator<String> stream2 = (ListIterator<String>) stream;
-		boolean exCaught = false;
-		String string = null;
-		while (stream2.hasPrevious()) {
-			string = stream2.previous();
-		}
-		try {
-			string = stream2.previous();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
-	}
-
-	@Override
-	void verifyUnsupportedOperationException(Iterator<String> stream) {
-		super.verifyUnsupportedOperationException(stream);
-		boolean exCaught = false;
-		ListIterator<String> stream2 = (ListIterator<String>) stream;
-		while (stream2.hasPrevious()) {
-			Object string = stream2.previous();
-			if (string.equals("333")) {
-				try {
-					stream2.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	@Override
-	void verifyIllegalStateException(Iterator<String> stream) {
-		super.verifyIllegalStateException(stream);
-		ListIterator<String> stream2 = (ListIterator<String>) stream;
-		boolean exCaught = false;
-		try {
-			stream2.set("junk");
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue("IllegalStateException not thrown", exCaught);
-	}
-
-	@Override
-	void verifyEmptyHasAnother(Iterator<String> stream) {
-		super.verifyEmptyHasAnother(stream);
-		ListIterator<String> stream2 = (ListIterator<String>) stream;
-		int i = 0;
-		while (stream2.hasPrevious()) {
-			stream2.previous();
-			i++;
-		}
-		assertEquals(0, i);
-	}
-
-	// unchecked so we can override the unchecked method in superclass
-	@Override
-	@SuppressWarnings({"rawtypes", "unchecked"})
-	Iterator<String> buildCompositeIterator(Iterator iterators) {
-		return new ReadOnlyCompositeListIterator<String>((ListIterator<ListIterator<String>>) iterators);
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	Iterator<String> buildCompositeIterator2() {
-		return new ReadOnlyCompositeListIterator<String>(this.buildIterator1(), this.buildIterator2(), this.buildIterator3());
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	Iterator<String> buildCompositeIterator3() {
-		return new ReadOnlyCompositeListIterator<String>(new ListIterator[] { this.buildIterator1(), this.buildIterator2(), this.buildIterator3() });
-	}
-
-	Iterator<String> buildCompositeIterator(String string, ListIterator<String> iterator) {
-		return this.buildCompositeListIterator(string, iterator);
-	}
-
-	ListIterator<String> buildCompositeListIterator(String string, ListIterator<String> iterator) {
-		return new ReadOnlyCompositeListIterator<String>(string, iterator);
-	}
-
-	public void testVariedNestedIterators() {
-		List<Integer> integerList = new ArrayList<Integer>();
-		integerList.add(new Integer(42));
-		integerList.add(new Integer(42));
-		integerList.add(new Integer(111));
-		integerList.add(new Integer(77));
-
-		List<Float> floatList = new ArrayList<Float>();
-		floatList.add(new Float(42.42f));
-		floatList.add(new Float(22.22f));
-		floatList.add(new Float(111.111f));
-		floatList.add(new Float(77.77f));
-
-		List<List<? extends Number>> list = new ArrayList<List<? extends Number>>();
-		list.add(integerList);
-		list.add(floatList);
-		ListIterator<Number> li = new ReadOnlyCompositeListIterator<Number>(list);
-		while (li.hasNext()) {
-			assertTrue(li.next().intValue() > 0);
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ReadOnlyIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ReadOnlyIteratorTests.java
deleted file mode 100644
index df2613b..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ReadOnlyIteratorTests.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import java.util.Vector;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterators.ReadOnlyIterator;
-
-@SuppressWarnings("nls")
-public class ReadOnlyIteratorTests extends TestCase {
-
-	public ReadOnlyIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testHasNext() {
-		int i = 0;
-		for (Iterator<String> stream = this.buildReadOnlyIterator(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(this.buildVector().size(), i);
-	}
-
-	public void testHasNextUpcast() {
-		int i = 0;
-		for (Iterator<Object> stream = this.buildReadOnlyIteratorUpcast(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(this.buildVector().size(), i);
-	}
-
-	public void testNext() {
-		Iterator<String> nestedIterator = this.buildNestedIterator();
-		for (Iterator<String> stream = this.buildReadOnlyIterator(); stream.hasNext();) {
-			assertEquals("bogus element", nestedIterator.next(), stream.next());
-		}
-	}
-
-	public void testNextUpcast() {
-		Iterator<String> nestedIterator = this.buildNestedIterator();
-		for (Iterator<Object> stream = this.buildReadOnlyIteratorUpcast(); stream.hasNext();) {
-			assertEquals("bogus element", nestedIterator.next(), stream.next());
-		}
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		Iterator<String> stream = this.buildReadOnlyIterator();
-		String string = null;
-		while (stream.hasNext()) {
-			string = stream.next();
-		}
-		try {
-			string = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
-	}
-
-	public void testRemove() {
-		boolean exCaught = false;
-		for (Iterator<String> stream = this.buildReadOnlyIterator(); stream.hasNext();) {
-			if (stream.next().equals("three")) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	private Iterator<String> buildReadOnlyIterator() {
-		return this.buildReadOnlyIterator(this.buildNestedIterator());
-	}
-
-	private Iterator<Object> buildReadOnlyIteratorUpcast() {
-		return this.buildReadOnlyIteratorUpcast(this.buildNestedIterator());
-	}
-
-	private Iterator<String> buildReadOnlyIterator(Iterator<String> nestedIterator) {
-		return new ReadOnlyIterator<String>(nestedIterator);
-	}
-
-	private Iterator<Object> buildReadOnlyIteratorUpcast(Iterator<String> nestedIterator) {
-		return new ReadOnlyIterator<Object>(nestedIterator);
-	}
-
-	private Iterator<String> buildNestedIterator() {
-		return this.buildVector().iterator();
-	}
-
-	private Vector<String> buildVector() {
-		Vector<String> v = new Vector<String>();
-		v.addElement("one");
-		v.addElement("two");
-		v.addElement("three");
-		v.addElement("four");
-		v.addElement("five");
-		v.addElement("six");
-		v.addElement("seven");
-		v.addElement("eight");
-		return v;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ReadOnlyListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ReadOnlyListIteratorTests.java
deleted file mode 100644
index 866d355..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/ReadOnlyListIteratorTests.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterators.ReadOnlyListIterator;
-
-@SuppressWarnings("nls")
-public class ReadOnlyListIteratorTests extends TestCase {
-
-	public ReadOnlyListIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testHasNextAndHasPrevious() {
-		int i = 0;
-		ListIterator<String> stream = this.buildReadOnlyListIterator();
-		while (stream.hasNext()) {
-			stream.next();
-			i++;
-		}
-		assertEquals(this.buildList().size(), i);
-
-		while (stream.hasPrevious()) {
-			stream.previous();
-			i--;
-		}
-		assertEquals(0, i);
-	}
-
-	public void testHasNextAndHasPreviousUpcast() {
-		int i = 0;
-		ListIterator<Object> stream = this.buildReadOnlyListIteratorUpcast();
-		while (stream.hasNext()) {
-			stream.next();
-			i++;
-		}
-		assertEquals(this.buildList().size(), i);
-
-		while (stream.hasPrevious()) {
-			stream.previous();
-			i--;
-		}
-		assertEquals(0, i);
-	}
-
-	public void testNextAndPrevious() {
-		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
-		ListIterator<String> stream = this.buildReadOnlyListIterator();
-		while (stream.hasNext()) {
-			assertEquals("bogus element", nestedListIterator.next(), stream.next());
-		}
-		while (stream.hasPrevious()) {
-			assertEquals("bogus element", nestedListIterator.previous(), stream.previous());
-		}
-	}
-
-	public void testNextAndPreviousUpcast() {
-		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
-		ListIterator<Object> stream = this.buildReadOnlyListIteratorUpcast();
-		while (stream.hasNext()) {
-			assertEquals("bogus element", nestedListIterator.next(), stream.next());
-		}
-		while (stream.hasPrevious()) {
-			assertEquals("bogus element", nestedListIterator.previous(), stream.previous());
-		}
-	}
-
-	public void testNextIndexAndPreviousIndex() {
-		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
-		ListIterator<String> stream = this.buildReadOnlyListIterator();
-		while (stream.hasNext()) {
-			assertEquals("bogus index", nestedListIterator.nextIndex(), stream.nextIndex());
-			nestedListIterator.next();
-			stream.next();
-		}
-		assertEquals("bogus index", this.buildList().size(), stream.nextIndex());
-		while (stream.hasPrevious()) {
-			assertEquals("bogus element", nestedListIterator.previousIndex(), stream.previousIndex());
-			nestedListIterator.previous();
-			stream.previous();
-		}
-		assertEquals("bogus index", -1, stream.previousIndex());
-	}
-
-	public void testNextIndexAndPreviousIndexUpcast() {
-		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
-		ListIterator<Object> stream = this.buildReadOnlyListIteratorUpcast();
-		while (stream.hasNext()) {
-			assertEquals("bogus index", nestedListIterator.nextIndex(), stream.nextIndex());
-			nestedListIterator.next();
-			stream.next();
-		}
-		assertEquals("bogus index", this.buildList().size(), stream.nextIndex());
-		while (stream.hasPrevious()) {
-			assertEquals("bogus element", nestedListIterator.previousIndex(), stream.previousIndex());
-			nestedListIterator.previous();
-			stream.previous();
-		}
-		assertEquals("bogus index", -1, stream.previousIndex());
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		ListIterator<String> stream = this.buildReadOnlyListIterator();
-		String string = null;
-		while (stream.hasNext()) {
-			string = stream.next();
-		}
-		try {
-			string = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
-	}
-
-	public void testRemove() {
-		boolean exCaught = false;
-		for (ListIterator<String> stream = this.buildReadOnlyListIterator(); stream.hasNext();) {
-			if (stream.next().equals("three")) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	public void testSet() {
-		boolean exCaught = false;
-		for (ListIterator<String> stream = this.buildReadOnlyListIterator(); stream.hasNext();) {
-			if (stream.next().equals("three")) {
-				try {
-					stream.set("bogus");
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	public void testAdd() {
-		boolean exCaught = false;
-		for (ListIterator<String> stream = this.buildReadOnlyListIterator(); stream.hasNext();) {
-			if (stream.next().equals("three")) {
-				try {
-					stream.add("bogus");
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	private ListIterator<String> buildReadOnlyListIterator() {
-		return this.buildReadOnlyListIterator(this.buildNestedListIterator());
-	}
-
-	private ListIterator<Object> buildReadOnlyListIteratorUpcast() {
-		return this.buildReadOnlyListIteratorUpcast(this.buildNestedListIterator());
-	}
-
-	private ListIterator<String> buildReadOnlyListIterator(ListIterator<String> nestedListIterator) {
-		return new ReadOnlyListIterator<String>(nestedListIterator);
-	}
-
-	private ListIterator<Object> buildReadOnlyListIteratorUpcast(ListIterator<String> nestedListIterator) {
-		return new ReadOnlyListIterator<Object>(nestedListIterator);
-	}
-
-	private ListIterator<String> buildNestedListIterator() {
-		return this.buildList().listIterator();
-	}
-
-	private List<String> buildList() {
-		List<String> l = new ArrayList<String>();
-		l.add("one");
-		l.add("two");
-		l.add("three");
-		l.add("four");
-		l.add("five");
-		l.add("six");
-		l.add("seven");
-		l.add("eight");
-		return l;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SingleElementIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SingleElementIteratorTests.java
deleted file mode 100644
index 453bb86..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SingleElementIteratorTests.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterators.SingleElementIterator;
-
-@SuppressWarnings("nls")
-public class SingleElementIteratorTests extends TestCase {
-
-	public SingleElementIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testHasNext() {
-		int i = 0;
-		for (Iterator<String> stream = this.buildSingleElementIterator(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(1, i);
-	}
-
-	public void testNext() {
-		for (Iterator<String> stream = this.buildSingleElementIterator(); stream.hasNext();) {
-			assertEquals("bogus element", this.singleElement(), stream.next());
-		}
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		Iterator<String> stream = this.buildSingleElementIterator();
-		String string = stream.next();
-		try {
-			string = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
-	}
-
-	public void testRemove() {
-		boolean exCaught = false;
-		for (Iterator<String> stream = this.buildSingleElementIterator(); stream.hasNext();) {
-			if (stream.next().equals(this.singleElement())) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	protected Iterator<String> buildSingleElementIterator() {
-		return new SingleElementIterator<String>(this.singleElement());
-	}
-
-	protected String singleElement() {
-		return "single element";
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SingleElementListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SingleElementListIteratorTests.java
deleted file mode 100644
index 728403a..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SingleElementListIteratorTests.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.Iterator;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.iterators.SingleElementListIterator;
-
-@SuppressWarnings("nls")
-public class SingleElementListIteratorTests extends SingleElementIteratorTests {
-
-	public SingleElementListIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testNextIndex() {
-		ListIterator<String> stream = this.buildSingleElementListIterator();
-		while (stream.hasNext()) {
-			assertEquals("bogus index", 0, stream.nextIndex());
-			stream.next();
-		}
-		assertEquals("bogus index", 1, stream.nextIndex());
-	}
-
-	public void testHasPrevious() {
-		int i = 0;
-		ListIterator<String> stream = this.buildSingleElementListIterator();
-		while (stream.hasNext()) {
-			stream.next();
-			i++;
-		}
-		assertEquals(1, i);
-
-		while (stream.hasPrevious()) {
-			stream.previous();
-			i++;
-		}
-		assertEquals(2, i);
-	}
-
-	public void testPrevious() {
-		ListIterator<String> stream = this.buildSingleElementListIterator();
-
-		while (stream.hasNext()) {
-			assertEquals("bogus element", this.singleElement(), stream.next());
-		}
-
-		while (stream.hasPrevious()) {
-			assertEquals("bogus element", this.singleElement(), stream.previous());
-		}
-	}
-
-	public void testPreviousIndex() {
-		ListIterator<String> stream = this.buildSingleElementListIterator();
-
-		while (stream.hasNext()) {
-			assertEquals("bogus index", 0, stream.nextIndex());
-			stream.next();
-		}
-
-		while (stream.hasPrevious()) {
-			assertEquals("bogus index", 0, stream.previousIndex());
-			stream.previous();
-		}
-
-		assertEquals("bogus index", -1, stream.previousIndex());
-	}
-
-	public void testAdd() {
-		boolean exCaught = false;
-		ListIterator<String> stream = this.buildSingleElementListIterator();
-
-		try {
-			stream.add("foo");
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	public void testSet() {
-		boolean exCaught = false;
-		for (ListIterator<String> stream = this.buildSingleElementListIterator(); stream.hasNext();) {
-			if (stream.next().equals(this.singleElement())) {
-				try {
-					stream.set("foo");
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	@Override
-	protected Iterator<String> buildSingleElementIterator() {
-		return new SingleElementListIterator<String>(this.singleElement());
-	}
-
-	protected ListIterator<String> buildSingleElementListIterator() {
-		return (ListIterator<String>) this.buildSingleElementIterator();
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SuperIteratorWrapperTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SuperIteratorWrapperTests.java
deleted file mode 100644
index 9e4c83f..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SuperIteratorWrapperTests.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterators.SuperIteratorWrapper;
-
-@SuppressWarnings("nls")
-public class SuperIteratorWrapperTests extends TestCase {
-
-	public SuperIteratorWrapperTests(String name) {
-		super(name);
-	}
-
-	public void testIterator() {
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("foo");
-		list.add("bar");
-		list.add("baz");
-		String concat = "";
-		for (Iterator<String> stream = list.iterator(); stream.hasNext(); ) {
-			concat += stream.next();
-		}
-		assertEquals("foobarbaz", concat);
-
-		Iterator<Object> iterator = new SuperIteratorWrapper<Object>(list);
-		concat = "";
-		while (iterator.hasNext()) {
-			Object next = iterator.next();
-			if (next.equals("bar")) {
-				iterator.remove();
-			} else {
-				concat += next;
-			}
-		}
-		assertEquals("foobaz", concat);
-		assertEquals(2, list.size());
-		assertFalse(list.contains("bar"));
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SynchronizedIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SynchronizedIteratorTests.java
deleted file mode 100644
index fd9b2ca..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SynchronizedIteratorTests.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.iterators.SynchronizedIterator;
-import org.eclipse.persistence.tools.utility.tests.internal.MultiThreadedTestCase;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-
-@SuppressWarnings("nls")
-public class SynchronizedIteratorTests
-	extends MultiThreadedTestCase
-{
-	public SynchronizedIteratorTests(String name) {
-		super(name);
-	}
-
-	/**
-	 * test that an unsynchronized iterator will produce corrupt output;
-	 * thread 1 will read the first element from the iterator
-	 * and then sleep for a bit, allowing thread 2 to sneak in and
-	 * read the same element from the iterator
-	 */
-	public void testUnsynchronizedNext() throws Exception {
-		TestIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
-
-		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		NextTestRunnable<String> runnable2 = new NextTestRunnable<String>(iterator);
-		Thread thread2 = this.buildThread(runnable2);
-		iterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// both threads should have read the same element from the iterator :-(
-		assertEquals("foo", runnable1.next);
-		assertEquals("foo", runnable2.next);
-	}
-
-	/**
-	 * test that a synchronized iterator will produce valid output;
-	 * thread 1 will read the first element from the iterator
-	 * and then sleep for a bit, but thread 2 will be locked out and
-	 * wait to read the second element from the iterator
-	 */
-	public void testSynchronizedNext() throws Exception {
-		TestIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
-		Iterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
-
-		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		NextTestRunnable<String> runnable2 = new NextTestRunnable<String>(iterator);
-		Thread thread2 = this.buildThread(runnable2);
-		nestedIterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// the threads should have read the correct elements from the iterator :-)
-		assertEquals("foo", runnable1.next);
-		assertEquals("bar", runnable2.next);
-	}
-
-	public void testUnsynchronizedHasNext() throws Exception {
-		TestIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
-		iterator.next();
-		iterator.next();
-
-		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		HasNextTestRunnable<String> runnable2 = new HasNextTestRunnable<String>(iterator);
-		Thread thread2 = this.buildThread(runnable2);
-		iterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// thread 1 will have the last element,
-		// but thread 2 will think there are more elements on the iterator :-(
-		assertEquals("baz", runnable1.next);
-		assertEquals(true, runnable2.hasNext);
-	}
-
-	public void testSynchronizedHasNext() throws Exception {
-		TestIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
-		Iterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
-		iterator.next();
-		iterator.next();
-
-		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		HasNextTestRunnable<String> runnable2 = new HasNextTestRunnable<String>(iterator);
-		Thread thread2 = this.buildThread(runnable2);
-		nestedIterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// thread 1 will have the last element,
-		// and thread 2 will think there are no more elements on the iterator :-)
-		assertEquals("baz", runnable1.next);
-		assertEquals(false, runnable2.hasNext);
-	}
-
-	public void testUnsynchronizedRemove() throws Exception {
-		TestIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
-		iterator.next();
-
-		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		RemoveTestRunnable<String> runnable2 = new RemoveTestRunnable<String>(iterator);
-		Thread thread2 = this.buildThread(runnable2);
-		iterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// the wrong element was removed :-(
-		assertEquals("bar", runnable1.next);
-		assertFalse(iterator.list.contains("foo"));
-		assertTrue(iterator.list.contains("bar"));
-		assertTrue(iterator.list.contains("baz"));
-	}
-
-	public void testSynchronizedRemove() throws Exception {
-		TestIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
-		Iterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
-		iterator.next();
-
-		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		RemoveTestRunnable<String> runnable2 = new RemoveTestRunnable<String>(iterator);
-		Thread thread2 = this.buildThread(runnable2);
-		nestedIterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// the correct element was removed :-)
-		assertEquals("bar", runnable1.next);
-		assertTrue(nestedIterator.list.contains("foo"));
-		assertFalse(nestedIterator.list.contains("bar"));
-		assertTrue(nestedIterator.list.contains("baz"));
-	}
-
-	TestIterator<String> buildTestIterator(long delay) {
-		return new TestIterator<String>(delay, this.buildArray());
-	}
-
-	String[] buildArray() {
-		return new String[] {"foo", "bar", "baz"};
-	}
-
-	Iterator<String> buildSynchronizedIterator(Iterator<String> nestedIterator) {
-		return new SynchronizedIterator<String>(nestedIterator);
-	}
-
-
-	/**
-	 * next runnable
-	 */
-	class NextTestRunnable<E> implements Runnable {
-		final Iterator<E> iterator;
-		E next;
-
-		NextTestRunnable(Iterator<E> iterator) {
-			super();
-			this.iterator = iterator;
-		}
-
-		public void run() {
-			this.next = this.iterator.next();
-		}
-
-	}
-
-	/**
-	 * has next runnable
-	 */
-	class HasNextTestRunnable<E> implements Runnable {
-		final Iterator<E> iterator;
-		boolean hasNext;
-
-		HasNextTestRunnable(Iterator<E> iterator) {
-			super();
-			this.iterator = iterator;
-		}
-
-		public void run() {
-			this.hasNext = this.iterator.hasNext();
-		}
-
-	}
-
-	/**
-	 * remove runnable
-	 */
-	class RemoveTestRunnable<E> implements Runnable {
-		final Iterator<E> iterator;
-
-		RemoveTestRunnable(Iterator<E> iterator) {
-			super();
-			this.iterator = iterator;
-		}
-
-		public void run() {
-			this.iterator.remove();
-		}
-
-	}
-
-	/**
-	 * Test iterator: If {@link #next()} is called while executing on the
-	 * {@link slowThread}, the iterator will delay for the configured time.
-	 */
-	static class TestIterator<E> implements Iterator<E> {
-		final long delay;
-		final ArrayList<E> list = new ArrayList<E>();
-		int nextIndex = 0;
-		int lastIndex = -1;
-		Thread slowThread;
-
-		TestIterator(long delay, E... array) {
-			super();
-			this.delay = delay;
-			CollectionTools.addAll(this.list, array);
-		}
-
-		public boolean hasNext() {
-			return this.nextIndex != this.list.size();
-		}
-
-		public E next() {
-			if (this.hasNext()) {
-				E next = this.list.get(this.nextIndex);
-				if (Thread.currentThread() == this.slowThread) {
-					TestTools.sleep(this.delay);
-				}
-				this.lastIndex = this.nextIndex++;
-				return next;
-			}
-			throw new NoSuchElementException();
-		}
-
-		public void remove() {
-			if (this.lastIndex == -1) {
-				throw new IllegalStateException();
-			}
-			this.list.remove(this.lastIndex);
-			if (this.lastIndex < this.nextIndex) {  // check necessary for ListIterator
-				this.nextIndex--;
-			}
-			this.lastIndex = -1;
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SynchronizedListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SynchronizedListIteratorTests.java
deleted file mode 100644
index 2315a63..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/SynchronizedListIteratorTests.java
+++ /dev/null
@@ -1,527 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.Iterator;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.iterators.SynchronizedListIterator;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-
-@SuppressWarnings("nls")
-public class SynchronizedListIteratorTests
-	extends SynchronizedIteratorTests
-{
-	public SynchronizedListIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testUnsynchronizedPrevious() throws Exception {
-		TestListIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
-		iterator.next();
-		iterator.next();
-
-		PreviousTestRunnable<String> runnable1 = new PreviousTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		PreviousTestRunnable<String> runnable2 = new PreviousTestRunnable<String>(iterator);
-		Thread thread2 = this.buildThread(runnable2);
-		iterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// both threads should have read the same element from the iterator :-(
-		assertEquals("bar", runnable1.previous);
-		assertEquals("bar", runnable2.previous);
-	}
-
-	public void testSynchronizedPrevious() throws Exception {
-		TestListIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
-		ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
-		iterator.next();
-		iterator.next();
-
-		PreviousTestRunnable<String> runnable1 = new PreviousTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		PreviousTestRunnable<String> runnable2 = new PreviousTestRunnable<String>(iterator);
-		Thread thread2 = this.buildThread(runnable2);
-		nestedIterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// the threads should have read the correct elements from the iterator :-)
-		assertEquals("bar", runnable1.previous);
-		assertEquals("foo", runnable2.previous);
-	}
-
-	public void testUnsynchronizedHasPrevious() throws Exception {
-		TestListIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
-		iterator.next();
-
-		PreviousTestRunnable<String> runnable1 = new PreviousTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		HasPreviousTestRunnable<String> runnable2 = new HasPreviousTestRunnable<String>(iterator);
-		Thread thread2 = this.buildThread(runnable2);
-		iterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// thread 1 will have the first element,
-		// but thread 2 will think there are more "previous" elements on the iterator :-(
-		assertEquals("foo", runnable1.previous);
-		assertEquals(true, runnable2.hasPrevious);
-	}
-
-	public void testSynchronizedHasPrevious() throws Exception {
-		TestListIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
-		ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
-		iterator.next();
-
-		PreviousTestRunnable<String> runnable1 = new PreviousTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		HasPreviousTestRunnable<String> runnable2 = new HasPreviousTestRunnable<String>(iterator);
-		Thread thread2 = this.buildThread(runnable2);
-		nestedIterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// thread 1 will have the first element,
-		// and thread 2 will think there are no more "previous" elements on the iterator :-)
-		assertEquals("foo", runnable1.previous);
-		assertEquals(false, runnable2.hasPrevious);
-	}
-
-	public void testUnsynchronizedNextIndex() throws Exception {
-		TestListIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
-
-		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		NextIndexTestRunnable<String> runnable2 = new NextIndexTestRunnable<String>(iterator);
-		Thread thread2 = this.buildThread(runnable2);
-		iterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// thread 1 will have the first element,
-		// but thread 2 will think the next index is still 0 :-(
-		assertEquals("foo", runnable1.next);
-		assertEquals(0, runnable2.nextIndex);
-	}
-
-	public void testSynchronizedNextIndex() throws Exception {
-		TestListIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
-		ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
-
-		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		NextIndexTestRunnable<String> runnable2 = new NextIndexTestRunnable<String>(iterator);
-		Thread thread2 = this.buildThread(runnable2);
-		nestedIterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// thread 1 will have the first element,
-		// and thread 2 will think the next index is 1 :-)
-		assertEquals("foo", runnable1.next);
-		assertEquals(1, runnable2.nextIndex);
-	}
-
-	public void testUnsynchronizedPreviousIndex() throws Exception {
-		TestListIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
-		iterator.next();
-
-		PreviousTestRunnable<String> runnable1 = new PreviousTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		PreviousIndexTestRunnable<String> runnable2 = new PreviousIndexTestRunnable<String>(iterator);
-		Thread thread2 = this.buildThread(runnable2);
-		iterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// thread 1 will have the first element,
-		// but thread 2 will think the next index is still 0 :-(
-		assertEquals("foo", runnable1.previous);
-		assertEquals(0, runnable2.previousIndex);
-	}
-
-	public void testSynchronizedPreviousIndex() throws Exception {
-		TestListIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
-		ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
-		iterator.next();
-
-		PreviousTestRunnable<String> runnable1 = new PreviousTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		PreviousIndexTestRunnable<String> runnable2 = new PreviousIndexTestRunnable<String>(iterator);
-		Thread thread2 = this.buildThread(runnable2);
-		nestedIterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// thread 1 will have the first element,
-		// and thread 2 will think the next index is -1 :-)
-		assertEquals("foo", runnable1.previous);
-		assertEquals(-1, runnable2.previousIndex);
-	}
-
-	public void testUnsynchronizedSet() throws Exception {
-		TestListIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
-		iterator.next();
-
-		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		SetTestRunnable<String> runnable2 = new SetTestRunnable<String>(iterator, "xxx");
-		Thread thread2 = this.buildThread(runnable2);
-		iterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// the wrong element was set :-(
-		assertEquals("bar", runnable1.next);
-		assertFalse(iterator.list.contains("foo"));
-		assertTrue(iterator.list.contains("xxx"));
-		assertTrue(iterator.list.contains("bar"));
-		assertTrue(iterator.list.contains("baz"));
-	}
-
-	public void testSynchronizedSet() throws Exception {
-		TestListIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
-		ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
-		iterator.next();
-
-		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		SetTestRunnable<String> runnable2 = new SetTestRunnable<String>(iterator, "xxx");
-		Thread thread2 = this.buildThread(runnable2);
-		nestedIterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// the right element was set :-)
-		assertEquals("bar", runnable1.next);
-		assertTrue(nestedIterator.list.contains("foo"));
-		assertFalse(nestedIterator.list.contains("bar"));
-		assertTrue(nestedIterator.list.contains("xxx"));
-		assertTrue(nestedIterator.list.contains("baz"));
-	}
-
-	public void testUnsynchronizedAdd() throws Exception {
-		TestListIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
-		iterator.next();
-
-		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		AddTestRunnable<String> runnable2 = new AddTestRunnable<String>(iterator, "xxx");
-		Thread thread2 = this.buildThread(runnable2);
-		iterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// the element was added at the wrong index :-(
-		assertEquals("bar", runnable1.next);
-		assertTrue(iterator.list.contains("foo"));
-		assertEquals(0, iterator.list.indexOf("xxx"));
-		assertTrue(iterator.list.contains("xxx"));
-		assertTrue(iterator.list.contains("bar"));
-		assertTrue(iterator.list.contains("baz"));
-	}
-
-	public void testSynchronizedAdd() throws Exception {
-		TestListIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
-		ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
-		iterator.next();
-
-		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
-		Thread thread1 = this.buildThread(runnable1);
-		AddTestRunnable<String> runnable2 = new AddTestRunnable<String>(iterator, "xxx");
-		Thread thread2 = this.buildThread(runnable2);
-		nestedIterator.slowThread = thread1;
-
-		thread1.start();
-
-		// allow thread 1 to read the first element and get bogged down
-		this.sleep(TICK);
-		thread2.start();
-
-		// wait for the threads to finish
-		thread1.join();
-		thread2.join();
-
-		// the element was added at the correct index :-)
-		assertEquals("bar", runnable1.next);
-		assertTrue(nestedIterator.list.contains("foo"));
-		assertEquals(1, nestedIterator.list.indexOf("xxx"));
-		assertTrue(nestedIterator.list.contains("xxx"));
-		assertTrue(nestedIterator.list.contains("bar"));
-		assertTrue(nestedIterator.list.contains("baz"));
-	}
-
-	@Override
-	ListIterator<String> buildSynchronizedIterator(Iterator<String> nestedIterator) {
-		return new SynchronizedListIterator<String>((ListIterator<String>) nestedIterator);
-	}
-
-	@Override
-	TestListIterator<String> buildTestIterator(long delay) {
-		return new TestListIterator<String>(delay, this.buildArray());
-	}
-
-	/**
-	 * previous runnable
-	 */
-	class PreviousTestRunnable<E> implements Runnable {
-		final ListIterator<E> iterator;
-		E previous;
-
-		PreviousTestRunnable(ListIterator<E> iterator) {
-			super();
-			this.iterator = iterator;
-		}
-
-		public void run() {
-			this.previous = this.iterator.previous();
-		}
-
-	}
-
-	/**
-	 * has previous runnable
-	 */
-	class HasPreviousTestRunnable<E> implements Runnable {
-		final ListIterator<E> iterator;
-		boolean hasPrevious;
-
-		HasPreviousTestRunnable(ListIterator<E> iterator) {
-			super();
-			this.iterator = iterator;
-		}
-
-		public void run() {
-			this.hasPrevious = this.iterator.hasPrevious();
-		}
-
-	}
-
-	/**
-	 * next index runnable
-	 */
-	class NextIndexTestRunnable<E> implements Runnable {
-		final ListIterator<E> iterator;
-		int nextIndex;
-
-		NextIndexTestRunnable(ListIterator<E> iterator) {
-			super();
-			this.iterator = iterator;
-		}
-
-		public void run() {
-			this.nextIndex = this.iterator.nextIndex();
-		}
-
-	}
-
-	/**
-	 * previous index runnable
-	 */
-	class PreviousIndexTestRunnable<E> implements Runnable {
-		final ListIterator<E> iterator;
-		int previousIndex;
-
-		PreviousIndexTestRunnable(ListIterator<E> iterator) {
-			super();
-			this.iterator = iterator;
-		}
-
-		public void run() {
-			this.previousIndex = this.iterator.previousIndex();
-		}
-
-	}
-
-	/**
-	 * set runnable
-	 */
-	class SetTestRunnable<E> implements Runnable {
-		final ListIterator<E> iterator;
-		final E element;
-
-		SetTestRunnable(ListIterator<E> iterator, E element) {
-			super();
-			this.iterator = iterator;
-			this.element = element;
-		}
-
-		public void run() {
-			this.iterator.set(this.element);
-		}
-
-	}
-
-	/**
-	 * add runnable
-	 */
-	class AddTestRunnable<E> implements Runnable {
-		final ListIterator<E> iterator;
-		final E element;
-
-		AddTestRunnable(ListIterator<E> iterator, E element) {
-			super();
-			this.iterator = iterator;
-			this.element = element;
-		}
-
-		public void run() {
-			this.iterator.add(this.element);
-		}
-
-	}
-
-	/**
-	 * Test iterator: If {@link #next()} or {@link #previous()} is called
-	 * while executing on the {@link slowThread}, the iterator will delay
-	 * for the configured time.
-	 */
-	static class TestListIterator<E> extends TestIterator<E> implements ListIterator<E> {
-
-		TestListIterator(long delay, E... array) {
-			super(delay, array);
-		}
-
-		public int nextIndex() {
-			return this.nextIndex;
-		}
-
-		public boolean hasPrevious() {
-			return this.nextIndex != 0;
-		}
-
-		public E previous() {
-			if (this.hasPrevious()) {
-				E previous = this.list.get(this.previousIndex());
-				if (Thread.currentThread() == this.slowThread) {
-					TestTools.sleep(this.delay);
-				}
-				this.nextIndex--;
-				this.lastIndex = this.nextIndex;
-				return previous;
-			}
-			throw new NoSuchElementException();
-		}
-
-		public int previousIndex() {
-			return this.nextIndex - 1;
-		}
-
-		public void set(E e) {
-			if (this.lastIndex == -1) {
-				throw new IllegalStateException();
-			}
-			this.list.set(this.lastIndex, e);
-		}
-
-		public void add(E e) {
-			this.list.add(this.lastIndex, e);
-			this.lastIndex++;
-			this.lastIndex = -1;
-		}
-
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/TransformationIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/TransformationIteratorTests.java
deleted file mode 100644
index a96ce10..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/TransformationIteratorTests.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.Transformer;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
-
-@SuppressWarnings("nls")
-public class TransformationIteratorTests extends TestCase {
-
-	public TransformationIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testHasNext() {
-		int i = 0;
-		for (Iterator<Integer> stream = this.buildIterator(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(8, i);
-	}
-
-	public void testHasNextUpcast() {
-		int i = 0;
-		for (Iterator<Object> stream = this.buildIteratorUpcast(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(8, i);
-	}
-
-	public void testInnerHasNext() {
-		int i = 0;
-		for (Iterator<Integer> stream = this.buildInnerIterator(); stream.hasNext();) {
-			stream.next();
-			i++;
-		}
-		assertEquals(8, i);
-	}
-
-	public void testNext() {
-		int i = 0;
-		for (Iterator<Integer> stream = this.buildIterator(); stream.hasNext();) {
-			assertEquals("bogus transformation", ++i, stream.next().intValue());
-		}
-	}
-
-	public void testNextUpcast() {
-		int i = 0;
-		for (Iterator<Object> stream = this.buildIteratorUpcast(); stream.hasNext();) {
-			assertEquals("bogus transformation", ++i, ((Integer) stream.next()).intValue());
-		}
-	}
-
-	public void testInnerNext() {
-		int i = 0;
-		for (Iterator<Integer> stream = this.buildInnerIterator(); stream.hasNext();) {
-			assertEquals("bogus transformation", ++i, stream.next().intValue());
-		}
-	}
-
-	public void testRemove() {
-		Collection<String> c = this.buildCollection();
-		for (Iterator<Integer> stream = this.buildInnerTransformationIterator(c.iterator()); stream.hasNext();) {
-			if (stream.next().intValue() == 3) {
-				stream.remove();
-			}
-		}
-		assertEquals("nothing removed", this.buildCollection().size() - 1, c.size());
-		assertFalse("element still in collection", c.contains("333"));
-		assertTrue("wrong element removed", c.contains("22"));
-	}
-
-	public void testInnerRemove() {
-		Collection<String> c = this.buildCollection();
-		for (Iterator<Integer> stream = this.buildTransformationIterator(c.iterator(), this.buildTransformer()); stream.hasNext();) {
-			if (stream.next().intValue() == 3) {
-				stream.remove();
-			}
-		}
-		assertEquals("nothing removed", this.buildCollection().size() - 1, c.size());
-		assertFalse("element still in collection", c.contains("333"));
-		assertTrue("wrong element removed", c.contains("22"));
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		Iterator<Integer> stream = this.buildIterator();
-		Integer integer = null;
-		while (stream.hasNext()) {
-			integer = stream.next();
-		}
-		try {
-			integer = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + integer, exCaught);
-	}
-
-	public void testUnsupportedOperationException() {
-		boolean exCaught = false;
-		for (Iterator<Integer> stream = this.buildUnmodifiableIterator(); stream.hasNext();) {
-			int i = stream.next().intValue();
-			if (i == 3) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	public void testIllegalStateException() {
-		boolean exCaught = false;
-		try {
-			this.buildIterator().remove();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue("IllegalStateException not thrown", exCaught);
-	}
-
-	private Iterator<Integer> buildIterator() {
-		return this.buildTransformationIterator(this.buildNestedIterator(), this.buildTransformer());
-	}
-
-	private Iterator<Object> buildIteratorUpcast() {
-		return this.buildTransformationIteratorUpcast(this.buildNestedIterator(), this.buildTransformerUpcast());
-	}
-
-	private Iterator<Integer> buildInnerIterator() {
-		return this.buildInnerTransformationIterator(this.buildNestedIterator());
-	}
-
-	private Iterator<Integer> buildUnmodifiableIterator() {
-		return this.buildTransformationIterator(this.buildUnmodifiableNestedIterator(), this.buildTransformer());
-	}
-
-	private Iterator<Integer> buildTransformationIterator(Iterator<String> nestedIterator, Transformer<Integer, String> transformer) {
-		return new TransformationIterator<Integer, String>(nestedIterator, transformer);
-	}
-
-	private Iterator<Object> buildTransformationIteratorUpcast(Iterator<String> nestedIterator, Transformer<Integer, Object> transformer) {
-		return new TransformationIterator<Object, Object>(nestedIterator, transformer);
-	}
-
-	private Transformer<Integer, String> buildTransformer() {
-		// transform each string into an integer with a value of the string's length
-		return new Transformer<Integer, String>() {
-			public Integer transform(String next) {
-				return new Integer(next.length());
-			}
-		};
-	}
-
-	private Transformer<Integer, Object> buildTransformerUpcast() {
-		// transform each string into an integer with a value of the string's length
-		return new Transformer<Integer, Object>() {
-			public Integer transform(Object next) {
-				return new Integer(((String) next).length());
-			}
-		};
-	}
-
-	private Iterator<Integer> buildInnerTransformationIterator(Iterator<String> nestedIterator) {
-		// transform each string into an integer with a value of the string's length
-		return new TransformationIterator<Integer, String>(nestedIterator) {
-			@Override
-			protected Integer transform(String next) {
-				return new Integer(next.length());
-			}
-		};
-	}
-
-	private Iterator<String> buildNestedIterator() {
-		return this.buildCollection().iterator();
-	}
-
-	private Iterator<String> buildUnmodifiableNestedIterator() {
-		return this.buildUnmodifiableCollection().iterator();
-	}
-
-	private Collection<String> buildCollection() {
-		Collection<String> c = new ArrayList<String>();
-		c.add("1");
-		c.add("22");
-		c.add("333");
-		c.add("4444");
-		c.add("55555");
-		c.add("666666");
-		c.add("7777777");
-		c.add("88888888");
-		return c;
-	}
-
-	private Collection<String> buildUnmodifiableCollection() {
-		return Collections.unmodifiableCollection(this.buildCollection());
-	}
-
-	public void testInvalidTransformationIterator() {
-		// missing method override
-		Iterator<Integer> iterator = new TransformationIterator<Integer, String>(this.buildCollection().iterator());
-		boolean exCaught = false;
-		try {
-			Integer integer = iterator.next();
-			fail("invalid integer: " + integer);
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown", exCaught);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/TransformationListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/TransformationListIteratorTests.java
deleted file mode 100644
index b260593..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/TransformationListIteratorTests.java
+++ /dev/null
@@ -1,325 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.Transformer;
-import org.eclipse.persistence.tools.utility.iterators.TransformationListIterator;
-
-@SuppressWarnings("nls")
-public class TransformationListIteratorTests extends TestCase {
-
-	public TransformationListIteratorTests(String name) {
-		super(name);
-	}
-
-	public void testHasNextAndHasPrevious() {
-		int i = 0;
-		ListIterator<Integer> stream = this.buildIterator();
-
-		while (stream.hasNext()) {
-			stream.next();
-			i++;
-		}
-		assertEquals(8, i);
-
-		while (stream.hasPrevious()) {
-			stream.previous();
-			i--;
-		}
-		assertEquals(0, i);
-	}
-
-	public void testHasNextAndHasPreviousUpcast() {
-		int i = 0;
-		ListIterator<Object> stream = this.buildIteratorUpcast();
-
-		while (stream.hasNext()) {
-			stream.next();
-			i++;
-		}
-		assertEquals(8, i);
-
-		while (stream.hasPrevious()) {
-			stream.previous();
-			i--;
-		}
-		assertEquals(0, i);
-	}
-
-	public void testInnerHasNextAndHasPrevious() {
-		int i = 0;
-		ListIterator<Integer> stream = this.buildInnerIterator();
-
-		while (stream.hasNext()) {
-			stream.next();
-			i++;
-		}
-		assertEquals(8, i);
-
-		while (stream.hasPrevious()) {
-			stream.previous();
-			i--;
-		}
-		assertEquals(0, i);
-	}
-
-	public void testNextAndPrevious() {
-		int i = 0;
-		ListIterator<Integer> stream = this.buildIterator();
-
-		while (stream.hasNext()) {
-			assertEquals(++i, stream.next().intValue());
-		}
-
-		++i;
-
-		while (stream.hasPrevious()) {
-			assertEquals(--i, stream.previous().intValue());
-		}
-	}
-
-	public void testInnerNextAndPrevious() {
-		int i = 0;
-		ListIterator<Integer> stream = this.buildInnerIterator();
-
-		while (stream.hasNext()) {
-			assertEquals(++i, stream.next().intValue());
-		}
-
-		++i;
-
-		while (stream.hasPrevious()) {
-			assertEquals(--i, stream.previous().intValue());
-		}
-	}
-
-	public void testNextIndexAndPreviousIndex() {
-		int i = -1;
-		ListIterator<Integer> stream = this.buildIterator();
-
-		while (stream.hasNext()) {
-			assertEquals(++i, stream.nextIndex());
-			stream.next();
-		}
-
-		++i;
-
-		while (stream.hasPrevious()) {
-			assertEquals(--i, stream.previousIndex());
-			stream.previous();
-		}
-	}
-
-	public void testInnerNextIndexAndPreviousIndex() {
-		int i = -1;
-		ListIterator<Integer> stream = this.buildInnerIterator();
-
-		while (stream.hasNext()) {
-			assertEquals(++i, stream.nextIndex());
-			stream.next();
-		}
-
-		++i;
-
-		while (stream.hasPrevious()) {
-			assertEquals(--i, stream.previousIndex());
-			stream.previous();
-		}
-	}
-
-	public void testRemove() {
-		List<String> l = this.buildList();
-		for (ListIterator<Integer> stream = this.buildInnerTransformationListIterator(l.listIterator()); stream.hasNext();) {
-			if (stream.next().intValue() == 3) {
-				stream.remove();
-			}
-		}
-		assertEquals("nothing removed", this.buildList().size() - 1, l.size());
-		assertFalse("element still in list", l.contains("333"));
-		assertTrue("wrong element removed", l.contains("22"));
-	}
-
-	public void testInnerRemove() {
-		List<String> l = this.buildList();
-		for (ListIterator<Integer> stream = this.buildTransformationListIterator(l.listIterator(), this.buildTransformer()); stream.hasNext();) {
-			if (stream.next().intValue() == 3) {
-				stream.remove();
-			}
-		}
-		assertEquals("nothing removed", this.buildList().size() - 1, l.size());
-		assertFalse("element still in list", l.contains("333"));
-		assertTrue("wrong element removed", l.contains("22"));
-	}
-
-	public void testUnsupportedOperationExceptionOnAdd() {
-		ListIterator<Integer> stream = this.buildIterator();
-		boolean exCaught = false;
-		try {
-			stream.add(new Integer(0));
-			fail("exception not thrown");
-		} catch (UnsupportedOperationException e) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testUnsupportedOperationExceptionOnSet() {
-		ListIterator<Integer> stream = this.buildIterator();
-		boolean exCaught = false;
-		try {
-			stream.set(new Integer(0));
-			fail("exception not thrown");
-		} catch (UnsupportedOperationException e) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testNoSuchElementException() {
-		boolean exCaught = false;
-		ListIterator<Integer> stream = this.buildIterator();
-		Integer integer = null;
-		while (stream.hasNext()) {
-			integer = stream.next();
-		}
-		try {
-			integer = stream.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown: " + integer, exCaught);
-	}
-
-	public void testUnsupportedOperationException() {
-		boolean exCaught = false;
-		for (Iterator<Integer> stream = this.buildUnmodifiableIterator(); stream.hasNext();) {
-			int i = stream.next().intValue();
-			if (i == 3) {
-				try {
-					stream.remove();
-				} catch (UnsupportedOperationException ex) {
-					exCaught = true;
-				}
-			}
-		}
-		assertTrue("UnsupportedOperationException not thrown", exCaught);
-	}
-
-	public void testIllegalStateException() {
-		boolean exCaught = false;
-		try {
-			this.buildIterator().remove();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue("IllegalStateException not thrown", exCaught);
-	}
-
-	private ListIterator<Integer> buildIterator() {
-		return this.buildTransformationListIterator(this.buildNestedIterator(), this.buildTransformer());
-	}
-
-	private ListIterator<Object> buildIteratorUpcast() {
-		return this.buildTransformationListIteratorUpcast(this.buildNestedIterator(), this.buildTransformerUpcast());
-	}
-
-	private ListIterator<Integer> buildInnerIterator() {
-		return this.buildInnerTransformationListIterator(this.buildNestedIterator());
-	}
-
-	private ListIterator<Integer> buildUnmodifiableIterator() {
-		return this.buildTransformationListIterator(this.buildUnmodifiableNestedIterator(), this.buildTransformer());
-	}
-
-	private ListIterator<Integer> buildTransformationListIterator(ListIterator<String> nestedIterator, Transformer<Integer, String> transformer) {
-		return new TransformationListIterator<Integer, String>(nestedIterator, transformer);
-	}
-
-	private ListIterator<Object> buildTransformationListIteratorUpcast(ListIterator<String> nestedIterator, Transformer<Integer, Object> transformer) {
-		return new TransformationListIterator<Object, Object>(nestedIterator, transformer);
-	}
-
-	private Transformer<Integer, String> buildTransformer() {
-		// transform each string into an integer with a value of the string's length
-		return new Transformer<Integer, String>() {
-			public Integer transform(String next) {
-				return new Integer(next.length());
-			}
-		};
-	}
-
-	private Transformer<Integer, Object> buildTransformerUpcast() {
-		// transform each string into an integer with a value of the string's length
-		return new Transformer<Integer, Object>() {
-			public Integer transform(Object next) {
-				return new Integer(((String) next).length());
-			}
-		};
-	}
-
-	private ListIterator<Integer> buildInnerTransformationListIterator(ListIterator<String> nestedIterator) {
-		// transform each string into an integer with a value of the string's length
-		return new TransformationListIterator<Integer, String>(nestedIterator) {
-			@Override
-			protected Integer transform(String next) {
-				return new Integer(next.length());
-			}
-		};
-	}
-
-	private ListIterator<String> buildNestedIterator() {
-		return this.buildList().listIterator();
-	}
-
-	private ListIterator<String> buildUnmodifiableNestedIterator() {
-		return this.buildUnmodifiableList().listIterator();
-	}
-
-	private List<String> buildList() {
-		List<String> l = new ArrayList<String>();
-		l.add("1");
-		l.add("22");
-		l.add("333");
-		l.add("4444");
-		l.add("55555");
-		l.add("666666");
-		l.add("7777777");
-		l.add("88888888");
-		return l;
-	}
-
-	private List<String> buildUnmodifiableList() {
-		return Collections.unmodifiableList(this.buildList());
-	}
-
-	public void testInvalidTransformationListIterator() {
-		// missing method override
-		Iterator<Integer> iterator = new TransformationListIterator<Integer, String>(this.buildList().listIterator());
-		boolean exCaught = false;
-		try {
-			Integer integer = iterator.next();
-			fail("invalid integer: " + integer);
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown", exCaught);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/TreeIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/TreeIteratorTests.java
deleted file mode 100644
index 90f6b58..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/TreeIteratorTests.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.iterators.TreeIterator;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-import org.eclipse.persistence.tools.utility.tests.internal.iterables.TreeIterableTests.TreeNode;
-
-@SuppressWarnings("nls")
-public class TreeIteratorTests extends TestCase {
-	/** this will be populated with all the nodes created for the test */
-	Collection<TreeNode> nodes = new ArrayList<TreeNode>();
-
-	public TreeIteratorTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		TestTools.clear(this);
-		super.tearDown();
-	}
-
-	public void testHasNext1() {
-		this.verifyHasNext(this.buildTreeIterator1());
-	}
-
-	public void testHasNext2() {
-		this.verifyHasNext(this.buildTreeIterator2());
-	}
-
-	private void verifyHasNext(Iterator<TreeNode> iterator) {
-		int i = 0;
-		while (iterator.hasNext()) {
-			iterator.next();
-			i++;
-		}
-		assertEquals(this.nodes.size(), i);
-	}
-
-	public void testNext1() {
-		this.verifyNext(this.buildTreeIterator1());
-	}
-
-	public void testNext2() {
-		this.verifyNext(this.buildTreeIterator2());
-	}
-
-	private void verifyNext(Iterator<TreeNode> iterator) {
-		while (iterator.hasNext()) {
-			assertTrue("bogus element", this.nodes.contains(iterator.next()));
-		}
-	}
-
-	public void testNoSuchElementException1() {
-		this.verifyNoSuchElementException(this.buildTreeIterator1());
-	}
-
-	public void testNoSuchElementException2() {
-		this.verifyNoSuchElementException(this.buildTreeIterator2());
-	}
-
-	private void verifyNoSuchElementException(Iterator<TreeNode> iterator) {
-		boolean exCaught = false;
-		while (iterator.hasNext()) {
-			iterator.next();
-		}
-		try {
-			iterator.next();
-		} catch (NoSuchElementException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown", exCaught);
-	}
-
-	public void testRemove1() {
-		this.verifyRemove(this.buildTreeIterator1());
-	}
-
-	public void testRemove2() {
-		this.verifyRemove(this.buildTreeIterator2());
-	}
-
-	private void verifyRemove(Iterator<TreeNode> iterator) {
-		String parentName = "child 2";
-		String childName = "grandchild 2A";
-		int startSize = this.childrenSize(parentName);
-		while (iterator.hasNext()) {
-			TreeNode node = iterator.next();
-			if (node.getName().equals(childName)) {
-				iterator.remove();
-			}
-		}
-		int endSize = this.childrenSize(parentName);
-		assertEquals(startSize - 1, endSize);
-	}
-
-	private int childrenSize(String nodeName) {
-		for (Iterator<TreeNode> stream = this.nodes.iterator(); stream.hasNext();) {
-			TreeNode node = stream.next();
-			if (node.getName().equals(nodeName)) {
-				return node.childrenSize();
-			}
-		}
-		throw new IllegalArgumentException(nodeName);
-	}
-
-	/**
-	 * build a tree iterator with an explicit midwife
-	 */
-	private Iterator<TreeNode> buildTreeIterator1() {
-		return new TreeIterator<TreeNode>(this.buildTree(), this.buildMidwife());
-	}
-
-	private TreeIterator.Midwife<TreeNode> buildMidwife() {
-		return new TreeIterator.Midwife<TreeNode>() {
-			public Iterator<TreeNode> children(TreeNode next) {
-				return next.children();
-			}
-		};
-	}
-
-	/**
-	 * build a tree iterator with an override
-	 */
-	private Iterator<TreeNode> buildTreeIterator2() {
-		return new TreeIterator<TreeNode>(this.buildTree()) {
-			@Override
-			public Iterator<TreeNode> children(TreeNode next) {
-				return next.children();
-			}
-		};
-	}
-
-	public void testInvalidTreeIterator() {
-		// missing method override
-		Iterator<TreeNode> iterator = new TreeIterator<TreeNode>(this.buildTree());
-		boolean exCaught = false;
-		try {
-			TreeNode tn = iterator.next();
-			fail("invalid tree node: " + tn);
-		} catch (UnsupportedOperationException ex) {
-			exCaught = true;
-		}
-		assertTrue("NoSuchElementException not thrown", exCaught);
-	}
-
-	private TreeNode buildTree() {
-		TreeNode root = new TreeNode("root");
-		TreeNode child1 = new TreeNode(root, "child 1");
-		new TreeNode(child1, "grandchild 1A");
-		TreeNode child2 = new TreeNode(root, "child 2");
-		new TreeNode(child2, "grandchild 2A");
-		TreeNode grandchild2B = new TreeNode(child2, "grandchild 2B");
-		new TreeNode(grandchild2B, "great-grandchild 2B1");
-		new TreeNode(grandchild2B, "great-grandchild 2B2");
-		TreeNode grandchild2C = new TreeNode(child2, "grandchild 2C");
-		new TreeNode(grandchild2C, "great-grandchild 2C1");
-		new TreeNode(root, "child 3");
-		return root;
-	}
-
-	private class TreeNode {
-		private String name;
-		private Collection<TreeNode> children = new ArrayList<TreeNode>();
-
-		public TreeNode(String name) {
-			super();
-			TreeIteratorTests.this.nodes.add(this); // log node
-			this.name = name;
-		}
-
-		public TreeNode(TreeNode parent, String name) {
-			this(name);
-			parent.addChild(this);
-		}
-
-		public String getName() {
-			return this.name;
-		}
-
-		private void addChild(TreeNode child) {
-			this.children.add(child);
-		}
-
-		public Iterator<TreeNode> children() {
-			return this.children.iterator();
-		}
-
-		public int childrenSize() {
-			return this.children.size();
-		}
-
-		@Override
-		public String toString() {
-			return "TreeNode(" + this.name + ")";
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/UtilityIteratorsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/UtilityIteratorsTests.java
deleted file mode 100644
index 3dc5b6c..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/iterators/UtilityIteratorsTests.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.iterators;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * decentralize test creation code
- */
-public class UtilityIteratorsTests {
-
-	public static Test suite() {
-		TestSuite suite = new TestSuite(UtilityIteratorsTests.class.getPackage().getName());
-
-		suite.addTestSuite(ArrayIteratorTests.class);
-		suite.addTestSuite(ArrayListIteratorTests.class);
-		suite.addTestSuite(ChainIteratorTests.class);
-		suite.addTestSuite(CloneIteratorTests.class);
-		suite.addTestSuite(CloneListIteratorTests.class);
-		suite.addTestSuite(CompositeIteratorTests.class);
-		suite.addTestSuite(CompositeListIteratorTests.class);
-		suite.addTestSuite(EmptyIteratorTests.class);
-		suite.addTestSuite(EmptyListIteratorTests.class);
-		suite.addTestSuite(EnumerationIteratorTests.class);
-		suite.addTestSuite(FilteringIteratorTests.class);
-		suite.addTestSuite(SuperIteratorWrapperTests.class);
-		suite.addTestSuite(GraphIteratorTests.class);
-		suite.addTestSuite(PeekableIteratorTests.class);
-		suite.addTestSuite(ReadOnlyCompositeListIteratorTests.class);
-		suite.addTestSuite(ReadOnlyIteratorTests.class);
-		suite.addTestSuite(ReadOnlyListIteratorTests.class);
-		suite.addTestSuite(SingleElementIteratorTests.class);
-		suite.addTestSuite(SingleElementListIteratorTests.class);
-		suite.addTestSuite(SynchronizedIteratorTests.class);
-		suite.addTestSuite(SynchronizedListIteratorTests.class);
-		suite.addTestSuite(TransformationIteratorTests.class);
-		suite.addTestSuite(TransformationListIteratorTests.class);
-		suite.addTestSuite(TreeIteratorTests.class);
-
-		return suite;
-	}
-
-	private UtilityIteratorsTests() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/ChangeSupportTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/ChangeSupportTests.java
deleted file mode 100644
index cf12dc4..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/ChangeSupportTests.java
+++ /dev/null
@@ -1,4577 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.model;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EventListener;
-import java.util.HashSet;
-import java.util.List;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.ArrayTools;
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.ListenerList;
-import org.eclipse.persistence.tools.utility.ReflectionTools;
-import org.eclipse.persistence.tools.utility.Tools;
-import org.eclipse.persistence.tools.utility.model.AbstractModel;
-import org.eclipse.persistence.tools.utility.model.ChangeSupport;
-import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.CollectionEvent;
-import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
-import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.ListEvent;
-import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
-import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
-import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
-import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeRemoveEvent;
-import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
-import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeAdapter;
-import org.eclipse.persistence.tools.utility.model.listener.ListChangeAdapter;
-import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeAdapter;
-import org.eclipse.persistence.tools.utility.model.listener.StateChangeAdapter;
-import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.TreeChangeAdapter;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-
-@SuppressWarnings("nls")
-public class ChangeSupportTests
-	extends TestCase
-{
-	TestModel testModel;
-	static final String TEST_TO_STRING = "this is a test";
-
-	ChangeListener changeListener = new Adapter();
-
-	StateChangeEvent stateChangeEvent;
-	boolean stateChangedCalled = false;
-
-	PropertyChangeEvent propertyChangeEvent;
-	boolean propertyChangeCalled = false;
-	static final String PROPERTY_NAME = "propertyName";
-	static final Object OLD_OBJECT_VALUE = new Object();
-	static final Object NEW_OBJECT_VALUE = new Object();
-	static final Integer OLD_INT_VALUE = new Integer(27);
-	static final Boolean OLD_BOOLEAN_VALUE = Boolean.TRUE;
-	static final Integer NEW_INT_VALUE = new Integer(42);
-	static final Boolean NEW_BOOLEAN_VALUE = Boolean.FALSE;
-
-	CollectionEvent collectionEvent;
-	boolean itemsAddedCollectionCalled = false;
-	boolean itemsRemovedCollectionCalled = false;
-	boolean collectionChangedCalled = false;
-	boolean collectionClearedCalled = false;
-	static final String COLLECTION_NAME = "collectionName";
-	static final Object ADDED_OBJECT_VALUE = new Object();
-	static final Object ADDED_OBJECT_VALUE_2 = new Object();
-	static final Object REMOVED_OBJECT_VALUE = new Object();
-	static final int TARGET_INDEX = 7;
-	static final int SOURCE_INDEX = 22;
-
-	ListEvent listEvent;
-	boolean itemsAddedListCalled = false;
-	boolean itemsRemovedListCalled = false;
-	boolean itemsReplacedListCalled = false;
-	boolean itemsMovedListCalled = false;
-	boolean listChangedCalled = false;
-	boolean listClearedCalled = false;
-	static final String LIST_NAME = "listName";
-	static final int ADD_INDEX = 3;
-	static final int REMOVE_INDEX = 5;
-	static final int REPLACE_INDEX = 2;
-
-	TreeEvent treeEvent;
-	boolean nodeAddedCalled = false;
-	boolean nodeRemovedCalled = false;
-	boolean treeChangedCalled = false;
-	boolean treeClearedCalled = false;
-	static final String TREE_NAME = "treeName";
-	static final List<Object> OBJECT_PATH = Arrays.asList(new Object[] {new Object(), new Object(), new String()});
-
-
-	public ChangeSupportTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.testModel = new TestModel();
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		TestTools.clear(this);
-		super.tearDown();
-	}
-
-
-	// ********** general tests **********
-
-	public void testNullSource() {
-		boolean exCaught = false;
-		try {
-			ChangeSupport cs = new ChangeSupport(null);
-			fail("bogus change support: " + cs);
-		} catch (NullPointerException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	// ********** state change tests **********
-
-	public void testFireStateChange() {
-		this.stateChangeEvent = null;
-		this.stateChangedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireStateChange();
-		assertNotNull(this.stateChangeEvent);
-		assertEquals(this.testModel, this.stateChangeEvent.getSource());
-		assertTrue(this.stateChangedCalled);
-	}
-
-	public void testHasAnyStateChangeListeners() {
-		assertTrue(this.testModel.hasNoStateChangeListeners());
-		this.testModel.addChangeListener(this.changeListener);
-		assertTrue(this.testModel.hasAnyStateChangeListeners());
-		this.testModel.removeChangeListener(this.changeListener);
-		assertTrue(this.testModel.hasNoStateChangeListeners());
-	}
-
-	public void testHasAnyStateChangeListenersDuplicate() {
-		assertTrue(this.testModel.hasNoStateChangeListeners());
-		this.testModel.addChangeListener(this.changeListener);
-		boolean exCaught = false;
-		try {
-			this.testModel.addChangeListener(this.changeListener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-		assertTrue(this.testModel.hasAnyStateChangeListeners());
-		this.testModel.removeChangeListener(this.changeListener);
-		assertTrue(this.testModel.hasNoStateChangeListeners());
-
-		exCaught = false;
-		try {
-			this.testModel.removeChangeListener(this.changeListener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(this.testModel.hasNoStateChangeListeners());
-	}
-
-	public void testAddNullStateListener() {
-		boolean exCaught = false;
-		try {
-			this.testModel.addStateChangeListener(null);
-		} catch (NullPointerException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testRemoveBogusStateListener() {
-		boolean exCaught = false;
-		try {
-			this.testModel.removeChangeListener(this.changeListener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		this.testModel.addPropertyChangeListener("foo", this.changeListener);
-		exCaught = false;
-		try {
-			this.testModel.removeChangeListener(this.changeListener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		this.testModel.addChangeListener(this.changeListener);
-		exCaught = false;
-		try {
-			this.testModel.removeStateChangeListener(new Adapter());
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		exCaught = false;
-		try {
-			this.testModel.removeStateChangeListener(new StateChangeAdapter());
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-
-	// ********** property change tests **********
-
-	public void testFirePropertyChangedEvent() {
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedEvent();
-		this.verifyPropertyChangeEvent(OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
-		assertTrue(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedEvent();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedEvent();
-		this.verifyPropertyChangeEvent(OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
-		assertTrue(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedEvent();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-	}
-
-	public void testFirePropertyChangedEventNoChange() {
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedEventNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedEventNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedEventNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedEventNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-	}
-
-	public void testFirePropertyChangedObjectObject() {
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedObjectObject();
-		this.verifyPropertyChangeEvent(OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
-		assertTrue(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedObjectObject();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedObjectObject();
-		this.verifyPropertyChangeEvent(OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
-		assertTrue(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedObjectObject();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-	}
-
-	public void testFirePropertyChangedObjectObjectNoChange() {
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedObjectObjectNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedObjectObjectNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedObjectObjectNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedObjectObjectNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-	}
-
-	public void testFirePropertyChangedObject() {
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedObject();
-		this.verifyPropertyChangeEvent(null, NEW_OBJECT_VALUE);
-		assertTrue(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedObject();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedObject();
-		this.verifyPropertyChangeEvent(null, NEW_OBJECT_VALUE);
-		assertTrue(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedObject();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-	}
-
-	public void testFirePropertyChangedObjectNoChange() {
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedObjectNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedObjectNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedObjectNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedObjectNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-	}
-
-	public void testFirePropertyChangedIntInt() {
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedIntInt();
-		this.verifyPropertyChangeEvent(OLD_INT_VALUE, NEW_INT_VALUE);
-		assertTrue(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedIntInt();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedIntInt();
-		this.verifyPropertyChangeEvent(OLD_INT_VALUE, NEW_INT_VALUE);
-		assertTrue(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedIntInt();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-	}
-
-	public void testFirePropertyChangedIntIntNoChange() {
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedIntIntNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedIntIntNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedIntIntNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedIntIntNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-	}
-
-	public void testFirePropertyChangedBooleanBoolean() {
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedBooleanBoolean();
-		this.verifyPropertyChangeEvent(OLD_BOOLEAN_VALUE, NEW_BOOLEAN_VALUE);
-		assertTrue(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedBooleanBoolean();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedBooleanBoolean();
-		this.verifyPropertyChangeEvent(OLD_BOOLEAN_VALUE, NEW_BOOLEAN_VALUE);
-		assertTrue(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedBooleanBoolean();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-	}
-
-	public void testFirePropertyChangedBooleanBooleanNoChange() {
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedBooleanBooleanNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFirePropertyChangedBooleanBooleanNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedBooleanBooleanNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		this.testModel.testFirePropertyChangedBooleanBooleanNoChange();
-		assertNull(this.propertyChangeEvent);
-		assertFalse(this.propertyChangeCalled);
-	}
-
-	public void testHasAnyPropertyChangeListeners() {
-		assertTrue(this.testModel.hasNoPropertyChangeListeners(PROPERTY_NAME));
-		this.testModel.addChangeListener(this.changeListener);
-		assertTrue(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
-		this.testModel.removeChangeListener(this.changeListener);
-		assertTrue(this.testModel.hasNoPropertyChangeListeners(PROPERTY_NAME));
-
-		assertTrue(this.testModel.hasNoPropertyChangeListeners(PROPERTY_NAME));
-		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		assertTrue(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
-		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
-		assertTrue(this.testModel.hasNoPropertyChangeListeners(PROPERTY_NAME));
-	}
-
-	public void testAddNullPropertyListener() {
-		boolean exCaught = false;
-		try {
-			this.testModel.addChangeListener(null);
-		} catch (NullPointerException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testAddNullPropertyListenerName() {
-		boolean exCaught = false;
-		try {
-			this.testModel.addPropertyChangeListener("foo", null);
-		} catch (NullPointerException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testRemoveBogusPropertyListener() {
-		boolean exCaught = false;
-		try {
-			this.testModel.removePropertyChangeListener("foo", new PropertyChangeAdapter());
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		this.testModel.addCollectionChangeListener("foo", this.changeListener);
-		exCaught = false;
-		try {
-			this.testModel.removePropertyChangeListener("foo", this.changeListener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		this.testModel.addPropertyChangeListener("foo", this.changeListener);
-		exCaught = false;
-		try {
-			this.testModel.removePropertyChangeListener("foo", new PropertyChangeAdapter());
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		exCaught = false;
-		try {
-			this.testModel.removePropertyChangeListener("foo", new PropertyChangeAdapter());
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	private void verifyPropertyChangeEvent(Object oldValue, Object newValue) {
-		this.verifyPropertyChangeEvent(this.testModel, oldValue, newValue);
-	}
-
-	private void verifyPropertyChangeEvent(Object source, Object oldValue, Object newValue) {
-		assertNotNull(this.propertyChangeEvent);
-		assertEquals(source, this.propertyChangeEvent.getSource());
-		assertEquals(PROPERTY_NAME, this.propertyChangeEvent.getPropertyName());
-		assertEquals(oldValue, this.propertyChangeEvent.getOldValue());
-		assertEquals(newValue, this.propertyChangeEvent.getNewValue());
-	}
-
-
-	// ********** collection change tests **********
-
-	public void testFireItemsAddedCollectionEvent() {
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedCollectionEvent();
-		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedCollectionEvent();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedCollectionEvent();
-		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedCollectionEvent();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-	}
-
-	public void testFireItemsAddedCollectionEventNoChange() {
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedCollectionEventNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedCollectionEventNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedCollectionEventNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedCollectionEventNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-	}
-
-	public void testFireItemsAddedCollection() {
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedCollection();
-		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedCollection();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedCollection();
-		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedCollection();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-	}
-
-	public void testFireItemsAddedCollectionNoChange() {
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedCollectionNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedCollectionNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedCollectionNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedCollectionNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-	}
-
-	public void testFireItemAddedCollection() {
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemAddedCollection();
-		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemAddedCollection();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemAddedCollection();
-		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemAddedCollection();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-	}
-
-	public void testFireItemsRemovedCollectionEvent() {
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedCollectionEvent();
-		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedCollectionEvent();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedCollectionEvent();
-		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedCollectionEvent();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-	}
-
-	public void testFireItemsRemovedCollectionEventNoChange() {
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedCollectionEventNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedCollectionEventNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedCollectionEventNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedCollectionEventNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-	}
-
-	public void testFireItemsRemovedCollection() {
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedCollection();
-		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedCollection();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedCollection();
-		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedCollection();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-	}
-
-	public void testFireItemsRemovedCollectionNoChange() {
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedCollectionNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedCollectionNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedCollectionNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedCollectionNoChange();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-	}
-
-	public void testFireItemRemovedCollection() {
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemRemovedCollection();
-		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemRemovedCollection();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemRemovedCollection();
-		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireItemRemovedCollection();
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-	}
-
-	public void testFireCollectionCleared() {
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireCollectionCleared();
-		this.verifyCollectionEvent(null);
-		assertTrue(this.collectionClearedCalled);
-
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireCollectionCleared();
-		assertNull(this.collectionEvent);
-		assertFalse(this.collectionClearedCalled);
-
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireCollectionCleared();
-		this.verifyCollectionEvent(null);
-		assertTrue(this.collectionClearedCalled);
-
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireCollectionCleared();
-		assertNull(this.collectionEvent);
-		assertFalse(this.collectionClearedCalled);
-	}
-
-	public void testFireCollectionChangedEvent() {
-		this.collectionEvent = null;
-		this.collectionChangedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireCollectionChangedEvent();
-		this.verifyCollectionEvent(null);
-		assertTrue(this.collectionChangedCalled);
-
-		this.collectionEvent = null;
-		this.collectionChangedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireCollectionChangedEvent();
-		assertNull(this.collectionEvent);
-		assertFalse(this.collectionChangedCalled);
-
-		this.collectionEvent = null;
-		this.collectionChangedCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireCollectionChangedEvent();
-		this.verifyCollectionEvent(null);
-		assertTrue(this.collectionChangedCalled);
-
-		this.collectionEvent = null;
-		this.collectionChangedCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireCollectionChangedEvent();
-		assertNull(this.collectionEvent);
-		assertFalse(this.collectionChangedCalled);
-	}
-
-	public void testFireCollectionChanged() {
-		this.collectionEvent = null;
-		this.collectionChangedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireCollectionChanged();
-		this.verifyCollectionEvent(null);
-		assertTrue(this.collectionChangedCalled);
-
-		this.collectionEvent = null;
-		this.collectionChangedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireCollectionChanged();
-		assertNull(this.collectionEvent);
-		assertFalse(this.collectionChangedCalled);
-
-		this.collectionEvent = null;
-		this.collectionChangedCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireCollectionChanged();
-		this.verifyCollectionEvent(null);
-		assertTrue(this.collectionChangedCalled);
-
-		this.collectionEvent = null;
-		this.collectionChangedCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		this.testModel.testFireCollectionChanged();
-		assertNull(this.collectionEvent);
-		assertFalse(this.collectionChangedCalled);
-	}
-
-	public void testAddItemToCollection() {
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertTrue(this.testModel.testAddItemToCollection());
-		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertTrue(this.testModel.testAddItemToCollection());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testAddItemToCollection());
-		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testAddItemToCollection());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-	}
-
-	public void testAddItemToCollectionNoChange() {
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertFalse(this.testModel.testAddItemToCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertFalse(this.testModel.testAddItemToCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testAddItemToCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testAddItemToCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-	}
-
-	public void testAddItemsToCollection() {
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertTrue(this.testModel.testAddItemsToCollection());
-		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertTrue(this.testModel.testAddItemsToCollection());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testAddItemsToCollection());
-		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testAddItemsToCollection());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-	}
-
-	public void testAddItemsToCollectionNoChange() {
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertFalse(this.testModel.testAddItemsToCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertFalse(this.testModel.testAddItemsToCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testAddItemsToCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testAddItemsToCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-	}
-
-	public void testAddItemsToCollectionMixed() {
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertTrue(this.testModel.testAddItemsToCollectionMixed());
-		this.verifyCollectionEvent(ADDED_OBJECT_VALUE_2);
-		assertTrue(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertTrue(this.testModel.testAddItemsToCollectionMixed());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testAddItemsToCollectionMixed());
-		this.verifyCollectionEvent(ADDED_OBJECT_VALUE_2);
-		assertTrue(this.itemsAddedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsAddedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testAddItemsToCollectionMixed());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsAddedCollectionCalled);
-	}
-
-	public void testRemoveItemFromCollection() {
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertTrue(this.testModel.testRemoveItemFromCollection());
-		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertTrue(this.testModel.testRemoveItemFromCollection());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testRemoveItemFromCollection());
-		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testRemoveItemFromCollection());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-	}
-
-	public void testRemoveItemFromCollectionNoChange() {
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertFalse(this.testModel.testRemoveItemFromCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertFalse(this.testModel.testRemoveItemFromCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testRemoveItemFromCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testRemoveItemFromCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-	}
-
-	public void testRemoveItemsFromCollection() {
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertTrue(this.testModel.testRemoveItemsFromCollection());
-		this.verifyCollectionChangeEvent2(REMOVED_OBJECT_VALUE, "foo", "bar");
-		assertTrue(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertTrue(this.testModel.testRemoveItemsFromCollection());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testRemoveItemsFromCollection());
-		this.verifyCollectionChangeEvent2(REMOVED_OBJECT_VALUE, "foo", "bar");
-		assertTrue(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testRemoveItemsFromCollection());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-	}
-
-	public void testRemoveItemsFromCollectionNoChange1() {
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange1());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange1());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange1());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange1());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-	}
-
-	public void testRemoveItemsFromCollectionNoChange2() {
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange2());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange2());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange2());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange2());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-	}
-
-	public void testRemoveItemsFromCollectionNoChange3() {
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange3());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange3());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange3());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange3());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-	}
-
-	public void testRetainItemsInCollection1() {
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertTrue(this.testModel.testRetainItemsInCollection1());
-		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertTrue(this.testModel.testRetainItemsInCollection1());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testRetainItemsInCollection1());
-		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testRetainItemsInCollection1());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-	}
-
-	// collection cleared...
-	public void testRetainItemsInCollection2() {
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertTrue(this.testModel.testRetainItemsInCollection2());
-		this.verifyCollectionEvent(null);
-		assertTrue(this.collectionClearedCalled);
-
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertTrue(this.testModel.testRetainItemsInCollection2());
-		assertNull(this.collectionEvent);
-		assertFalse(this.collectionClearedCalled);
-
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testRetainItemsInCollection2());
-		this.verifyCollectionEvent(null);
-		assertTrue(this.collectionClearedCalled);
-
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testRetainItemsInCollection2());
-		assertNull(this.collectionEvent);
-		assertFalse(this.collectionClearedCalled);
-	}
-
-	public void testRetainItemsInCollectionNoChange1() {
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertFalse(this.testModel.testRetainItemsInCollectionNoChange1());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertFalse(this.testModel.testRetainItemsInCollectionNoChange1());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testRetainItemsInCollectionNoChange1());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testRetainItemsInCollectionNoChange1());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-	}
-
-	public void testRetainItemsInCollectionNoChange2() {
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertFalse(this.testModel.testRetainItemsInCollectionNoChange2());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertFalse(this.testModel.testRetainItemsInCollectionNoChange2());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testRetainItemsInCollectionNoChange2());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-
-		this.collectionEvent = null;
-		this.itemsRemovedCollectionCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testRetainItemsInCollectionNoChange2());
-		assertNull(this.collectionEvent);
-		assertFalse(this.itemsRemovedCollectionCalled);
-	}
-
-	public void testClearCollection() {
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertTrue(this.testModel.testClearCollection());
-		this.verifyCollectionEvent(null);
-		assertTrue(this.collectionClearedCalled);
-
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertTrue(this.testModel.testClearCollection());
-		assertNull(this.collectionEvent);
-		assertFalse(this.collectionClearedCalled);
-
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testClearCollection());
-		this.verifyCollectionEvent(null);
-		assertTrue(this.collectionClearedCalled);
-
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.testClearCollection());
-		assertNull(this.collectionEvent);
-		assertFalse(this.collectionClearedCalled);
-	}
-
-	public void testClearCollectionNoChange() {
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		assertFalse(this.testModel.testClearCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.collectionClearedCalled);
-
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		assertFalse(this.testModel.testClearCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.collectionClearedCalled);
-
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testClearCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.collectionClearedCalled);
-
-		this.collectionEvent = null;
-		this.collectionClearedCalled = false;
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertFalse(this.testModel.testClearCollectionNoChange());
-		assertNull(this.collectionEvent);
-		assertFalse(this.collectionClearedCalled);
-	}
-
-	public void testSynchronizeCollection1() {
-		CollectionSynchListener csl = new CollectionSynchListener();
-		this.testModel.addChangeListener(csl);
-		assertTrue(this.testModel.testSynchronizeCollection1());
-		assertTrue(csl.itemsAdded);
-		assertTrue(csl.itemsRemoved);
-		assertFalse(csl.collectionChanged);
-		assertFalse(csl.collectionCleared);
-		assertEquals(2, csl.addedItems.size());
-		assertTrue(CollectionTools.containsAll(csl.addedItems, new Object[] {"joo", "jar"}));
-		assertEquals(2, csl.removedItems.size());
-		assertTrue(CollectionTools.containsAll(csl.removedItems, new Object[] {"foo", "bar"}));
-	}
-
-	public void testSynchronizeCollection2() {
-		CollectionSynchListener csl = new CollectionSynchListener();
-		this.testModel.addChangeListener(csl);
-		assertTrue(this.testModel.testSynchronizeCollection2());
-		assertFalse(csl.itemsAdded);
-		assertFalse(csl.itemsRemoved);
-		assertFalse(csl.collectionChanged);
-		assertTrue(csl.collectionCleared);
-		assertTrue(csl.addedItems.isEmpty());
-		assertTrue(csl.removedItems.isEmpty());
-	}
-
-	public void testSynchronizeCollection3() {
-		CollectionSynchListener csl = new CollectionSynchListener();
-		this.testModel.addChangeListener(csl);
-		assertTrue(this.testModel.testSynchronizeCollection3());
-		assertTrue(csl.itemsAdded);
-		assertFalse(csl.itemsRemoved);
-		assertFalse(csl.collectionChanged);
-		assertFalse(csl.collectionCleared);
-		assertEquals(3, csl.addedItems.size());
-		assertTrue(CollectionTools.containsAll(csl.addedItems, new Object[] {"joo", "jar", "baz"}));
-		assertTrue(csl.removedItems.isEmpty());
-	}
-
-	class CollectionSynchListener extends ChangeAdapter {
-		boolean itemsAdded = false;
-		boolean itemsRemoved = false;
-		boolean collectionChanged = false;
-		boolean collectionCleared = false;
-		Collection<Object> addedItems = new ArrayList<Object>();
-		Collection<Object> removedItems = new ArrayList<Object>();
-		@Override
-		public void collectionChanged(CollectionChangeEvent event) {
-			this.collectionChanged = true;
-		}
-		@Override
-		public void collectionCleared(CollectionClearEvent event) {
-			this.collectionCleared = true;
-		}
-		@Override
-		public void itemsAdded(CollectionAddEvent event) {
-			this.itemsAdded = true;
-			CollectionTools.addAll(this.addedItems, event.getItems());
-		}
-		@Override
-		public void itemsRemoved(CollectionRemoveEvent event) {
-			this.itemsRemoved = true;
-			CollectionTools.addAll(this.removedItems, event.getItems());
-		}
-	}
-
-	public void testHasAnyCollectionChangeListeners() {
-		assertTrue(this.testModel.hasNoCollectionChangeListeners(COLLECTION_NAME));
-		this.testModel.addChangeListener(this.changeListener);
-		assertTrue(this.testModel.hasAnyCollectionChangeListeners(COLLECTION_NAME));
-		this.testModel.removeChangeListener(this.changeListener);
-		assertTrue(this.testModel.hasNoCollectionChangeListeners(COLLECTION_NAME));
-
-		assertTrue(this.testModel.hasNoCollectionChangeListeners(COLLECTION_NAME));
-		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.hasAnyCollectionChangeListeners(COLLECTION_NAME));
-		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
-		assertTrue(this.testModel.hasNoCollectionChangeListeners(COLLECTION_NAME));
-	}
-
-	public void testAddNullCollectionListener() {
-		boolean exCaught = false;
-		try {
-			this.testModel.addCollectionChangeListener("foo", null);
-		} catch (NullPointerException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testRemoveBogusCollectionListener() {
-		boolean exCaught = false;
-		try {
-			this.testModel.removeCollectionChangeListener("foo", this.changeListener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		this.testModel.addPropertyChangeListener("foo", this.changeListener);
-		exCaught = false;
-		try {
-			this.testModel.removeCollectionChangeListener("foo", this.changeListener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		this.testModel.addCollectionChangeListener("foo", this.changeListener);
-		exCaught = false;
-		try {
-			this.testModel.removeCollectionChangeListener("foo", new CollectionChangeAdapter());
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		exCaught = false;
-		try {
-			this.testModel.removeCollectionChangeListener("foo", new CollectionChangeAdapter());
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	private void verifyCollectionEvent(Object item) {
-		assertNotNull(this.collectionEvent);
-		assertEquals(this.testModel, this.collectionEvent.getSource());
-		assertEquals(COLLECTION_NAME, this.collectionEvent.getCollectionName());
-		if (item != null) {
-			assertEquals(item, this.getCollectionEventItems().iterator().next());
-		}
-	}
-
-	private Iterable<?> getCollectionEventItems() {
-		if (this.collectionEvent instanceof CollectionAddEvent) {
-			return ((CollectionAddEvent) this.collectionEvent).getItems();
-		} else if (this.collectionEvent instanceof CollectionRemoveEvent) {
-			return ((CollectionRemoveEvent) this.collectionEvent).getItems();
-		}
-		throw new IllegalStateException();
-	}
-
-	private void verifyCollectionChangeEvent2(Object... items) {
-		assertNotNull(this.collectionEvent);
-		assertEquals(this.testModel, this.collectionEvent.getSource());
-		assertEquals(COLLECTION_NAME, this.collectionEvent.getCollectionName());
-		assertEquals(items.length, this.getCollectionEventItemsSize());
-		for (Object item : items) {
-			assertTrue(CollectionTools.contains(this.getCollectionEventItems(), item));
-		}
-	}
-
-	private int getCollectionEventItemsSize() {
-		if (this.collectionEvent instanceof CollectionAddEvent) {
-			return ((CollectionAddEvent) this.collectionEvent).getItemsSize();
-		} else if (this.collectionEvent instanceof CollectionRemoveEvent) {
-			return ((CollectionRemoveEvent) this.collectionEvent).getItemsSize();
-		}
-		throw new IllegalStateException();
-	}
-
-
-	// ********** list change tests **********
-
-	public void testFireItemsAddedListEvent() {
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedListEvent();
-		this.verifyListAddEvent(ADD_INDEX, ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedListEvent();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedListEvent();
-		this.verifyListAddEvent(ADD_INDEX, ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedListEvent();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-	}
-
-	public void testFireItemsAddedListEventNoChange() {
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-	}
-
-	public void testFireItemsAddedList() {
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedList();
-		this.verifyListAddEvent(ADD_INDEX, ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedList();
-		this.verifyListAddEvent(ADD_INDEX, ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-	}
-
-	public void testFireItemsAddedListNoChange() {
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsAddedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsAddedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-	}
-
-	public void testFireItemAddedList() {
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemAddedList();
-		this.verifyListAddEvent(ADD_INDEX, ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemAddedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemAddedList();
-		this.verifyListAddEvent(ADD_INDEX, ADDED_OBJECT_VALUE);
-		assertTrue(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemAddedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-	}
-
-	public void testFireItemsRemovedListEvent() {
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedListEvent();
-		this.verifyListRemoveEvent(REMOVE_INDEX, REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedListEvent();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedListEvent();
-		this.verifyListRemoveEvent(REMOVE_INDEX, REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedListEvent();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-	}
-
-	public void testFireItemsRemovedListEventNoChange() {
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-	}
-
-	public void testFireItemsRemovedList() {
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedList();
-		this.verifyListRemoveEvent(REMOVE_INDEX, REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedList();
-		this.verifyListRemoveEvent(REMOVE_INDEX, REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-	}
-
-	public void testFireItemsRemovedListNoChange() {
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsRemovedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsRemovedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-	}
-
-	public void testFireItemRemovedList() {
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemRemovedList();
-		this.verifyListRemoveEvent(REMOVE_INDEX, REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemRemovedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemRemovedList();
-		this.verifyListRemoveEvent(REMOVE_INDEX, REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemRemovedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-	}
-
-	public void testFireItemsReplacedListEvent() {
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsReplacedListEvent();
-		this.verifyListReplaceEvent(REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsReplacedListEvent();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsReplacedListEvent();
-		this.verifyListReplaceEvent(REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsReplacedListEvent();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-	}
-
-	public void testFireItemsReplacedListEventNoChange() {
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsReplacedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsReplacedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsReplacedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsReplacedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-	}
-
-	public void testFireItemsReplacedList() {
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsReplacedList();
-		this.verifyListReplaceEvent(REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsReplacedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsReplacedList();
-		this.verifyListReplaceEvent(REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsReplacedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-	}
-
-	public void testFireItemsReplacedListNoChange() {
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsReplacedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsReplacedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsReplacedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsReplacedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-	}
-
-	public void testFireItemReplacedList() {
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemReplacedList();
-		this.verifyListReplaceEvent(REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemReplacedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemReplacedList();
-		this.verifyListReplaceEvent(REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
-		assertTrue(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemReplacedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-	}
-
-	public void testFireItemsMovedListEvent() {
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsMovedListEvent();
-		this.verifyListMoveEvent(TARGET_INDEX, SOURCE_INDEX);
-		assertTrue(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsMovedListEvent();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsMovedListEvent();
-		this.verifyListMoveEvent(TARGET_INDEX, SOURCE_INDEX);
-		assertTrue(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsMovedListEvent();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-	}
-
-	public void testFireItemsMovedListEventNoChange() {
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsMovedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsMovedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsMovedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsMovedListEventNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-	}
-
-	public void testFireItemsMovedList() {
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsMovedList();
-		this.verifyListMoveEvent(TARGET_INDEX, SOURCE_INDEX);
-		assertTrue(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsMovedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsMovedList();
-		this.verifyListMoveEvent(TARGET_INDEX, SOURCE_INDEX);
-		assertTrue(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsMovedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-	}
-
-	public void testFireItemsMovedListNoChange() {
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemsMovedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemsMovedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsMovedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemsMovedListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-	}
-
-	public void testFireItemMovedList() {
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireItemMovedList();
-		this.verifyListMoveEvent(TARGET_INDEX, SOURCE_INDEX);
-		assertTrue(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireItemMovedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemMovedList();
-		this.verifyListMoveEvent(TARGET_INDEX, SOURCE_INDEX);
-		assertTrue(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireItemMovedList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-	}
-
-	public void testFireListClearedEvent() {
-		this.listEvent = null;
-		this.listClearedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireListClearedEvent();
-		this.verifyListClearEvent();
-		assertTrue(this.listClearedCalled);
-
-		this.listEvent = null;
-		this.listClearedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireListClearedEvent();
-		assertNull(this.listEvent);
-		assertFalse(this.listClearedCalled);
-
-		this.listEvent = null;
-		this.listClearedCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireListClearedEvent();
-		this.verifyListClearEvent();
-		assertTrue(this.listClearedCalled);
-
-		this.listEvent = null;
-		this.listClearedCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireListClearedEvent();
-		assertNull(this.listEvent);
-		assertFalse(this.listClearedCalled);
-	}
-
-	public void testFireListCleared() {
-		this.listEvent = null;
-		this.listClearedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireListCleared();
-		this.verifyListClearEvent();
-		assertTrue(this.listClearedCalled);
-
-		this.listEvent = null;
-		this.listClearedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireListCleared();
-		assertNull(this.listEvent);
-		assertFalse(this.listClearedCalled);
-
-		this.listEvent = null;
-		this.listClearedCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireListCleared();
-		this.verifyListClearEvent();
-		assertTrue(this.listClearedCalled);
-
-		this.listEvent = null;
-		this.listClearedCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireListCleared();
-		assertNull(this.listEvent);
-		assertFalse(this.listClearedCalled);
-	}
-
-	public void testFireListChangedEvent() {
-		this.listEvent = null;
-		this.listChangedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireListChangedEvent();
-		this.verifyListChangeEvent();
-		assertTrue(this.listChangedCalled);
-
-		this.listEvent = null;
-		this.listChangedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireListChangedEvent();
-		assertNull(this.listEvent);
-		assertFalse(this.listChangedCalled);
-
-		this.listEvent = null;
-		this.listChangedCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireListChangedEvent();
-		this.verifyListChangeEvent();
-		assertTrue(this.listChangedCalled);
-
-		this.listEvent = null;
-		this.listChangedCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireListChangedEvent();
-		assertNull(this.listEvent);
-		assertFalse(this.listChangedCalled);
-	}
-
-	public void testFireListChanged() {
-		this.listEvent = null;
-		this.listChangedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireListChanged();
-		this.verifyListChangeEvent();
-		assertTrue(this.listChangedCalled);
-
-		this.listEvent = null;
-		this.listChangedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireListChanged();
-		assertNull(this.listEvent);
-		assertFalse(this.listChangedCalled);
-
-		this.listEvent = null;
-		this.listChangedCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireListChanged();
-		this.verifyListChangeEvent();
-		assertTrue(this.listChangedCalled);
-
-		this.listEvent = null;
-		this.listChangedCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testFireListChanged();
-		assertNull(this.listEvent);
-		assertFalse(this.listChangedCalled);
-	}
-
-	public void testAddItemToListIndex() {
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testAddItemToListIndex();
-		this.verifyListAddEvent(2, "joo");
-		assertTrue(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testAddItemToListIndex();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testAddItemToListIndex();
-		this.verifyListAddEvent(2, "joo");
-		assertTrue(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testAddItemToListIndex();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-	}
-
-	public void testAddItemToList() {
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testAddItemToList();
-		this.verifyListAddEvent(3, "joo");
-		assertTrue(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testAddItemToList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testAddItemToList();
-		this.verifyListAddEvent(3, "joo");
-		assertTrue(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testAddItemToList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-	}
-
-	public void testAddItemsToListIndex() {
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testAddItemsToListIndex();
-		this.verifyListAddEvent(2, "joo");
-		assertTrue(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testAddItemsToListIndex();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testAddItemsToListIndex();
-		this.verifyListAddEvent(2, "joo");
-		assertTrue(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testAddItemsToListIndex();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-	}
-
-	public void testAddItemsToListIndexNoChange() {
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testAddItemsToListIndexNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testAddItemsToListIndexNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testAddItemsToListIndexNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testAddItemsToListIndexNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-	}
-
-	public void testAddItemsToList() {
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testAddItemsToList();
-		this.verifyListAddEvent(3, "joo");
-		assertTrue(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testAddItemsToList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testAddItemsToList();
-		this.verifyListAddEvent(3, "joo");
-		assertTrue(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testAddItemsToList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-	}
-
-	public void testAddItemsToListNoChange() {
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testAddItemsToListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testAddItemsToListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testAddItemsToListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-
-		this.listEvent = null;
-		this.itemsAddedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testAddItemsToListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsAddedListCalled);
-	}
-
-	public void testRemoveItemFromListIndex() {
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testRemoveItemFromListIndex();
-		this.verifyListRemoveEvent(1, "bar");
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testRemoveItemFromListIndex();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testRemoveItemFromListIndex();
-		this.verifyListRemoveEvent(1, "bar");
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testRemoveItemFromListIndex();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-	}
-
-	public void testRemoveItemFromList() {
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testRemoveItemFromList();
-		this.verifyListRemoveEvent(1, "bar");
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testRemoveItemFromList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testRemoveItemFromList();
-		this.verifyListRemoveEvent(1, "bar");
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testRemoveItemFromList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-	}
-
-	public void testRemoveItemsFromListIndex() {
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testRemoveItemsFromListIndex();
-		this.verifyListRemoveEvent(1, "bar");
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testRemoveItemsFromListIndex();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testRemoveItemsFromListIndex();
-		this.verifyListRemoveEvent(1, "bar");
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testRemoveItemsFromListIndex();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-	}
-
-	public void testRemoveItemsFromListIndexNoChange() {
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testRemoveItemsFromListIndexNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testRemoveItemsFromListIndexNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testRemoveItemsFromListIndexNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testRemoveItemsFromListIndexNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-	}
-
-	public void testRemoveItemsFromList() {
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testRemoveItemsFromList();
-		this.verifyListRemoveEvent(1, "bar");
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testRemoveItemsFromList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testRemoveItemsFromList();
-		this.verifyListRemoveEvent(1, "bar");
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testRemoveItemsFromList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-	}
-
-	public void testRemoveItemsFromListNoChange() {
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testRemoveItemsFromListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testRemoveItemsFromListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testRemoveItemsFromListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testRemoveItemsFromListNoChange();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-	}
-
-	public void testRetainItemsInList() {
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testRetainItemsInList();
-		this.verifyListRemoveEvent(0, "foo");
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testRetainItemsInList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testRetainItemsInList();
-		this.verifyListRemoveEvent(0, "foo");
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testRetainItemsInList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsRemovedListCalled);
-	}
-
-	public void testReplaceItemInList() {
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testReplaceItemInList();
-		this.verifyListReplaceEvent(1, "xxx", "bar");
-		assertTrue(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testReplaceItemInList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testReplaceItemInList();
-		this.verifyListReplaceEvent(1, "xxx", "bar");
-		assertTrue(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testReplaceItemInList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-	}
-
-	public void testSetItemsInList() {
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testSetItemsInList();
-		this.verifyListReplaceEvent(1, "xxx", "bar");
-		assertTrue(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testSetItemsInList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testSetItemsInList();
-		this.verifyListReplaceEvent(1, "xxx", "bar");
-		assertTrue(this.itemsReplacedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testSetItemsInList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-	}
-
-	public void testMoveItemsInList() {
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testMoveItemsInList();
-		this.verifyListMoveEvent(2, 4, 2);
-		assertTrue(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testMoveItemsInList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testMoveItemsInList();
-		this.verifyListMoveEvent(2, 4, 2);
-		assertTrue(this.itemsMovedListCalled);
-
-		this.listEvent = null;
-		this.itemsMovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testMoveItemsInList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsMovedListCalled);
-	}
-
-	public void testClearList() {
-		this.listEvent = null;
-		this.listClearedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testClearList();
-		this.verifyListClearEvent();
-		assertTrue(this.listClearedCalled);
-
-		this.listEvent = null;
-		this.listClearedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testClearList();
-		assertNull(this.listEvent);
-		assertFalse(this.listClearedCalled);
-
-		this.listEvent = null;
-		this.listClearedCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testClearList();
-		this.verifyListClearEvent();
-		assertTrue(this.listClearedCalled);
-
-		this.listEvent = null;
-		this.listClearedCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testClearList();
-		assertNull(this.listEvent);
-		assertFalse(this.listClearedCalled);
-	}
-
-	public void testSynchronizeList() {
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testSynchronizeList();
-		assertNotNull(this.listEvent);
-		assertTrue(this.itemsReplacedListCalled);
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testSynchronizeList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-		assertFalse(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.itemsRemovedListCalled = false;
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testSynchronizeList();
-		assertNotNull(this.listEvent);
-		assertTrue(this.itemsReplacedListCalled);
-		assertTrue(this.itemsRemovedListCalled);
-
-		this.listEvent = null;
-		this.itemsReplacedListCalled = false;
-		this.itemsRemovedListCalled = false;
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		this.testModel.testSynchronizeList();
-		assertNull(this.listEvent);
-		assertFalse(this.itemsReplacedListCalled);
-		assertFalse(this.itemsRemovedListCalled);
-	}
-
-	public void testHasAnyListChangeListeners() {
-		assertTrue(this.testModel.hasNoListChangeListeners(LIST_NAME));
-		this.testModel.addChangeListener(this.changeListener);
-		assertTrue(this.testModel.hasAnyListChangeListeners(LIST_NAME));
-		this.testModel.removeChangeListener(this.changeListener);
-		assertTrue(this.testModel.hasNoListChangeListeners(LIST_NAME));
-
-		assertTrue(this.testModel.hasNoListChangeListeners(LIST_NAME));
-		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
-		assertTrue(this.testModel.hasAnyListChangeListeners(LIST_NAME));
-		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
-		assertTrue(this.testModel.hasNoListChangeListeners(LIST_NAME));
-	}
-
-	public void testAddNullListListener() {
-		boolean exCaught = false;
-		try {
-			this.testModel.addListChangeListener("foo", null);
-		} catch (NullPointerException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testRemoveBogusListListener() {
-		boolean exCaught = false;
-		try {
-			this.testModel.removeListChangeListener("foo", this.changeListener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		this.testModel.addPropertyChangeListener("foo", this.changeListener);
-		exCaught = false;
-		try {
-			this.testModel.removeListChangeListener("foo", this.changeListener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		this.testModel.addListChangeListener("foo", this.changeListener);
-		exCaught = false;
-		try {
-			this.testModel.removeListChangeListener("foo", new ListChangeAdapter());
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		exCaught = false;
-		try {
-			this.testModel.removeListChangeListener("foo", new ListChangeAdapter());
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	private void verifyListAddEvent(int index, Object item) {
-		assertNotNull(this.listEvent);
-		assertEquals(this.testModel, this.listEvent.getSource());
-		assertEquals(LIST_NAME, this.listEvent.getListName());
-		assertEquals(index, ((ListAddEvent) this.listEvent).getIndex());
-		assertEquals(item, ((ListAddEvent) this.listEvent).getItems().iterator().next());
-	}
-
-	private void verifyListRemoveEvent(int index, Object item) {
-		assertNotNull(this.listEvent);
-		assertEquals(this.testModel, this.listEvent.getSource());
-		assertEquals(LIST_NAME, this.listEvent.getListName());
-		assertEquals(index, ((ListRemoveEvent) this.listEvent).getIndex());
-		assertEquals(item, ((ListRemoveEvent) this.listEvent).getItems().iterator().next());
-	}
-
-	private void verifyListReplaceEvent(int index, Object newItem, Object oldItem) {
-		assertNotNull(this.listEvent);
-		assertEquals(this.testModel, this.listEvent.getSource());
-		assertEquals(LIST_NAME, this.listEvent.getListName());
-		assertEquals(index, ((ListReplaceEvent) this.listEvent).getIndex());
-		assertEquals(newItem, ((ListReplaceEvent) this.listEvent).getNewItems().iterator().next());
-		assertEquals(oldItem, ((ListReplaceEvent) this.listEvent).getOldItems().iterator().next());
-	}
-
-	private void verifyListMoveEvent(int targetIndex, int sourceIndex) {
-		this.verifyListMoveEvent(targetIndex, sourceIndex, 1);
-	}
-
-	private void verifyListMoveEvent(int targetIndex, int sourceIndex, int length) {
-		assertNotNull(this.listEvent);
-		assertEquals(this.testModel, this.listEvent.getSource());
-		assertEquals(LIST_NAME, this.listEvent.getListName());
-		assertEquals(targetIndex, ((ListMoveEvent) this.listEvent).getTargetIndex());
-		assertEquals(sourceIndex, ((ListMoveEvent) this.listEvent).getSourceIndex());
-		assertEquals(length, ((ListMoveEvent) this.listEvent).getLength());
-	}
-
-	private void verifyListClearEvent() {
-		assertNotNull(this.listEvent);
-		assertEquals(this.testModel, this.listEvent.getSource());
-		assertEquals(LIST_NAME, this.listEvent.getListName());
-		assertEquals(ListClearEvent.class, this.listEvent.getClass());
-	}
-
-	private void verifyListChangeEvent() {
-		assertNotNull(this.listEvent);
-		assertEquals(this.testModel, this.listEvent.getSource());
-		assertEquals(LIST_NAME, this.listEvent.getListName());
-		assertEquals(ListChangeEvent.class, this.listEvent.getClass());
-	}
-
-
-	// ********** tree change tests **********
-
-	public void testFireNodeAddedTree() {
-		this.treeEvent = null;
-		this.nodeAddedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireNodeAddedTree();
-		this.verifyTreeEvent(OBJECT_PATH);
-		assertTrue(this.nodeAddedCalled);
-
-		this.treeEvent = null;
-		this.nodeAddedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireNodeAddedTree();
-		assertNull(this.treeEvent);
-		assertFalse(this.nodeAddedCalled);
-
-		this.treeEvent = null;
-		this.nodeAddedCalled = false;
-		this.testModel.addTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireNodeAddedTree();
-		this.verifyTreeEvent(OBJECT_PATH);
-		assertTrue(this.nodeAddedCalled);
-
-		this.treeEvent = null;
-		this.nodeAddedCalled = false;
-		this.testModel.removeTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireNodeAddedTree();
-		assertNull(this.treeEvent);
-		assertFalse(this.nodeAddedCalled);
-	}
-
-	public void testFireNodeAddedTreeEvent() {
-		this.treeEvent = null;
-		this.nodeAddedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireNodeAddedTreeEvent();
-		this.verifyTreeEvent(OBJECT_PATH);
-		assertTrue(this.nodeAddedCalled);
-
-		this.treeEvent = null;
-		this.nodeAddedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireNodeAddedTreeEvent();
-		assertNull(this.treeEvent);
-		assertFalse(this.nodeAddedCalled);
-
-		this.treeEvent = null;
-		this.nodeAddedCalled = false;
-		this.testModel.addTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireNodeAddedTreeEvent();
-		this.verifyTreeEvent(OBJECT_PATH);
-		assertTrue(this.nodeAddedCalled);
-
-		this.treeEvent = null;
-		this.nodeAddedCalled = false;
-		this.testModel.removeTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireNodeAddedTreeEvent();
-		assertNull(this.treeEvent);
-		assertFalse(this.nodeAddedCalled);
-	}
-
-	public void testFireNodeRemovedTreeEvent() {
-		this.treeEvent = null;
-		this.nodeRemovedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireNodeRemovedTreeEvent();
-		this.verifyTreeEvent(OBJECT_PATH);
-		assertTrue(this.nodeRemovedCalled);
-
-		this.treeEvent = null;
-		this.nodeRemovedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireNodeRemovedTreeEvent();
-		assertNull(this.treeEvent);
-		assertFalse(this.nodeRemovedCalled);
-
-		this.treeEvent = null;
-		this.nodeRemovedCalled = false;
-		this.testModel.addTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireNodeRemovedTreeEvent();
-		this.verifyTreeEvent(OBJECT_PATH);
-		assertTrue(this.nodeRemovedCalled);
-
-		this.treeEvent = null;
-		this.nodeRemovedCalled = false;
-		this.testModel.removeTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireNodeRemovedTreeEvent();
-		assertNull(this.treeEvent);
-		assertFalse(this.nodeRemovedCalled);
-	}
-
-	public void testFireNodeRemovedTree() {
-		this.treeEvent = null;
-		this.nodeRemovedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireNodeRemovedTree();
-		this.verifyTreeEvent(OBJECT_PATH);
-		assertTrue(this.nodeRemovedCalled);
-
-		this.treeEvent = null;
-		this.nodeRemovedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireNodeRemovedTree();
-		assertNull(this.treeEvent);
-		assertFalse(this.nodeRemovedCalled);
-
-		this.treeEvent = null;
-		this.nodeRemovedCalled = false;
-		this.testModel.addTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireNodeRemovedTree();
-		this.verifyTreeEvent(OBJECT_PATH);
-		assertTrue(this.nodeRemovedCalled);
-
-		this.treeEvent = null;
-		this.nodeRemovedCalled = false;
-		this.testModel.removeTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireNodeRemovedTree();
-		assertNull(this.treeEvent);
-		assertFalse(this.nodeRemovedCalled);
-	}
-
-	public void testFireTreeClearedEvent() {
-		this.treeEvent = null;
-		this.treeClearedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireTreeClearedEvent();
-		this.verifyTreeEvent(null);
-		assertTrue(this.treeClearedCalled);
-
-		this.treeEvent = null;
-		this.treeClearedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireTreeClearedEvent();
-		assertNull(this.treeEvent);
-		assertFalse(this.treeClearedCalled);
-
-		this.treeEvent = null;
-		this.treeClearedCalled = false;
-		this.testModel.addTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireTreeClearedEvent();
-		this.verifyTreeEvent(null);
-		assertTrue(this.treeClearedCalled);
-
-		this.treeEvent = null;
-		this.treeClearedCalled = false;
-		this.testModel.removeTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireTreeClearedEvent();
-		assertNull(this.treeEvent);
-		assertFalse(this.treeClearedCalled);
-	}
-
-	public void testFireTreeCleared() {
-		this.treeEvent = null;
-		this.treeClearedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireTreeCleared();
-		this.verifyTreeEvent(null);
-		assertTrue(this.treeClearedCalled);
-
-		this.treeEvent = null;
-		this.treeClearedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireTreeCleared();
-		assertNull(this.treeEvent);
-		assertFalse(this.treeClearedCalled);
-
-		this.treeEvent = null;
-		this.treeClearedCalled = false;
-		this.testModel.addTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireTreeCleared();
-		this.verifyTreeEvent(null);
-		assertTrue(this.treeClearedCalled);
-
-		this.treeEvent = null;
-		this.treeClearedCalled = false;
-		this.testModel.removeTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireTreeCleared();
-		assertNull(this.treeEvent);
-		assertFalse(this.treeClearedCalled);
-	}
-
-	public void testFireTreeChangedEvent() {
-		this.treeEvent = null;
-		this.treeChangedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireTreeChangedEvent();
-		this.verifyTreeEvent(null);
-		assertTrue(this.treeChangedCalled);
-
-		this.treeEvent = null;
-		this.treeChangedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireTreeChangedEvent();
-		assertNull(this.treeEvent);
-		assertFalse(this.treeChangedCalled);
-
-		this.treeEvent = null;
-		this.treeChangedCalled = false;
-		this.testModel.addTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireTreeChangedEvent();
-		this.verifyTreeEvent(null);
-		assertTrue(this.treeChangedCalled);
-
-		this.treeEvent = null;
-		this.treeChangedCalled = false;
-		this.testModel.removeTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireTreeChangedEvent();
-		assertNull(this.treeEvent);
-		assertFalse(this.treeChangedCalled);
-	}
-
-	public void testFireTreeChanged() {
-		this.treeEvent = null;
-		this.treeChangedCalled = false;
-		this.testModel.addChangeListener(this.changeListener);
-		this.testModel.testFireTreeChanged();
-		this.verifyTreeEvent(null);
-		assertTrue(this.treeChangedCalled);
-
-		this.treeEvent = null;
-		this.treeChangedCalled = false;
-		this.testModel.removeChangeListener(this.changeListener);
-		this.testModel.testFireTreeChanged();
-		assertNull(this.treeEvent);
-		assertFalse(this.treeChangedCalled);
-
-		this.treeEvent = null;
-		this.treeChangedCalled = false;
-		this.testModel.addTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireTreeChanged();
-		this.verifyTreeEvent(null);
-		assertTrue(this.treeChangedCalled);
-
-		this.treeEvent = null;
-		this.treeChangedCalled = false;
-		this.testModel.removeTreeChangeListener(TREE_NAME, this.changeListener);
-		this.testModel.testFireTreeChanged();
-		assertNull(this.treeEvent);
-		assertFalse(this.treeChangedCalled);
-	}
-
-	public void testHasAnyTreeChangeListeners() {
-		assertTrue(this.testModel.hasNoTreeChangeListeners(TREE_NAME));
-		this.testModel.addChangeListener(this.changeListener);
-		assertTrue(this.testModel.hasAnyTreeChangeListeners(TREE_NAME));
-		this.testModel.removeChangeListener(this.changeListener);
-		assertTrue(this.testModel.hasNoTreeChangeListeners(TREE_NAME));
-
-		assertTrue(this.testModel.hasNoTreeChangeListeners(TREE_NAME));
-		this.testModel.addTreeChangeListener(TREE_NAME, this.changeListener);
-		assertTrue(this.testModel.hasAnyTreeChangeListeners(TREE_NAME));
-		this.testModel.removeTreeChangeListener(TREE_NAME, this.changeListener);
-		assertTrue(this.testModel.hasNoTreeChangeListeners(TREE_NAME));
-	}
-
-	public void testAddNullTreeListener() {
-		boolean exCaught = false;
-		try {
-			this.testModel.addTreeChangeListener("foo", null);
-		} catch (NullPointerException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testRemoveBogusTreeListener() {
-		boolean exCaught = false;
-		try {
-			this.testModel.removeTreeChangeListener("foo", this.changeListener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		this.testModel.addPropertyChangeListener("foo", this.changeListener);
-		exCaught = false;
-		try {
-			this.testModel.removeTreeChangeListener("foo", this.changeListener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		this.testModel.addTreeChangeListener("foo", this.changeListener);
-		exCaught = false;
-		try {
-			this.testModel.removeTreeChangeListener("foo", new TreeChangeAdapter());
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-
-		exCaught = false;
-		try {
-			this.testModel.removeTreeChangeListener("foo", new TreeChangeAdapter());
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	private void verifyTreeEvent(List<?> path) {
-		assertNotNull(this.treeEvent);
-		assertEquals(this.testModel, this.treeEvent.getSource());
-		assertEquals(TREE_NAME, this.treeEvent.getTreeName());
-		assertEquals(path, this.getListPath());
-	}
-
-	private List<?> getListPath() {
-		Iterable<?> iterable = this.getPath();
-		return (iterable == null)  ? null : CollectionTools.list(iterable);
-	}
-
-	private Iterable<?> getPath() {
-		if (this.treeEvent instanceof TreeAddEvent) {
-			return ((TreeAddEvent) this.treeEvent).getPath();
-		}
-		if (this.treeEvent instanceof TreeRemoveEvent) {
-			return ((TreeRemoveEvent) this.treeEvent).getPath();
-		}
-		return null;
-	}
-
-
-
-	// ********** convenience method tests **********
-
-	public void testElementsAreEqual() {
-		Collection<String> c1 = new ArrayList<String>();
-		c1.add("foo");
-		c1.add("bar");
-		c1.add("baz");
-		Collection<String> c2 = new ArrayList<String>();
-		c2.add("foo");
-		c2.add("bar");
-		c2.add("baz");
-		assertTrue(this.testModel.testElementsAreEqual(c1, c2));
-	}
-
-	public void testElementsAreDifferent() {
-		Collection<String> c1 = new ArrayList<String>();
-		c1.add("foo");
-		c1.add("bar");
-		c1.add("baz");
-		Collection<String> c2 = new ArrayList<String>();
-		c2.add("baz");
-		c2.add("bar");
-		c2.add("foo");
-		assertTrue(this.testModel.testElementsAreDifferent(c1, c2));
-	}
-
-
-	// ********** AbstractModel tests **********
-
-	public void testAbstractModelValuesAreEqual1() {
-		assertTrue(this.testModel.testValuesAreEqual(null, null));
-	}
-
-	public void testAbstractModelValuesAreEqual2() {
-		assertTrue(this.testModel.testValuesAreEqual("foo", "foo"));
-	}
-
-	public void testAbstractModelValuesAreEqual3() {
-		assertFalse(this.testModel.testValuesAreEqual("foo", null));
-	}
-
-	public void testAbstractModelValuesAreEqual4() {
-		assertFalse(this.testModel.testValuesAreEqual(null, "foo"));
-	}
-
-	public void testAbstractModelValuesAreEqual5() {
-		assertFalse(this.testModel.testValuesAreEqual("bar", "foo"));
-	}
-
-	public void testAbstractModelValuesAreDifferent1() {
-		assertFalse(this.testModel.testValuesAreDifferent(null, null));
-	}
-
-	public void testAbstractModelValuesAreDifferent2() {
-		assertFalse(this.testModel.testValuesAreDifferent("foo", "foo"));
-	}
-
-	public void testAbstractModelValuesAreDifferent3() {
-		assertTrue(this.testModel.testValuesAreDifferent("foo", null));
-	}
-
-	public void testAbstractModelValuesAreDifferent4() {
-		assertTrue(this.testModel.testValuesAreDifferent(null, "foo"));
-	}
-
-	public void testAbstractModelValuesAreDifferent5() {
-		assertTrue(this.testModel.testValuesAreDifferent("bar", "foo"));
-	}
-
-	public void testAbstractModelAttributeValueHasChanged1() {
-		assertFalse(this.testModel.testAttributeValueHasChanged(null, null));
-	}
-
-	public void testAbstractModelAttributeValueHasChanged2() {
-		assertFalse(this.testModel.testAttributeValueHasChanged("foo", "foo"));
-	}
-
-	public void testAbstractModelAttributeValueHasChanged3() {
-		assertTrue(this.testModel.testAttributeValueHasChanged("foo", null));
-	}
-
-	public void testAbstractModelAttributeValueHasChanged4() {
-		assertTrue(this.testModel.testAttributeValueHasChanged(null, "foo"));
-	}
-
-	public void testAbstractModelAttributeValueHasChanged5() {
-		assertTrue(this.testModel.testAttributeValueHasChanged("bar", "foo"));
-	}
-
-	public void testAbstractModelAttributeValueHasNotChanged1() {
-		assertTrue(this.testModel.testAttributeValueHasNotChanged(null, null));
-	}
-
-	public void testAbstractModelAttributeValueHasNotChanged2() {
-		assertTrue(this.testModel.testAttributeValueHasNotChanged("foo", "foo"));
-	}
-
-	public void testAbstractModelAttributeValueHasNotChanged3() {
-		assertFalse(this.testModel.testAttributeValueHasNotChanged("foo", null));
-	}
-
-	public void testAbstractModelAttributeValueHasNotChanged4() {
-		assertFalse(this.testModel.testAttributeValueHasNotChanged(null, "foo"));
-	}
-
-	public void testAbstractModelAttributeValueHasNotChanged5() {
-		assertFalse(this.testModel.testAttributeValueHasNotChanged("bar", "foo"));
-	}
-
-	public void testAbstractModelClone() {
-		assertFalse(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
-		this.testModel.addChangeListener(this.changeListener);
-		assertTrue(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
-
-		// verify that the clone does not have any listeners
-		TestModel clone = this.testModel.clone();
-		assertFalse(clone.hasAnyPropertyChangeListeners(PROPERTY_NAME));
-		clone.addChangeListener(this.changeListener);
-		assertTrue(clone.hasAnyPropertyChangeListeners(PROPERTY_NAME));
-		// check original
-		assertTrue(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
-
-		// now test events fired by original
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		this.testModel.testFirePropertyChangedObjectObject();
-		this.verifyPropertyChangeEvent(OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
-		assertTrue(this.propertyChangeCalled);
-
-		// now test events fired by clone
-		this.propertyChangeEvent = null;
-		this.propertyChangeCalled = false;
-		clone.testFirePropertyChangedObjectObject();
-		this.verifyPropertyChangeEvent(clone, OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
-		assertTrue(this.propertyChangeCalled);
-	}
-
-	public void testAbstractModelToString() {
-		assertTrue(this.testModel.toString().contains('(' + TEST_TO_STRING + ')'));
-	}
-
-
-	// ********** listener implementations **********
-
-	class Adapter implements ChangeListener {
-		public void stateChanged(StateChangeEvent e) {
-			ChangeSupportTests.this.stateChangedCalled = true;
-			ChangeSupportTests.this.stateChangeEvent = e;
-		}
-
-		public void propertyChanged(PropertyChangeEvent e) {
-			ChangeSupportTests.this.propertyChangeCalled = true;
-			ChangeSupportTests.this.propertyChangeEvent = e;
-		}
-
-
-		public void itemsAdded(CollectionAddEvent e) {
-			ChangeSupportTests.this.itemsAddedCollectionCalled = true;
-			ChangeSupportTests.this.collectionEvent = e;
-		}
-		public void itemsRemoved(CollectionRemoveEvent e) {
-			ChangeSupportTests.this.itemsRemovedCollectionCalled = true;
-			ChangeSupportTests.this.collectionEvent = e;
-		}
-		public void collectionCleared(CollectionClearEvent e) {
-			ChangeSupportTests.this.collectionClearedCalled = true;
-			ChangeSupportTests.this.collectionEvent = e;
-		}
-		public void collectionChanged(CollectionChangeEvent e) {
-			ChangeSupportTests.this.collectionChangedCalled = true;
-			ChangeSupportTests.this.collectionEvent = e;
-		}
-
-		public void itemsAdded(ListAddEvent e) {
-			ChangeSupportTests.this.itemsAddedListCalled = true;
-			ChangeSupportTests.this.listEvent = e;
-		}
-		public void itemsRemoved(ListRemoveEvent e) {
-			ChangeSupportTests.this.itemsRemovedListCalled = true;
-			ChangeSupportTests.this.listEvent = e;
-		}
-		public void itemsReplaced(ListReplaceEvent e) {
-			ChangeSupportTests.this.itemsReplacedListCalled = true;
-			ChangeSupportTests.this.listEvent = e;
-		}
-		public void itemsMoved(ListMoveEvent e) {
-			ChangeSupportTests.this.itemsMovedListCalled = true;
-			ChangeSupportTests.this.listEvent = e;
-		}
-		public void listCleared(ListClearEvent e) {
-			ChangeSupportTests.this.listClearedCalled = true;
-			ChangeSupportTests.this.listEvent = e;
-		}
-		public void listChanged(ListChangeEvent e) {
-			ChangeSupportTests.this.listChangedCalled = true;
-			ChangeSupportTests.this.listEvent = e;
-		}
-
-		public void nodeAdded(TreeAddEvent e) {
-			ChangeSupportTests.this.nodeAddedCalled = true;
-			ChangeSupportTests.this.treeEvent = e;
-		}
-		public void nodeRemoved(TreeRemoveEvent e) {
-			ChangeSupportTests.this.nodeRemovedCalled = true;
-			ChangeSupportTests.this.treeEvent = e;
-		}
-		public void treeCleared(TreeClearEvent e) {
-			ChangeSupportTests.this.treeClearedCalled = true;
-			ChangeSupportTests.this.treeEvent = e;
-		}
-		public void treeChanged(TreeChangeEvent e) {
-			ChangeSupportTests.this.treeChangedCalled = true;
-			ChangeSupportTests.this.treeEvent = e;
-		}
-	}
-
-
-	// ********** inner class **********
-
-	private static class TestModel extends AbstractModel implements Cloneable {
-		TestModel() {
-			super();
-		}
-
-		// ***** state
-		public void testFireStateChange() {
-			this.fireStateChanged();
-		}
-
-		// ***** property
-		public void testFirePropertyChangedEvent() {
-			this.firePropertyChanged(new PropertyChangeEvent(this, PROPERTY_NAME, OLD_OBJECT_VALUE, NEW_OBJECT_VALUE));
-		}
-
-		public void testFirePropertyChangedEventNoChange() {
-			this.firePropertyChanged(new PropertyChangeEvent(this, PROPERTY_NAME, OLD_OBJECT_VALUE, OLD_OBJECT_VALUE));
-		}
-
-		public void testFirePropertyChangedObjectObject() {
-			this.firePropertyChanged(PROPERTY_NAME, OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
-		}
-
-		public void testFirePropertyChangedObjectObjectNoChange() {
-			this.firePropertyChanged(PROPERTY_NAME, OLD_OBJECT_VALUE, OLD_OBJECT_VALUE);
-		}
-
-		public void testFirePropertyChangedObject() {
-			this.firePropertyChanged(PROPERTY_NAME, NEW_OBJECT_VALUE);
-		}
-
-		public void testFirePropertyChangedObjectNoChange() {
-			this.firePropertyChanged(PROPERTY_NAME, null);
-		}
-
-		public void testFirePropertyChangedIntInt() {
-			this.firePropertyChanged(PROPERTY_NAME, OLD_INT_VALUE.intValue(), NEW_INT_VALUE.intValue());
-		}
-
-		public void testFirePropertyChangedIntIntNoChange() {
-			this.firePropertyChanged(PROPERTY_NAME, OLD_INT_VALUE.intValue(), OLD_INT_VALUE.intValue());
-		}
-
-		public void testFirePropertyChangedBooleanBoolean() {
-			this.firePropertyChanged(PROPERTY_NAME, OLD_BOOLEAN_VALUE.booleanValue(), NEW_BOOLEAN_VALUE.booleanValue());
-		}
-
-		public void testFirePropertyChangedBooleanBooleanNoChange() {
-			this.firePropertyChanged(PROPERTY_NAME, OLD_BOOLEAN_VALUE.booleanValue(), OLD_BOOLEAN_VALUE.booleanValue());
-		}
-
-		// ***** collection
-		public void testFireItemsAddedCollectionEvent() {
-			this.fireItemsAdded(new CollectionAddEvent(this, COLLECTION_NAME, ADDED_OBJECT_VALUE));
-		}
-
-		public void testFireItemsAddedCollectionEventNoChange() {
-			this.fireItemsAdded(new CollectionAddEvent(this, COLLECTION_NAME, Collections.emptySet()));
-		}
-
-		public void testFireItemsAddedCollection() {
-			this.fireItemsAdded(COLLECTION_NAME, Collections.singleton(ADDED_OBJECT_VALUE));
-		}
-
-		public void testFireItemsAddedCollectionNoChange() {
-			this.fireItemsAdded(COLLECTION_NAME, Collections.emptySet());
-		}
-
-		public void testFireItemAddedCollection() {
-			this.fireItemAdded(COLLECTION_NAME, ADDED_OBJECT_VALUE);
-		}
-
-		public void testFireItemsRemovedCollectionEvent() {
-			this.fireItemsRemoved(new CollectionRemoveEvent(this, COLLECTION_NAME, REMOVED_OBJECT_VALUE));
-		}
-
-		public void testFireItemsRemovedCollectionEventNoChange() {
-			this.fireItemsRemoved(new CollectionRemoveEvent(this, COLLECTION_NAME, Collections.emptySet()));
-		}
-
-		public void testFireItemsRemovedCollection() {
-			this.fireItemsRemoved(COLLECTION_NAME, Collections.singleton(REMOVED_OBJECT_VALUE));
-		}
-
-		public void testFireItemsRemovedCollectionNoChange() {
-			this.fireItemsRemoved(COLLECTION_NAME, Collections.emptySet());
-		}
-
-		public void testFireItemRemovedCollection() {
-			this.fireItemRemoved(COLLECTION_NAME, REMOVED_OBJECT_VALUE);
-		}
-
-		public void testFireCollectionCleared() {
-			this.fireCollectionCleared(COLLECTION_NAME);
-		}
-
-		public void testFireCollectionChangedEvent() {
-			this.fireCollectionChanged(new CollectionChangeEvent(this, COLLECTION_NAME, Collections.emptySet()));
-		}
-
-		public void testFireCollectionChanged() {
-			this.fireCollectionChanged(COLLECTION_NAME, Collections.emptySet());
-		}
-
-		public boolean testAddItemToCollection() {
-			return this.addItemToCollection(ADDED_OBJECT_VALUE, new ArrayList<Object>(), COLLECTION_NAME);
-		}
-
-		public boolean testAddItemToCollectionNoChange() {
-			Collection<Object> collection = new HashSet<Object>();
-			collection.add(ADDED_OBJECT_VALUE);
-			return this.addItemToCollection(ADDED_OBJECT_VALUE, collection, COLLECTION_NAME);
-		}
-
-		public boolean testAddItemsToCollection() {
-			return this.addItemsToCollection(Collections.singleton(ADDED_OBJECT_VALUE), new ArrayList<Object>(), COLLECTION_NAME);
-		}
-
-		public boolean testAddItemsToCollectionNoChange() {
-			Collection<Object> collection = new HashSet<Object>();
-			collection.add(ADDED_OBJECT_VALUE);
-			return this.addItemsToCollection(Collections.singleton(ADDED_OBJECT_VALUE), collection, COLLECTION_NAME);
-		}
-
-		public boolean testAddItemsToCollectionMixed() {
-			Collection<Object> collection = new HashSet<Object>();
-			collection.add(ADDED_OBJECT_VALUE);
-			return this.addItemsToCollection(new Object[] {ADDED_OBJECT_VALUE, ADDED_OBJECT_VALUE_2}, collection, COLLECTION_NAME);
-		}
-
-		public boolean testRemoveItemFromCollection() {
-			Collection<Object> collection = new HashSet<Object>();
-			collection.add(REMOVED_OBJECT_VALUE);
-			return this.removeItemFromCollection(REMOVED_OBJECT_VALUE, collection, COLLECTION_NAME);
-		}
-
-		public boolean testRemoveItemFromCollectionNoChange() {
-			Collection<Object> collection = new HashSet<Object>();
-			collection.add(REMOVED_OBJECT_VALUE);
-			return this.removeItemFromCollection("foo", collection, COLLECTION_NAME);
-		}
-
-		public boolean testRemoveItemsFromCollection() {
-			Collection<Object> collection = new HashSet<Object>();
-			collection.add(REMOVED_OBJECT_VALUE);
-			collection.add("foo");
-			collection.add("bar");
-			return this.removeItemsFromCollection(new Object[] {"foo", "bar", REMOVED_OBJECT_VALUE}, collection, COLLECTION_NAME);
-		}
-
-		public boolean testRemoveItemsFromCollectionNoChange1() {
-			Collection<Object> collection = new HashSet<Object>();
-			collection.add(REMOVED_OBJECT_VALUE);
-			return this.removeItemsFromCollection(Collections.emptySet(), collection, COLLECTION_NAME);
-		}
-
-		public boolean testRemoveItemsFromCollectionNoChange2() {
-			Collection<Object> collection = new HashSet<Object>();
-			return this.removeItemsFromCollection(Collections.singleton("foo"), collection, COLLECTION_NAME);
-		}
-
-		public boolean testRemoveItemsFromCollectionNoChange3() {
-			Collection<Object> collection = new HashSet<Object>();
-			collection.add(REMOVED_OBJECT_VALUE);
-			return this.removeItemsFromCollection(Collections.singleton("foo"), collection, COLLECTION_NAME);
-		}
-
-		public boolean testRetainItemsInCollection1() {
-			Collection<Object> collection = new HashSet<Object>();
-			collection.add(REMOVED_OBJECT_VALUE);
-			collection.add("foo");
-			collection.add("bar");
-			return this.retainItemsInCollection(new Object[] {"foo", "bar"}, collection, COLLECTION_NAME);
-		}
-
-		public boolean testRetainItemsInCollection2() {
-			Collection<Object> collection = new HashSet<Object>();
-			collection.add(REMOVED_OBJECT_VALUE);
-			collection.add("foo");
-			collection.add("bar");
-			return this.retainItemsInCollection(Collections.emptySet(), collection, COLLECTION_NAME);
-		}
-
-		public boolean testRetainItemsInCollectionNoChange1() {
-			Collection<Object> collection = new HashSet<Object>();
-			return this.retainItemsInCollection(new Object[] {"foo", "bar"}, collection, COLLECTION_NAME);
-		}
-
-		public boolean testRetainItemsInCollectionNoChange2() {
-			Collection<Object> collection = new HashSet<Object>();
-			collection.add(REMOVED_OBJECT_VALUE);
-			collection.add("foo");
-			collection.add("bar");
-			return this.retainItemsInCollection(new Object[] {"foo", "bar", REMOVED_OBJECT_VALUE}, collection, COLLECTION_NAME);
-		}
-
-		public boolean testClearCollection() {
-			Collection<Object> collection = new HashSet<Object>();
-			collection.add(REMOVED_OBJECT_VALUE);
-			collection.add("foo");
-			collection.add("bar");
-			return this.clearCollection(collection, COLLECTION_NAME);
-		}
-
-		public boolean testClearCollectionNoChange() {
-			Collection<Object> collection = new HashSet<Object>();
-			return this.clearCollection(collection, COLLECTION_NAME);
-		}
-
-		public boolean testSynchronizeCollection1() {
-			Collection<Object> collection = new HashSet<Object>();
-			collection.add("foo");
-			collection.add("bar");
-			collection.add("baz");
-			Collection<Object> newCollection = new HashSet<Object>();
-			newCollection.add("joo");
-			newCollection.add("jar");
-			newCollection.add("baz");
-			boolean result = this.synchronizeCollection(newCollection, collection, COLLECTION_NAME);
-			assertEquals(newCollection, collection);
-			return result;
-		}
-
-		public boolean testSynchronizeCollection2() {
-			Collection<Object> collection = new HashSet<Object>();
-			collection.add("foo");
-			collection.add("bar");
-			collection.add("baz");
-			Collection<Object> newCollection = new HashSet<Object>();
-			boolean result = this.synchronizeCollection(newCollection, collection, COLLECTION_NAME);
-			assertEquals(newCollection, collection);
-			return result;
-		}
-
-		public boolean testSynchronizeCollection3() {
-			Collection<Object> collection = new HashSet<Object>();
-			Collection<Object> newCollection = new HashSet<Object>();
-			newCollection.add("joo");
-			newCollection.add("jar");
-			newCollection.add("baz");
-			boolean result = this.synchronizeCollection(newCollection, collection, COLLECTION_NAME);
-			assertEquals(newCollection, collection);
-			return result;
-		}
-
-		// ***** list
-		public void testFireItemsAddedListEvent() {
-			this.fireItemsAdded(new ListAddEvent(this, LIST_NAME, ADD_INDEX, ADDED_OBJECT_VALUE));
-		}
-
-		public void testFireItemsAddedListEventNoChange() {
-			this.fireItemsAdded(new ListAddEvent(this, LIST_NAME, ADD_INDEX, Collections.emptyList()));
-		}
-
-		public void testFireItemsAddedList() {
-			this.fireItemsAdded(LIST_NAME, ADD_INDEX, Collections.singletonList(ADDED_OBJECT_VALUE));
-		}
-
-		public void testFireItemsAddedListNoChange() {
-			this.fireItemsAdded(LIST_NAME, ADD_INDEX, Collections.emptyList());
-		}
-
-		public void testFireItemAddedList() {
-			this.fireItemAdded(LIST_NAME, ADD_INDEX, ADDED_OBJECT_VALUE);
-		}
-
-		public void testFireItemsRemovedListEvent() {
-			this.fireItemsRemoved(new ListRemoveEvent(this, LIST_NAME, REMOVE_INDEX, REMOVED_OBJECT_VALUE));
-		}
-
-		public void testFireItemsRemovedListEventNoChange() {
-			this.fireItemsRemoved(new ListRemoveEvent(this, LIST_NAME, REMOVE_INDEX, Collections.emptyList()));
-		}
-
-		public void testFireItemsRemovedList() {
-			this.fireItemsRemoved(LIST_NAME, REMOVE_INDEX, Collections.singletonList(REMOVED_OBJECT_VALUE));
-		}
-
-		public void testFireItemsRemovedListNoChange() {
-			this.fireItemsRemoved(LIST_NAME, REMOVE_INDEX, Collections.emptyList());
-		}
-
-		public void testFireItemRemovedList() {
-			this.fireItemRemoved(LIST_NAME, REMOVE_INDEX, REMOVED_OBJECT_VALUE);
-		}
-
-		public void testFireItemsReplacedListEvent() {
-			this.fireItemsReplaced(new ListReplaceEvent(this, LIST_NAME, REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE));
-		}
-
-		public void testFireItemsReplacedListEventNoChange() {
-			this.fireItemsReplaced(new ListReplaceEvent(this, LIST_NAME, REPLACE_INDEX, Collections.emptyList(), Collections.emptyList()));
-		}
-
-		public void testFireItemsReplacedList() {
-			this.fireItemsReplaced(LIST_NAME, REPLACE_INDEX, Collections.singletonList(ADDED_OBJECT_VALUE), Collections.singletonList(REMOVED_OBJECT_VALUE));
-		}
-
-		public void testFireItemsReplacedListNoChange() {
-			this.fireItemsReplaced(LIST_NAME, REPLACE_INDEX, Collections.emptyList(), Collections.emptyList());
-		}
-
-		public void testFireItemReplacedList() {
-			this.fireItemReplaced(LIST_NAME, REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
-		}
-
-		public void testFireItemsMovedListEvent() {
-			this.fireItemsMoved(new ListMoveEvent(this, LIST_NAME, TARGET_INDEX, SOURCE_INDEX, 1));
-		}
-
-		public void testFireItemsMovedListEventNoChange() {
-			this.fireItemsMoved(new ListMoveEvent(this, LIST_NAME, SOURCE_INDEX, SOURCE_INDEX, 1));
-		}
-
-		public void testFireItemsMovedList() {
-			this.fireItemsMoved(LIST_NAME, TARGET_INDEX, SOURCE_INDEX, 1);
-		}
-
-		public void testFireItemsMovedListNoChange() {
-			this.fireItemsMoved(LIST_NAME, SOURCE_INDEX, SOURCE_INDEX, 1);
-		}
-
-		public void testFireItemMovedList() {
-			this.fireItemMoved(LIST_NAME, TARGET_INDEX, SOURCE_INDEX);
-		}
-
-		public void testFireListClearedEvent() {
-			this.fireListCleared(new ListClearEvent(this, LIST_NAME));
-		}
-
-		public void testFireListCleared() {
-			this.fireListCleared(LIST_NAME);
-		}
-
-		public void testFireListChangedEvent() {
-			this.fireListChanged(new ListChangeEvent(this, LIST_NAME, Collections.emptyList()));
-		}
-
-		public void testFireListChanged() {
-			this.fireListChanged(LIST_NAME, Collections.emptyList());
-		}
-
-		public void testAddItemToListIndex() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.addItemToList(2, "joo", list, LIST_NAME);
-		}
-
-		public void testAddItemToList() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.addItemToList("joo", list, LIST_NAME);
-		}
-
-		public void testAddItemsToListIndex() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.addItemsToList(2, Collections.singletonList("joo"), list, LIST_NAME);
-		}
-
-		public void testAddItemsToListIndexNoChange() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.addItemsToList(2, Collections.<String>emptyList(), list, LIST_NAME);
-		}
-
-		public void testAddItemsToList() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.addItemsToList(Collections.singletonList("joo"), list, LIST_NAME);
-		}
-
-		public void testAddItemsToListNoChange() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.addItemsToList(Collections.<String>emptyList(), list, LIST_NAME);
-		}
-
-		public void testRemoveItemFromListIndex() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.removeItemFromList(1, list, LIST_NAME);
-		}
-
-		public void testRemoveItemFromList() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.removeItemFromList("bar", list, LIST_NAME);
-		}
-
-		public void testRemoveItemsFromListIndex() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.removeItemsFromList(1, 1, list, LIST_NAME);
-		}
-
-		public void testRemoveItemsFromListIndexNoChange() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.removeItemsFromList(2, 0, list, LIST_NAME);
-		}
-
-		public void testRemoveItemsFromList() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.removeItemsFromList(Collections.singletonList("bar"), list, LIST_NAME);
-		}
-
-		public void testRemoveItemsFromListNoChange() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.addItemsToList(Collections.<String>emptyList(), list, LIST_NAME);
-		}
-
-		public void testRetainItemsInList() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.retainItemsInList(new String[] {"bar", "baz"}, list, LIST_NAME);
-		}
-
-		public void testReplaceItemInList() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.replaceItemInList("bar", "xxx", list, LIST_NAME);
-		}
-
-		public void testSetItemsInList() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.setItemsInList(1, new String[] {"xxx"}, list, LIST_NAME);
-		}
-
-		public void testMoveItemsInList() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			list.add("xxx");
-			list.add("yyy");
-			list.add("zzz");
-			this.moveItemsInList(2, 4, 2, list, LIST_NAME);
-		}
-
-		public void testClearList() {
-			List<String> list = new ArrayList<String>();
-			list.add("foo");
-			list.add("bar");
-			list.add("baz");
-			this.clearList(list, LIST_NAME);
-		}
-
-		public void testSynchronizeList() {
-			List<String> oldList = new ArrayList<String>();
-			oldList.add("foo");
-			oldList.add("bar");
-			oldList.add("baz");
-			oldList.add("xxx");
-			oldList.add("yyy");
-			oldList.add("zzz");
-			List<String> newList = new ArrayList<String>();
-			newList.add("foo");
-			newList.add("ppp");
-			newList.add("baz");
-			newList.add("xxx");
-			newList.add("qqq");
-			this.synchronizeList(newList, oldList, LIST_NAME);
-			assertEquals(newList, oldList);
-		}
-
-		// ***** tree
-		public void testFireNodeAddedTreeEvent() {
-			this.fireNodeAdded(new TreeAddEvent(this, TREE_NAME, OBJECT_PATH));
-		}
-
-		public void testFireNodeAddedTree() {
-			this.fireNodeAdded(TREE_NAME, OBJECT_PATH);
-		}
-
-		public void testFireNodeRemovedTreeEvent() {
-			this.fireNodeRemoved(new TreeRemoveEvent(this, TREE_NAME, OBJECT_PATH));
-		}
-
-		public void testFireNodeRemovedTree() {
-			this.fireNodeRemoved(TREE_NAME, OBJECT_PATH);
-		}
-
-		public void testFireTreeClearedEvent() {
-			this.fireTreeCleared(new TreeClearEvent(this, TREE_NAME));
-		}
-
-		public void testFireTreeCleared() {
-			this.fireTreeCleared(TREE_NAME);
-		}
-
-		public void testFireTreeChangedEvent() {
-			this.fireTreeChanged(new TreeChangeEvent(this, TREE_NAME, OBJECT_PATH));
-		}
-
-		public void testFireTreeChanged() {
-			this.fireTreeChanged(TREE_NAME, OBJECT_PATH);
-		}
-
-		public boolean testAttributeValueHasChanged(Object value1, Object value2) {
-			return this.attributeValueHasChanged(value1, value2);
-		}
-
-		public boolean testAttributeValueHasNotChanged(Object value1, Object value2) {
-			return this.attributeValueHasNotChanged(value1, value2);
-		}
-
-		// ***** misc
-		@Override
-		public TestModel clone() {
-			try {
-				return (TestModel) super.clone();
-			} catch (CloneNotSupportedException ex) {
-				throw new InternalError();
-			}
-		}
-
-		public boolean testValuesAreDifferent(Object value1, Object value2) {
-			return this.valuesAreDifferent(value1, value2);
-		}
-
-		public boolean testValuesAreEqual(Object value1, Object value2) {
-			return this.valuesAreEqual(value1, value2);
-		}
-
-		public boolean testElementsAreDifferent(Iterable<?> iterable1, Iterable<?> iterable2) {
-			return this.getChangeSupport().elementsAreDifferent(iterable1, iterable2);
-		}
-
-		public boolean testElementsAreEqual(Iterable<?> iterable1, Iterable<?> iterable2) {
-			return this.getChangeSupport().elementsAreEqual(iterable1, iterable2);
-		}
-
-		@Override
-		public void toString(StringBuilder sb) {
-			sb.append(TEST_TO_STRING);
-		}
-
-	}
-
-
-	// ********** serialization test **********
-	public void testSerialization() throws java.io.IOException, ClassNotFoundException {
-		if (Tools.jvmIsSun()) {
-			// This test doesn't pass in the Eclipse build environment (Linux/IBM JVM) for some reason
-			this.verifySerialization();
-		}
-	}
-
-	private void verifySerialization() throws java.io.IOException, ClassNotFoundException {
-		LocalModel model1 = new LocalModel();
-		Foo foo1 = new Foo();
-		Bar bar1 = new Bar();
-		Joo joo1 = new Joo();
-		Jar jar1 = new Jar();
-		model1.addStateChangeListener(foo1);
-		model1.addStateChangeListener(bar1);
-		model1.addListChangeListener("foo", joo1);
-		model1.addListChangeListener("foo", jar1);
-
-		Iterable<EventListener> listeners1 = this.getListeners(model1, StateChangeListener.class, null);
-		Object[] listenersArray1 = ArrayTools.array(listeners1);
-		assertEquals(2, listenersArray1.length);
-		// the order of these could change...
-		assertEquals(Foo.class, listenersArray1[0].getClass());
-		assertEquals(Bar.class, listenersArray1[1].getClass());
-
-		listeners1 = this.getListeners(model1, ListChangeListener.class, "foo");
-		listenersArray1 = ArrayTools.array(listeners1);
-		assertEquals(2, listenersArray1.length);
-		// the order of these could change...
-		assertEquals(Joo.class, listenersArray1[0].getClass());
-		assertEquals(Jar.class, listenersArray1[1].getClass());
-
-		LocalModel model2 = TestTools.serialize(model1);
-
-		Iterable<EventListener> listeners2 = this.getListeners(model2, StateChangeListener.class, null);
-		Object[] listenersArray2 = ArrayTools.array(listeners2);
-		assertEquals(1, listenersArray2.length);
-		assertEquals(Foo.class, listenersArray2[0].getClass());
-
-		listeners2 = this.getListeners(model2, ListChangeListener.class, "foo");
-		listenersArray2 = ArrayTools.array(listeners2);
-		assertEquals(1, listenersArray2.length);
-		assertEquals(Joo.class, listenersArray2[0].getClass());
-	}
-
-	private Iterable<EventListener> getListeners(LocalModel model, Class<? extends EventListener> listenerClass, String aspectName) {
-		return this.getListenerList(model, listenerClass, aspectName).getListeners();
-	}
-
-	@SuppressWarnings("unchecked")
-	private ListenerList<EventListener> getListenerList(LocalModel model, Class<? extends EventListener> listenerClass, String aspectName) {
-		ChangeSupport changeSupport = (ChangeSupport) ReflectionTools.getFieldValue(model, "changeSupport");
-		return (ListenerList<EventListener>) ReflectionTools.executeMethod(changeSupport, "getListenerList_", new Class<?>[] {Class.class, String.class}, new Object[] {listenerClass, aspectName});
-	}
-
-	// we have to manually handle 'changeSupport' since AbstractModel is not Serializable
-	private static class LocalModel extends AbstractModel implements Serializable {
-		LocalModel() {
-			super();
-		}
-		private synchronized void writeObject(ObjectOutputStream s) throws IOException {
-			s.defaultWriteObject();
-			s.writeObject(this.changeSupport);
-	    }
-		private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
-			s.defaultReadObject();
-			this.changeSupport = (ChangeSupport) s.readObject();
-		}
-	}
-
-	private static class Foo implements Serializable, StateChangeListener {
-		Foo() {
-			super();
-		}
-		public void stateChanged(StateChangeEvent event) {
-			// do nothing
-		}
-	}
-
-	private static class Bar implements StateChangeListener {
-		Bar() {
-			super();
-		}
-		public void stateChanged(StateChangeEvent event) {
-			// do nothing
-		}
-	}
-
-	private static class Joo extends ListChangeAdapter implements Serializable {
-		Joo() {
-			super();
-		}
-	}
-
-	private static class Jar extends ListChangeAdapter {
-		Jar() {
-			super();
-		}
-	}
-
-
-	// ********** bug(?) test **********
-
-	private static final String ISE_MESSAGE = "this object is no longer listening to localA";
-
-	/**
-	 * Test the following situation:
-	 * 	- both B and C are listening to A
-	 * 	- C is also listening to B
-	 * 	- when B receives an event from A, it will fire an event to C
-	 * 	- when C receives an event from B, it will STOP listening to A
-	 * 	- the event from B to C may be preceded or followed (depending on
-	 * 		the hash positions of listeners) by an event from A to C:
-	 * 		- if the A to C event comes first, no problem
-	 * 		- but if the A to B event comes first, the A to C event should NOT happen
-	 */
-	public void testIndirectRemoveStateListener() {
-		this.verifyIndirectRemoveListener(
-			new NotifyCommand() {
-				public void notifyListeners(LocalA localA) {
-					localA.notifyStateListeners();
-				}
-			}
-		);
-	}
-
-	public void testIndirectRemovePropertyListener() {
-		this.verifyIndirectRemoveListener(
-			new NotifyCommand() {
-				public void notifyListeners(LocalA localA) {
-					localA.notifyPropertyListeners();
-				}
-			}
-		);
-	}
-
-	public void testIndirectRemoveCollectionListener() {
-		this.verifyIndirectRemoveListener(
-			new NotifyCommand() {
-				public void notifyListeners(LocalA localA) {
-					localA.notifyCollectionListeners();
-				}
-			}
-		);
-	}
-
-	public void testIndirectRemoveListListener() {
-		this.verifyIndirectRemoveListener(
-			new NotifyCommand() {
-				public void notifyListeners(LocalA localA) {
-					localA.notifyListListeners();
-				}
-			}
-		);
-	}
-
-	public void testIndirectRemoveTreeListener() {
-		this.verifyIndirectRemoveListener(
-			new NotifyCommand() {
-				public void notifyListeners(LocalA localA) {
-					localA.notifyTreeListeners();
-				}
-			}
-		);
-	}
-
-	public void verifyIndirectRemoveListener(NotifyCommand command) {
-		LocalA localA = new LocalA();
-		LocalB localB = new LocalB(localA);
-
-		// build a bunch of LocalCs so at least one of them is notified AFTER the LocalB;
-		// using 1000 seemed to fail very consistently before ChangeSupport was fixed
-		LocalC[] localCs = new LocalC[1000];
-		for (int i = localCs.length; i-- > 0; ) {
-			localCs[i] = new LocalC(localA, localB);
-		}
-
-		boolean exCaught = false;
-		try {
-			command.notifyListeners(localA);
-		} catch (IllegalStateException ex) {
-			if (ex.getMessage() == ISE_MESSAGE) {
-				exCaught = true;
-			} else {
-				throw ex;
-			}
-		}
-		assertFalse(exCaught);
-
-		for (int i = localCs.length; i-- > 0; ) {
-			assertFalse(localCs[i].isListeningToLocalA());
-		}
-	}
-
-	private interface NotifyCommand {
-		void notifyListeners(LocalA localA);
-	}
-
-	/**
-	 * This object simply fires a state change event. Both LocalB and LocalC
-	 * will be listeners.
-	 */
-	private static class LocalA extends AbstractModel {
-		LocalA() {
-			super();
-		}
-		void notifyStateListeners() {
-			this.fireStateChanged();
-		}
-		void notifyPropertyListeners() {
-			this.firePropertyChanged("foo", 1, 2);
-		}
-		void notifyCollectionListeners() {
-			this.fireCollectionChanged("foo", Collections.emptySet());
-		}
-		void notifyListListeners() {
-			this.fireListChanged("foo", Collections.emptyList());
-		}
-		void notifyTreeListeners() {
-			this.fireTreeChanged("foo", Collections.emptySet());
-		}
-	}
-
-	/**
-	 * This object will fire state change events whenever it receives
-	 * a state change event from localA.
-	 */
-	private static class LocalB
-		extends AbstractModel
-		implements ChangeListener
-	{
-		LocalB(LocalA localA) {
-			super();
-			localA.addChangeListener(this);
-		}
-
-		public void stateChanged(StateChangeEvent e) {
-			this.fireStateChanged();
-		}
-
-		public void propertyChanged(PropertyChangeEvent evt) {
-			this.firePropertyChanged("bar", 1, 2);
-		}
-
-		public void collectionChanged(CollectionChangeEvent e) {
-			this.fireCollectionChanged("bar", Collections.emptySet());
-		}
-		public void collectionCleared(CollectionClearEvent e) {/*ignore*/}
-		public void itemsAdded(CollectionAddEvent e) {/*ignore*/}
-		public void itemsRemoved(CollectionRemoveEvent e) {/*ignore*/}
-
-		public void listChanged(ListChangeEvent e) {
-			this.fireListChanged("bar", Collections.emptyList());
-		}
-		public void listCleared(ListClearEvent e) {/*ignore*/}
-		public void itemsAdded(ListAddEvent e) {/*ignore*/}
-		public void itemsRemoved(ListRemoveEvent e) {/*ignore*/}
-		public void itemsReplaced(ListReplaceEvent e) {/*ignore*/}
-		public void itemsMoved(ListMoveEvent e) {/*ignore*/}
-
-		public void treeChanged(TreeChangeEvent e) {
-			this.fireTreeChanged("bar", Collections.emptySet());
-		}
-		public void treeCleared(TreeClearEvent e) {/*ignore*/}
-		public void nodeAdded(TreeAddEvent e) {/*ignore*/}
-		public void nodeRemoved(TreeRemoveEvent e) {/*ignore*/}
-
-	}
-
-	/**
-	 * This object will listen to two other objects, localA and localB.
-	 * If this object receives notification from localB, it will stop listening to
-	 * localA. If this object receives notification from localA, it will check to
-	 * see whether it still listening to localA. If this object is no longer
-	 * listening to localA, it will complain about receiving the event and
-	 * throw an exception.
-	 */
-	private static class LocalC
-		extends AbstractModel
-		implements ChangeListener
-	{
-		private LocalA localA;
-		private LocalB localB;
-		private boolean listeningToLocalA;
-
-		LocalC(LocalA localA, LocalB localB) {
-			super();
-			this.localA = localA;
-			this.localB = localB;
-
-			localA.addChangeListener(this);
-			this.listeningToLocalA = true;
-
-			localB.addChangeListener(this);
-		}
-		boolean isListeningToLocalA() {
-			return this.listeningToLocalA;
-		}
-
-		public void stateChanged(StateChangeEvent e) {
-			Object source = e.getSource();
-			if (source == this.localA) {
-				if ( ! this.listeningToLocalA) {
-					throw new IllegalStateException(ISE_MESSAGE);
-				}
-			} else if (source == this.localB) {
-				this.localA.removeChangeListener(this);
-				this.listeningToLocalA = false;
-			} else {
-				throw new IllegalStateException("bogus event source: " + source);
-			}
-		}
-
-		public void propertyChanged(PropertyChangeEvent e) {
-			Object source = e.getSource();
-			if (source == this.localA) {
-				if ( ! this.listeningToLocalA) {
-					throw new IllegalStateException(ISE_MESSAGE);
-				}
-			} else if (source == this.localB) {
-				this.localA.removeChangeListener(this);
-				this.listeningToLocalA = false;
-			} else {
-				throw new IllegalStateException("bogus event source: " + source);
-			}
-		}
-
-		public void collectionChanged(CollectionChangeEvent e) {
-			Object source = e.getSource();
-			if (source == this.localA) {
-				if ( ! this.listeningToLocalA) {
-					throw new IllegalStateException(ISE_MESSAGE);
-				}
-			} else if (source == this.localB) {
-				this.localA.removeChangeListener(this);
-				this.listeningToLocalA = false;
-			} else {
-				throw new IllegalStateException("bogus event source: " + source);
-			}
-		}
-		public void collectionCleared(CollectionClearEvent e) {/*ignore*/}
-		public void itemsAdded(CollectionAddEvent e) {/*ignore*/}
-		public void itemsRemoved(CollectionRemoveEvent e) {/*ignore*/}
-
-		public void listChanged(ListChangeEvent e) {
-			Object source = e.getSource();
-			if (source == this.localA) {
-				if ( ! this.listeningToLocalA) {
-					throw new IllegalStateException(ISE_MESSAGE);
-				}
-			} else if (source == this.localB) {
-				this.localA.removeChangeListener(this);
-				this.listeningToLocalA = false;
-			} else {
-				throw new IllegalStateException("bogus event source: " + source);
-			}
-		}
-		public void listCleared(ListClearEvent e) {/*ignore*/}
-		public void itemsAdded(ListAddEvent e) {/*ignore*/}
-		public void itemsRemoved(ListRemoveEvent e) {/*ignore*/}
-		public void itemsReplaced(ListReplaceEvent e) {/*ignore*/}
-		public void itemsMoved(ListMoveEvent e) {/*ignore*/}
-
-		public void treeChanged(TreeChangeEvent e) {
-			Object source = e.getSource();
-			if (source == this.localA) {
-				if ( ! this.listeningToLocalA) {
-					throw new IllegalStateException(ISE_MESSAGE);
-				}
-			} else if (source == this.localB) {
-				this.localA.removeChangeListener(this);
-				this.listeningToLocalA = false;
-			} else {
-				throw new IllegalStateException("bogus event source: " + source);
-			}
-		}
-		public void treeCleared(TreeClearEvent e) {/*ignore*/}
-		public void nodeAdded(TreeAddEvent e) {/*ignore*/}
-		public void nodeRemoved(TreeRemoveEvent e) {/*ignore*/}
-
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/NewEventTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/NewEventTests.java
deleted file mode 100644
index 5ad6320..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/NewEventTests.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.model;
-
-import java.util.EventListener;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.ListenerList;
-import org.eclipse.persistence.tools.utility.model.AbstractModel;
-import org.eclipse.persistence.tools.utility.model.ChangeSupport;
-import org.eclipse.persistence.tools.utility.model.Model;
-import org.eclipse.persistence.tools.utility.model.event.ChangeEvent;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-
-/**
- * test what it takes to add a new type of event to
- * model and change support
- */
-public class NewEventTests extends TestCase {
-	private Foo foo;
-
-	public NewEventTests(String name) {
-		super(name);
-	}
-	
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.foo = new Foo();
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		TestTools.clear(this);
-		super.tearDown();
-	}
-
-	public void testHasNoFooChangeListeners() {
-		assertTrue(this.foo.hasNoFooChangeListeners());
-		LocalListener listener = new LocalListener();
-		this.foo.addFooChangeListener(listener);
-		assertFalse(this.foo.hasNoFooChangeListeners());
-		this.foo.removeFooChangeListener(listener);
-		assertTrue(this.foo.hasNoFooChangeListeners());
-	}
-
-	public void testHasAnyFooChangeListeners() {
-		assertFalse(this.foo.hasAnyFooChangeListeners());
-		LocalListener listener = new LocalListener();
-		this.foo.addFooChangeListener(listener);
-		assertTrue(this.foo.hasAnyFooChangeListeners());
-		this.foo.removeFooChangeListener(listener);
-		assertFalse(this.foo.hasAnyFooChangeListeners());
-	}
-
-	public void testFireFooChangeEvent() {
-		LocalListener listener = new LocalListener();
-		assertFalse(listener.receivedFooEvent);
-		this.foo.addFooChangeListener(listener);
-		this.foo.foo();
-		assertTrue(listener.receivedFooEvent);
-	}
-
-
-	// ********** harness classes **********
-
-	class Foo extends AbstractFooModel {
-		Foo() {
-			super();
-		}
-		void foo() {
-			this.fireFooChangeEvent();
-		}
-	}
-
-	class LocalListener implements FooChangeListener {
-		boolean receivedFooEvent = false;
-		LocalListener() {
-			super();
-		}
-		public void fooChanged(FooChangeEvent event) {
-			this.receivedFooEvent = true;
-		}
-	}
-
-	interface FooModel extends Model {
-		void addFooChangeListener(FooChangeListener listener);
-		void removeFooChangeListener(FooChangeListener listener);
-	}
-
-	interface FooChangeListener extends EventListener {
-		void fooChanged(FooChangeEvent event);
-	}
-
-	static class FooChangeEvent extends ChangeEvent {
-		private static final long serialVersionUID = 1L;
-		public FooChangeEvent(FooModel source) {
-			super(source);
-		}
-		public FooChangeEvent clone(Model newSource) {
-			return new FooChangeEvent((FooModel) newSource);
-		}
-	}
-
-	static class AbstractFooModel extends AbstractModel implements FooModel {
-		@Override
-		protected synchronized FooChangeSupport getChangeSupport() {
-			return (FooChangeSupport) super.getChangeSupport();
-		}
-		@Override
-		protected ChangeSupport buildChangeSupport() {
-			return new FooChangeSupport(this);
-		}
-		public void addFooChangeListener(FooChangeListener listener) {
-			this.getChangeSupport().addFooChangeListener(listener);
-		}
-		public void removeFooChangeListener(FooChangeListener listener) {
-			this.getChangeSupport().removeFooChangeListener(listener);
-		}
-		protected void fireFooChangeEvent() {
-			this.getChangeSupport().fireFooChanged();
-		}
-		public boolean hasAnyFooChangeListeners() {
-			return this.getChangeSupport().hasAnyFooChangeListeners();
-		}
-		public boolean hasNoFooChangeListeners() {
-			return ! this.hasAnyFooChangeListeners();
-		}
-	}
-
-	static class FooChangeSupport extends ChangeSupport {
-		FooChangeSupport(FooModel source) {
-			super(source);
-		}
-		protected static final Class<FooChangeListener> FOO_CHANGE_LISTENER_CLASS = FooChangeListener.class;
-		void addFooChangeListener(FooChangeListener listener) {
-			this.addListener(FOO_CHANGE_LISTENER_CLASS, listener);
-		}
-		void removeFooChangeListener(FooChangeListener listener) {
-			this.removeListener(FOO_CHANGE_LISTENER_CLASS, listener);
-		}
-		public boolean hasAnyFooChangeListeners() {
-			return this.hasAnyListeners(FOO_CHANGE_LISTENER_CLASS);
-		}
-		private ListenerList<FooChangeListener> getFooChangeListenerList() {
-			return this.getListenerList(FOO_CHANGE_LISTENER_CLASS);
-		}
-		private Iterable<FooChangeListener> getFooChangeListeners() {
-			ListenerList<FooChangeListener> listenerList = this.getFooChangeListenerList();
-			return (listenerList == null) ? null : listenerList.getListeners();
-		}
-		private boolean hasFooChangeListener(FooChangeListener listener) {
-			return CollectionTools.contains(this.getFooChangeListeners(), listener);
-		}
-		public void fireFooChanged() {
-			Iterable<FooChangeListener> listeners = this.getFooChangeListeners();
-			if (listeners != null) {
-				FooChangeEvent event = null;
-				for (FooChangeListener listener : listeners) {
-					if (this.hasFooChangeListener(listener)) {
-						if (event == null) {
-							// here's the reason for the duplicate code...
-							event = new FooChangeEvent((FooModel) this.source);
-						}
-						listener.fooChanged(event);
-					}
-				}
-			}
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/SingleAspectChangeSupportTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/SingleAspectChangeSupportTests.java
deleted file mode 100644
index 346a8ee..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/SingleAspectChangeSupportTests.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.model;
-
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.model.AbstractModel;
-import org.eclipse.persistence.tools.utility.model.ChangeSupport;
-import org.eclipse.persistence.tools.utility.model.Model;
-import org.eclipse.persistence.tools.utility.model.SingleAspectChangeSupport;
-import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeAdapter;
-import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.ListChangeAdapter;
-import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeAdapter;
-import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.TreeChangeAdapter;
-import org.eclipse.persistence.tools.utility.model.listener.TreeChangeListener;
-
-@SuppressWarnings("nls")
-public class SingleAspectChangeSupportTests extends TestCase {
-
-	public SingleAspectChangeSupportTests(String name) {
-		super(name);
-	}
-
-	public void testAddPropertyChangeListenerInvalidClass() {
-		Model model = new StateTestModel();
-		boolean exCaught = false;
-		PropertyChangeListener listener = new PropertyChangeAdapter();
-		try {
-			model.addPropertyChangeListener("foo", listener);
-			fail("bogus listener: " + listener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testAddPropertyChangeListenerInvalidAspect() {
-		Model model = new PropertyTestModel();
-		boolean exCaught = false;
-		PropertyChangeListener listener = new PropertyChangeAdapter();
-		try {
-			model.addPropertyChangeListener("bar", listener);
-			fail("bogus listener: " + listener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testAddCollectionChangeListenerInvalidClass() {
-		Model model = new StateTestModel();
-		boolean exCaught = false;
-		CollectionChangeListener listener = new CollectionChangeAdapter();
-		try {
-			model.addCollectionChangeListener("foo", listener);
-			fail("bogus listener: " + listener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testAddCollectionChangeListenerInvalidAspect() {
-		Model model = new CollectionTestModel();
-		boolean exCaught = false;
-		CollectionChangeListener listener = new CollectionChangeAdapter();
-		try {
-			model.addCollectionChangeListener("bar", listener);
-			fail("bogus listener: " + listener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testAddListChangeListenerInvalidClass() {
-		Model model = new StateTestModel();
-		boolean exCaught = false;
-		ListChangeListener listener = new ListChangeAdapter();
-		try {
-			model.addListChangeListener("foo", listener);
-			fail("bogus listener: " + listener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testAddListChangeListenerInvalidAspect() {
-		Model model = new ListTestModel();
-		boolean exCaught = false;
-		ListChangeListener listener = new ListChangeAdapter();
-		try {
-			model.addListChangeListener("bar", listener);
-			fail("bogus listener: " + listener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testAddTreeChangeListenerInvalidClass() {
-		Model model = new StateTestModel();
-		boolean exCaught = false;
-		TreeChangeListener listener = new TreeChangeAdapter();
-		try {
-			model.addTreeChangeListener("foo", listener);
-			fail("bogus listener: " + listener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testAddTreeChangeListenerInvalidAspect() {
-		Model model = new TreeTestModel();
-		boolean exCaught = false;
-		TreeChangeListener listener = new TreeChangeAdapter();
-		try {
-			model.addTreeChangeListener("bar", listener);
-			fail("bogus listener: " + listener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-
-	// ********** test models **********
-
-	static class StateTestModel extends AbstractModel {
-		StateTestModel() {
-			super();
-		}
-		@Override
-		protected ChangeSupport buildChangeSupport() {
-			return new SingleAspectChangeSupport(this, StateChangeListener.class, null);
-		}
-	}
-
-	static class PropertyTestModel extends AbstractModel {
-		PropertyTestModel() {
-			super();
-		}
-		@Override
-		protected ChangeSupport buildChangeSupport() {
-			return new SingleAspectChangeSupport(this, PropertyChangeListener.class, "foo");
-		}
-	}
-
-	static class CollectionTestModel extends AbstractModel {
-		CollectionTestModel() {
-			super();
-		}
-		@Override
-		protected ChangeSupport buildChangeSupport() {
-			return new SingleAspectChangeSupport(this, CollectionChangeListener.class, "foo");
-		}
-	}
-
-	static class ListTestModel extends AbstractModel {
-		ListTestModel() {
-			super();
-		}
-		@Override
-		protected ChangeSupport buildChangeSupport() {
-			return new SingleAspectChangeSupport(this, ListChangeListener.class, "foo");
-		}
-	}
-
-	static class TreeTestModel extends AbstractModel {
-		TreeTestModel() {
-			super();
-		}
-		@Override
-		protected ChangeSupport buildChangeSupport() {
-			return new SingleAspectChangeSupport(this, TreeChangeListener.class, "foo");
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/UtilityModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/UtilityModelTests.java
deleted file mode 100644
index 6e30f8e..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/UtilityModelTests.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.model;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import org.eclipse.persistence.tools.utility.tests.internal.model.listener.JptUtilityModelListenerTests;
-
-public class UtilityModelTests {
-
-	public static Test suite() {
-		TestSuite suite = new TestSuite(UtilityModelTests.class.getPackage().getName());
-
-		suite.addTest(JptUtilityModelListenerTests.suite());
-
-		suite.addTestSuite(ChangeSupportTests.class);
-		suite.addTestSuite(NewEventTests.class);
-		suite.addTestSuite(SingleAspectChangeSupportTests.class);
-
-		return suite;
-	}
-
-	private UtilityModelTests() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/JptUtilityModelListenerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/JptUtilityModelListenerTests.java
deleted file mode 100644
index 87a8c86..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/JptUtilityModelListenerTests.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.model.listener;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class JptUtilityModelListenerTests {
-	
-	public static Test suite() {
-		TestSuite suite = new TestSuite(JptUtilityModelListenerTests.class.getPackage().getName());
-
-		suite.addTestSuite(ReflectiveCollectionChangeListenerTests.class);
-		suite.addTestSuite(ReflectiveListChangeListenerTests.class);
-		suite.addTestSuite(ReflectivePropertyChangeListenerTests.class);
-		suite.addTestSuite(ReflectiveStateChangeListenerTests.class);
-		suite.addTestSuite(ReflectiveTreeChangeListenerTests.class);
-	
-		return suite;
-	}
-	
-	private JptUtilityModelListenerTests() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-	
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectiveCollectionChangeListenerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectiveCollectionChangeListenerTests.java
deleted file mode 100644
index 52fad3d..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectiveCollectionChangeListenerTests.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.model.listener;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.ReflectionTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.model.AbstractModel;
-import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.CollectionEvent;
-import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
-import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.ReflectiveChangeListener;
-
-@SuppressWarnings("nls")
-public class ReflectiveCollectionChangeListenerTests extends TestCase {
-	
-	public ReflectiveCollectionChangeListenerTests(String name) {
-		super(name);
-	}
-
-	private CollectionChangeListener buildZeroArgumentListener(Object target) {
-		return ReflectiveChangeListener.buildCollectionChangeListener(target, "itemAddedZeroArgument", "itemRemovedZeroArgument", "collectionClearedZeroArgument", "collectionChangedZeroArgument");
-	}
-
-	private CollectionChangeListener buildSingleArgumentListener(Object target) {
-		return ReflectiveChangeListener.buildCollectionChangeListener(target, "itemAddedSingleArgument", "itemRemovedSingleArgument", "collectionClearedSingleArgument", "collectionChangedSingleArgument");
-	}
-
-	public void testItemAddedZeroArgumentNamedCollection() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
-		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildZeroArgumentListener(target));
-		testModel.addString(string);
-		assertTrue(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.collectionClearedZeroArgumentFlag);
-		assertFalse(target.collectionClearedSingleArgumentFlag);
-		assertFalse(target.collectionChangedZeroArgumentFlag);
-		assertFalse(target.collectionChangedSingleArgumentFlag);
-	}
-
-	public void testItemAddedSingleArgumentNamedCollection() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
-		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildSingleArgumentListener(target));
-		testModel.addString(string);
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertTrue(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.collectionClearedZeroArgumentFlag);
-		assertFalse(target.collectionClearedSingleArgumentFlag);
-		assertFalse(target.collectionChangedZeroArgumentFlag);
-		assertFalse(target.collectionChangedSingleArgumentFlag);
-	}
-
-	public void testItemRemovedZeroArgumentNamedCollection() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		testModel.addString(string);
-		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
-		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildZeroArgumentListener(target));
-		testModel.removeString(string);
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertTrue(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.collectionClearedZeroArgumentFlag);
-		assertFalse(target.collectionClearedSingleArgumentFlag);
-		assertFalse(target.collectionChangedZeroArgumentFlag);
-		assertFalse(target.collectionChangedSingleArgumentFlag);
-	}
-
-	public void testItemRemovedSingleArgumentNamedCollection() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		testModel.addString(string);
-		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
-		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildSingleArgumentListener(target));
-		testModel.removeString(string);
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertTrue(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.collectionClearedZeroArgumentFlag);
-		assertFalse(target.collectionClearedSingleArgumentFlag);
-		assertFalse(target.collectionChangedZeroArgumentFlag);
-		assertFalse(target.collectionChangedSingleArgumentFlag);
-	}
-
-	public void testCollectionClearedZeroArgumentNamedCollection() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		testModel.addString(string);
-		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
-		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildZeroArgumentListener(target));
-		testModel.clearStrings();
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertTrue(target.collectionClearedZeroArgumentFlag);
-		assertFalse(target.collectionClearedSingleArgumentFlag);
-		assertFalse(target.collectionChangedZeroArgumentFlag);
-		assertFalse(target.collectionChangedSingleArgumentFlag);
-	}
-
-	public void testCollectionClearedSingleArgumentNamedCollection() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		testModel.addString(string);
-		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
-		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildSingleArgumentListener(target));
-		testModel.clearStrings();
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.collectionClearedZeroArgumentFlag);
-		assertTrue(target.collectionClearedSingleArgumentFlag);
-		assertFalse(target.collectionChangedZeroArgumentFlag);
-		assertFalse(target.collectionChangedSingleArgumentFlag);
-	}
-
-	public void testCollectionChangedZeroArgumentNamedCollection() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		testModel.addString(string);
-		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
-		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildZeroArgumentListener(target));
-		testModel.replaceStrings(new String[] {"bar", "baz"});
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.collectionClearedZeroArgumentFlag);
-		assertFalse(target.collectionClearedSingleArgumentFlag);
-		assertTrue(target.collectionChangedZeroArgumentFlag);
-		assertFalse(target.collectionChangedSingleArgumentFlag);
-	}
-
-	public void testCollectionChangedSingleArgumentNamedCollection() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		testModel.addString(string);
-		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
-		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildSingleArgumentListener(target));
-		testModel.replaceStrings(new String[] {"bar", "baz"});
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.collectionClearedZeroArgumentFlag);
-		assertFalse(target.collectionClearedSingleArgumentFlag);
-		assertFalse(target.collectionChangedZeroArgumentFlag);
-		assertTrue(target.collectionChangedSingleArgumentFlag);
-	}
-
-	public void testBogusDoubleArgument1() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
-		boolean exCaught = false;
-		try {
-			CollectionChangeListener listener = ReflectiveChangeListener.buildCollectionChangeListener(target, "collectionChangedDoubleArgument");
-			fail("bogus listener: " + listener);
-		} catch (RuntimeException ex) {
-			if (ex.getCause().getClass() == NoSuchMethodException.class) {
-				exCaught = true;
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testBogusDoubleArgument2() throws Exception {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
-		Method method = ReflectionTools.getMethod(target, "collectionChangedDoubleArgument", new Class[] {CollectionChangeEvent.class, Object.class});
-		boolean exCaught = false;
-		try {
-			CollectionChangeListener listener = ReflectiveChangeListener.buildCollectionChangeListener(target, method);
-			fail("bogus listener: " + listener);
-		} catch (RuntimeException ex) {
-			if (ex.getMessage().equals(method.toString())) {
-				exCaught = true;
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testListenerMismatch() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
-		// build a COLLECTION change listener and hack it so we
-		// can add it as a LIST change listener
-		Object listener = ReflectiveChangeListener.buildCollectionChangeListener(target, "collectionEventSingleArgument");
-		testModel.addListChangeListener("bogus list", (ListChangeListener) listener);
-
-		boolean exCaught = false;
-		try {
-			testModel.changeList();
-			fail("listener mismatch: " + listener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-
-	class TestModel extends AbstractModel {
-		private Collection<String> strings = new ArrayList<String>();
-			public static final String STRINGS_COLLECTION = "strings";
-		TestModel() {
-			super();
-		}
-		Iterator<String> strings() {
-			return new CloneIterator<String>(this.strings) {
-				@Override
-				protected void remove(String s) {
-					TestModel.this.removeString(s);
-				}
-			};
-		}
-		void addString(String string) {
-			this.addItemToCollection(string, this.strings, STRINGS_COLLECTION);
-		}
-		void removeString(String string) {
-			this.removeItemFromCollection(string, this.strings, STRINGS_COLLECTION);
-		}
-		void clearStrings() {
-			this.clearCollection(this.strings, STRINGS_COLLECTION);
-		}
-		void replaceStrings(String[] newStrings) {
-			this.strings.clear();
-			CollectionTools.addAll(this.strings, newStrings);
-			this.fireCollectionChanged(STRINGS_COLLECTION, this.strings);
-		}
-		void changeList() {
-			this.fireListChanged("bogus list", Collections.emptyList());
-		}
-	}
-
-	class Target {
-		TestModel testModel;
-		String collectionName;
-		String string;
-		boolean itemAddedZeroArgumentFlag = false;
-		boolean itemAddedSingleArgumentFlag = false;
-		boolean itemRemovedZeroArgumentFlag = false;
-		boolean itemRemovedSingleArgumentFlag = false;
-		boolean collectionClearedZeroArgumentFlag = false;
-		boolean collectionClearedSingleArgumentFlag = false;
-		boolean collectionChangedZeroArgumentFlag = false;
-		boolean collectionChangedSingleArgumentFlag = false;
-		boolean collectionEventSingleArgumentFlag = false;
-		Target(TestModel testModel, String collectionName, String string) {
-			super();
-			this.testModel = testModel;
-			this.collectionName = collectionName;
-			this.string = string;
-		}
-		void itemAddedZeroArgument() {
-			this.itemAddedZeroArgumentFlag = true;
-		}
-		void itemAddedSingleArgument(CollectionAddEvent e) {
-			this.itemAddedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.collectionName, e.getCollectionName());
-			assertEquals(this.string, e.getItems().iterator().next());
-		}
-		void itemRemovedZeroArgument() {
-			this.itemRemovedZeroArgumentFlag = true;
-		}
-		void itemRemovedSingleArgument(CollectionRemoveEvent e) {
-			this.itemRemovedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.collectionName, e.getCollectionName());
-			assertEquals(this.string, e.getItems().iterator().next());
-		}
-		void collectionClearedZeroArgument() {
-			this.collectionClearedZeroArgumentFlag = true;
-		}
-		void collectionClearedSingleArgument(CollectionClearEvent e) {
-			this.collectionClearedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.collectionName, e.getCollectionName());
-		}
-		void collectionChangedZeroArgument() {
-			this.collectionChangedZeroArgumentFlag = true;
-		}
-		void collectionChangedSingleArgument(CollectionChangeEvent e) {
-			this.collectionChangedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.collectionName, e.getCollectionName());
-		}
-		void collectionEventSingleArgument(CollectionEvent e) {
-			this.collectionEventSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.collectionName, e.getCollectionName());
-		}
-		void collectionChangedDoubleArgument(CollectionChangeEvent e, Object o) {
-			fail("bogus event: " + e + " object: " + o);
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectiveListChangeListenerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectiveListChangeListenerTests.java
deleted file mode 100644
index e24a602..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectiveListChangeListenerTests.java
+++ /dev/null
@@ -1,500 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.model.listener;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.ListIterator;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.ReflectionTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneListIterator;
-import org.eclipse.persistence.tools.utility.model.AbstractModel;
-import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.ListEvent;
-import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
-import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
-import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
-import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.ReflectiveChangeListener;
-
-@SuppressWarnings("nls")
-public class ReflectiveListChangeListenerTests extends TestCase {
-	
-	public ReflectiveListChangeListenerTests(String name) {
-		super(name);
-	}
-
-	private ListChangeListener buildZeroArgumentListener(Object target) {
-		return ReflectiveChangeListener.buildListChangeListener(target, "itemAddedZeroArgument", "itemRemovedZeroArgument", "itemReplacedZeroArgument", "itemMovedZeroArgument", "listClearedZeroArgument", "listChangedZeroArgument");
-	}
-
-	private ListChangeListener buildSingleArgumentListener(Object target) {
-		return ReflectiveChangeListener.buildListChangeListener(target, "itemAddedSingleArgument", "itemRemovedSingleArgument", "itemReplacedSingleArgument", "itemMovedSingleArgument", "listClearedSingleArgument", "listChangedSingleArgument");
-	}
-
-	public void testItemAddedZeroArgumentNamedList() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
-		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
-		testModel.addString(string);
-		assertTrue(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.itemReplacedZeroArgumentFlag);
-		assertFalse(target.itemReplacedSingleArgumentFlag);
-		assertFalse(target.itemMovedZeroArgumentFlag);
-		assertFalse(target.itemMovedSingleArgumentFlag);
-		assertFalse(target.listClearedZeroArgumentFlag);
-		assertFalse(target.listClearedSingleArgumentFlag);
-		assertFalse(target.listChangedZeroArgumentFlag);
-		assertFalse(target.listChangedSingleArgumentFlag);
-	}
-
-	public void testItemAddedSingleArgumentNamedList() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
-		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
-		testModel.addString(string);
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertTrue(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.itemReplacedZeroArgumentFlag);
-		assertFalse(target.itemReplacedSingleArgumentFlag);
-		assertFalse(target.itemMovedZeroArgumentFlag);
-		assertFalse(target.itemMovedSingleArgumentFlag);
-		assertFalse(target.listClearedZeroArgumentFlag);
-		assertFalse(target.listClearedSingleArgumentFlag);
-		assertFalse(target.listChangedZeroArgumentFlag);
-		assertFalse(target.listChangedSingleArgumentFlag);
-	}
-
-	public void testItemRemovedZeroArgumentNamedList() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		testModel.addString(string);
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
-		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
-		testModel.removeString(string);
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertTrue(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.itemReplacedZeroArgumentFlag);
-		assertFalse(target.itemReplacedSingleArgumentFlag);
-		assertFalse(target.itemMovedZeroArgumentFlag);
-		assertFalse(target.itemMovedSingleArgumentFlag);
-		assertFalse(target.listClearedZeroArgumentFlag);
-		assertFalse(target.listClearedSingleArgumentFlag);
-		assertFalse(target.listChangedZeroArgumentFlag);
-		assertFalse(target.listChangedSingleArgumentFlag);
-	}
-
-	public void testItemRemovedSingleArgumentNamedList() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		testModel.addString(string);
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
-		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
-		testModel.removeString(string);
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertTrue(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.itemReplacedZeroArgumentFlag);
-		assertFalse(target.itemReplacedSingleArgumentFlag);
-		assertFalse(target.itemMovedZeroArgumentFlag);
-		assertFalse(target.itemMovedSingleArgumentFlag);
-		assertFalse(target.listClearedZeroArgumentFlag);
-		assertFalse(target.listClearedSingleArgumentFlag);
-		assertFalse(target.listChangedZeroArgumentFlag);
-		assertFalse(target.listChangedSingleArgumentFlag);
-	}
-
-	public void testItemReplacedZeroArgumentNamedList() {
-		TestModel testModel = new TestModel();
-		String oldString = "foo";
-		String newString = "bar";
-		testModel.addString(oldString);
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, newString, 0, oldString);
-		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
-		testModel.replaceString(oldString, newString);
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertTrue(target.itemReplacedZeroArgumentFlag);
-		assertFalse(target.itemReplacedSingleArgumentFlag);
-		assertFalse(target.itemMovedZeroArgumentFlag);
-		assertFalse(target.itemMovedSingleArgumentFlag);
-		assertFalse(target.listClearedZeroArgumentFlag);
-		assertFalse(target.listClearedSingleArgumentFlag);
-		assertFalse(target.listChangedZeroArgumentFlag);
-		assertFalse(target.listChangedSingleArgumentFlag);
-	}
-
-	public void testItemReplacedSingleArgumentNamedList() {
-		TestModel testModel = new TestModel();
-		String oldString = "foo";
-		String newString = "bar";
-		testModel.addString(oldString);
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, newString, 0, oldString);
-		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
-		testModel.replaceString(oldString, newString);
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.itemReplacedZeroArgumentFlag);
-		assertTrue(target.itemReplacedSingleArgumentFlag);
-		assertFalse(target.itemMovedZeroArgumentFlag);
-		assertFalse(target.itemMovedSingleArgumentFlag);
-		assertFalse(target.listClearedZeroArgumentFlag);
-		assertFalse(target.listClearedSingleArgumentFlag);
-		assertFalse(target.listChangedZeroArgumentFlag);
-		assertFalse(target.listChangedSingleArgumentFlag);
-	}
-
-	public void testItemMovedZeroArgumentNamedList() {
-		TestModel testModel = new TestModel();
-		testModel.addString("zero");
-		testModel.addString("one");
-		testModel.addString("two");
-		testModel.addString("three");
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, 0, 2);
-		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
-		testModel.moveString(0, 2);
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.itemReplacedZeroArgumentFlag);
-		assertFalse(target.itemReplacedSingleArgumentFlag);
-		assertTrue(target.itemMovedZeroArgumentFlag);
-		assertFalse(target.itemMovedSingleArgumentFlag);
-		assertFalse(target.listClearedZeroArgumentFlag);
-		assertFalse(target.listClearedSingleArgumentFlag);
-		assertFalse(target.listChangedZeroArgumentFlag);
-		assertFalse(target.listChangedSingleArgumentFlag);
-	}
-
-	public void testItemMovedSingleArgumentNamedList() {
-		TestModel testModel = new TestModel();
-		testModel.addString("zero");
-		testModel.addString("one");
-		testModel.addString("two");
-		testModel.addString("three");
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, 0, 2);
-		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
-		testModel.moveString(0, 2);
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.itemReplacedZeroArgumentFlag);
-		assertFalse(target.itemReplacedSingleArgumentFlag);
-		assertFalse(target.itemMovedZeroArgumentFlag);
-		assertTrue(target.itemMovedSingleArgumentFlag);
-		assertFalse(target.listClearedZeroArgumentFlag);
-		assertFalse(target.listClearedSingleArgumentFlag);
-		assertFalse(target.listChangedZeroArgumentFlag);
-		assertFalse(target.listChangedSingleArgumentFlag);
-	}
-
-	public void testListClearedZeroArgumentNamedList() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		testModel.addString(string);
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
-		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
-		testModel.clearStrings();
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.itemReplacedZeroArgumentFlag);
-		assertFalse(target.itemReplacedSingleArgumentFlag);
-		assertFalse(target.itemMovedZeroArgumentFlag);
-		assertFalse(target.itemMovedSingleArgumentFlag);
-		assertTrue(target.listClearedZeroArgumentFlag);
-		assertFalse(target.listClearedSingleArgumentFlag);
-		assertFalse(target.listChangedZeroArgumentFlag);
-		assertFalse(target.listChangedSingleArgumentFlag);
-	}
-
-	public void testListClearedSingleArgumentNamedList() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		testModel.addString(string);
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
-		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
-		testModel.clearStrings();
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.itemReplacedZeroArgumentFlag);
-		assertFalse(target.itemReplacedSingleArgumentFlag);
-		assertFalse(target.itemMovedZeroArgumentFlag);
-		assertFalse(target.itemMovedSingleArgumentFlag);
-		assertFalse(target.listClearedZeroArgumentFlag);
-		assertTrue(target.listClearedSingleArgumentFlag);
-		assertFalse(target.listChangedZeroArgumentFlag);
-		assertFalse(target.listChangedSingleArgumentFlag);
-	}
-
-	public void testListChangedZeroArgumentNamedList() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		testModel.addString(string);
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
-		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
-		testModel.replaceAllStrings(new String[] {"bar", "baz"});
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.itemReplacedZeroArgumentFlag);
-		assertFalse(target.itemReplacedSingleArgumentFlag);
-		assertFalse(target.itemMovedZeroArgumentFlag);
-		assertFalse(target.itemMovedSingleArgumentFlag);
-		assertFalse(target.listClearedZeroArgumentFlag);
-		assertFalse(target.listClearedSingleArgumentFlag);
-		assertTrue(target.listChangedZeroArgumentFlag);
-		assertFalse(target.listChangedSingleArgumentFlag);
-	}
-
-	public void testListChangedSingleArgumentNamedList() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		testModel.addString(string);
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
-		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
-		testModel.replaceAllStrings(new String[] {"bar", "baz"});
-		assertFalse(target.itemAddedZeroArgumentFlag);
-		assertFalse(target.itemAddedSingleArgumentFlag);
-		assertFalse(target.itemRemovedZeroArgumentFlag);
-		assertFalse(target.itemRemovedSingleArgumentFlag);
-		assertFalse(target.itemReplacedZeroArgumentFlag);
-		assertFalse(target.itemReplacedSingleArgumentFlag);
-		assertFalse(target.itemMovedZeroArgumentFlag);
-		assertFalse(target.itemMovedSingleArgumentFlag);
-		assertFalse(target.listClearedZeroArgumentFlag);
-		assertFalse(target.listClearedSingleArgumentFlag);
-		assertFalse(target.listChangedZeroArgumentFlag);
-		assertTrue(target.listChangedSingleArgumentFlag);
-	}
-
-	public void testBogusDoubleArgument1() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
-		boolean exCaught = false;
-		try {
-			ListChangeListener listener = ReflectiveChangeListener.buildListChangeListener(target, "listChangedDoubleArgument");
-			fail("bogus listener: " + listener);
-		} catch (RuntimeException ex) {
-			if (ex.getCause().getClass() == NoSuchMethodException.class) {
-				exCaught = true;
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testBogusDoubleArgument2() throws Exception {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
-		Method method = ReflectionTools.getMethod(target, "listChangedDoubleArgument", new Class[] {ListChangeEvent.class, Object.class});
-		boolean exCaught = false;
-		try {
-			ListChangeListener listener = ReflectiveChangeListener.buildListChangeListener(target, method);
-			fail("bogus listener: " + listener);
-		} catch (RuntimeException ex) {
-			if (ex.getMessage().equals(method.toString())) {
-				exCaught = true;
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testListenerMismatch() {
-		TestModel testModel = new TestModel();
-		String string = "foo";
-		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
-		// build a LIST change listener and hack it so we
-		// can add it as a COLLECTION change listener
-		Object listener = ReflectiveChangeListener.buildListChangeListener(target, "listEventSingleArgument");
-		testModel.addCollectionChangeListener("bogus collection", (CollectionChangeListener) listener);
-
-		boolean exCaught = false;
-		try {
-			testModel.changeCollection();
-			fail("listener mismatch: " + listener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-
-	class TestModel extends AbstractModel {
-		private List<String> strings = new ArrayList<String>();
-			public static final String STRINGS_LIST = "strings";
-		TestModel() {
-			super();
-		}
-		ListIterator<String> strings() {
-			return new CloneListIterator<String>(this.strings);
-		}
-		void addString(String string) {
-			this.addItemToList(string, this.strings, STRINGS_LIST);
-		}
-		void removeString(String string) {
-			this.removeItemFromList(this.strings.indexOf(string), this.strings, STRINGS_LIST);
-		}
-		void replaceString(String oldString, String newString) {
-			this.setItemInList(this.strings.indexOf(oldString), newString, this.strings, STRINGS_LIST);
-		}
-		void moveString(int targetIndex, int sourceIndex) {
-			this.moveItemInList(targetIndex, sourceIndex, this.strings, STRINGS_LIST);
-		}
-		void clearStrings() {
-			this.clearList(this.strings, STRINGS_LIST);
-		}
-		void replaceAllStrings(String[] newStrings) {
-			this.strings.clear();
-			CollectionTools.addAll(this.strings, newStrings);
-			this.fireListChanged(STRINGS_LIST, this.strings);
-		}
-		void changeCollection() {
-			this.fireCollectionChanged("bogus collection", Collections.emptySet());
-		}
-	}
-
-	class Target {
-		TestModel testModel;
-		String listName;
-		String string;
-		int index;
-		String replacedString;
-		int sourceIndex;
-		boolean itemAddedZeroArgumentFlag = false;
-		boolean itemAddedSingleArgumentFlag = false;
-		boolean itemRemovedZeroArgumentFlag = false;
-		boolean itemRemovedSingleArgumentFlag = false;
-		boolean itemReplacedZeroArgumentFlag = false;
-		boolean itemReplacedSingleArgumentFlag = false;
-		boolean itemMovedZeroArgumentFlag = false;
-		boolean itemMovedSingleArgumentFlag = false;
-		boolean listClearedZeroArgumentFlag = false;
-		boolean listClearedSingleArgumentFlag = false;
-		boolean listChangedZeroArgumentFlag = false;
-		boolean listChangedSingleArgumentFlag = false;
-		boolean listEventSingleArgumentFlag = false;
-		Target(TestModel testModel, String listName, String string, int index) {
-			super();
-			this.testModel = testModel;
-			this.listName = listName;
-			this.string = string;
-			this.index = index;
-		}
-		Target(TestModel testModel, String listName, String string, int index, String replacedString) {
-			this(testModel, listName, string, index);
-			this.replacedString = replacedString;
-		}
-		Target(TestModel testModel, String listName, int targetIndex, int sourceIndex) {
-			super();
-			this.testModel = testModel;
-			this.listName = listName;
-			this.index = targetIndex;
-			this.sourceIndex = sourceIndex;
-		}
-		void itemAddedZeroArgument() {
-			this.itemAddedZeroArgumentFlag = true;
-		}
-		void itemAddedSingleArgument(ListAddEvent e) {
-			this.itemAddedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.listName, e.getListName());
-			assertEquals(this.string, e.getItems().iterator().next());
-			assertEquals(this.index, e.getIndex());
-		}
-		void itemRemovedZeroArgument() {
-			this.itemRemovedZeroArgumentFlag = true;
-		}
-		void itemRemovedSingleArgument(ListRemoveEvent e) {
-			this.itemRemovedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.listName, e.getListName());
-			assertEquals(this.string, e.getItems().iterator().next());
-			assertEquals(this.index, e.getIndex());
-		}
-		void itemReplacedZeroArgument() {
-			this.itemReplacedZeroArgumentFlag = true;
-		}
-		void itemReplacedSingleArgument(ListReplaceEvent e) {
-			this.itemReplacedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.listName, e.getListName());
-			assertEquals(this.string, e.getNewItems().iterator().next());
-			assertEquals(this.replacedString, e.getOldItems().iterator().next());
-			assertEquals(this.index, e.getIndex());
-		}
-		void itemMovedZeroArgument() {
-			this.itemMovedZeroArgumentFlag = true;
-		}
-		void itemMovedSingleArgument(ListMoveEvent e) {
-			this.itemMovedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.listName, e.getListName());
-			assertEquals(this.index, e.getTargetIndex());
-			assertEquals(this.sourceIndex, e.getSourceIndex());
-		}
-		void listChangedZeroArgument() {
-			this.listChangedZeroArgumentFlag = true;
-		}
-		void listClearedSingleArgument(ListClearEvent e) {
-			this.listClearedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.listName, e.getListName());
-		}
-		void listClearedZeroArgument() {
-			this.listClearedZeroArgumentFlag = true;
-		}
-		void listChangedSingleArgument(ListChangeEvent e) {
-			this.listChangedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.listName, e.getListName());
-		}
-		void listChangedDoubleArgument(ListChangeEvent e, Object o) {
-			fail("bogus event: " + e + " - object: " + o);
-		}
-		void listEventSingleArgument(ListEvent e) {
-			this.listEventSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.listName, e.getListName());
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectivePropertyChangeListenerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectivePropertyChangeListenerTests.java
deleted file mode 100644
index fa49497..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectivePropertyChangeListenerTests.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.model.listener;
-
-import java.lang.reflect.Method;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.ReflectionTools;
-import org.eclipse.persistence.tools.utility.model.AbstractModel;
-import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
-import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.ReflectiveChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
-
-@SuppressWarnings("nls")
-public class ReflectivePropertyChangeListenerTests extends TestCase {
-
-	public ReflectivePropertyChangeListenerTests(String name) {
-		super(name);
-	}
-
-	public void testZeroArgumentNamedProperty() {
-		TestModel testModel = new TestModel(7);
-		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
-		testModel.addPropertyChangeListener(TestModel.VALUE_PROPERTY, ReflectiveChangeListener.buildPropertyChangeListener(target, "propertyChangedZeroArgument"));
-		testModel.setValue(99);
-		assertTrue(target.zeroArgumentFlag);
-		assertFalse(target.singleArgumentFlag);
-	}
-
-	/**
-	 * test method that has more general method parameter type
-	 */
-	public void testSingleArgument2() throws Exception {
-		TestModel testModel = new TestModel(7);
-		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
-		Method method = ReflectionTools.getMethod(target, "propertyChangedSingleArgument2", new Class[] {Object.class});
-		testModel.addPropertyChangeListener(TestModel.VALUE_PROPERTY, ReflectiveChangeListener.buildPropertyChangeListener(target, method));
-		testModel.setValue(99);
-		assertFalse(target.zeroArgumentFlag);
-		assertTrue(target.singleArgumentFlag);
-	}
-
-	public void testSingleArgumentNamedProperty() {
-		TestModel testModel = new TestModel(7);
-		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
-		testModel.addPropertyChangeListener(TestModel.VALUE_PROPERTY, ReflectiveChangeListener.buildPropertyChangeListener(target, "propertyChangedSingleArgument"));
-		testModel.setValue(99);
-		assertFalse(target.zeroArgumentFlag);
-		assertTrue(target.singleArgumentFlag);
-	}
-
-	/**
-	 * test method that has more general method parameter type
-	 */
-	public void testSingleArgumentNamedProperty2() throws Exception {
-		TestModel testModel = new TestModel(7);
-		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
-		Method method = ReflectionTools.getMethod(target, "propertyChangedSingleArgument2", new Class[] {Object.class});
-		testModel.addPropertyChangeListener(TestModel.VALUE_PROPERTY, ReflectiveChangeListener.buildPropertyChangeListener(target, method));
-		testModel.setValue(99);
-		assertFalse(target.zeroArgumentFlag);
-		assertTrue(target.singleArgumentFlag);
-	}
-
-	public void testListenerMismatch() {
-		TestModel testModel = new TestModel(7);
-		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
-		// build a PROPERTY change listener and hack it so we
-		// can add it as a STATE change listener
-		Object listener = ReflectiveChangeListener.buildPropertyChangeListener(target, "propertyChangedSingleArgument");
-		testModel.addStateChangeListener((StateChangeListener) listener);
-
-		boolean exCaught = false;
-		try {
-			testModel.setValue(99);
-			fail("listener mismatch: " + listener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testBogusDoubleArgument1() {
-		TestModel testModel = new TestModel(7);
-		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
-		boolean exCaught = false;
-		try {
-			PropertyChangeListener listener = ReflectiveChangeListener.buildPropertyChangeListener(target, "stateChangedDoubleArgument");
-			fail("bogus listener: " + listener);
-		} catch (RuntimeException ex) {
-			if (ex.getCause().getClass() == NoSuchMethodException.class) {
-				exCaught = true;
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testBogusDoubleArgument2() throws Exception {
-		TestModel testModel = new TestModel(7);
-		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
-		Method method = ReflectionTools.getMethod(target, "propertyChangedDoubleArgument", new Class[] {PropertyChangeEvent.class, Object.class});
-		boolean exCaught = false;
-		try {
-			PropertyChangeListener listener = ReflectiveChangeListener.buildPropertyChangeListener(target, method);
-			fail("bogus listener: " + listener);
-		} catch (RuntimeException ex) {
-			if (ex.getMessage().equals(method.toString())) {
-				exCaught = true;
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-
-	class TestModel extends AbstractModel {
-		private int value = 0;
-			public static final String VALUE_PROPERTY = "value";
-		TestModel(int value) {
-			super();
-			this.value = value;
-		}
-		void setValue(int value) {
-			int old = this.value;
-			this.value = value;
-			this.firePropertyChanged(VALUE_PROPERTY, old, value);
-			if (old != value) {
-				this.fireStateChanged();
-			}
-		}
-	}
-
-	class Target {
-		TestModel testModel;
-		String propertyName;
-		Object oldValue;
-		Object newValue;
-		boolean zeroArgumentFlag = false;
-		boolean singleArgumentFlag = false;
-		Target(TestModel testModel, String propertyName, int oldValue, int newValue) {
-			super();
-			this.testModel = testModel;
-			this.propertyName = propertyName;
-			this.oldValue = new Integer(oldValue);
-			this.newValue = new Integer(newValue);
-		}
-		void propertyChangedZeroArgument() {
-			this.zeroArgumentFlag = true;
-		}
-		void propertyChangedSingleArgument(PropertyChangeEvent e) {
-			this.singleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.propertyName, e.getPropertyName());
-			assertEquals(this.oldValue, e.getOldValue());
-			assertEquals(this.newValue, e.getNewValue());
-		}
-		void propertyChangedSingleArgument2(Object o) {
-			PropertyChangeEvent e = (PropertyChangeEvent) o;
-			this.singleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.propertyName, e.getPropertyName());
-			assertEquals(this.oldValue, e.getOldValue());
-			assertEquals(this.newValue, e.getNewValue());
-		}
-		void propertyChangedDoubleArgument(PropertyChangeEvent e, Object o) {
-			fail("bogus event: " + e + " - object: " + o);
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectiveStateChangeListenerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectiveStateChangeListenerTests.java
deleted file mode 100644
index 70bcee8..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectiveStateChangeListenerTests.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.model.listener;
-
-import java.lang.reflect.Method;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.ReflectionTools;
-import org.eclipse.persistence.tools.utility.model.AbstractModel;
-import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
-import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.ReflectiveChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
-
-@SuppressWarnings("nls")
-public class ReflectiveStateChangeListenerTests extends TestCase {
-
-	public ReflectiveStateChangeListenerTests(String name) {
-		super(name);
-	}
-
-	public void testZeroArgument() {
-		TestModel testModel = new TestModel();
-		Target target = new Target(testModel);
-		testModel.addStateChangeListener(ReflectiveChangeListener.buildStateChangeListener(target, "stateChangedZeroArgument"));
-		testModel.changeState();
-		assertTrue(target.zeroArgumentFlag);
-		assertFalse(target.singleArgumentFlag);
-	}
-
-	public void testSingleArgument() {
-		TestModel testModel = new TestModel();
-		Target target = new Target(testModel);
-		testModel.addStateChangeListener(ReflectiveChangeListener.buildStateChangeListener(target, "stateChangedSingleArgument"));
-		testModel.changeState();
-		assertFalse(target.zeroArgumentFlag);
-		assertTrue(target.singleArgumentFlag);
-	}
-
-	/**
-	 * test method that has more general method parameter type
-	 */
-	public void testSingleArgument2() throws Exception {
-		TestModel testModel = new TestModel();
-		Target target = new Target(testModel);
-		Method method = ReflectionTools.getMethod(target, "stateChangedSingleArgument2", new Class[] {Object.class});
-		testModel.addStateChangeListener(ReflectiveChangeListener.buildStateChangeListener(target, method));
-		testModel.changeState();
-		assertFalse(target.zeroArgumentFlag);
-		assertTrue(target.singleArgumentFlag);
-	}
-
-	public void testListenerMismatch() {
-		TestModel testModel = new TestModel();
-		Target target = new Target(testModel);
-		// build a STATE change listener and hack it so we
-		// can add it as a PROPERTY change listener
-		Object listener = ReflectiveChangeListener.buildStateChangeListener(target, "stateChangedSingleArgument");
-		testModel.addPropertyChangeListener("value", (PropertyChangeListener) listener);
-
-		boolean exCaught = false;
-		try {
-			testModel.changeProperty();
-			fail("listener mismatch: " + listener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testBogusDoubleArgument1() {
-		TestModel testModel = new TestModel();
-		Target target = new Target(testModel);
-		boolean exCaught = false;
-		try {
-			StateChangeListener listener = ReflectiveChangeListener.buildStateChangeListener(target, "stateChangedDoubleArgument");
-			fail("bogus listener: " + listener);
-		} catch (RuntimeException ex) {
-			if (ex.getCause().getClass() == NoSuchMethodException.class) {
-				exCaught = true;
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-	public void testBogusDoubleArgument2() throws Exception {
-		TestModel testModel = new TestModel();
-		Target target = new Target(testModel);
-		Method method = ReflectionTools.getMethod(target, "stateChangedDoubleArgument", new Class[] {StateChangeEvent.class, Object.class});
-		boolean exCaught = false;
-		try {
-			StateChangeListener listener = ReflectiveChangeListener.buildStateChangeListener(target, method);
-			fail("bogus listener: " + listener);
-		} catch (RuntimeException ex) {
-			if (ex.getMessage().equals(method.toString())) {
-				exCaught = true;
-			}
-		}
-		assertTrue(exCaught);
-	}
-
-
-	class TestModel extends AbstractModel {
-		TestModel() {
-			super();
-		}
-		void changeState() {
-			this.fireStateChanged();
-		}
-		void changeProperty() {
-			this.firePropertyChanged("value", 55, 42);
-		}
-	}
-
-	class Target {
-		TestModel testModel;
-		boolean zeroArgumentFlag = false;
-		boolean singleArgumentFlag = false;
-		Target(TestModel testModel) {
-			super();
-			this.testModel = testModel;
-		}
-		void stateChangedZeroArgument() {
-			this.zeroArgumentFlag = true;
-		}
-		void stateChangedSingleArgument(StateChangeEvent e) {
-			this.singleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-		}
-		void stateChangedSingleArgument2(Object e) {
-			this.singleArgumentFlag = true;
-			assertSame(this.testModel, ((StateChangeEvent) e).getSource());
-		}
-		void stateChangedDoubleArgument(StateChangeEvent e, Object o) {
-			fail("bogus event: " + e + " - object: " + o);
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectiveTreeChangeListenerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectiveTreeChangeListenerTests.java
deleted file mode 100644
index 4bb695f..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/model/listener/ReflectiveTreeChangeListenerTests.java
+++ /dev/null
@@ -1,364 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.model.listener;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.model.AbstractModel;
-import org.eclipse.persistence.tools.utility.model.event.TreeAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeRemoveEvent;
-import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.ReflectiveChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.TreeChangeListener;
-
-@SuppressWarnings("nls")
-public class ReflectiveTreeChangeListenerTests extends TestCase {
-	
-	public ReflectiveTreeChangeListenerTests(String name) {
-		super(name);
-	}
-
-	private TreeChangeListener buildZeroArgumentListener(Object target) {
-		return ReflectiveChangeListener.buildTreeChangeListener(target, "nodeAddedZeroArgument", "nodeRemovedZeroArgument", "treeClearedZeroArgument", "treeChangedZeroArgument");
-	}
-
-	private TreeChangeListener buildSingleArgumentListener(Object target) {
-		return ReflectiveChangeListener.buildTreeChangeListener(target, "nodeAddedSingleArgument", "nodeRemovedSingleArgument", "treeClearedSingleArgument", "treeChangedSingleArgument");
-	}
-
-	public void testNodeAddedZeroArgumentNamedTree() {
-		TestModel testModel = new TestModel("root");
-		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
-		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildZeroArgumentListener(target));
-		testModel.addNode("root", "child");
-		assertTrue(target.nodeAddedZeroArgumentFlag);
-		assertFalse(target.nodeAddedSingleArgumentFlag);
-		assertFalse(target.nodeRemovedZeroArgumentFlag);
-		assertFalse(target.nodeRemovedSingleArgumentFlag);
-		assertFalse(target.treeClearedZeroArgumentFlag);
-		assertFalse(target.treeClearedSingleArgumentFlag);
-		assertFalse(target.treeChangedZeroArgumentFlag);
-		assertFalse(target.treeChangedSingleArgumentFlag);
-	}
-
-	public void testNodeAddedSingleArgumentNamedTree() {
-		TestModel testModel = new TestModel("root");
-		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
-		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildSingleArgumentListener(target));
-		testModel.addNode("root", "child");
-		assertFalse(target.nodeAddedZeroArgumentFlag);
-		assertTrue(target.nodeAddedSingleArgumentFlag);
-		assertFalse(target.nodeRemovedZeroArgumentFlag);
-		assertFalse(target.nodeRemovedSingleArgumentFlag);
-		assertFalse(target.treeClearedZeroArgumentFlag);
-		assertFalse(target.treeClearedSingleArgumentFlag);
-		assertFalse(target.treeChangedZeroArgumentFlag);
-		assertFalse(target.treeChangedSingleArgumentFlag);
-	}
-
-	public void testNodeRemovedZeroArgumentNamedTree() {
-		TestModel testModel = new TestModel("root");
-		testModel.addNode("root", "child");
-		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
-		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildZeroArgumentListener(target));
-		testModel.removeNode("child");
-		assertFalse(target.nodeAddedZeroArgumentFlag);
-		assertFalse(target.nodeAddedSingleArgumentFlag);
-		assertTrue(target.nodeRemovedZeroArgumentFlag);
-		assertFalse(target.nodeRemovedSingleArgumentFlag);
-		assertFalse(target.treeClearedZeroArgumentFlag);
-		assertFalse(target.treeClearedSingleArgumentFlag);
-		assertFalse(target.treeChangedZeroArgumentFlag);
-		assertFalse(target.treeChangedSingleArgumentFlag);
-	}
-
-	public void testNodeRemovedSingleArgumentNamedTree() {
-		TestModel testModel = new TestModel("root");
-		testModel.addNode("root", "child");
-		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
-		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildSingleArgumentListener(target));
-		testModel.removeNode("child");
-		assertFalse(target.nodeAddedZeroArgumentFlag);
-		assertFalse(target.nodeAddedSingleArgumentFlag);
-		assertFalse(target.nodeRemovedZeroArgumentFlag);
-		assertTrue(target.nodeRemovedSingleArgumentFlag);
-		assertFalse(target.treeClearedZeroArgumentFlag);
-		assertFalse(target.treeClearedSingleArgumentFlag);
-		assertFalse(target.treeChangedZeroArgumentFlag);
-		assertFalse(target.treeChangedSingleArgumentFlag);
-	}
-
-	public void testTreeClearedZeroArgumentNamedTree() {
-		TestModel testModel = new TestModel("root");
-		testModel.addNode("root", "child");
-		testModel.addNode("child", "grandchild");
-		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[0]);
-		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildZeroArgumentListener(target));
-		testModel.clearTree();
-		assertFalse(target.nodeAddedZeroArgumentFlag);
-		assertFalse(target.nodeAddedSingleArgumentFlag);
-		assertFalse(target.nodeRemovedZeroArgumentFlag);
-		assertFalse(target.nodeRemovedSingleArgumentFlag);
-		assertTrue(target.treeClearedZeroArgumentFlag);
-		assertFalse(target.treeClearedSingleArgumentFlag);
-		assertFalse(target.treeChangedZeroArgumentFlag);
-		assertFalse(target.treeChangedSingleArgumentFlag);
-	}
-
-	public void testTreeClearedSingleArgumentNamedTree() {
-		TestModel testModel = new TestModel("root");
-		testModel.addNode("root", "child");
-		testModel.addNode("child", "grandchild");
-		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[0]);
-		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildSingleArgumentListener(target));
-		testModel.clearTree();
-		assertFalse(target.nodeAddedZeroArgumentFlag);
-		assertFalse(target.nodeAddedSingleArgumentFlag);
-		assertFalse(target.nodeRemovedZeroArgumentFlag);
-		assertFalse(target.nodeRemovedSingleArgumentFlag);
-		assertFalse(target.treeClearedZeroArgumentFlag);
-		assertTrue(target.treeClearedSingleArgumentFlag);
-		assertFalse(target.treeChangedZeroArgumentFlag);
-		assertFalse(target.treeChangedSingleArgumentFlag);
-	}
-
-	public void testTreeChangedZeroArgumentNamedTree() {
-		TestModel testModel = new TestModel("root");
-		testModel.addNode("root", "child");
-		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "another child"});
-		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildZeroArgumentListener(target));
-		testModel.replaceNode("child", "another child");
-		assertFalse(target.nodeAddedZeroArgumentFlag);
-		assertFalse(target.nodeAddedSingleArgumentFlag);
-		assertFalse(target.nodeRemovedZeroArgumentFlag);
-		assertFalse(target.nodeRemovedSingleArgumentFlag);
-		assertFalse(target.treeClearedZeroArgumentFlag);
-		assertFalse(target.treeClearedSingleArgumentFlag);
-		assertTrue(target.treeChangedZeroArgumentFlag);
-		assertFalse(target.treeChangedSingleArgumentFlag);
-	}
-
-	public void testTreeChangedSingleArgumentNamedTree() {
-		TestModel testModel = new TestModel("root");
-		testModel.addNode("root", "child");
-		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "another child"});
-		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildSingleArgumentListener(target));
-		testModel.replaceNode("child", "another child");
-		assertFalse(target.nodeAddedZeroArgumentFlag);
-		assertFalse(target.nodeAddedSingleArgumentFlag);
-		assertFalse(target.nodeRemovedZeroArgumentFlag);
-		assertFalse(target.nodeRemovedSingleArgumentFlag);
-		assertFalse(target.treeClearedZeroArgumentFlag);
-		assertFalse(target.treeClearedSingleArgumentFlag);
-		assertFalse(target.treeChangedZeroArgumentFlag);
-		assertTrue(target.treeChangedSingleArgumentFlag);
-	}
-
-	public void testListenerMismatch() {
-		TestModel testModel = new TestModel("root");
-		testModel.addNode("root", "child");
-		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
-		// build a TREE change listener and hack it so we
-		// can add it as a COLLECTION change listener
-		Object listener = ReflectiveChangeListener.buildTreeChangeListener(target, "treeEventSingleArgument");
-		testModel.addCollectionChangeListener("bogus collection", (CollectionChangeListener) listener);
-
-		boolean exCaught = false;
-		try {
-			testModel.changeCollection();
-			fail("listener mismatch: " + listener);
-		} catch (IllegalArgumentException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-	}
-
-
-	class TestModel extends AbstractModel {
-		private final String root;
-		private Map<String, Collection<String>> childrenLists = new HashMap<String, Collection<String>>();
-		private Map<String, String> parents = new HashMap<String, String>();
-			public static final String STRINGS_TREE = "strings";
-		TestModel(String root) {
-			super();
-			if (root == null) {
-				throw new NullPointerException();
-			}
-			this.root = root;
-			this.childrenLists.put(root, new ArrayList<String>());
-			this.parents.put(root, null);
-		}
-		String getRoot() {
-			return this.root;
-		}
-		private List<String> path(String node) {
-			String temp = node;
-			List<String> reversePath = new ArrayList<String>();
-			do {
-				reversePath.add(temp);
-				temp = this.parents.get(temp);
-			} while (temp != null);
-			return CollectionTools.reverse(reversePath);
-		}
-		Iterator<String> strings() {
-			return new CloneIterator<String>(this.childrenLists.keySet()) {
-				@Override
-				protected void remove(String s) {
-					TestModel.this.removeNode(s);
-				}
-			};
-		}
-		void addNode(String parent, String child) {
-			if ((parent == null) || (child == null)) {
-				throw new NullPointerException();
-			}
-
-			Collection<String> children = this.childrenLists.get(parent);
-			if (children == null) {
-				throw new IllegalStateException("cannot add a child to a non-existent parent");
-			}
-
-			if (this.childrenLists.get(child) != null) {
-				throw new IllegalStateException("cannot add a child that is already in the tree");
-			}
-			
-			children.add(child);
-			this.childrenLists.put(child, new ArrayList<String>());
-			this.parents.put(child, parent);
-			this.fireNodeAdded(STRINGS_TREE, this.path(child));
-		}
-		void removeNode(String node) {
-			if (node == null) {
-				throw new NullPointerException();
-			}
-
-			Collection<String> children = this.childrenLists.get(node);
-			if (children == null) {
-				throw new IllegalStateException("node is not in tree");
-			}
-			List<String> path = this.path(node);
-			for (String s : children) {
-				this.removeNode(s);
-			}
-			this.childrenLists.remove(node);
-			this.parents.remove(node);
-			this.fireNodeRemoved(STRINGS_TREE, path);
-		}
-		void replaceNode(String oldNode, String newNode) {
-			if ((oldNode == null) || (newNode == null)) {
-				throw new NullPointerException();
-			}
-
-			Collection<String> children = this.childrenLists.remove(oldNode);
-			if (children == null) {
-				throw new IllegalStateException("old node is not in tree");
-			}
-			this.childrenLists.put(newNode, children);
-			for (String child : children) {
-				this.parents.put(child, newNode);
-			}
-
-			String parent = this.parents.remove(oldNode);
-			this.parents.put(newNode, parent);
-
-			this.fireTreeChanged(STRINGS_TREE, this.path(newNode));
-		}
-		void clearTree() {
-			this.childrenLists.clear();
-			this.childrenLists.put(root, new ArrayList<String>());
-			this.parents.clear();
-			this.parents.put(root, null);
-			this.fireTreeCleared(STRINGS_TREE);
-		}
-		void changeCollection() {
-			this.fireCollectionChanged("bogus collection", Collections.emptySet());
-		}
-	}
-
-	class Target {
-		TestModel testModel;
-		String treeName;
-		List<String> path;
-		boolean nodeAddedZeroArgumentFlag = false;
-		boolean nodeAddedSingleArgumentFlag = false;
-		boolean nodeRemovedZeroArgumentFlag = false;
-		boolean nodeRemovedSingleArgumentFlag = false;
-		boolean treeClearedZeroArgumentFlag = false;
-		boolean treeClearedSingleArgumentFlag = false;
-		boolean treeChangedZeroArgumentFlag = false;
-		boolean treeChangedSingleArgumentFlag = false;
-		boolean treeEventSingleArgumentFlag = false;
-		Target(TestModel testModel, String treeName, String[] path) {
-			super();
-			this.testModel = testModel;
-			this.treeName = treeName;
-			this.path = Arrays.asList(path);
-		}
-		void nodeAddedZeroArgument() {
-			this.nodeAddedZeroArgumentFlag = true;
-		}
-		void nodeAddedSingleArgument(TreeAddEvent e) {
-			this.nodeAddedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.treeName, e.getTreeName());
-			assertEquals(this.path, CollectionTools.list(e.getPath()));
-		}
-		void nodeRemovedZeroArgument() {
-			this.nodeRemovedZeroArgumentFlag = true;
-		}
-		void nodeRemovedSingleArgument(TreeRemoveEvent e) {
-			this.nodeRemovedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.treeName, e.getTreeName());
-			assertEquals(this.path, CollectionTools.list(e.getPath()));
-		}
-		void treeClearedZeroArgument() {
-			this.treeClearedZeroArgumentFlag = true;
-		}
-		void treeClearedSingleArgument(TreeClearEvent e) {
-			this.treeClearedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.treeName, e.getTreeName());
-		}
-		void treeChangedZeroArgument() {
-			this.treeChangedZeroArgumentFlag = true;
-		}
-		void treeChangedSingleArgument(TreeChangeEvent e) {
-			this.treeChangedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.treeName, e.getTreeName());
-		}
-		void treeEventSingleArgument(TreeEvent e) {
-			this.treeChangedSingleArgumentFlag = true;
-			assertSame(this.testModel, e.getSource());
-			assertEquals(this.treeName, e.getTreeName());
-		}
-		void collectionChangedDoubleArgument(TreeChangeEvent e, Object o) {
-			fail("bogus event: " + e + " - object: " + o);
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/node/AbstractNodeTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/node/AbstractNodeTests.java
deleted file mode 100644
index c0be392..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/node/AbstractNodeTests.java
+++ /dev/null
@@ -1,495 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.node;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import junit.framework.TestCase;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.HashBag;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.node.AbstractNode;
-import org.eclipse.persistence.tools.utility.node.Node;
-import org.eclipse.persistence.tools.utility.node.Problem;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-
-@SuppressWarnings("nls")
-public class AbstractNodeTests extends TestCase {
-	private TestWorkbenchModel root;
-
-	public AbstractNodeTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.root = this.buildRoot();
-	}
-
-	private TestWorkbenchModel buildRoot() {
-		TestWorkbenchModel r = new RootTestWorkbenchModel("root");
-			TestWorkbenchModel node1 = r.addTestChildNamed("node 1");
-				TestWorkbenchModel node1_1 = node1.addTestChildNamed("node 1.1");
-					node1_1.addTestChildNamed("node 1.1.1");
-					node1_1.addTestChildNamed("node 1.1.2");
-					node1_1.addTestChildNamed("node 1.1.3");
-				node1.addTestChildNamed("node 1.2");
-			TestWorkbenchModel node2 = r.addTestChildNamed("node 2");
-				node2.addTestChildNamed("node 2.1");
-				node2.addTestChildNamed("node 2.2");
-			r.addTestChildNamed("node 3");
-			r.addTestChildNamed("node 4");
-
-		// mark the entire tree clean
-		r.markEntireBranchClean();
-		return r;
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		TestTools.clear(this);
-		super.tearDown();
-	}
-
-	public void testTestWorkbenchModel() {
-		// make sure our test class works OK...
-		assertNull(this.root.testChildNamed(""));
-		assertNotNull(this.root.testChildNamed("node 1"));
-		assertTrue(this.root.testChildNamed("node 1").isClean());
-		assertTrue(this.root.testChildNamed("node 1").isCleanBranch());
-		assertNotNull(this.root.testChildNamed("node 2"));
-		assertTrue(this.root.testChildNamed("node 2").isClean());
-		assertTrue(this.root.testChildNamed("node 2").isCleanBranch());
-		assertNull(this.root.testChildNamed("node 2.1"));
-
-		assertNull(this.root.testDescendantNamed(""));
-		assertNotNull(this.root.testDescendantNamed("node 1"));
-		assertNotNull(this.root.testDescendantNamed("node 2"));
-		assertNotNull(this.root.testDescendantNamed("node 2.1"));
-		assertTrue(this.root.testDescendantNamed("node 2.1").isClean());
-		assertTrue(this.root.testDescendantNamed("node 2.1").isCleanBranch());
-		assertNotNull(this.root.testDescendantNamed("node 1.1.3"));
-		assertTrue(this.root.testDescendantNamed("node 1.1.3").isClean());
-		assertTrue(this.root.testDescendantNamed("node 1.1.3").isCleanBranch());
-	}
-
-	public void testParentAndChildren() {
-		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
-		assertEquals("node 1.1.3", node.getName());
-		assertEquals(0, CollectionTools.size(node.children()));
-
-		node = (TestWorkbenchModel) node.getParent();
-		assertEquals("node 1.1", node.getName());
-		assertEquals(3, CollectionTools.size(node.children()));
-
-		node = (TestWorkbenchModel) node.getParent();
-		assertEquals("node 1", node.getName());
-		assertEquals(2, CollectionTools.size(node.children()));
-
-		node = (TestWorkbenchModel) node.getParent();
-		assertEquals("root", node.getName());
-		assertEquals(4, CollectionTools.size(node.children()));
-
-		node = (TestWorkbenchModel) node.getParent();
-		assertNull(node);
-	}
-
-	public void testDirty() {
-		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
-		node.setSize(42);
-		assertTrue(node.isDirty());
-
-		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
-		assertTrue(parent.isClean());
-		assertTrue(this.root.isClean());
-	}
-
-	public void testDirtyUnchangedAttribute() {
-		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
-		node.setSize(42);
-		assertTrue(node.isDirty());
-
-		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
-		assertTrue(parent.isClean());
-		assertTrue(this.root.isClean());
-
-		this.root.markEntireBranchClean();
-		// set size to same number - should stay clean
-		node.setSize(42);
-		assertTrue(node.isClean());
-		assertTrue(parent.isClean());
-		assertTrue(this.root.isClean());
-	}
-
-	public void testDirtyBranch() {
-		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
-		node.setSize(42);
-		assertTrue(node.isDirtyBranch());
-
-		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
-		assertTrue(parent.isDirtyBranch());
-		assertTrue(this.root.isDirtyBranch());
-
-		parent.setSize(77);
-		assertTrue(parent.isDirty());
-		assertTrue(parent.isDirtyBranch());
-
-		node.markEntireBranchClean();
-		assertTrue(parent.isDirty());
-		assertTrue(parent.isDirtyBranch());
-	}
-
-	public void testDirtyBranchCleanChildDirtyParent() {
-		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
-		node.setSize(42);
-
-		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
-		parent.setSize(77);
-		assertTrue(parent.isDirty());
-		assertTrue(parent.isDirtyBranch());
-
-		// now, clean the child, but leave the parent dirty
-		node.markEntireBranchClean();
-		assertTrue(parent.isDirty());
-		assertTrue(parent.isDirtyBranch());
-	}
-
-	public void testDirtyBranchCleanChildDirtyChild() {
-		TestWorkbenchModel node1 = this.root.testDescendantNamed("node 1.1.1");
-		node1.setSize(41);
-		TestWorkbenchModel node2 = this.root.testDescendantNamed("node 1.1.2");
-		node2.setSize(42);
-
-		TestWorkbenchModel parent = (TestWorkbenchModel) node1.getParent();
-		assertTrue(parent.isClean());
-		assertTrue(parent.isDirtyBranch());
-
-		// now, clean the first child, but leave the second child dirty
-		node1.markEntireBranchClean();
-		assertTrue(parent.isClean());
-		assertTrue(parent.isDirtyBranch());
-	}
-
-	public void testDirtyBranchForced() {
-		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
-		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
-
-		assertTrue(node.isClean());
-		assertTrue(node.isCleanBranch());
-		assertTrue(parent.isClean());
-		assertTrue(parent.isCleanBranch());
-		assertTrue(this.root.isClean());
-		assertTrue(this.root.isCleanBranch());
-
-		this.root.markEntireBranchDirty();
-
-		assertTrue(node.isDirty());
-		assertTrue(node.isDirtyBranch());
-		assertTrue(parent.isDirty());
-		assertTrue(parent.isDirtyBranch());
-		assertTrue(this.root.isDirty());
-		assertTrue(this.root.isDirtyBranch());
-	}
-
-	public void testDirtyTransientAttribute() {
-		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
-		node.setName("BOGUS");
-		assertTrue(node.isDirty());
-		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
-		assertTrue(parent.isClean());
-		assertTrue(parent.isDirtyBranch());
-		assertTrue(this.root.isClean());
-		assertTrue(this.root.isDirtyBranch());
-
-		this.root.markEntireBranchClean();
-
-		this.root.validateBranch();
-
-		assertTrue(this.root.problemsSize() == 0);
-		assertTrue(node.branchProblems().hasNext());
-		assertTrue(parent.problemsSize() == 0);
-		assertTrue(parent.branchProblems().hasNext());
-		assertTrue(node.problemsSize() > 0);
-
-		// since problems are transient, everything should still be clean
-		assertTrue(node.isClean());
-		assertTrue(node.isCleanBranch());
-		assertTrue(parent.isClean());
-		assertTrue(parent.isCleanBranch());
-		assertTrue(this.root.isClean());
-		assertTrue(this.root.isCleanBranch());
-	}
-
-	public void testProblems() {
-		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
-		node.setName("BOGUS");
-		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
-
-		this.root.validateBranch();
-
-		assertEquals(0, this.root.problemsSize());
-		assertTrue(node.branchProblems().hasNext());
-		assertEquals(0, parent.problemsSize());
-		assertTrue(parent.branchProblems().hasNext());
-		assertEquals(1, node.problemsSize());
-		Problem problem1 = node.problems().next();
-
-		// now create another problem that should remove the old problem
-		node.setName("STILL BOGUS");
-		this.root.validateBranch();
-
-		assertEquals(0, this.root.problemsSize());
-		assertTrue(node.branchProblems().hasNext());
-		assertEquals(0, parent.problemsSize());
-		assertTrue(parent.branchProblems().hasNext());
-		assertEquals(1, node.problemsSize());
-		Problem problem2 = node.problems().next();
-		assertFalse(problem1 == problem2);
-		problem1 = problem2;
-
-		// now create another problem that should replace the old problem
-		node.setName("STILL BOGUS");
-		this.root.validateBranch();
-
-		assertEquals(0, this.root.problemsSize());
-		assertTrue(node.branchProblems().hasNext());
-		assertEquals(0, parent.problemsSize());
-		assertTrue(parent.branchProblems().hasNext());
-		assertEquals(1, node.problemsSize());
-		problem2 = node.problems().next();
-		// the same problem should be there
-		assertTrue(problem1.equals(problem2));
-	}
-
-	public void testBranchProblems() {
-		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
-		node.setName("BOGUS");
-		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
-		parent.setName("BOGUS TOO");
-		this.root.setName("BOGUS TOO TOO");
-
-		this.root.validateBranch();
-
-		assertEquals(1, this.root.problemsSize());
-		assertEquals(3, this.root.branchProblemsSize());
-		assertEquals(1, parent.problemsSize());
-		assertEquals(2, parent.branchProblemsSize());
-		assertEquals(1, node.problemsSize());
-		assertEquals(1, node.branchProblemsSize());
-
-		node.setName("okie-dokie");
-
-		this.root.validateBranch();
-
-		assertEquals(1, this.root.problemsSize());
-		assertEquals(2, this.root.branchProblemsSize());
-		assertEquals(1, parent.problemsSize());
-		assertEquals(1, parent.branchProblemsSize());
-		assertEquals(0, node.problemsSize());
-		assertEquals(0, node.branchProblemsSize());
-	}
-
-	public void testClearAllBranchProblems() {
-		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
-		node.setName("BOGUS");
-		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
-		parent.setName("BOGUS TOO");
-		this.root.setName("BOGUS TOO TOO");
-
-		this.root.validateBranch();
-
-		assertEquals(1, this.root.problemsSize());
-		assertEquals(3, this.root.branchProblemsSize());
-		assertEquals(1, parent.problemsSize());
-		assertEquals(2, parent.branchProblemsSize());
-		assertEquals(1, node.problemsSize());
-		assertEquals(1, node.branchProblemsSize());
-
-		parent.clearAllBranchProblems();
-
-		assertEquals(1, this.root.problemsSize());
-		assertEquals(1, this.root.branchProblemsSize());
-		assertEquals(0, parent.problemsSize());
-		assertEquals(0, parent.branchProblemsSize());
-		assertEquals(0, node.problemsSize());
-		assertEquals(0, CollectionTools.size(node.branchProblems()));
-	}
-
-	public void testRemovedBranchProblems() {
-		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
-		node.setName("BOGUS");
-		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
-		parent.setName("BOGUS TOO");
-		this.root.setName("BOGUS TOO TOO");
-
-		this.root.validateBranch();
-
-		assertEquals(1, this.root.problemsSize());
-		assertEquals(3, CollectionTools.size(this.root.branchProblems()));
-		assertEquals(1, parent.problemsSize());
-		assertEquals(2, parent.branchProblemsSize());
-		assertEquals(1, node.problemsSize());
-		assertEquals(1, CollectionTools.size(node.branchProblems()));
-
-		// completely remove a node that has problems -
-		// the entire tree should recalculate its "branch" problems
-		parent.removeTestChild(node);
-
-		this.root.validateBranch();
-
-		assertEquals(1, this.root.problemsSize());
-		assertEquals(2, CollectionTools.size(this.root.branchProblems()));
-		assertEquals(1, parent.problemsSize());
-		assertEquals(1, parent.branchProblemsSize());
-	}
-
-
-	// ********** inner classes **********
-
-	public class TestWorkbenchModel extends AbstractNode {
-		private String name;
-			public static final String NAME_PROPERTY = "name";
-		private int size;
-			public static final String SIZE_PROPERTY = "size";
-		private Collection<TestWorkbenchModel> testChildren;
-			public static final String TEST_CHILDREN_COLLECTION = "children";
-
-		// ********** construction/initialization **********
-		public TestWorkbenchModel(TestWorkbenchModel parent, String name) {
-			super(parent);
-			if (name == null) {
-				throw new NullPointerException();
-			}
-			this.name = name;
-		}
-		@Override
-		protected void initialize() {
-			super.initialize();
-			this.size = 0;
-			this.testChildren = new HashBag<TestWorkbenchModel>();
-		}
-
-		@Override
-		protected void checkParent(Node parent) {
-			// do nothing
-		}
-
-
-		// ********** accessors **********
-		public String getName() {
-			return this.name;
-		}
-		public void setName(String name) {
-			Object old = this.name;
-			this.name = name;
-			this.firePropertyChanged(NAME_PROPERTY, old, name);
-		}
-
-		public int getSize() {
-			return this.size;
-		}
-		public void setSize(int size) {
-			int old = this.size;
-			this.size = size;
-			this.firePropertyChanged(SIZE_PROPERTY, old, size);
-		}
-
-		public Iterator<TestWorkbenchModel> testChildren() {
-			return new CloneIterator<TestWorkbenchModel>(this.testChildren) {
-				@Override
-				protected void remove(TestWorkbenchModel current) {
-					TestWorkbenchModel.this.removeTestChild(current);
-				}
-			};
-		}
-		public int testChildrenSize() {
-			return this.testChildren.size();
-		}
-		private TestWorkbenchModel addTestChild(TestWorkbenchModel testChild) {
-			this.addItemToCollection(testChild, this.testChildren, TEST_CHILDREN_COLLECTION);
-			return testChild;
-		}
-		public TestWorkbenchModel addTestChildNamed(String childName) {
-			if (this.testChildNamed(childName) != null) {
-				throw new IllegalArgumentException(childName);
-			}
-			return this.addTestChild(new TestWorkbenchModel(this, childName));
-		}
-		public void removeTestChild(TestWorkbenchModel testChild) {
-			this.removeItemFromCollection(testChild, this.testChildren, TEST_CHILDREN_COLLECTION);
-		}
-
-		// ********** queries **********
-		public String displayString() {
-			return this.name;
-		}
-		public TestWorkbenchModel testChildNamed(String childName) {
-			for (TestWorkbenchModel testChild : this.testChildren) {
-				if (testChild.getName().equals(childName)) {
-					return testChild;
-				}
-			}
-			return null;
-		}
-		public TestWorkbenchModel testDescendantNamed(String descendantName) {
-			for (TestWorkbenchModel testDescendant : this.testChildren) {
-				if (testDescendant.getName().equals(descendantName)) {
-					return testDescendant;
-				}
-				// recurse...
-				testDescendant = testDescendant.testDescendantNamed(descendantName);
-				if (testDescendant != null) {
-					return testDescendant;
-				}
-			}
-			return null;
-		}
-
-		// ********** behavior **********
-		@Override
-		protected void addChildrenTo(List<Node> children) {
-			super.addChildrenTo(children);
-			children.addAll(this.testChildren);
-		}
-		@Override
-		protected void addProblemsTo(List<Problem> currentProblems) {
-			super.addProblemsTo(currentProblems);
-			// names must be all lowercase...
-			for (int i = this.name.length(); i-- > 0; ) {
-				char c = this.name.charAt(i);
-				if (Character.isLetter(c) && ! Character.isLowerCase(c)) {
-					currentProblems.add(this.buildProblem("NAME_MUST_BE_LOWERCASE", 3 ,this.name));
-					return;
-				}
-			}
-		}
-		@Override
-		public void toString(StringBuilder sb) {
-			sb.append(this.name);
-		}
-	}
-
-
-	private class RootTestWorkbenchModel extends TestWorkbenchModel {
-		public RootTestWorkbenchModel(String name) {
-			super(null, name);
-		}
-		@Override
-		public Validator getValidator() {
-			return Node.NULL_VALIDATOR;
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/node/UtilityNodeTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/node/UtilityNodeTests.java
deleted file mode 100644
index 5707cbc..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/node/UtilityNodeTests.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.node;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class UtilityNodeTests {
-	
-	public static Test suite() {
-		TestSuite suite = new TestSuite(UtilityNodeTests.class.getPackage().getName());
-	
-		suite.addTestSuite(AbstractNodeTests.class);
-	
-		return suite;
-	}
-	
-	private UtilityNodeTests() {
-		super();
-	}
-	
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/synchronizers/SynchronizerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/synchronizers/SynchronizerTests.java
deleted file mode 100644
index 22af8d2..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/synchronizers/SynchronizerTests.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.synchronizers;
-
-import junit.framework.TestCase;
-import org.eclipse.persistence.tools.utility.synchronizers.Synchronizer;
-
-public class SynchronizerTests extends TestCase {
-
-	public SynchronizerTests(String name) {
-		super(name);
-	}
-
-	public void testNullSynchronizerStart() {
-		Synchronizer synchronizer = Synchronizer.Null.instance();
-		synchronizer.start();  // just make sure it doesn't blow up?
-	}
-
-	public void testNullSynchronizerSynchronize() {
-		Synchronizer synchronizer = Synchronizer.Null.instance();
-		synchronizer.synchronize();  // just make sure it doesn't blow up?
-	}
-
-	public void testNullSynchronizerStop() {
-		Synchronizer synchronizer = Synchronizer.Null.instance();
-		synchronizer.stop();  // just make sure it doesn't blow up?
-	}
-
-	public void testNullSynchronizerToString() {
-		Synchronizer synchronizer = Synchronizer.Null.instance();
-		assertNotNull(synchronizer.toString());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/synchronizers/SynchronousSynchronizerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/synchronizers/SynchronousSynchronizerTests.java
deleted file mode 100644
index 71a4103..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/synchronizers/SynchronousSynchronizerTests.java
+++ /dev/null
@@ -1,758 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.synchronizers;
-
-import org.eclipse.persistence.tools.utility.CompositeException;
-import org.eclipse.persistence.tools.utility.SynchronizedBoolean;
-import org.eclipse.persistence.tools.utility.command.Command;
-import org.eclipse.persistence.tools.utility.synchronizers.SynchronousSynchronizer;
-import org.eclipse.persistence.tools.utility.synchronizers.Synchronizer;
-import org.eclipse.persistence.tools.utility.tests.internal.MultiThreadedTestCase;
-import org.eclipse.persistence.tools.utility.tests.internal.TestTools;
-
-@SuppressWarnings("nls")
-public class SynchronousSynchronizerTests
-	extends MultiThreadedTestCase
-{
-	PrimaryModel1 primaryModel1;
-	SecondaryModel1 secondaryModel1;
-	Command command1;
-	Synchronizer synchronizer1;
-
-	PrimaryModel2 primaryModel2;
-	SecondaryModel2 secondaryModel2;
-	Command command2;
-	Synchronizer synchronizer2;
-
-	public SynchronousSynchronizerTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.primaryModel1 = new PrimaryModel1();
-		this.secondaryModel1 = new SecondaryModel1(this.primaryModel1);
-		this.command1 = new SynchronizeSecondaryModelCommand1(this.secondaryModel1);
-		this.synchronizer1 = new SynchronousSynchronizer(this.command1);
-		this.primaryModel1.setSynchronizer(this.synchronizer1);
-
-		this.primaryModel2 = new PrimaryModel2();
-		this.secondaryModel2 = new SecondaryModel2(this.primaryModel2);
-		this.command2 = new SynchronizeSecondaryModelCommand2(this.primaryModel2, this.secondaryModel2);
-		this.synchronizer2 = new SynchronousSynchronizer(this.command2);
-		this.primaryModel2.setSynchronizer(this.synchronizer2);
-	}
-
-	public void testInitialization() {
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-	}
-
-	public void testToString() {
-		assertNotNull(this.synchronizer1.toString());
-	}
-
-	public void testChange() {
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-		this.primaryModel1.setCount(7);
-		assertEquals(14, this.secondaryModel1.getDoubleCount());
-	}
-
-	public void testStart() {
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-		this.primaryModel1.setSynchronizer(Synchronizer.Null.instance());
-		this.primaryModel1.setCount(7);
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-		this.primaryModel1.setSynchronizer(this.synchronizer1);
-		assertEquals(14, this.secondaryModel1.getDoubleCount());
-	}
-
-	public void testStop() {
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-		this.primaryModel1.dispose();
-		this.primaryModel1.setCount(7);
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-	}
-
-	public void testDoubleStart() {
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-		boolean exCaught = false;
-		try {
-			this.primaryModel1.startSynchronizer();
-			fail();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-		this.primaryModel1.setCount(7);
-		assertEquals(14, this.secondaryModel1.getDoubleCount());
-	}
-
-	public void testDoubleStop() {
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-		this.primaryModel1.dispose();
-		boolean exCaught = false;
-		try {
-			this.primaryModel1.dispose();
-			fail();
-		} catch (IllegalStateException ex) {
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-		this.primaryModel1.setCount(7);
-		assertEquals(4, this.secondaryModel1.getDoubleCount());
-	}
-
-	public void testRecursiveChange() {
-		assertEquals(4, this.secondaryModel2.getDoubleCount());
-		this.primaryModel2.setCount(7);
-		assertEquals(10, this.primaryModel2.getCountPlus3());
-		assertEquals(14, this.secondaryModel2.getDoubleCount());
-		assertEquals(20, this.secondaryModel2.getDoubleCountPlus3());
-	}
-
-	/**
-	 * Call #stop() from another thread.
-	 * Verify that no further synchronizations occur.
-	 * Verify the call to #stop() does not return until the pending
-	 * synchronization is complete (must set {@link #DEBUG} to true and
-	 * look at the console).
-	 * 
-	 * ticks:
-	 * 0 - start "sync" thread (which will sleep for 1 tick);
-	 *      start "stop" thread (which will sleep for 2 ticks)
-	 * 1 - "sync" thread wakes up and calls PrimaryModel1.setCount(int)
-	 *      which triggers call to Synchronizer.synchronize() to begin
-	 *      synchronization of SecondaryModel (which will run for 2 ticks;
-	 *      i.e. it will finish on tick 3)
-	 * 2 - "stop" thread wakes up and calls Synchronizer.stop() and should
-	 *      wait until synchronization is complete
-	 * 3 - synchronization completes first execution and should stop;
-	 *      "stop" thread should run to completion once the synchronization has stopped
-	 */
-	public void testCallStopFromAnotherThread() throws Exception {
-		log("=====" + this.getName() + "=====");
-		PrimaryModel2 primaryModel3 = new PrimaryModel2();
-		// a synchronize will occur here:
-		SecondaryModel3 secondaryModel3 = new SecondaryModel3(primaryModel3);
-		Command command3 = new SynchronizeSecondaryModelCommand2(primaryModel3, secondaryModel3);
-		Synchronizer synchronizer3 = new SynchronousSynchronizer(command3);
-		// another synchronize will occur here:
-		primaryModel3.setSynchronizer(synchronizer3);
-		secondaryModel3.setTicks(2);
-
-		assertEquals(2, primaryModel3.getCount());
-		assertEquals(5, primaryModel3.getCountPlus3());
-		assertEquals(4, secondaryModel3.getDoubleCount());
-		assertEquals(10, secondaryModel3.getDoubleCountPlus3());
-
-		Thread syncThread = this.buildTriggerSynchronizeThread(primaryModel3, 1);
-		Thread stopThread = this.buildStopThread(synchronizer3, 2);
-
-		log("ALL threads start");
-		stopThread.start();
-		syncThread.start();
-
-		stopThread.join();
-		syncThread.join();
-
-		// 'doubleCount' is synchronized; but the synchronization is stopped
-		// while that is happening (by the 'stopThread'), so 'doubleCountPlus3'
-		// does not get synchronized
-		assertEquals(7, primaryModel3.getCount());
-		assertEquals(10, primaryModel3.getCountPlus3());
-		assertEquals(14, secondaryModel3.getDoubleCount());
-
-		// this does not get updated because it would've been updated by the
-		// recursive call to #synchronize(), but by that time #stop() had been called
-		assertEquals(10, secondaryModel3.getDoubleCountPlus3());
-	}
-
-	private Thread buildTriggerSynchronizeThread(PrimaryModel2 primaryModel, long ticks) {
-		return this.buildThread(this.buildTriggerSynchronizeRunnable(primaryModel, ticks), "trigger sync");
-	}
-
-	private Runnable buildTriggerSynchronizeRunnable(final PrimaryModel2 primaryModel, final long ticks) {
-		return new Runnable() {
-			public void run() {
-				TestTools.sleep(ticks * TICK);
-				primaryModel.setCount(7);
-			}
-		};
-	}
-
-	private Thread buildStopThread(Synchronizer synchronizer, long ticks) {
-		return this.buildThread(this.buildStopRunnable(synchronizer, ticks), "stop");
-	}
-
-	private Runnable buildStopRunnable(final Synchronizer synchronizer, final long ticks) {
-		return new Runnable() {
-			public void run() {
-				TestTools.sleep(ticks * TICK);
-				log("STOP thread Synchronizer.stop()");
-				synchronizer.stop();
-				log("STOP thread stop");
-			}
-		};
-	}
-
-	/**
-	 * Code cloned from {@link #testStopCalledFromAnotherThread()}.
-	 * 
-	 * Interrupt the "stop" thread while it is waiting for the "synch" thread to finish.
-	 * Verify that no further synchronizations occur.
-	 * Verify the call to #stop() returns *before*
-	 * synchronization is complete (must set {@link #DEBUG} to true and
-	 * look at the console).
-	 * 
-	 * ticks:
-	 * 0 - start "sync" thread (which will sleep for 1 tick);
-	 *      start "stop" thread (which will sleep for 2 ticks);
-	 *      start "interrupt" thread (which will sleep for 3 ticks)
-	 * 1 - "sync" thread wakes up and calls PrimaryModel1.setCount(int)
-	 *      which triggers call to Synchronizer.synchronize() to begin
-	 *      synchronization of SecondaryModel (which will run for 3 ticks;
-	 *      i.e. it will finish on tick 4)
-	 * 2 - "stop" thread wakes up and calls Synchronizer.stop() and should
-	 *      wait until it is interrupted
-	 * 3 - "interrupt" thread wakes up and interrupts "stop" thread;
-	 *       both will run to completion at that point
-	 * 4 - synchronization completes first execution and should stop since the
-	 *      "stop" thread, before it was interrupted, told the "synch" thread to stop
-	 */
-	public void testInterruptStopThread() throws Exception {
-		log("=====" + this.getName() + "=====");
-		PrimaryModel2 primaryModel3 = new PrimaryModel2();
-		// a synchronize will occur here:
-		SecondaryModel3 secondaryModel3 = new SecondaryModel3(primaryModel3);
-		Command command3 = new SynchronizeSecondaryModelCommand2(primaryModel3, secondaryModel3);
-		Synchronizer synchronizer3 = new SynchronousSynchronizer(command3);
-		// another synchronize will occur here:
-		primaryModel3.setSynchronizer(synchronizer3);
-		secondaryModel3.setTicks(3);
-
-		assertEquals(2, primaryModel3.getCount());
-		assertEquals(5, primaryModel3.getCountPlus3());
-		assertEquals(4, secondaryModel3.getDoubleCount());
-		assertEquals(10, secondaryModel3.getDoubleCountPlus3());
-
-		Thread syncThread = this.buildTriggerSynchronizeThread(primaryModel3, 1);
-		Thread stopThread = this.buildStopThread(synchronizer3, 2);
-		Thread interruptThread = this.buildInterruptThread(stopThread, 3);
-
-		log("ALL threads start");
-		stopThread.start();
-		syncThread.start();
-		interruptThread.start();
-
-		stopThread.join();
-		syncThread.join();
-		interruptThread.join();
-
-		// 'doubleCount' is synchronized; but the synchronization is stopped
-		// while that is happening (by the 'stopThread'), so 'doubleCountPlus3'
-		// does not get synchronized
-		assertEquals(7, primaryModel3.getCount());
-		assertEquals(10, primaryModel3.getCountPlus3());
-		assertEquals(14, secondaryModel3.getDoubleCount());
-
-		// this does not get updated because it would've been updated by the
-		// recursive call to #synchronize(), but by that time #stop() had been called
-		assertEquals(10, secondaryModel3.getDoubleCountPlus3());
-	}
-
-	/**
-	 * Code cloned from {@link #testStopCalledFromAnotherThread()}.
-	 * 
-	 * Interrupt the "sync" thread while it is synchronizing, cutting short the synchronization.
-	 * Verify that no further synchronizations occur.
-	 * Verify the call to #stop() does not return until the pending
-	 * synchronization is stops after it is interrupted (must set {@link #DEBUG} to true and
-	 * look at the console).
-	 * 
-	 * ticks:
-	 * 0 - start "sync" thread (which will sleep for 1 tick)
-	 *      start "stop" thread (which will sleep for 2 ticks)
-	 *      start "interrupt" thread (which will sleep for 3 ticks)
-	 * 1 - "sync" thread wakes up and calls PrimaryModel1.setCount(int)
-	 *      which triggers call to Synchronizer.synchronize() to begin
-	 *      synchronization of SecondaryModel (which will run for 4 ticks;
-	 *      i.e. it will finish on tick 5)
-	 * 2 - "stop" thread wakes up and calls Synchronizer.stop() and should
-	 *      wait until the synchronization is interrupted
-	 * 3 - "interrupt" thread wakes up and interrupts "sync" thread;
-	 *      the "interrupt" thread runs to completion, while the "sync" thread keeps
-	 *      going for another tick before it stops in "mid-synchronize"
-	 * 4 - the "sync" thread acknowledges the interrupt and stops in
-	 *      "mid-synchronize"; it will stop since the "stop" thread told it to at tick 2;
-	 *      the "sync" and "stop" threads run to completion
-	 */
-	public void testInterruptSyncThread() throws Exception {
-		log("=====" + this.getName() + "=====");
-		PrimaryModel2 primaryModel3 = new PrimaryModel2();
-		// a synchronize will occur here:
-		SecondaryModel3 secondaryModel3 = new SecondaryModel3(primaryModel3);
-		Command command3 = new SynchronizeSecondaryModelCommand2(primaryModel3, secondaryModel3);
-		Synchronizer synchronizer3 = new SynchronousSynchronizer(command3);
-		// another synchronize will occur here:
-		primaryModel3.setSynchronizer(synchronizer3);
-		secondaryModel3.setTicks(4);
-
-		assertEquals(2, primaryModel3.getCount());
-		assertEquals(5, primaryModel3.getCountPlus3());
-		assertEquals(4, secondaryModel3.getDoubleCount());
-		assertEquals(10, secondaryModel3.getDoubleCountPlus3());
-
-		Thread syncThread = this.buildTriggerSynchronizeThread(primaryModel3, 1);
-		Thread stopThread = this.buildStopThread(synchronizer3, 2);
-		Thread interruptThread = this.buildInterruptThread(syncThread, 3);
-
-		log("ALL threads start");
-		stopThread.start();
-		syncThread.start();
-		interruptThread.start();
-
-		stopThread.join();
-		syncThread.join();
-		interruptThread.join();
-
-		assertEquals(7, primaryModel3.getCount());
-		assertEquals(10, primaryModel3.getCountPlus3());
-
-		// none of the secondary model is synchronized because the synchronize()
-		// method was interrupted before any synchronization had occurred
-		assertEquals(4, secondaryModel3.getDoubleCount());
-		assertEquals(10, secondaryModel3.getDoubleCountPlus3());
-	}
-
-	private Thread buildInterruptThread(Thread thread, long ticks) {
-		return this.buildThread(this.buildInterruptRunnable(thread, ticks), "interrupt");
-	}
-
-	private Runnable buildInterruptRunnable(final Thread thread, final long ticks) {
-		return new Runnable() {
-			public void run() {
-				TestTools.sleep(ticks * TICK);
-				log("INTERRUPT thread Thread.interrupt()");
-				thread.interrupt();
-			}
-		};
-	}
-
-	/**
-	 * Call #stop() during a long-running "synchronize"; then call #start()
-	 * while the #stop() is waiting for the "synchronize" to complete.
-	 * 
-	 * ticks:
-	 * 0 - start "sync" thread (which will sleep for 1 tick)
-	 *      start "stop" thread (which will sleep for 2 ticks)
-	 *      start "start" thread (which will sleep for 3 ticks)
-	 * 1 - "sync" thread wakes up and calls Synchronizer.synchronize() to begin
-	 *      synchronization (which will run for 3 ticks; i.e. it will finish on tick 4)
-	 * 2 - "stop" thread wakes up and calls Synchronizer.stop() and should
-	 *      wait until the synchronization is finished (i.e. tick 4)
-	 * 3 - "start" thread wakes up and calls Synchronizer.start()
-	 *      which will throw an exception
-	 * 4 - the "sync" thread finishes execution;
-	 *      it will stop since the "stop" thread told it to at tick 2;
-	 *      the "sync" and "stop" threads run to completion
-	 */
-	public void testCallStartDuringStop() throws Exception {
-		log("=====" + this.getName() + "=====");
-		DelayCommand command = this.buildDelayCommand(3);
-		Synchronizer synchronizer = new SynchronousSynchronizer(command);
-		synchronizer.start();
-
-		Thread syncThread = this.buildSynchronizeThread(synchronizer, 1);
-		Thread stopThread = this.buildStopThread(synchronizer, 2);
-		SynchronizedBoolean exCaught = new SynchronizedBoolean(false);
-		Thread startThread = this.buildStartThread(synchronizer, 3, exCaught);
-
-		log("ALL threads start");
-		syncThread.start();
-		stopThread.start();
-		startThread.start();
-
-		syncThread.join();
-		stopThread.join();
-		startThread.join();
-
-		assertTrue(exCaught.getValue());
-		assertEquals(2, command.count);
-	}
-
-	private DelayCommand buildDelayCommand(int ticks) {
-		return new DelayCommand(ticks);
-	}
-
-	class DelayCommand implements Command {
-		final long ticks;
-		boolean first = true;
-		int count = 0;
-
-		DelayCommand(int ticks) {
-			super();
-			this.ticks = ticks;
-		}
-
-		public void execute() {
-			this.count++;
-			// do nothing for the first call (from #start())
-			if (this.first) {
-				log("EXEC first");
-				this.first = false;
-				return;
-			}
-			log("EXEC start " + this.count);
-			TestTools.sleep(this.ticks * TICK);
-			log("EXEC stop " + this.count);
-		}
-
-	}
-
-	private Thread buildStartThread(Synchronizer synchronizer, long ticks, SynchronizedBoolean exCaught) {
-		return this.buildThread(this.buildStartRunnable(synchronizer, ticks, exCaught), "start");
-	}
-
-	private Runnable buildStartRunnable(final Synchronizer synchronizer, final long ticks, final SynchronizedBoolean exCaught) {
-		return new Runnable() {
-			public void run() {
-				TestTools.sleep(ticks * TICK);
-				log("START thread Synchronizer.start()");
-				try {
-					synchronizer.start();
-				} catch (IllegalStateException ex) {
-					exCaught.setTrue();
-					log("START thread exception");
-				}
-				log("START thread stop");
-			}
-		};
-	}
-
-	private Thread buildSynchronizeThread(Synchronizer synchronizer, long ticks) {
-		return this.buildThread(this.buildSynchronizeRunnable(synchronizer, ticks), "synchronize");
-	}
-
-	private Runnable buildSynchronizeRunnable(final Synchronizer synchronizer, final long ticks) {
-		return new Runnable() {
-			public void run() {
-				TestTools.sleep(ticks * TICK);
-				log("SYNC thread Synchronizer.synchronize()");
-				synchronizer.synchronize();
-				log("SYNC thread stop");
-			}
-		};
-	}
-
-	public void testException() throws Exception {
-		BogusCommand command = new BogusCommand();
-		Synchronizer synchronizer = new SynchronousSynchronizer(command);
-		synchronizer.start();
-
-		try {
-			synchronizer.synchronize();
-		} catch (NullPointerException ex) {
-			// ignore
-		}
-
-		boolean exCaught = false;
-		try {
-			// we used to hang here, before we began handling exceptions
-			synchronizer.stop();
-			fail();
-		} catch (CompositeException ex) {
-			assertEquals(1, ex.getExceptions().length);
-			exCaught = true;
-		}
-		assertTrue(exCaught);
-		// start + synchronize
-		assertEquals(2, command.count);
-	}
-
-	public class BogusCommand implements Command {
-		int count = 0;
-		public void execute() {
-			this.count++;
-			if (this.count > 1) {
-				throw new NullPointerException();
-			}
-		}
-	}
-
-
-	// ********** synchronize commands **********
-	public static class SynchronizeSecondaryModelCommand1 implements Command {
-		private final SecondaryModel1 secondaryModel;
-
-		public SynchronizeSecondaryModelCommand1(SecondaryModel1 secondaryModel) {
-			super();
-			this.secondaryModel = secondaryModel;
-		}
-
-		public void execute() {
-			this.secondaryModel.synchronize();
-		}
-
-	}
-
-	/**
-	 * the primary model (subclass) has to synchronize with itself (superclass)
-	 */
-	public static class SynchronizeSecondaryModelCommand2 extends SynchronizeSecondaryModelCommand1 {
-		private final PrimaryModel2 primaryModel;
-
-		public SynchronizeSecondaryModelCommand2(PrimaryModel2 primaryModel, SecondaryModel2 secondaryModel) {
-			super(secondaryModel);
-			this.primaryModel = primaryModel;
-		}
-
-		@Override
-		public void execute() {
-			super.execute();
-			this.primaryModel.synchronize();
-		}
-
-	}
-
-	// ********** primary models **********
-	/**
-	 * this object will call the synchronizer whenever its count changes,
-	 * allowing interested parties to synchronize with the change
-	 */
-	public static class PrimaryModel1 {
-		protected Synchronizer synchronizer;
-		protected int count = 2;
-
-		public PrimaryModel1() {
-			super();
-			this.setSynchronizer_(Synchronizer.Null.instance());
-		}
-
-		public int getCount() {
-			return this.count;
-		}
-		public void setCount(int count) {
-			if (count != this.count) {
-				this.count = count;
-				this.stateChanged();
-			}
-		}
-
-		protected void stateChanged() {
-			this.synchronizer.synchronize();
-		}
-
-		public void setSynchronizer(Synchronizer synchronizer) {
-			if (synchronizer == null) {
-				throw new NullPointerException();
-			}
-			this.synchronizer.stop();
-			this.setSynchronizer_(synchronizer);
-		}
-			
-		protected void setSynchronizer_(Synchronizer synchronizer) {
-			this.synchronizer = synchronizer;
-			this.synchronizer.start();
-		}
-
-		public void startSynchronizer() {
-			this.synchronizer.start();  // this should cause an exception
-		}
-		public void dispose() {
-			this.synchronizer.stop();
-		}
-
-		@Override
-		public String toString() {
-			StringBuilder sb = new StringBuilder();
-			sb.append(this.getClass().getSimpleName());
-			sb.append('(');
-			this.toString(sb);
-			sb.append(')');
-			return sb.toString();
-		}
-		public void toString(StringBuilder sb) {
-			sb.append("count=");
-			sb.append(this.count);
-		}
-
-	}
-
-	/**
-	 * This model synchronizes with itself, triggering a recursive synchronization
-	 * with the change. Whenever the [inherited] 'count' changes, 'countPlus3'
-	 * is updated appropriately and another synchronize is initiated if appropriate.
-	 */
-	public static class PrimaryModel2 extends PrimaryModel1 {
-		private int countPlus3 = 0;
-
-		public PrimaryModel2() {
-			super();
-			this.countPlus3 = this.count + 3;
-		}
-
-		public int getCountPlus3() {
-			return this.countPlus3;
-		}
-		protected void setCountPlus3(int countPlus3) {
-			if (countPlus3 != this.countPlus3) {
-				this.countPlus3 = countPlus3;
-				this.stateChanged();
-			}
-		}
-
-		// synchronize with itself, so to speak
-		public void synchronize() {
-			this.setCountPlus3(this.count + 3);
-		}
-
-		@Override
-		public void toString(StringBuilder sb) {
-			super.toString(sb);
-			sb.append(", countPlus3=");
-			sb.append(this.countPlus3);
-		}
-
-	}
-
-	// ********** secondary models **********
-	/**
-	 * This dependent object updates its 'doubleCount' whenever the
-	 * PrimaryModel1's 'count' changes, via the 'synchronizer'.
-	 */
-	public static class SecondaryModel1 {
-		protected final PrimaryModel1 primaryModel;
-		protected int doubleCount = 0;
-
-		public SecondaryModel1(PrimaryModel1 primaryModel) {
-			super();
-			this.primaryModel = primaryModel;
-			this.synchronize();
-		}
-
-		public void synchronize() {
-			this.doubleCount = this.primaryModel.getCount() * 2;
-		}
-
-		public int getDoubleCount() {
-			return this.doubleCount;
-		}
-
-		@Override
-		public String toString() {
-			StringBuilder sb = new StringBuilder();
-			sb.append(this.getClass().getSimpleName());
-			sb.append('(');
-			this.toString(sb);
-			sb.append(')');
-			return sb.toString();
-		}
-		public void toString(StringBuilder sb) {
-			sb.append("doubleCount=");
-			sb.append(this.doubleCount);
-		}
-
-	}
-
-	public static class SecondaryModel2 extends SecondaryModel1 {
-		private int doubleCountPlus3 = 0;
-
-		public SecondaryModel2(PrimaryModel2 extendedPrimaryModel) {
-			super(extendedPrimaryModel);
-		}
-
-		protected PrimaryModel2 getExtendedPrimaryModel() {
-			return (PrimaryModel2) this.primaryModel;
-		}
-
-		@Override
-		public void synchronize() {
-			super.synchronize();
-			int temp = this.getExtendedPrimaryModel().getCountPlus3() * 2;
-			if (this.doubleCountPlus3 != temp) {
-				this.doubleCountPlus3 = temp;
-			}
-		}
-
-		public int getDoubleCountPlus3() {
-			return this.doubleCountPlus3;
-		}
-
-		@Override
-		public void toString(StringBuilder sb) {
-			super.toString(sb);
-			sb.append(", doubleCountPlus3=");
-			sb.append(this.doubleCountPlus3);
-		}
-
-	}
-
-	/**
-	 * Allow the time required to synchronize to be specified.
-	 * A (non-delayed) synchronize will execute before we have a chance to
-	 * change the tick count. (It is called in the SecondaryModel1 constructor.)
-	 */
-	public static class SecondaryModel3 extends SecondaryModel2 {
-		private long delay = 0;
-		public SecondaryModel3(PrimaryModel2 primaryModel) {
-			super(primaryModel);
-		}
-
-		public void setTicks(long ticks) {
-			this.delay = ticks * TICK;
-		}
-
-		@Override
-		public void synchronize() {
-			// don't log anything until 'ticks' is set
-			if (this.delay == 0) {
-				super.synchronize();
-			} else {
-				log("SYNC thread start - sync duration will be: " + (this.delay / TICK) + " ticks");
-				try {
-					Thread.sleep(this.delay);
-				} catch (InterruptedException ex) {
-					log("SYNC thread interrupted");
-					TestTools.sleep(TICK);
-					return;  // stop synchronize (i.e. don't call super.synchronize())
-				}
-				super.synchronize();
-				log("SYNC thread stop");
-			}
-		}
-
-	}
-
-	public void testDEBUG() {
-		assertFalse(DEBUG);
-	}
-
-	public static final boolean DEBUG = false;
-	public static void log(String message) {
-		if (DEBUG) {
-			log_(message);
-		}
-	}
-
-	private static void log_(String message) {
-		System.out.print(timestamp());
-		System.out.print(' ');
-		System.out.print(message);
-		System.out.println();
-	}
-
-	public static String timestamp() {
-		return String.valueOf((System.currentTimeMillis() % 10000) / 1000f);
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/synchronizers/UtilitySynchronizersTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/synchronizers/UtilitySynchronizersTests.java
deleted file mode 100644
index 894ce0f..0000000
--- a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/internal/synchronizers/UtilitySynchronizersTests.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.tests.internal.synchronizers;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * decentralize test creation code
- */
-public class UtilitySynchronizersTests {
-
-	public static Test suite() {
-		TestSuite suite = new TestSuite(UtilitySynchronizersTests.class.getPackage().getName());
-
-		suite.addTestSuite(SynchronizerTests.class);
-		suite.addTestSuite(SynchronousSynchronizerTests.class);
-
-		return suite;
-	}
-
-	private UtilitySynchronizersTests() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/CommonUtilityIOTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/CommonUtilityIOTests.java
new file mode 100644
index 0000000..a92ba1f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/CommonUtilityIOTests.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.io;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CommonUtilityIOTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CommonUtilityIOTests.class.getPackage().getName());
+
+		suite.addTestSuite(FileToolsTests.class);
+		suite.addTestSuite(IndentingPrintWriterTests.class);
+		suite.addTestSuite(InvalidInputStreamTests.class);
+		suite.addTestSuite(InvalidOutputStreamTests.class);
+		suite.addTestSuite(InvalidReaderTests.class);
+		suite.addTestSuite(InvalidWriterTests.class);
+		suite.addTestSuite(NullInputStreamTests.class);
+		suite.addTestSuite(NullOutputStreamTests.class);
+		suite.addTestSuite(NullReaderTests.class);
+		suite.addTestSuite(NullWriterTests.class);
+		suite.addTestSuite(PipeTests.class);
+		suite.addTestSuite(StringBufferWriterTests.class);
+		suite.addTestSuite(StringBuilderWriterTests.class);
+		suite.addTestSuite(CompositeOutputStreamTests.class);
+		suite.addTestSuite(CompositeWriterTests.class);
+		suite.addTestSuite(WriterToolsTests.class);
+
+		return suite;
+	}
+
+	private CommonUtilityIOTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/CompositeOutputStreamTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/CompositeOutputStreamTests.java
new file mode 100644
index 0000000..b0b693d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/CompositeOutputStreamTests.java
@@ -0,0 +1,57 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.io;

+

+import java.io.ByteArrayOutputStream;

+import java.io.OutputStream;

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.io.CompositeOutputStream;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+@SuppressWarnings("nls")

+public class CompositeOutputStreamTests

+	extends TestCase

+{

+	private OutputStream out1;

+	private OutputStream out2;

+	private OutputStream tee;

+

+

+	public CompositeOutputStreamTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.out1 = new ByteArrayOutputStream();

+		this.out2 = new ByteArrayOutputStream();

+		this.tee = new CompositeOutputStream(this.out1, this.out2);

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testWrite() throws Exception {

+		String string = "The quick brown fox jumps over the lazy dog.";

+		this.tee.write(string.getBytes());

+		assertEquals(string, this.out1.toString());

+		assertNotSame(string, this.out1.toString());

+		assertEquals(string, this.out2.toString());

+		assertNotSame(string, this.out2.toString());

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/CompositeWriterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/CompositeWriterTests.java
new file mode 100644
index 0000000..59da6a3
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/CompositeWriterTests.java
@@ -0,0 +1,57 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.io;

+

+import java.io.CharArrayWriter;

+import java.io.Writer;

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.io.CompositeWriter;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+@SuppressWarnings("nls")

+public class CompositeWriterTests

+	extends TestCase

+{

+	private Writer writer1;

+	private Writer writer2;

+	private Writer tee;

+

+

+	public CompositeWriterTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.writer1 = new CharArrayWriter();

+		this.writer2 = new CharArrayWriter();

+		this.tee = new CompositeWriter(this.writer1, this.writer2);

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testWrite() throws Exception {

+		String string = "The quick brown fox jumps over the lazy dog.";

+		this.tee.write(string);

+		assertEquals(string, this.writer1.toString());

+		assertNotSame(string, this.writer1.toString());

+		assertEquals(string, this.writer2.toString());

+		assertNotSame(string, this.writer2.toString());

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/FileToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/FileToolsTests.java
new file mode 100644
index 0000000..77b8baa
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/FileToolsTests.java
@@ -0,0 +1,598 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.io;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ClassTools;
+import org.eclipse.persistence.tools.utility.SystemTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.io.FileTools;
+
+
+@SuppressWarnings("nls")
+public class FileToolsTests
+	extends TestCase
+{
+	private File tempDir;
+
+	public FileToolsTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.tempDir = this.buildTempDir();
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		super.tearDown();
+		this.deleteDir(this.tempDir);
+	}
+
+	public void testFilesIn() {
+		Collection<File> files = CollectionTools.collection(FileTools.files(this.tempDir.getPath()));
+		assertEquals("invalid file count", 3, files.size());
+	}
+
+	public void testDirectoriesIn() {
+		Collection<File> files = CollectionTools.collection(FileTools.directories(this.tempDir.getPath()));
+		assertEquals("invalid directory count", 2, files.size());
+	}
+
+	public void testFilesInTree() {
+		Collection<File> files = CollectionTools.collection(FileTools.allFiles(this.tempDir.getPath()));
+		assertEquals("invalid file count", 9, files.size());
+	}
+
+	public void testDirectoriesInTree() {
+		Collection<File> files = CollectionTools.collection(FileTools.allDirectories(this.tempDir.getPath()));
+		assertEquals("invalid directory count", 3, files.size());
+	}
+
+	public void testDeleteDirectory() throws IOException {
+		// build another temporary directory just for this test
+		File dir = this.buildTempDir();
+		assertTrue("temporary directory not created", dir.exists());
+		FileTools.deleteDirectory(dir.getPath());
+		assertFalse("temporary directory not deleted", dir.exists());
+	}
+
+	public void testDeleteDirectoryContents() throws IOException {
+		// build another temporary directory just for this test
+		File dir = this.buildTempDir();
+		assertTrue("temporary directory not created", dir.exists());
+		FileTools.deleteDirectoryContents(dir.getPath());
+		assertTrue("temporary directory should not have been deleted", dir.exists());
+		assertTrue("temporary directory contents not deleted", dir.listFiles().length == 0);
+		dir.delete();
+	}
+
+	public void testCopyToFile() throws IOException {
+		File destFile = new File(this.tempDir, "destfile.txt");
+		this.copyToFile(destFile, "testCopyToFile");
+	}
+
+	public void testCopyToPreExistingFile() throws IOException {
+		File destFile = new File(this.tempDir, "destfile.txt");
+		Writer writer = new OutputStreamWriter(new FileOutputStream(destFile));
+		writer.write("this text should be replaced...");
+		writer.close();
+		this.copyToFile(destFile, "testCopyToPreExistingFile");
+	}
+
+	private void copyToFile(File destFile, String writeString) throws IOException {
+		File sourceFile = new File(this.tempDir, "sourcefile.txt");
+		char[] readBuffer = new char[writeString.length()];
+
+		Writer writer = new OutputStreamWriter(new FileOutputStream(sourceFile));
+		writer.write(writeString);
+		writer.close();
+
+		FileTools.copyToFile(sourceFile, destFile);
+
+		Reader reader = new InputStreamReader(new FileInputStream(destFile));
+		reader.read(readBuffer);
+		reader.close();
+		String readString = new String(readBuffer);
+		assertEquals(writeString, readString);
+	}
+
+	public void testCopyToDirectory() throws IOException {
+		File sourceFile = new File(this.tempDir, "sourcefile.txt");
+		String writeString = "testCopyToDirectory";
+
+		File destDir = new File(this.tempDir, "destdir");
+		destDir.mkdir();
+		File destFile = new File(destDir, "sourcefile.txt");
+		char[] readBuffer = new char[writeString.length()];
+
+		Writer writer = new OutputStreamWriter(new FileOutputStream(sourceFile));
+		writer.write(writeString);
+		writer.close();
+
+		FileTools.copyToDirectory(sourceFile, destDir);
+
+		Reader reader = new InputStreamReader(new FileInputStream(destFile));
+		reader.read(readBuffer);
+		reader.close();
+		String readString = new String(readBuffer);
+		assertEquals(writeString, readString);
+
+		FileTools.copyToDirectory(sourceFile, destDir); //Try again with the directory is already created
+		reader = new InputStreamReader(new FileInputStream(destFile));
+		reader.read(readBuffer);
+		reader.close();
+		readString = new String(readBuffer);
+		assertEquals(writeString, readString);
+	}
+
+	public void testFilter() throws IOException {
+		String prefix = "XXXtestFileXXX";
+		File testFile1 = new File(this.tempDir, prefix + "1");
+		testFile1.createNewFile();
+		File testFile2 = new File(this.tempDir, prefix + "2");
+		testFile2.createNewFile();
+
+		FileFilter filter = this.buildFileFilter(prefix);
+		Iterator<File> filteredFilesIterator = FileTools.filter(FileTools.files(this.tempDir), filter);
+		Collection<File> filteredFiles = CollectionTools.collection(filteredFilesIterator);
+		assertEquals(2, filteredFiles.size());
+		assertTrue(filteredFiles.contains(testFile1));
+		assertTrue(filteredFiles.contains(testFile2));
+	}
+
+	private FileFilter buildFileFilter(final String prefix) {
+		return new FileFilter() {
+			@Override
+			public boolean accept(File file) {
+				return file.getName().startsWith(prefix);
+			}
+		};
+	}
+
+	public void testStripExtension() {
+		assertEquals("foo", FileTools.stripExtension("foo.xml"));
+		assertEquals("foo.bar", FileTools.stripExtension("foo.bar.xml"));
+		assertEquals("foo", FileTools.stripExtension("foo"));
+		assertEquals("foo", FileTools.stripExtension("foo."));
+	}
+
+	public void testExtension() {
+		assertEquals(".xml", FileTools.extension("foo.xml"));
+		assertEquals(".xml", FileTools.extension("foo.bar.xml"));
+		assertEquals("", FileTools.extension("foo"));
+		assertEquals("", FileTools.extension("foo,xml"));
+		assertEquals(".", FileTools.extension("foo."));
+	}
+
+	public void testEmptyTemporaryDirectory() throws IOException {
+		File tempDir1 = FileTools.temporaryDirectory();
+		File testFile1 = new File(tempDir1, "junk");
+		testFile1.createNewFile();
+
+		File tempDir2 = FileTools.emptyTemporaryDirectory();
+		assertEquals(tempDir1, tempDir2);
+		assertTrue(tempDir2.isDirectory());
+		assertEquals(0, tempDir2.listFiles().length);
+		tempDir2.delete();
+	}
+
+	public void testCanonicalFileName() {
+		File file1 = new File("foo");
+		file1 = new File(file1, "bar");
+		file1 = new File(file1, "baz");
+		file1 = new File(file1, "..");
+		file1 = new File(file1, "..");
+		file1 = new File(file1, "bar");
+		file1 = new File(file1, "baz");
+		File file2 = new File(System.getProperty("user.dir"));
+		file2 = new File(file2, "foo");
+		file2 = new File(file2, "bar");
+		file2 = new File(file2, "baz");
+		File file3 = FileTools.canonicalFile(file1);
+		assertEquals(file2, file3);
+	}
+
+	public void testPathFiles() {
+		File[] expected;
+		File[] actual;
+
+		if (SystemTools.osIsWindows()) {
+			expected = new File[] { new File("C:/"), new File("C:/foo"), new File("C:/foo/bar"), new File("C:/foo/bar/baz.txt") };
+			actual = this.pathFiles(new File("C:/foo/bar/baz.txt"));
+			assertTrue(Arrays.equals(expected, actual));
+		}
+
+		expected = new File[] { new File("/"), new File("/foo"), new File("/foo/bar"), new File("/foo/bar/baz.txt") };
+		actual = this.pathFiles(new File("/foo/bar/baz.txt"));
+		assertTrue(Arrays.equals(expected, actual));
+
+		expected = new File[] { new File("foo"), new File("foo/bar"), new File("foo/bar/baz.txt") };
+		actual = this.pathFiles(new File("foo/bar/baz.txt"));
+		assertTrue(Arrays.equals(expected, actual));
+
+		expected = new File[] { new File(".."), new File("../foo"), new File("../foo/bar"), new File("../foo/bar/baz.txt") };
+		actual = this.pathFiles(new File("../foo/bar/baz.txt"));
+		assertTrue(Arrays.equals(expected, actual));
+
+		expected = new File[] { new File("."), new File("./foo"), new File("./foo/bar"), new File("./foo/bar/baz.txt") };
+		actual = this.pathFiles(new File("./foo/bar/baz.txt"));
+		assertTrue(Arrays.equals(expected, actual));
+	}
+
+	private File[] pathFiles(File file) {
+		return (File[]) ClassTools.execute(FileTools.class, "pathFiles", File.class, file);
+	}
+
+	public void testRelativeParentFile() {
+		assertEquals(new File(".."), this.relativeParentFile(1));
+		assertEquals(new File("../.."), this.relativeParentFile(2));
+		assertEquals(new File("../../.."), this.relativeParentFile(3));
+
+		boolean exCaught = false;
+		try {
+			File file = this.relativeParentFile(0);
+			fail("invalid return: " + file);
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof InvocationTargetException) {
+				InvocationTargetException ite = (InvocationTargetException) ex.getCause();
+				if (ite.getTargetException() instanceof IllegalArgumentException) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	private File relativeParentFile(int len) {
+		return (File) ClassTools.execute(FileTools.class, "relativeParentFile", int.class, new Integer(len));
+	}
+
+	public void testConvertToRelativeFile() {
+		String prefix = SystemTools.osIsWindows() ? "C:" : "";
+		File file;
+		File dir;
+		File relativeFile;
+
+		if (SystemTools.osIsWindows()) {
+			// on Windows, a drive must be specified for a file to be absolute (i.e. not relative)
+			this.verifyUnchangedRelativeFile("/dir1/dir2/file.txt", "C:/dir1/dir2");
+			// different drives
+			this.verifyUnchangedRelativeFile("D:/dir1/dir2/file.txt", "C:/dir1/dir2");
+		}
+		this.verifyUnchangedRelativeFile("dir1/dir2/file.txt", prefix + "/dir1/dir2");
+		this.verifyUnchangedRelativeFile("./dir1/dir2/file.txt", prefix + "/dir1/dir2");
+		this.verifyUnchangedRelativeFile("../../dir1/dir2/file.txt", prefix + "/dir1/dir2");
+
+		file = new File(prefix + "/dir1/dir2");
+		dir = new File(prefix + "/dir1/dir2");
+		relativeFile = FileTools.convertToRelativeFile(file, dir);
+		assertEquals(new File("."), relativeFile);
+
+		file = new File(prefix + "/dir1/dir2/file.txt");
+		dir = new File(prefix + "/dir1/dir2");
+		relativeFile = FileTools.convertToRelativeFile(file, dir);
+		assertEquals(new File("file.txt"), relativeFile);
+
+		file = new File(prefix + "/dir1/dir2/../dir2/file.txt");
+		dir = new File(prefix + "/dir1/dir2");
+		relativeFile = FileTools.convertToRelativeFile(file, dir);
+		assertEquals(new File("file.txt"), relativeFile);
+
+		file = new File(prefix + "/dir1/dir2/dir3/dir4/dir5/file.txt");
+		dir = new File(prefix + "/dir1/dir2");
+		relativeFile = FileTools.convertToRelativeFile(file, dir);
+		assertEquals(new File("dir3/dir4/dir5/file.txt"), relativeFile);
+
+		file = new File(prefix + "/dir1/dir2/file.txt");
+		dir = new File(prefix + "/dir1/dir2/dir3/dir4/dir5");
+		relativeFile = FileTools.convertToRelativeFile(file, dir);
+		assertEquals(new File("../../../file.txt"), relativeFile);
+
+		file = new File(prefix + "/dir1/dir2/file.txt");
+		dir = new File(prefix + "/dir1/dir2/dir3");
+		relativeFile = FileTools.convertToRelativeFile(file, dir);
+		assertEquals(new File("../file.txt"), relativeFile);
+
+		file = new File(prefix + "/dir1/dir2/dirA/dirB/dirC/file.txt");
+		dir = new File(prefix + "/dir1/dir2/dir3/dir4/dir5");
+		relativeFile = FileTools.convertToRelativeFile(file, dir);
+		assertEquals(new File("../../../dirA/dirB/dirC/file.txt"), relativeFile);
+
+		file = new File(prefix + "/dir1/dir2");
+		dir = new File(prefix + "/dir1/dir2/dir3/dir4/dir5");
+		relativeFile = FileTools.convertToRelativeFile(file, dir);
+		assertEquals(new File("../../.."), relativeFile);
+
+		file = new File(prefix + "/My Documents/My Workspace/Project 1/lib/toplink.jar");
+		dir = new File(prefix + "/My Documents/My Workspace/Project 1");
+		relativeFile = FileTools.convertToRelativeFile(file, dir);
+		assertEquals(new File("lib/toplink.jar"), relativeFile);
+	}
+
+	private void verifyUnchangedRelativeFile(String fileName, String dirName) {
+		File file = new File(fileName);
+		File dir = new File(dirName);
+		File relativeFile = FileTools.convertToRelativeFile(file, dir);
+		assertEquals(file, relativeFile);
+	}
+
+	public void testConvertToAbsoluteFile() {
+		String prefix = SystemTools.osIsWindows() ? "C:" : "";
+		File file;
+		File dir;
+		File absoluteFile;
+
+		if (SystemTools.osIsWindows()) {
+			// on Windows, a drive must be specified for a file to be absolute (i.e. not relative)
+			this.verifyUnchangedAbsoluteFile("C:/dir1/dir2/file.txt", "C:/dir1/dir2");
+			// different drives
+			this.verifyUnchangedAbsoluteFile("D:/dir1/dir2/file.txt", "C:/dir1/dir2");
+		}
+		this.verifyUnchangedAbsoluteFile(prefix + "/dir1/dir2/file.txt", prefix + "/dir1/dir2");
+		this.verifyUnchangedAbsoluteFile(prefix + "/./dir1/dir2/file.txt", prefix + "/dir1/dir2");
+		this.verifyUnchangedAbsoluteFile(prefix + "/dir1/dir2/../../dir1/dir2/file.txt", prefix + "/dir1/dir2");
+
+		file = new File(".");
+		dir = new File(prefix + "/dir1/dir2");
+		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
+		assertEquals(new File(prefix + "/dir1/dir2"), absoluteFile);
+
+		file = new File("./file.txt");
+		dir = new File(prefix + "/dir1/dir2");
+		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
+		assertEquals(new File(prefix + "/dir1/dir2/file.txt"), absoluteFile);
+
+		file = new File("file.txt");
+		dir = new File(prefix + "/dir1/dir2");
+		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
+		assertEquals(new File(prefix + "/dir1/dir2/file.txt"), absoluteFile);
+
+		file = new File("../dir2/file.txt");
+		dir = new File(prefix + "/dir1/dir2");
+		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
+		assertEquals(new File(prefix + "/dir1/dir2/file.txt"), absoluteFile);
+
+		file = new File("dir3/dir4/dir5/file.txt");
+		dir = new File(prefix + "/dir1/dir2");
+		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
+		assertEquals(new File(prefix + "/dir1/dir2/dir3/dir4/dir5/file.txt"), absoluteFile);
+
+		file = new File("../../../file.txt");
+		dir = new File(prefix + "/dir1/dir2/dir3/dir4/dir5");
+		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
+		assertEquals(new File(prefix + "/dir1/dir2/file.txt"), absoluteFile);
+
+		// too many ".." directories will resolve to the root;
+		// this is consistent with Windows and Linux command shells
+		file = new File("../../../../../../../../file.txt");
+		dir = new File(prefix + "/dir1/dir2");
+		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
+		assertEquals(new File(prefix + "/file.txt"), absoluteFile);
+
+		file = new File("../file.txt");
+		dir = new File(prefix + "/dir1/dir2/dir3");
+		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
+		assertEquals(new File(prefix + "/dir1/dir2/file.txt"), absoluteFile);
+
+		file = new File("../../../dirA/dirB/dirC/file.txt");
+		dir = new File(prefix + "/dir1/dir2/dir3/dir4/dir5");
+		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
+		assertEquals(new File(prefix + "/dir1/dir2/dirA/dirB/dirC/file.txt"), absoluteFile);
+
+		file = new File("../../..");
+		dir = new File(prefix + "/dir1/dir2/dir3/dir4/dir5");
+		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
+		assertEquals(new File(prefix + "/dir1/dir2"), absoluteFile);
+
+		file = new File("lib/toplink.jar");
+		dir = new File(prefix + "/My Documents/My Workspace/Project 1");
+		absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
+		assertEquals(new File(prefix + "/My Documents/My Workspace/Project 1/lib/toplink.jar"), absoluteFile);
+	}
+
+	public void testFileNameIsReserved() {
+		boolean expected = SystemTools.osIsWindows();
+		assertEquals(expected, FileTools.fileNameIsReserved("CON"));
+		assertEquals(expected, FileTools.fileNameIsReserved("con"));
+		assertEquals(expected, FileTools.fileNameIsReserved("cON"));
+		assertEquals(expected, FileTools.fileNameIsReserved("AUX"));
+		assertEquals(expected, FileTools.fileNameIsReserved("COM3"));
+		assertEquals(expected, FileTools.fileNameIsReserved("LPT3"));
+		assertEquals(expected, FileTools.fileNameIsReserved("nUL"));
+		assertEquals(expected, FileTools.fileNameIsReserved("Prn"));
+	}
+
+	public void testFileHasAnyReservedComponents() {
+		boolean expected = SystemTools.osIsWindows();
+		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("C:/CON")));
+		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("/con/foo")));
+		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("c:/temp/cON")));
+		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("bar//baz//AUX")));
+		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("COM3//ttt")));
+		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("d:/LPT3/xxx")));
+		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("c:/my docs and stuff/tuesday/nUL")));
+		assertEquals(expected, FileTools.fileHasAnyReservedComponents(new File("Prn")));
+	}
+
+	public void testShortenFileNameFile() {
+		if (SystemTools.osIsWindows()) {
+			this.verifyShortenFileNameFileWin();
+		} else {
+			this.verifyShortenFileNameFileNonWin();
+		}
+	}
+
+	private void verifyShortenFileNameFileWin() {
+		File file = new File("C:\\Documents and Settings\\Administrator\\Desktop\\Project\\Text.txt");
+		String fileName = FileTools.shortenFileName(file);
+		assertEquals("C:\\Documents and Settings\\...\\Desktop\\Project\\Text.txt", fileName);
+		assertTrue(fileName.length() <= FileTools.MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
+
+		file = new File("C:/");
+		fileName = FileTools.shortenFileName(file);
+		assertEquals("C:\\", fileName);
+		assertTrue(fileName.length() <= FileTools.MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
+	}
+
+	private void verifyShortenFileNameFileNonWin() {
+		File file = new File("/home/administrator/documents and settings/desktop/Project/Text.txt");
+		String fileName = FileTools.shortenFileName(file);
+		assertEquals("/home/administrator/.../desktop/Project/Text.txt", fileName);
+		assertTrue(fileName.length() <= FileTools.MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
+
+		file = new File("/home");
+		fileName = FileTools.shortenFileName(file);
+		assertEquals("/home", fileName);
+		assertTrue(fileName.length() <= FileTools.MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
+	}
+
+	public void testShortenFileNameFileInt() {
+		if (SystemTools.osIsWindows()) {
+			this.verifyShortenFileNameFileIntWin();
+		} else {
+			this.verifyShortenFileNameFileIntNonWin();
+		}
+	}
+
+	private void verifyShortenFileNameFileIntWin() {
+		File file = new File("C:\\Documents and Settings\\Administrator\\Desktop\\Project\\Text.txt");
+		String fileName = FileTools.shortenFileName(file, 31);
+		assertEquals("C:\\...\\Desktop\\Project\\Text.txt", fileName);
+		assertEquals(31, fileName.length());
+
+		file = new File("C:/This is the file name.txt");
+		fileName = FileTools.shortenFileName(file, 10);
+		assertEquals("C:\\This is the file name.txt", fileName);
+		assertEquals(28, fileName.length());
+	}
+
+	private void verifyShortenFileNameFileIntNonWin() {
+		File file = new File("/home/administrator/documents and settings/desktop/Project/Text.txt");
+		String fileName = FileTools.shortenFileName(file, 31);
+		assertEquals("/home/.../desktop/Project/Text.txt", fileName);
+		assertEquals(34, fileName.length());
+
+		file = new File("/This is the file name.txt");
+		fileName = FileTools.shortenFileName(file, 10);
+		assertEquals("/This is the file name.txt", fileName);
+		assertEquals(26, fileName.length());
+	}
+
+	public void testShortenFileNameURL() throws Exception {
+		if (SystemTools.osIsWindows()) {
+			this.verifyShortenFileNameURLWin();
+		} else {
+			this.verifyShortenFileNameURLNonWin();
+		}
+	}
+
+	private void verifyShortenFileNameURLWin() throws Exception {
+		URL url = new URL("file", "", "C:/Documents and Settings/Administrator/Desktop/Project/Text.txt");
+		String fileName = FileTools.shortenFileName(url);
+		assertEquals("C:\\Documents and Settings\\...\\Desktop\\Project\\Text.txt", fileName);
+		assertTrue(fileName.length() <= FileTools.MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
+	}
+
+	private void verifyShortenFileNameURLNonWin() throws Exception {
+		URL url = new URL("file", "", "/home/administrator/documents and settings/desktop/Project/Text.txt");
+		String fileName = FileTools.shortenFileName(url);
+		assertEquals("/home/administrator/.../desktop/Project/Text.txt", fileName);
+		assertTrue(fileName.length() <= FileTools.MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
+	}
+
+	public void testShortenFileNameURLInt() throws Exception {
+		if (SystemTools.osIsWindows()) {
+			this.verifyShortenFileNameURLIntWin();
+		} else {
+			this.verifyShortenFileNameURLIntNonWin();
+		}
+	}
+
+	private void verifyShortenFileNameURLIntWin() throws Exception {
+		URL url = new URL("file", "", "/C:/Documents and Settings/Administrator/Desktop/Project/Text.txt");
+		String fileName = FileTools.shortenFileName(url, 31);
+		assertEquals("C:\\...\\Desktop\\Project\\Text.txt", fileName);
+		assertEquals(31, fileName.length());
+	}
+
+	private void verifyShortenFileNameURLIntNonWin() throws Exception {
+		URL url = new URL("file", "", "/home/administrator/documents and settings/desktop/Project/Text.txt");
+		String fileName = FileTools.shortenFileName(url, 31);
+		assertEquals("/home/.../desktop/Project/Text.txt", fileName);
+		assertEquals(34, fileName.length());
+	}
+
+	private void verifyUnchangedAbsoluteFile(String fileName, String dirName) {
+		File file = new File(fileName);
+		File dir = new File(dirName);
+		File absoluteFile = FileTools.convertToAbsoluteFile(file, dir);
+		assertEquals(file, absoluteFile);
+	}
+
+	private File buildTempDir() throws IOException {
+		// build a new directory for each test, to prevent any cross-test effects
+		File dir = FileTools.newTemporaryDirectory(this.getClass().getSimpleName() + "." + this.getName());
+
+		File file0a = new File(dir, "file0a");
+		file0a.createNewFile();
+		File file0b = new File(dir, "file0b");
+		file0b.createNewFile();
+		File file0c = new File(dir, "file0c");
+		file0c.createNewFile();
+
+		File subdir1 = new File(dir, "subdir1");
+		subdir1.mkdir();
+		File file1a = new File(subdir1, "file1a");
+		file1a.createNewFile();
+		File file1b = new File(subdir1, "file1b");
+		file1b.createNewFile();
+
+		File subdir2 = new File(dir, "subdir2");
+		subdir2.mkdir();
+		File file2a = new File(subdir2, "file2a");
+		file2a.createNewFile();
+		File file2b = new File(subdir2, "file2b");
+		file2b.createNewFile();
+
+		File subdir3 = new File(subdir2, "subdir3");
+		subdir3.mkdir();
+		File file3a = new File(subdir3, "file3a");
+		file3a.createNewFile();
+		File file3b = new File(subdir3, "file3b");
+		file3b.createNewFile();
+
+		return dir;
+	}
+
+	private void deleteDir(File dir) {
+		FileTools.deleteDirectory(dir);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/IndentingPrintWriterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/IndentingPrintWriterTests.java
new file mode 100644
index 0000000..f9d8118
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/IndentingPrintWriterTests.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.io;
+
+import java.io.StringWriter;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.io.IndentingPrintWriter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class IndentingPrintWriterTests extends TestCase {
+	StringWriter sw1;
+	StringWriter sw2;
+	IndentingPrintWriter ipw1;
+	IndentingPrintWriter ipw2;
+
+	static final String CR = System.getProperty("line.separator");
+
+	public IndentingPrintWriterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	public void setUp() throws Exception {
+		super.setUp();
+		this.sw1 = new StringWriter();
+		this.ipw1 = new IndentingPrintWriter(this.sw1);
+		this.sw2 = new StringWriter();
+		this.ipw2 = new IndentingPrintWriter(this.sw2, "    "); // indent with 4 spaces instead of a tab
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testIndent() {
+		assertEquals("wrong indent level", 0, this.ipw1.getIndentLevel());
+		this.ipw1.indent();
+		assertEquals("wrong indent level", 1, this.ipw1.getIndentLevel());
+	}
+
+	public void testUndent() {
+		assertEquals("wrong indent level", 0, this.ipw1.getIndentLevel());
+		this.ipw1.indent();
+		assertEquals("wrong indent level", 1, this.ipw1.getIndentLevel());
+		this.ipw1.undent();
+		assertEquals("wrong indent level", 0, this.ipw1.getIndentLevel());
+	}
+
+	public void testIncrementIndentLevel() {
+		assertEquals("wrong indent level", 0, this.ipw1.getIndentLevel());
+		this.ipw1.incrementIndentLevel();
+		assertEquals("wrong indent level", 1, this.ipw1.getIndentLevel());
+	}
+
+	public void testDecrementIndentLevel() {
+		assertEquals("wrong indent level", 0, this.ipw1.getIndentLevel());
+		this.ipw1.incrementIndentLevel();
+		assertEquals("wrong indent level", 1, this.ipw1.getIndentLevel());
+		this.ipw1.decrementIndentLevel();
+		assertEquals("wrong indent level", 0, this.ipw1.getIndentLevel());
+	}
+
+	public void testPrintTab() {
+		String expected = "foo0" + CR + "\tfoo1" + CR + "\tfoo1" + CR + "\t\tfoo2" + CR + "\tfoo1" + CR + "\tfoo1" + CR + "foo0" + CR;
+
+		this.ipw1.println("foo0");
+		this.ipw1.indent();
+		this.ipw1.println("foo1");
+		this.ipw1.println("foo1");
+		this.ipw1.indent();
+		this.ipw1.println("foo2");
+		this.ipw1.undent();
+		this.ipw1.println("foo1");
+		this.ipw1.println("foo1");
+		this.ipw1.undent();
+		this.ipw1.println("foo0");
+
+		assertEquals("bogus output", expected, this.sw1.toString());
+	}
+
+	public void testPrintSpaces() {
+		String expected = "foo0" + CR + "    foo1" + CR + "    foo1" + CR + "        foo2" + CR + "    foo1" + CR + "    foo1" + CR + "foo0" + CR;
+
+		this.ipw2.println("foo0");
+		this.ipw2.indent();
+		this.ipw2.println("foo1");
+		this.ipw2.println("foo1");
+		this.ipw2.indent();
+		this.ipw2.println("foo2");
+		this.ipw2.undent();
+		this.ipw2.println("foo1");
+		this.ipw2.println("foo1");
+		this.ipw2.undent();
+		this.ipw2.println("foo0");
+
+		assertEquals("bogus output", expected, this.sw2.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/InvalidInputStreamTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/InvalidInputStreamTests.java
new file mode 100644
index 0000000..f41b7d8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/InvalidInputStreamTests.java
@@ -0,0 +1,111 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.io;

+

+import java.io.IOException;

+import java.io.InputStream;

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.io.InvalidInputStream;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+public class InvalidInputStreamTests

+	extends TestCase

+{

+	private InputStream invalidInputStream;

+

+

+	public InvalidInputStreamTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.invalidInputStream = InvalidInputStream.instance();

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testAvailable() throws IOException {

+		assertEquals(0, this.invalidInputStream.available());

+	}

+

+	public void testClose() throws IOException {

+		this.invalidInputStream.close();

+	}

+

+	public void testMark() {

+		this.invalidInputStream.mark(100);

+	}

+

+	public void testMarkSupported() {

+		assertFalse(this.invalidInputStream.markSupported());

+	}

+

+	public void testRead() throws IOException {

+		boolean exCaught = false;

+		try {

+			this.invalidInputStream.read();

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testReadByteArray() throws IOException {

+		byte[] b = new byte[10];

+		boolean exCaught = false;

+		try {

+			this.invalidInputStream.read(b);

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testReadByteArrayIntInt() throws IOException {

+		byte[] b = new byte[10];

+		boolean exCaught = false;

+		try {

+			this.invalidInputStream.read(b, 3, 2);

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testReset() {

+		boolean exCaught = false;

+		try {

+			this.invalidInputStream.reset();

+		} catch (IOException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testSkip() throws IOException {

+		boolean exCaught = false;

+		try {

+			this.invalidInputStream.skip(44);

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/InvalidOutputStreamTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/InvalidOutputStreamTests.java
new file mode 100644
index 0000000..f9d3186
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/InvalidOutputStreamTests.java
@@ -0,0 +1,83 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.io;

+

+import java.io.IOException;

+import java.io.OutputStream;

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.io.InvalidOutputStream;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+public class InvalidOutputStreamTests

+	extends TestCase

+{

+	private OutputStream invalidOutputStream;

+

+

+	public InvalidOutputStreamTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.invalidOutputStream = InvalidOutputStream.instance();

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testClose() throws IOException {

+		this.invalidOutputStream.close();

+	}

+

+	public void testFlush() throws IOException {

+		this.invalidOutputStream.flush();

+	}

+

+	public void testWriteByteArray() throws IOException {

+		byte[] b = new byte[10];

+		boolean exCaught = false;

+		try {

+			this.invalidOutputStream.write(b);

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testWriteByteArrayIntInt() throws IOException {

+		byte[] b = new byte[10];

+		boolean exCaught = false;

+		try {

+			this.invalidOutputStream.write(b, 3, 2);

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testWriteInt() throws IOException {

+		boolean exCaught = false;

+		try {

+			this.invalidOutputStream.write(77);

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/InvalidReaderTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/InvalidReaderTests.java
new file mode 100644
index 0000000..de3c4f5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/InvalidReaderTests.java
@@ -0,0 +1,117 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.io;

+

+import java.io.IOException;

+import java.io.Reader;

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.io.InvalidReader;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+public class InvalidReaderTests

+	extends TestCase

+{

+	private Reader invalidReader;

+

+

+	public InvalidReaderTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.invalidReader = InvalidReader.instance();

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testClose() throws IOException {

+		this.invalidReader.close();

+	}

+

+	public void testMark() {

+		boolean exCaught = false;

+		try {

+			this.invalidReader.mark(100);

+		} catch (IOException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testMarkSupported() {

+		assertFalse(this.invalidReader.markSupported());

+	}

+

+	public void testRead() throws IOException {

+		boolean exCaught = false;

+		try {

+			this.invalidReader.read();

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testReadCharArray() throws IOException {

+		char[] cbuf = new char[10];

+		boolean exCaught = false;

+		try {

+			this.invalidReader.read(cbuf);

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testReadCharArrayIntInt() throws IOException {

+		char[] cbuf = new char[10];

+		boolean exCaught = false;

+		try {

+			this.invalidReader.read(cbuf, 3, 2);

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testReady() throws IOException {

+		assertFalse(this.invalidReader.ready());

+	}

+

+	public void testReset() {

+		boolean exCaught = false;

+		try {

+			this.invalidReader.reset();

+		} catch (IOException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testSkip() throws IOException {

+		boolean exCaught = false;

+		try {

+			this.invalidReader.skip(44);

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/InvalidWriterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/InvalidWriterTests.java
new file mode 100644
index 0000000..7a25e1e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/InvalidWriterTests.java
@@ -0,0 +1,104 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.io;

+

+import java.io.IOException;

+import java.io.Writer;

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.io.InvalidWriter;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+@SuppressWarnings("nls")

+public class InvalidWriterTests

+	extends TestCase

+{

+	private Writer invalidWriter;

+

+

+	public InvalidWriterTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.invalidWriter = InvalidWriter.instance();

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testClose() throws IOException {

+		this.invalidWriter.close();

+	}

+

+	public void testFlush() throws IOException {

+		this.invalidWriter.flush();

+	}

+

+	public void testWriteCharArray() throws IOException {

+		char[] cbuf = new char[10];

+		boolean exCaught = false;

+		try {

+			this.invalidWriter.write(cbuf);

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testWriteCharArrayIntInt() throws IOException {

+		char[] cbuf = new char[10];

+		boolean exCaught = false;

+		try {

+			this.invalidWriter.write(cbuf, 3, 2);

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testWriteInt() throws IOException {

+		boolean exCaught = false;

+		try {

+			this.invalidWriter.write(77);

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testWriteString() throws IOException {

+		boolean exCaught = false;

+		try {

+			this.invalidWriter.write("cbuf");

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testWriteStringIntInt() throws IOException {

+		boolean exCaught = false;

+		try {

+			this.invalidWriter.write("cbuf", 1, 2);

+		} catch (UnsupportedOperationException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/NullInputStreamTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/NullInputStreamTests.java
new file mode 100644
index 0000000..19b3bd5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/NullInputStreamTests.java
@@ -0,0 +1,96 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.io;

+

+import java.io.IOException;

+import java.io.InputStream;

+import java.util.Arrays;

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.io.NullInputStream;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+public class NullInputStreamTests

+	extends TestCase

+{

+	private InputStream nullInputStream;

+

+

+	public NullInputStreamTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.nullInputStream = NullInputStream.instance();

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testAvailable() throws IOException {

+		assertEquals(0, this.nullInputStream.available());

+	}

+

+	public void testClose() throws IOException {

+		this.nullInputStream.close();

+	}

+

+	public void testMark() {

+		this.nullInputStream.mark(5);

+	}

+

+	public void testMarkSupported() {

+		assertFalse(this.nullInputStream.markSupported());

+	}

+

+	public void testRead() throws IOException {

+		assertEquals(-1, this.nullInputStream.read());

+	}

+

+	public void testReadByteArray() throws IOException {

+		byte[] expected = new byte[10];

+		Arrays.fill(expected, (byte) 7);

+		byte[] actual = new byte[10];

+		Arrays.fill(actual, (byte) 7);

+		assertEquals(-1, this.nullInputStream.read(actual));

+		assertTrue(Arrays.equals(actual, expected));

+	}

+

+	public void testReadByteArrayIntInt() throws IOException {

+		byte[] expected = new byte[10];

+		Arrays.fill(expected, (byte) 7);

+		byte[] actual = new byte[10];

+		Arrays.fill(actual, (byte) 7);

+		assertEquals(-1, this.nullInputStream.read(actual, 2, 5));

+		assertTrue(Arrays.equals(actual, expected));

+	}

+

+	public void testReset() {

+		boolean exCaught = false;

+		try {

+			this.nullInputStream.reset();

+		} catch (IOException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testSkip() throws IOException {

+		assertEquals(0, this.nullInputStream.skip(5));

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/NullOutputStreamTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/NullOutputStreamTests.java
new file mode 100644
index 0000000..ede5c47
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/NullOutputStreamTests.java
@@ -0,0 +1,68 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.io;

+

+import java.io.IOException;

+import java.io.OutputStream;

+import java.util.Arrays;

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.io.NullOutputStream;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+public class NullOutputStreamTests

+	extends TestCase

+{

+	private OutputStream nullOutputStream;

+

+

+	public NullOutputStreamTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.nullOutputStream = NullOutputStream.instance();

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testClose() throws IOException {

+		this.nullOutputStream.close();

+	}

+

+	public void testFlush() throws IOException {

+		this.nullOutputStream.flush();

+	}

+

+	public void testWriteByteArray() throws IOException {

+		byte[] byteArray = new byte[10];

+		Arrays.fill(byteArray, (byte) 7);

+		this.nullOutputStream.write(byteArray);

+	}

+

+	public void testWriteByteArrayIntInt() throws IOException {

+		byte[] byteArray = new byte[10];

+		Arrays.fill(byteArray, (byte) 7);

+		this.nullOutputStream.write(byteArray, 2, 5);

+	}

+

+	public void testWriteInt() throws IOException {

+		this.nullOutputStream.write(10);

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/NullReaderTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/NullReaderTests.java
new file mode 100644
index 0000000..8f41532
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/NullReaderTests.java
@@ -0,0 +1,102 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.io;

+

+import java.io.IOException;

+import java.io.Reader;

+import java.util.Arrays;

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.io.NullReader;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+public class NullReaderTests

+	extends TestCase

+{

+	private Reader nullReader;

+

+

+	public NullReaderTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.nullReader = NullReader.instance();

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testClose() throws IOException {

+		this.nullReader.close();

+	}

+

+	public void testRead() throws IOException {

+		assertEquals(-1, this.nullReader.read());

+	}

+

+	public void testReadCharArray() throws IOException {

+		char[] expected = new char[10];

+		Arrays.fill(expected, 'a');

+		char[] actual = new char[10];

+		Arrays.fill(actual, 'a');

+		assertEquals(-1, this.nullReader.read(actual));

+		assertTrue(Arrays.equals(actual, expected));

+	}

+

+	public void testReadCharArrayIntInt() throws IOException {

+		char[] expected = new char[10];

+		Arrays.fill(expected, 'a');

+		char[] actual = new char[10];

+		Arrays.fill(actual, 'a');

+		assertEquals(-1, this.nullReader.read(actual, 2, 5));

+		assertTrue(Arrays.equals(actual, expected));

+	}

+

+	public void testSkip() throws IOException {

+		assertEquals(0, this.nullReader.skip(5));

+	}

+

+	public void testMark() {

+		boolean exCaught = false;

+		try {

+			this.nullReader.mark(5);

+		} catch (IOException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+

+	public void testMarkSupported() {

+		assertFalse(this.nullReader.markSupported());

+	}

+

+	public void testReady() {

+		assertFalse(this.nullReader.markSupported());

+	}

+

+	public void testReset() {

+		boolean exCaught = false;

+		try {

+			this.nullReader.reset();

+		} catch (IOException ex) {

+			exCaught = true;

+		}

+		assertTrue(exCaught);

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/NullWriterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/NullWriterTests.java
new file mode 100644
index 0000000..15393b5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/NullWriterTests.java
@@ -0,0 +1,75 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.io;

+

+import java.io.IOException;

+import java.io.Writer;

+import java.util.Arrays;

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.io.NullWriter;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+@SuppressWarnings("nls")

+public class NullWriterTests

+	extends TestCase

+{

+	private Writer nullWriter;

+

+

+	public NullWriterTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.nullWriter = NullWriter.instance();

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testWriteCharArrayIntInt() throws IOException {

+		this.nullWriter.write(new char[10], 2, 5);

+	}

+

+	public void testFlush() throws IOException {

+		this.nullWriter.flush();

+	}

+

+	public void testClose() throws IOException {

+		this.nullWriter.close();

+	}

+

+	public void testWriteCharArray() throws IOException {

+		char[] charArray = new char[10];

+		Arrays.fill(charArray, 'a');

+		this.nullWriter.write(charArray);

+	}

+

+	public void testWriteInt() throws IOException {

+		this.nullWriter.write(10);

+	}

+

+	public void testWriteStringIntInt() throws IOException {

+		this.nullWriter.write("0123456789", 2, 5);

+	}

+

+	public void testWriteString() throws IOException {

+		this.nullWriter.write("0123456789");

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/PipeTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/PipeTests.java
new file mode 100644
index 0000000..0e70e26
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/PipeTests.java
@@ -0,0 +1,455 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.io;

+

+import java.io.InputStream;

+import java.io.InterruptedIOException;

+import java.io.OutputStream;

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.io.Pipe;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+@SuppressWarnings("nls")

+public class PipeTests

+	extends TestCase

+{

+	volatile Pipe pipe;

+	volatile byte[] buffer;

+	volatile int position;

+	volatile String string;

+	volatile boolean exCaught;

+

+

+	public PipeTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.pipe = new Pipe(10);

+		this.buffer = new byte[1000];

+		this.position = 0;

+		this.string = "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.";

+		this.exCaught = false;

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	/**

+	 * test with a normal writer and normal reader

+	 */

+	public void testPipe() throws Exception {

+		this.verifyPipe(this.buildWriteRunnable(), this.buildReadRunnable());

+	}

+

+	/**

+	 * test with a 1-byte writer and a normal reader

+	 */

+	public void testPipeWrite1() throws Exception {

+		this.verifyPipe(this.buildWriteRunnable1(), this.buildReadRunnable());

+	}

+

+	/**

+	 * test with a normal writer and a 1-byte reader

+	 */

+	public void testPipeRead1() throws Exception {

+		this.verifyPipe(this.buildWriteRunnable(), this.buildReadRunnable1());

+	}

+

+	/**

+	 * test with a 1-byte writer and a 1-byte reader

+	 */

+	public void testPipeWrite1Read1() throws Exception {

+		this.verifyPipe(this.buildWriteRunnable1(), this.buildReadRunnable1());

+	}

+

+	private void verifyPipe(Runnable writer, Runnable reader)  throws Exception {

+		Thread readThread = new Thread(reader);

+		readThread.start();

+		writer.run();

+		readThread.join();

+		assertFalse(this.exCaught);

+		assertEquals(this.string, new String(this.buffer, 0, this.position));

+	}

+

+	/**

+	 * test with a normal writer and a normal reader

+	 */

+	public void testPipeTruncate() throws Exception {

+		this.verifyPipeTruncate(this.buildWriteRunnable(), this.buildReadRunnable());

+	}

+

+	/**

+	 * test with a 1-byte writer and a normal reader

+	 */

+	public void testPipeTruncateWrite1() throws Exception {

+		this.verifyPipeTruncate(this.buildWriteRunnable1(), this.buildReadRunnable());

+	}

+

+	/**

+	 * test with a normal writer and 1-byte reader

+	 */

+	public void testPipeTruncateRead1() throws Exception {

+		this.verifyPipeTruncate(this.buildWriteRunnable(), this.buildReadRunnable1());

+	}

+

+	/**

+	 * test with a 1-byte writer and 1-byte reader

+	 */

+	public void testPipeTruncateWrite1Read1() throws Exception {

+		this.verifyPipeTruncate(this.buildWriteRunnable1(), this.buildReadRunnable1());

+	}

+

+	private void verifyPipeTruncate(Runnable writer, Runnable reader) throws Exception {

+		// use a buffer that will truncate the string

+		this.buffer = new byte[20];

+		Thread readThread = new Thread(reader);

+		readThread.start();

+		writer.run();

+		readThread.join();

+		assertFalse(this.exCaught);

+		assertEquals(this.string.substring(0, 20), new String(this.buffer, 0, this.position));

+	}

+

+	private Runnable buildWriteRunnable() {

+		return new Runnable() {

+			@Override

+			public void run() {

+				@SuppressWarnings("resource")

+				OutputStream out = PipeTests.this.pipe.getOutputStream();

+				try {

+					out.write(PipeTests.this.string.getBytes());

+					out.close();

+				} catch (Exception ex) {

+					// the pipe will be closed when the read buffer is full

+					if ( ! ex.getMessage().equals("Pipe closed")) {

+						PipeTests.this.exCaught = true;

+						ex.printStackTrace();

+					}

+				}

+			}

+		};

+	}

+

+	/**

+	 * build a writer that writes 1 byte at a time

+	 */

+	private Runnable buildWriteRunnable1() {

+		return new Runnable() {

+			@Override

+			public void run() {

+				@SuppressWarnings("resource")

+				OutputStream out = PipeTests.this.pipe.getOutputStream();

+				try {

+					byte[] bytes = PipeTests.this.string.getBytes();

+					for (byte b : bytes) {

+						out.write(b);

+					}

+					out.close();

+				} catch (Exception ex) {

+					// the pipe will be closed when the read buffer is full

+					if ( ! ex.getMessage().equals("Pipe closed")) {

+						PipeTests.this.exCaught = true;

+						ex.printStackTrace();

+					}

+				}

+			}

+		};

+	}

+

+	private Runnable buildReadRunnable() {

+		return new Runnable() {

+			@Override

+			public void run() {

+				try {

+					InputStream in = PipeTests.this.pipe.getInputStream();

+					int len = PipeTests.this.buffer.length;

+					int bytesRead = 0;

+					do {

+						if (len <= 0) {

+							in.close();

+							return;

+						}

+						bytesRead = in.read(PipeTests.this.buffer, PipeTests.this.position, len);

+						if (bytesRead != -1) {

+							PipeTests.this.position += bytesRead;

+							len -= bytesRead;

+						}

+					} while (bytesRead != -1);

+					in.close();

+				} catch (Exception ex) {

+					PipeTests.this.exCaught = true;

+					ex.printStackTrace();

+				}

+			}

+		};

+	}

+

+	/**

+	 * build a reader that reads 1 byte at a time

+	 */

+	private Runnable buildReadRunnable1() {

+		return new Runnable() {

+			@Override

+			public void run() {

+				try {

+					InputStream in = PipeTests.this.pipe.getInputStream();

+					int len = PipeTests.this.buffer.length;

+					int b = -1;

+					do {

+						if (len <= 0) {

+							in.close();

+							return;

+						}

+						b = in.read();

+						if (b != -1) {

+							PipeTests.this.buffer[PipeTests.this.position] = (byte) b;

+							PipeTests.this.position++;

+							len--;

+						}

+					} while (b != -1);

+					in.close();

+				} catch (Exception ex) {

+					PipeTests.this.exCaught = true;

+					ex.printStackTrace();

+				}

+			}

+		};

+	}

+

+	public void testAvailable() throws Exception {

+		// use a bigger pipe so the entire string can be buffered at once

+		this.pipe = new Pipe(5000);

+		this.buildWriteRunnable().run();

+		assertEquals(this.string.length(), this.pipe.getInputStream().available());

+		byte[] bytes = new byte[20];

+		this.pipe.getInputStream().read(bytes);

+		assertEquals(this.string.substring(0, 20), new String(bytes));

+		assertEquals(this.string.length() - 20, this.pipe.getInputStream().available());

+	}

+

+	public void testFullPipe() throws Exception {

+		this.verifyFullPipe(this.buildWriteRunnable(), this.buildReadRunnable());

+	}

+

+	public void testFullPipe1() throws Exception {

+		this.verifyFullPipe(this.buildWriteRunnable1(), this.buildReadRunnable1());

+	}

+

+	private void verifyFullPipe(Runnable writer, Runnable reader) throws Exception {

+		this.pipe = new Pipe(5);

+		this.string = "12345";

+		int len = this.string.length();

+		this.buffer = new byte[len];

+		// this write should not block

+		writer.run();

+		reader.run();

+		assertEquals(this.string, new String(this.buffer, 0, len));

+	}

+

+	public void testPipeLaps() throws Exception {

+		this.pipe = new Pipe(10);

+		@SuppressWarnings("resource")

+		OutputStream out = this.pipe.getOutputStream();

+		@SuppressWarnings("resource")

+		InputStream in = this.pipe.getInputStream();

+		this.string = "0123456789";

+		// fill the pipe - this write should not block

+		out.write(this.string.getBytes());

+		assertEquals(10, in.available());

+		// read half the bytes

+		int bytesRead = in.read(this.buffer, 0, 5);

+		assertEquals(5, in.available());

+		assertEquals(5, bytesRead);

+		assertEquals("01234", new String(this.buffer, 0, 5));

+

+		// fill the pipe again

+		this.string = "abcde";

+		out.write(this.string.getBytes());

+		assertEquals(10, in.available());

+		// read all the bytes, which are wrapped in the pipe

+		bytesRead = in.read(this.buffer, 0, 10);

+		assertEquals(0, in.available());

+		assertEquals(10, bytesRead);

+		assertEquals("56789abcde", new String(this.buffer, 0, 10));

+	}

+

+	public void testPipeLaps1() throws Exception {

+		this.pipe = new Pipe(10);

+		@SuppressWarnings("resource")

+		OutputStream out = this.pipe.getOutputStream();

+		@SuppressWarnings("resource")

+		InputStream in = this.pipe.getInputStream();

+		this.string = "0123456789";

+		// fill the pipe - this write should not block

+		byte[] bytes = this.string.getBytes();

+		for (byte b : bytes) {

+			out.write(b);

+		}

+		assertEquals(10, in.available());

+		// read half the bytes

+		for (int i = 0; i < 5; i++) {

+			this.buffer[i] = (byte) in.read();

+		}

+		assertEquals(5, in.available());

+		assertEquals("01234", new String(this.buffer, 0, 5));

+

+		// fill the pipe again

+		this.string = "abcde";

+		bytes = this.string.getBytes();

+		for (byte b : bytes) {

+			out.write(b);

+		}

+		assertEquals(10, in.available());

+		// read all the bytes, which are wrapped in the pipe

+		for (int i = 0; i < 10; i++) {

+			this.buffer[i] = (byte) in.read();

+		}

+		assertEquals(0, in.available());

+		assertEquals("56789abcde", new String(this.buffer, 0, 10));

+	}

+

+	public void testTimeout() throws Exception {

+		this.pipe = new Pipe(100, 100L);

+		boolean timeout = false;

+		try {

+			this.pipe.getInputStream().read(new byte[50]);

+		} catch (InterruptedIOException ex) {

+			// the pipe should already be closed

+			timeout = true;

+		}

+		assertTrue(timeout);

+	}

+

+	public void testRecloseWriteStream() throws Exception {

+		this.testPipe();

+		boolean closeFailed = false;

+		try {

+			this.pipe.getOutputStream().close();

+		} catch (IllegalStateException ex) {

+			// the pipe should already be closed

+			if (ex.getMessage().equals("OutputStream already closed")) {

+				closeFailed = true;

+			} else {

+				throw ex;

+			}

+		}

+		assertTrue(closeFailed);

+	}

+

+	public void testRecloseReadStream() throws Exception {

+		this.testPipe();

+		boolean closeFailed = false;

+		try {

+			this.pipe.getInputStream().close();

+		} catch (IllegalStateException ex) {

+			// the pipe should already be closed

+			if (ex.getMessage().equals("InputStream already closed")) {

+				closeFailed = true;

+			} else {

+				throw ex;

+			}

+		}

+		assertTrue(closeFailed);

+	}

+

+	public void testMultipleThreads() throws Exception {

+		Thread rt1 = new Thread(this.buildReadRunnable(2));

+		rt1.start();

+

+		Thread rt2 = new Thread(this.buildReadRunnable(2));

+		rt2.start();

+

+		String string1 = "abcdefghijklmnopqrstuvwxyz";

+		Thread wt1 = new Thread(this.buildWriteRunnable(string1.getBytes(), 3));

+		wt1.start();

+

+		String string2 = "01234567890123456789";

+		Thread wt2 = new Thread(this.buildWriteRunnable(string2.getBytes(), 3));

+		wt2.start();

+

+		wt2.join();

+		wt1.join();

+		this.pipe.getOutputStream().close();

+		rt2.join();

+		rt1.join();

+

+		// we just want to make sure the above code does not suspend

+		// indefinitely or trigger a deadlock; uncomment the appropriate line

+		// in #buildReadRunnable(int) to see the results on the console - it

+		// will probably look something like this:

+		//     abc012def345ghi678jkl901mno234pqr567stu89vwxyz

+		assertFalse(this.exCaught);

+	}

+

+	private Runnable buildReadRunnable(final int chunkSize) {

+		return new Runnable() {

+			@Override

+			public void run() {

+				try {

+					@SuppressWarnings("resource")

+					InputStream in = PipeTests.this.pipe.getInputStream();

+					byte[] bytes = new byte[chunkSize];

+					boolean moreBytes = true;

+					while (moreBytes) {

+						int totalBytesRead = 0;

+						while (totalBytesRead < chunkSize) {

+							int bytesRead = in.read(bytes, totalBytesRead, bytes.length - totalBytesRead);

+							if (bytesRead == -1) {

+								moreBytes = false;

+								break;

+							}

+							totalBytesRead += bytesRead;

+						}

+						// uncomment the following line to see what happens

+						// System.out.print(new String(bytes, 0, totalBytesRead));

+						Thread.sleep(100);

+					}

+				} catch (Exception ex) {

+					PipeTests.this.exCaught = true;

+					ex.printStackTrace();

+				}

+			}

+		};

+	}

+

+	private Runnable buildWriteRunnable(final byte[] bytes, final int chunkSize) {

+		return new Runnable() {

+			@Override

+			public void run() {

+				try {

+					@SuppressWarnings("resource")

+					OutputStream out = PipeTests.this.pipe.getOutputStream();

+					int totalBytesWritten = 0;

+					int remainingBytes = bytes.length;

+					while (remainingBytes > 0) {

+						int bytesWritten = Math.min(chunkSize, remainingBytes);

+						out.write(bytes, totalBytesWritten, bytesWritten);

+						totalBytesWritten += bytesWritten;

+						remainingBytes -= bytesWritten;

+						Thread.sleep(100);

+					}

+				} catch (Exception ex) {

+					PipeTests.this.exCaught = true;

+					ex.printStackTrace();

+				}

+			}

+		};

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/StringBufferWriterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/StringBufferWriterTests.java
new file mode 100644
index 0000000..a6a73c5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/StringBufferWriterTests.java
@@ -0,0 +1,71 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.io;

+

+import junit.framework.TestCase;

+import org.eclipse.persistence.tools.utility.io.StringBufferWriter;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+@SuppressWarnings("nls")

+public class StringBufferWriterTests

+	extends TestCase

+{

+	private StringBufferWriter writer;

+

+

+	public StringBufferWriterTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.writer = new StringBufferWriter();

+	}

+

+	@Override

+	protected void tearDown() throws Exception {

+		TestTools.clear(this);

+		super.tearDown();

+	}

+

+	public void testWriteInt() throws Exception {

+		this.writer.write('a');

+		this.writer.write('b');

+		this.writer.write('c');

+		assertEquals(3, this.writer.getBuffer().length());

+		assertEquals("abc", this.writer.toString());

+	}

+

+	public void testWriteCharArray() throws Exception {

+		this.writer.write(new char[] {'a', 'b', 'c'});

+		this.writer.write(new char[] {'a', 'b', 'c'});

+		assertEquals(6, this.writer.getBuffer().length());

+		assertEquals("abcabc", this.writer.toString());

+	}

+

+	public void testWriteString() throws Exception {

+		this.writer.write("abc");

+		this.writer.write("abc");

+		assertEquals(6, this.writer.getBuffer().length());

+		assertEquals("abcabc", this.writer.toString());

+	}

+

+	public void testWriteStringIntInt() throws Exception {

+		this.writer.write("abc", 1, 2);

+		this.writer.write("abc", 2, 1);

+		assertEquals(3, this.writer.getBuffer().length());

+		assertEquals("bcc", this.writer.toString());

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/StringBuilderWriterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/StringBuilderWriterTests.java
new file mode 100644
index 0000000..8f8f412
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/StringBuilderWriterTests.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.io;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.io.StringBuilderWriter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class StringBuilderWriterTests
+	extends TestCase
+{
+	private StringBuilderWriter writer;
+
+
+	public StringBuilderWriterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.writer = new StringBuilderWriter();
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testWriteInt() throws Exception {
+		this.writer.write('a');
+		this.writer.write('b');
+		this.writer.write('c');
+		assertEquals(3, this.writer.getBuilder().length());
+		assertEquals("abc", this.writer.toString());
+	}
+
+	public void testWriteCharArray() throws Exception {
+		this.writer.write(new char[] {'a', 'b', 'c'});
+		this.writer.write(new char[] {'a', 'b', 'c'});
+		assertEquals(6, this.writer.getBuilder().length());
+		assertEquals("abcabc", this.writer.toString());
+	}
+
+	public void testWriteString() throws Exception {
+		this.writer.write("abc");
+		this.writer.write("abc");
+		assertEquals(6, this.writer.getBuilder().length());
+		assertEquals("abcabc", this.writer.toString());
+	}
+
+	public void testWriteStringIntInt() throws Exception {
+		this.writer.write("abc", 1, 2);
+		this.writer.write("abc", 2, 1);
+		assertEquals(3, this.writer.getBuilder().length());
+		assertEquals("bcc", this.writer.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/WriterToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/WriterToolsTests.java
new file mode 100644
index 0000000..7468ed9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/io/WriterToolsTests.java
@@ -0,0 +1,472 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.io;
+
+import java.io.StringWriter;
+import java.io.Writer;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.io.WriterTools;
+import org.eclipse.persistence.tools.utility.tests.StringToolsTests;
+
+@SuppressWarnings("nls")
+public class WriterToolsTests
+	extends TestCase
+{
+	public WriterToolsTests(String name) {
+		super(name);
+	}
+
+	// ********** padding/truncating/centering **********
+
+	public void testCenter() throws Exception {
+		this.verifyCenter("fred", "fred", 4);
+		this.verifyCenter(" fred ", "fred", 6);
+		this.verifyCenter(" fred  ", "fred", 7);
+		this.verifyCenter("re", "fred", 2);
+		this.verifyCenter("fre", "fred", 3);
+	}
+
+	private void verifyCenter(String expected, String s, int len) throws Exception {
+		Writer writer;
+		writer = new StringWriter();
+		WriterTools.center(writer, s, len);
+		assertEquals(expected, writer.toString());
+
+		writer = new StringWriter();
+		WriterTools.center(writer, s.toCharArray(), len);
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testPad() throws Exception {
+		Writer writer;
+		writer = new StringWriter();
+		WriterTools.pad(writer, "fred", 4);
+		assertEquals("fred", writer.toString());
+
+		writer = new StringWriter();
+		WriterTools.pad(writer, "fred", 6);
+		assertEquals("fred  ", writer.toString());
+
+		writer = new StringWriter();
+		boolean exThrown = false;
+		try {
+			WriterTools.pad(writer, "fred", 2);
+			fail();
+		} catch (IllegalArgumentException ex) {
+			exThrown = true;
+		}
+		assertTrue(exThrown);
+	}
+
+	public void testFit() throws Exception {
+		this.verifyFit("fred", "fred", 4);
+		this.verifyFit("fred  ", "fred", 6);
+		this.verifyFit("fr", "fred", 2);
+	}
+
+	private void verifyFit(String expected, String string, int length) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.fit(writer, string, length);
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testZeroPad() throws Exception {
+		Writer writer;
+		writer = new StringWriter();
+		WriterTools.zeroPad(writer, "1234", 4);
+		assertEquals("1234", writer.toString());
+
+		writer = new StringWriter();
+		WriterTools.zeroPad(writer, "1234", 6);
+		assertEquals("001234", writer.toString());
+
+		writer = new StringWriter();
+		boolean exThrown = false;
+		try {
+			WriterTools.zeroPad(writer, "1234", 2);
+			fail();
+		} catch (IllegalArgumentException ex) {
+			exThrown = true;
+		}
+		assertTrue(exThrown);
+	}
+
+	public void testZeroFit() throws Exception {
+		this.verifyZeroFit("1234", "1234", 4);
+		this.verifyZeroFit("001234", "1234", 6);
+		this.verifyZeroFit("34", "1234", 2);
+	}
+
+	private void verifyZeroFit(String expected, String string, int length) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.zeroFit(writer, string, length);
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testSeparateOnStringCharInt() throws Exception {
+		this.verifySeparate("012345", '-', 22, "012345");
+		this.verifySeparate("012345", '-',  6, "012345");
+		this.verifySeparate("012345", '-',  5, "01234-5");
+		this.verifySeparate("012345", '-',  4, "0123-45");
+		this.verifySeparate("012345", '-',  3, "012-345");
+		this.verifySeparate("012345", '-',  2, "01-23-45");
+		this.verifySeparate("012345", '-',  1, "0-1-2-3-4-5");
+	}
+
+	private void verifySeparate(String string, char separator, int segmentLength, String expected) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.separate(writer, string, separator, segmentLength);
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testSeparateOnCharArrayCharInt() throws Exception {
+		this.verifySeparateCharArray("012345", '-', 22, "012345");
+		this.verifySeparateCharArray("012345", '-',  6, "012345");
+		this.verifySeparateCharArray("012345", '-',  5, "01234-5");
+		this.verifySeparateCharArray("012345", '-',  4, "0123-45");
+		this.verifySeparateCharArray("012345", '-',  3, "012-345");
+		this.verifySeparateCharArray("012345", '-',  2, "01-23-45");
+		this.verifySeparateCharArray("012345", '-',  1, "0-1-2-3-4-5");
+	}
+
+	private void verifySeparateCharArray(String string, char separator, int segmentLength, String expected) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.separate(writer, string.toCharArray(), separator, segmentLength);
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testDelimit() throws Exception {
+		this.verifyDelimit("Employee", "123", "123Employee123");
+		this.verifyDelimit("123", "123", "123123123");
+		this.verifyDelimit("", "123", "123123");
+	}
+
+	private void verifyDelimit(String string, String delimiter, String expectedString) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.delimit(writer, string, delimiter);
+		assertEquals(expectedString, writer.toString());
+	}
+
+	public void testQuote() throws Exception {
+		this.verifyQuote("Employee", "\"Employee\"");
+		this.verifyQuote("123", "\"123\"");
+		this.verifyQuote("", "\"\"");
+		this.verifyQuote("Emp\"loyee", "\"Emp\"\"loyee\"");
+	}
+
+	private void verifyQuote(String string, String expectedString) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.quote(writer, string);
+		assertEquals(expectedString, writer.toString());
+	}
+
+	public void testRemoveFirstOccurrence() throws Exception {
+		this.verifyRemoveFirstOccurrence("Emplo&yee", '&', "Employee");
+		this.verifyRemoveFirstOccurrence("Emplo&yee&", '&', "Employee&");
+		this.verifyRemoveFirstOccurrence("Employee &Foo", '&', "Employee Foo");
+		this.verifyRemoveFirstOccurrence("Employee&", '&', "Employee");
+		this.verifyRemoveFirstOccurrence("&Employee", '&', "Employee");
+	}
+
+	private void verifyRemoveFirstOccurrence(String string, char charToRemove, String expectedString) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.removeFirstOccurrence(writer, string, charToRemove);
+		assertEquals(expectedString, writer.toString());
+	}
+
+	public void testRemoveAllOccurrences() throws Exception {
+		this.verifyRemoveAllOccurrences("Employee Fred", ' ', "EmployeeFred");
+		this.verifyRemoveAllOccurrences(" Employee ", ' ', "Employee");
+		this.verifyRemoveAllOccurrences("Employee   Foo", ' ', "EmployeeFoo");
+		this.verifyRemoveAllOccurrences(" Emp loyee   Foo", ' ', "EmployeeFoo");
+	}
+
+	private void verifyRemoveAllOccurrences(String string, char charToRemove, String expectedString) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.removeAllOccurrences(writer, string, charToRemove);
+		assertEquals(expectedString, writer.toString());
+	}
+
+	public void testRemoveAllWhitespace() throws Exception {
+		this.verifyRemoveAllWhitespace("Employee Fred\t", "EmployeeFred");
+		this.verifyRemoveAllWhitespace("\tEmployee\n", "Employee");
+		this.verifyRemoveAllWhitespace("Employee \t Foo", "EmployeeFoo");
+		this.verifyRemoveAllWhitespace(" Emp\tloyee \n Foo", "EmployeeFoo");
+	}
+
+	private void verifyRemoveAllWhitespace(String string, String expectedString) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.removeAllWhitespace(writer, string);
+		assertEquals(expectedString, writer.toString());
+	}
+
+	public void testCompressWhitespace() throws Exception {
+		this.verifyCompressWhitespace("Employee      Fred\t", "Employee Fred ");
+		this.verifyCompressWhitespace("\tEmployee  \n", " Employee ");
+		this.verifyCompressWhitespace("Employee \t Foo", "Employee Foo");
+		this.verifyCompressWhitespace(" Emp\tloyee \n Foo ", " Emp loyee Foo ");
+	}
+
+	private void verifyCompressWhitespace(String string, String expectedString) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.compressWhitespace(writer, string);
+		assertEquals(expectedString, writer.toString());
+	}
+
+	public void testCapitalizeOnStringWriter() throws Exception {
+		this.verifyCapitalizeOnStringWriter("Oracle", "Oracle");
+		this.verifyCapitalizeOnStringWriter("Oracle", "oracle");
+		this.verifyCapitalizeOnStringWriter("   ", "   ");
+		this.verifyCapitalizeOnStringWriter("ORACLE", "ORACLE");
+		this.verifyCapitalizeOnStringWriter("", "");
+		this.verifyCapitalizeOnStringWriter("A", "a");
+		this.verifyCapitalizeOnStringWriter("\u00C9cole", "\u00E9cole"); // e'cole -> E'cole
+	}
+
+	private void verifyCapitalizeOnStringWriter(String expected, String string) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.capitalize(writer, string);
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testCapitalizeOnCharArray() throws Exception {
+		this.verifyCapitalizeOnCharArray("Oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyCapitalizeOnCharArray("Oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyCapitalizeOnCharArray("   ", new char[] { ' ', ' ', ' ' });
+		this.verifyCapitalizeOnCharArray("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
+		this.verifyCapitalizeOnCharArray("", new char[0]);
+		this.verifyCapitalizeOnCharArray("A", new char[] { 'a' });
+		this.verifyCapitalizeOnCharArray("\u00C9cole", new char[] { '\u00E9', 'c', 'o', 'l', 'e' });
+	}
+
+	private void verifyCapitalizeOnCharArray(String expected, char[] string) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.capitalize(writer, string);
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testUncapitalizeOnStringWriter() throws Exception {
+		this.verifyUncapitalizeOnStringWriter("oracle", "Oracle");
+		this.verifyUncapitalizeOnStringWriter("oracle", "oracle");
+		this.verifyUncapitalizeOnStringWriter("   ", "   ");
+		this.verifyUncapitalizeOnStringWriter("ORACLE", "ORACLE");
+		this.verifyUncapitalizeOnStringWriter("", "");
+		this.verifyUncapitalizeOnStringWriter("a", "A");
+		this.verifyUncapitalizeOnStringWriter("\u00E9cole", "\u00C9cole"); // E'cole -> e'cole
+	}
+
+	private void verifyUncapitalizeOnStringWriter(String expected, String string) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.uncapitalize(writer, string);
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testUncapitalizeOnCharArray() throws Exception {
+		this.verifyUncapitalizeOnCharArray("oracle", new char[] { 'O', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyUncapitalizeOnCharArray("oracle", new char[] { 'o', 'r', 'a', 'c', 'l', 'e' });
+		this.verifyUncapitalizeOnCharArray("   ", new char[] { ' ', ' ', ' ' });
+		this.verifyUncapitalizeOnCharArray("ORACLE", new char[] { 'O', 'R', 'A', 'C', 'L', 'E' });
+		this.verifyUncapitalizeOnCharArray("", new char[0]);
+		this.verifyUncapitalizeOnCharArray("a", new char[] { 'A' });
+		this.verifyUncapitalizeOnCharArray("\u00E9cole", new char[] { '\u00C9', 'c', 'o', 'l', 'e' });
+	}
+
+	private void verifyUncapitalizeOnCharArray(String expected, char[] string) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.uncapitalize(writer, string);
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testConvertToHexString() throws Exception {
+		this.verifyConvertToHexString("74657374", "test"); // UTF-8 values
+	}
+
+	public void testConvertToHexString_negative() throws Exception {
+		this.verifyConvertToHexString(this.getHexCafe(), "caf\u00E9"); // UTF-8 values
+	}
+
+	private String getHexCafe() {
+		return StringToolsTests.getHexCafe();
+	}
+
+	private void verifyConvertToHexString(String expected, String string) throws Exception {
+		Writer sb = new StringWriter();
+		WriterTools.convertToHexString(sb, string.getBytes());
+		assertEquals(expected, sb.toString());
+	}
+
+	public void testConvertCamelCaseToAllCaps() throws Exception {
+		this.verifyConvertCamelCaseToAllCaps("TEST", "test");
+		this.verifyConvertCamelCaseToAllCaps("TEST", "TEST");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST", "testTest");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST", "TestTest");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST_TEST", "testTESTTest");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST_TEST", "TestTESTTest");
+		this.verifyConvertCamelCaseToAllCaps("TEST_TEST_TEST_T", "TestTESTTestT");
+	}
+
+	private void verifyConvertCamelCaseToAllCaps(String expected, String string) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.convertCamelCaseToAllCaps(writer, string);
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testConvertCamelCaseToAllCapsMaxLength() throws Exception {
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST", "test", 44);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST", "test", 4);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TES", "test", 3);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST", "TEST", 5);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TE", "TEST", 2);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TEST", "testTest", 9);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TES", "testTest", 8);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_T", "testTest", 6);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_", "testTest", 5);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST", "testTest", 4);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TEST", "TestTest", 9);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TEST", "TestTest", 1100);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TEST_", "testTESTTest", 10);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TEST_TEST", "TestTESTTest", 14);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TEST_TEST_T", "TestTESTTestT", 16);
+		this.verifyConvertCamelCaseToAllCapsMaxLength("TEST_TEST_TEST_", "TestTESTTestT", 15);
+	}
+
+	private void verifyConvertCamelCaseToAllCapsMaxLength(String expected, String string, int max) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.convertCamelCaseToAllCaps(writer, string, max);
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testConvertUnderscoresToCamelCase() throws Exception {
+		this.verifyConvertUnderscoresToCamelCase("test", "TEST", false);
+		this.verifyConvertUnderscoresToCamelCase("test", "TEST_", false);
+		this.verifyConvertUnderscoresToCamelCase("test", "TEST____", false);
+		this.verifyConvertUnderscoresToCamelCase("Test", "TEST", true);
+		this.verifyConvertUnderscoresToCamelCase("test", "TeST", false);
+		this.verifyConvertUnderscoresToCamelCase("testTest", "TEST_TEST", false);
+		this.verifyConvertUnderscoresToCamelCase("testTest", "TEST___TEST", false);
+		this.verifyConvertUnderscoresToCamelCase("TestTest", "TEST_TEST", true);
+		this.verifyConvertUnderscoresToCamelCase("testTestTest", "TEST_TEST_TEST", false);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTest", "TEST_TEST_TEST", true);
+		this.verifyConvertUnderscoresToCamelCase("testTestTestT", "TEST_TEST_TEST_T", false);
+		this.verifyConvertUnderscoresToCamelCase("testTestTestT", "_TEST_TEST_TEST_T", false);
+		this.verifyConvertUnderscoresToCamelCase("testTestTestT", "__TEST_TEST_TEST_T", false);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTestT", "TEST_TEST_TEST_T", true);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTestT", "_TEST_TEST_TEST_T", true);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTestT", "__TEST_TEST_TEST_T", true);
+	}
+
+	public void testConvertUnderscoresToCamelCaseLowercase() throws Exception {
+		this.verifyConvertUnderscoresToCamelCase("test", "test", false);
+		this.verifyConvertUnderscoresToCamelCase("test", "test_", false);
+		this.verifyConvertUnderscoresToCamelCase("test", "test____", false);
+		this.verifyConvertUnderscoresToCamelCase("Test", "test", true);
+		this.verifyConvertUnderscoresToCamelCase("test", "test", false);
+		this.verifyConvertUnderscoresToCamelCase("testTest", "test_test", false);
+		this.verifyConvertUnderscoresToCamelCase("testTest", "test___test", false);
+		this.verifyConvertUnderscoresToCamelCase("TestTest", "test_test", true);
+		this.verifyConvertUnderscoresToCamelCase("testTestTest", "test_test_test", false);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTest", "test_test_test", true);
+		this.verifyConvertUnderscoresToCamelCase("testTestTestT", "test_test_test_t", false);
+		this.verifyConvertUnderscoresToCamelCase("testTestTestT", "_test_test_test_t", false);
+		this.verifyConvertUnderscoresToCamelCase("testTestTestT", "__test_test_test_t", false);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTestT", "test_test_test_t", true);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTestT", "_test_test_test_t", true);
+		this.verifyConvertUnderscoresToCamelCase("TestTestTestT", "__test_test_test_t", true);
+	}
+
+	private void verifyConvertUnderscoresToCamelCase(String expected, String string, boolean capitalizeFirstLetter) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.convertAllCapsToCamelCase(writer, string, capitalizeFirstLetter);
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testUndelimit() throws Exception {
+		this.verifyUndelimit("\"foo\"", "foo");
+		this.verifyUndelimit("\"\"", "");
+		this.verifyUndelimit("'foo'", "foo");
+		this.verifyUndelimit("\"fo\"\"o\"", "fo\"o");
+		this.verifyUndelimit("\"foo\"\"\"", "foo\"");
+		this.verifyUndelimit("\"\"\"foo\"", "\"foo");
+		this.verifyUndelimit("[foo]", "foo");
+		this.verifyUndelimit("\"\"\"", "\"");
+		this.verifyUndelimit("\"foo\"bar\"", "foo\"");
+		this.verifyUndelimit("\"foo\"\"", "foo\"");
+	}
+
+	private void verifyUndelimit(String s, String expected) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.undelimit(writer, s);
+		assertEquals(expected, writer.toString());
+
+		writer = new StringWriter();
+		WriterTools.undelimit(writer, s.toCharArray());
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testUndelimitCount() throws Exception {
+		this.verifyUndelimitCount("\"foo\"", 2, "o");
+		this.verifyUndelimitCount("\"\"\"\"", 2, "");
+		this.verifyUndelimitCount("XXfooXX", 2, "foo");
+	}
+
+	private void verifyUndelimitCount(String s, int count, String expected) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.undelimit(writer, s, count);
+		assertEquals(expected, writer.toString());
+
+		writer = new StringWriter();
+		WriterTools.undelimit(writer, s.toCharArray(), count);
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testConvertToJavaStringLiteral() throws Exception {
+		this.verifyConvertToJavaStringLiteral("", "\"\"");
+		this.verifyConvertToJavaStringLiteral("\"\"", "\"\\\"\\\"\"");
+		this.verifyConvertToJavaStringLiteral("'foo'", "\"'foo'\"");
+		this.verifyConvertToJavaStringLiteral("foo\bbar", "\"foo\\bbar\"");
+		this.verifyConvertToJavaStringLiteral("foo\n\tbar", "\"foo\\n\\tbar\"");
+		this.verifyConvertToJavaStringLiteral("foo\"bar", "\"foo\\\"bar\"");
+		this.verifyConvertToJavaStringLiteral("foo\\bar", "\"foo\\\\bar\"");
+	}
+
+	private void verifyConvertToJavaStringLiteral(String s, String expected) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.convertToJavaStringLiteral(writer, s);
+		assertEquals(expected, writer.toString());
+
+		writer = new StringWriter();
+		WriterTools.convertToJavaStringLiteral(writer, s.toCharArray());
+		assertEquals(expected, writer.toString());
+	}
+
+	public void testConvertToJavaStringLiteralContent() throws Exception {
+		this.verifyConvertToJavaStringLiteralContent("", "");
+		this.verifyConvertToJavaStringLiteralContent("\"\"", "\\\"\\\"");
+		this.verifyConvertToJavaStringLiteralContent("'foo'", "'foo'");
+		this.verifyConvertToJavaStringLiteralContent("foo\bbar", "foo\\bbar");
+		this.verifyConvertToJavaStringLiteralContent("foo\n\tbar", "foo\\n\\tbar");
+		this.verifyConvertToJavaStringLiteralContent("foo\"bar", "foo\\\"bar");
+		this.verifyConvertToJavaStringLiteralContent("foo\\bar", "foo\\\\bar");
+	}
+
+	private void verifyConvertToJavaStringLiteralContent(String s, String expected) throws Exception {
+		Writer writer = new StringWriter();
+		WriterTools.convertToJavaStringLiteralContent(writer, s);
+		assertEquals(expected, writer.toString());
+
+		writer = new StringWriter();
+		WriterTools.convertToJavaStringLiteralContent(writer, s.toCharArray());
+		assertEquals(expected, writer.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ArrayIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ArrayIterableTests.java
new file mode 100644
index 0000000..b6fb190
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ArrayIterableTests.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
+
+
+@SuppressWarnings("nls")
+public class ArrayIterableTests extends TestCase {
+
+	public ArrayIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		int i = 1;
+		for (String string : this.buildIterable()) {
+			assertEquals(i++, Integer.parseInt(string));
+		}
+	}
+
+	public void testSubIterator() {
+		int i = 3;
+		for (String string : this.buildIterable(2)) {
+			assertEquals(i++, Integer.parseInt(string));
+		}
+	}
+
+	public void testIllegalArgumentException() {
+		this.triggerIllegalArgumentException(-1, 1);
+		this.triggerIllegalArgumentException(8, 1);
+		this.triggerIllegalArgumentException(0, -1);
+		this.triggerIllegalArgumentException(0, 9);
+	}
+
+	private void triggerIllegalArgumentException(int start, int end) {
+		boolean exCaught = false;
+		try {
+			Iterable<String> iterable = this.buildIterable(start, end);
+			fail("bogus iterable: " + iterable);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	private Iterable<String> buildIterable() {
+		return this.buildIterable(0);
+	}
+
+	private Iterable<String> buildIterable(int start) {
+		return this.buildIterable(this.buildArray(), start);
+	}
+
+	private Iterable<String> buildIterable(String[] array, int start) {
+		return new ArrayIterable<String>(array, start);
+	}
+
+	private Iterable<String> buildIterable(int start, int end) {
+		return this.buildIterable(this.buildArray(), start, end);
+	}
+
+	private Iterable<String> buildIterable(String[] array, int start, int end) {
+		return new ArrayIterable<String>(array, start, end);
+	}
+
+	private String[] buildArray() {
+		return new String[] { "1", "2", "3", "4", "5", "6", "7", "8" };
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ArrayListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ArrayListIterableTests.java
new file mode 100644
index 0000000..45777a7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ArrayListIterableTests.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.ListIterator;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.ArrayListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
+@SuppressWarnings("nls")
+public class ArrayListIterableTests extends TestCase {
+
+	public ArrayListIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		int i = 1;
+		ListIterable<String> iterable = this.buildIterable();
+		for (String string : iterable) {
+			assertEquals(i++, Integer.parseInt(string));
+		}
+		ListIterator<String> stream = iterable.iterator();
+		while (stream.hasNext()) {
+			stream.next();
+		}
+		while (stream.hasPrevious()) {
+			assertEquals(--i, Integer.parseInt(stream.previous()));
+		}
+	}
+
+	public void testSubIterator() {
+		int i = 3;
+		for (String string : this.buildIterable(2)) {
+			assertEquals(i++, Integer.parseInt(string));
+		}
+	}
+
+	public void testIllegalArgumentException() {
+		this.triggerIllegalArgumentException(-1, 1);
+		this.triggerIllegalArgumentException(8, 1);
+		this.triggerIllegalArgumentException(0, -1);
+		this.triggerIllegalArgumentException(0, 9);
+	}
+
+	private void triggerIllegalArgumentException(int start, int end) {
+		boolean exCaught = false;
+		try {
+			Iterable<String> iterable = this.buildIterable(start, end);
+			fail("bogus iterable: " + iterable);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	private ListIterable<String> buildIterable() {
+		return this.buildIterable(0);
+	}
+
+	private ListIterable<String> buildIterable(int start) {
+		return this.buildIterable(this.buildArray(), start);
+	}
+
+	private ListIterable<String> buildIterable(String[] array, int start) {
+		return (start == 0) ?
+				new ArrayListIterable<String>(array) :
+				new ArrayListIterable<String>(array, start);
+	}
+
+	private ListIterable<String> buildIterable(int start, int end) {
+		return this.buildIterable(this.buildArray(), start, end);
+	}
+
+	private ListIterable<String> buildIterable(String[] array, int start, int end) {
+		return new ArrayListIterable<String>(array, start, end);
+	}
+
+	private String[] buildArray() {
+		return new String[] { "1", "2", "3", "4", "5", "6", "7", "8" };
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ChainIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ChainIterableTests.java
new file mode 100644
index 0000000..22b162a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ChainIterableTests.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.AbstractCollection;
+import java.util.AbstractList;
+import java.util.Iterator;
+import java.util.Vector;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.ChainIterable;
+import org.eclipse.persistence.tools.utility.iterator.ChainIterator;
+
+@SuppressWarnings("nls")
+public class ChainIterableTests extends TestCase {
+	private final static Class<?>[] VECTOR_HIERARCHY = { Vector.class, AbstractList.class, AbstractCollection.class, Object.class };
+
+	public ChainIterableTests(String name) {
+		super(name);
+	}
+
+
+	public void testNextLink() {
+		int i = 0;
+		for (Class<?> clazz : this.buildIterable()) {
+			assertEquals(VECTOR_HIERARCHY[i++], clazz);
+		}
+	}
+
+	public void testLinker() {
+		int i = 0;
+		for (Class<?> clazz : new ChainIterable<Class<?>>(Vector.class, this.buildLinker())) {
+			assertEquals(VECTOR_HIERARCHY[i++], clazz);
+		}
+	}
+
+	public void testException() {
+		Iterable<Class<?>> iterable = new ChainIterable<Class<?>>(Vector.class);
+		Iterator<Class<?>> iterator = iterable.iterator();
+		boolean exCaught = false;
+		try {
+			Class<?> clazz = iterator.next();
+			fail("bogus class: " + clazz);
+		} catch (RuntimeException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testToString() {
+		assertNotNull(this.buildIterable().toString());
+	}
+
+	private Iterable<Class<?>> buildIterable() {
+		return this.buildChainIterable(Vector.class);
+	}
+
+	private Iterable<Class<?>> buildChainIterable(Class<?> startLink) {
+		// chain up the class's hierarchy
+		return new ChainIterable<Class<?>>(startLink) {
+			@Override
+			protected Class<?> nextLink(Class<?> currentLink) {
+				return currentLink.getSuperclass();
+			}
+		};
+	}
+
+	private ChainIterator.Linker<Class<?>> buildLinker() {
+		return new ChainIterator.Linker<Class<?>>() {
+			@Override
+			public Class<?> nextLink(Class<?> currentLink) {
+				return currentLink.getSuperclass();
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/CloneIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/CloneIterableTests.java
new file mode 100644
index 0000000..4343c7a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/CloneIterableTests.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.iterator.CloneIterator;
+import org.eclipse.persistence.tools.utility.iterator.CloneListIterator;
+
+
+@SuppressWarnings("nls")
+public abstract class CloneIterableTests extends TestCase {
+	Iterable<String> iterable;
+
+	public CloneIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		List<String> c = new ArrayList<String>();
+		c.add("0");
+		c.add("1");
+		c.add("2");
+		c.add("3");
+		assertEquals(4, c.size());
+		this.iterable = this.buildIterable(c);
+		int i = 0;
+		for (String s : this.iterable) {
+			assertEquals(String.valueOf(i++), s);
+			c.remove("3");
+		}
+		assertEquals(4, i);
+		assertEquals(3, c.size());
+	}
+
+	public void testRemove() {
+		final List<String> collection = this.buildCollection();
+		this.iterable = this.buildRemovingIterable(collection);
+
+		Object removed = "three";
+		assertTrue(IterableTools.contains(this.iterable, removed));
+		for (Iterator<String> iterator = this.iterable.iterator(); iterator.hasNext(); ) {
+			if (iterator.next().equals(removed)) {
+				iterator.remove();
+			}
+		}
+		assertFalse(collection.contains(removed));
+	}
+
+	public void testRemover() {
+		final List<String> collection = this.buildCollection();
+		this.iterable = this.buildIterableWithRemover(collection);
+
+		Object removed = "three";
+		assertTrue(IterableTools.contains(this.iterable, removed));
+		for (Iterator<String> iterator = this.iterable.iterator(); iterator.hasNext(); ) {
+			if (iterator.next().equals(removed)) {
+				iterator.remove();
+			}
+		}
+		assertFalse(collection.contains(removed));
+	}
+
+	public void testMissingRemover() {
+		final List<String> collection = this.buildCollection();
+		this.iterable = this.buildIterable(collection);
+		assertNotNull(this.iterable.toString());
+
+		Object removed = "three";
+		assertTrue(IterableTools.contains(this.iterable, removed));
+		boolean exCaught = false;
+		for (Iterator<String> iterator = this.iterable.iterator(); iterator.hasNext(); ) {
+			if (iterator.next().equals(removed)) {
+				try {
+					iterator.remove();
+					fail();
+				} catch (RuntimeException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testToString() {
+		final List<String> collection = this.buildCollection();
+		this.iterable = this.buildIterable(collection);
+		assertNotNull(this.iterable.toString());
+	}
+
+	abstract Iterable<String> buildIterable(List<String> c);
+
+	abstract Iterable<String> buildRemovingIterable(List<String> c);
+
+	abstract Iterable<String> buildIterableWithRemover(List<String> c);
+
+	CloneIterator.Remover<String> buildRemover(final Collection<String> c) {
+		return new CloneIterator.Remover<String>() {
+			@Override
+			public void remove(String current) {
+				c.remove(current);
+			}
+		};
+	}
+
+	CloneListIterator.Mutator<String> buildMutator(final List<String> list) {
+		return new CloneListIterator.Mutator<String>() {
+			@Override
+			public void add(int index, String string) {
+				list.add(index, string);
+			}
+			@Override
+			public void set(int index, String string) {
+				list.set(index, string);
+			}
+			@Override
+			public void remove(int index) {
+				list.remove(index);
+			}
+		};
+	}
+
+	List<String> buildCollection() {
+		List<String> c = new ArrayList<String>();
+		c.add("one");
+		c.add("two");
+		c.add("three");
+		c.add("four");
+		c.add("five");
+		c.add("six");
+		c.add("seven");
+		c.add("eight");
+		return c;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/CommonUtilityIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/CommonUtilityIterableTests.java
new file mode 100644
index 0000000..48391a3
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/CommonUtilityIterableTests.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * decentralize test creation code
+ */
+public class CommonUtilityIterableTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CommonUtilityIterableTests.class.getPackage().getName());
+
+		suite.addTestSuite(ArrayIterableTests.class);
+		suite.addTestSuite(ArrayListIterableTests.class);
+		suite.addTestSuite(ChainIterableTests.class);
+		suite.addTestSuite(CompositeIterableTests.class);
+		suite.addTestSuite(CompositeListIterableTests.class);
+		suite.addTestSuite(EmptyIterableTests.class);
+		suite.addTestSuite(EmptyListIterableTests.class);
+		suite.addTestSuite(FilteringIterableTests.class);
+		suite.addTestSuite(GraphIterableTests.class);
+		suite.addTestSuite(IterableToolsTests.class);
+		suite.addTestSuite(LiveCloneIterableTests.class);
+		suite.addTestSuite(LiveCloneListIterableTests.class);
+		suite.addTestSuite(PeekableIterableTests.class);
+		suite.addTestSuite(QueueIterableTests.class);
+		suite.addTestSuite(ReadOnlyCompositeListIterableTests.class);
+		suite.addTestSuite(ReadOnlyIterableTests.class);
+		suite.addTestSuite(ReadOnlyListIterableTests.class);
+		suite.addTestSuite(SingleElementIterableTests.class);
+		suite.addTestSuite(SingleElementListIterableTests.class);
+		suite.addTestSuite(SnapshotCloneIterableTests.class);
+		suite.addTestSuite(SnapshotCloneListIterableTests.class);
+		suite.addTestSuite(StackIterableTests.class);
+		suite.addTestSuite(SuperIterableWrapperTests.class);
+		suite.addTestSuite(TransformationIterableTests.class);
+		suite.addTestSuite(TransformationListIterableTests.class);
+		suite.addTestSuite(TreeIterableTests.class);
+
+		return suite;
+	}
+
+	private CommonUtilityIterableTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/CompositeIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/CompositeIterableTests.java
new file mode 100644
index 0000000..74d05f9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/CompositeIterableTests.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.CompositeIterable;
+
+
+@SuppressWarnings("nls")
+public class CompositeIterableTests extends TestCase {
+
+	public CompositeIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		Collection<String> c1 = new ArrayList<String>();
+		c1.add("0");
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+
+		Collection<String> c2 = new ArrayList<String>();
+		c2.add("4");
+		c2.add("5");
+		c2.add("6");
+		c2.add("7");
+
+		@SuppressWarnings("unchecked")
+		Iterable<String> composite = new CompositeIterable<String>(c1, c2);
+		int i = 0;
+		for (String s : composite) {
+			assertEquals(String.valueOf(i++), s);
+		}
+	}
+
+	public void testExtraElement1() {
+		Collection<String> c1 = new ArrayList<String>();
+		c1.add("0");
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+
+		Iterable<String> composite = new CompositeIterable<String>(c1, "4");
+		int i = 0;
+		for (String s : composite) {
+			assertEquals(String.valueOf(i++), s);
+		}
+	}
+
+	public void testExtraElement2() {
+		Collection<String> c1 = new ArrayList<String>();
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+
+		Iterable<String> composite = new CompositeIterable<String>("0", c1);
+		int i = 0;
+		for (String s : composite) {
+			assertEquals(String.valueOf(i++), s);
+		}
+	}
+
+	public void testCollectionOfIterables() {
+		Collection<String> c1 = new ArrayList<String>();
+		c1.add("0");
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+
+		Collection<String> c2 = new ArrayList<String>();
+		c2.add("4");
+		c2.add("5");
+		c2.add("6");
+		c2.add("7");
+
+		Collection<Iterable<String>> collection = new ArrayList<Iterable<String>>();
+		collection.add(c1);
+		collection.add(c2);
+		Iterable<String> composite = new CompositeIterable<String>(collection);
+		int i = 0;
+		for (String s : composite) {
+			assertEquals(String.valueOf(i++), s);
+		}
+	}
+
+	public void testToString() {
+		Collection<String> c1 = new ArrayList<String>();
+		c1.add("0");
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+
+		Collection<String> c2 = new ArrayList<String>();
+		c2.add("4");
+		c2.add("5");
+		c2.add("6");
+		c2.add("7");
+
+		@SuppressWarnings("unchecked")
+		Iterable<String> composite = new CompositeIterable<String>(c1, c2);
+		assertNotNull(composite.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/CompositeListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/CompositeListIterableTests.java
new file mode 100644
index 0000000..1e198f2
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/CompositeListIterableTests.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.ArrayList;
+import java.util.List;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.CompositeListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
+
+@SuppressWarnings("nls")
+public class CompositeListIterableTests extends TestCase {
+
+	public CompositeListIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		List<String> c1 = new ArrayList<String>();
+		c1.add("0");
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+
+		List<String> c2 = new ArrayList<String>();
+		c2.add("4");
+		c2.add("5");
+		c2.add("6");
+		c2.add("7");
+
+		@SuppressWarnings("unchecked")
+		Iterable<String> composite = new CompositeListIterable<String>(c1, c2);
+		int i = 0;
+		for (String s : composite) {
+			assertEquals(String.valueOf(i++), s);
+		}
+	}
+
+	public void testExtraElement1() {
+		List<String> c1 = new ArrayList<String>();
+		c1.add("0");
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+
+		Iterable<String> composite = new CompositeListIterable<String>(c1, "4");
+		int i = 0;
+		for (String s : composite) {
+			assertEquals(String.valueOf(i++), s);
+		}
+	}
+
+	public void testExtraElement2() {
+		List<String> c1 = new ArrayList<String>();
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+
+		Iterable<String> composite = new CompositeListIterable<String>("0", c1);
+		int i = 0;
+		for (String s : composite) {
+			assertEquals(String.valueOf(i++), s);
+		}
+	}
+
+	public void testCollectionOfIterables() {
+		List<String> c1 = new ArrayList<String>();
+		c1.add("0");
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+
+		List<String> c2 = new ArrayList<String>();
+		c2.add("4");
+		c2.add("5");
+		c2.add("6");
+		c2.add("7");
+
+		List<ListIterable<String>> collection = new ArrayList<ListIterable<String>>();
+		collection.add(new ListListIterable<String>(c1));
+		collection.add(new ListListIterable<String>(c2));
+		ListIterable<ListIterable<String>> li = new ListListIterable<ListIterable<String>>(collection);
+		Iterable<String> composite = new CompositeListIterable<String>(li);
+		int i = 0;
+		for (String s : composite) {
+			assertEquals(String.valueOf(i++), s);
+		}
+	}
+
+	public void testToString() {
+		List<String> c1 = new ArrayList<String>();
+		c1.add("0");
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+
+		List<String> c2 = new ArrayList<String>();
+		c2.add("4");
+		c2.add("5");
+		c2.add("6");
+		c2.add("7");
+
+		@SuppressWarnings("unchecked")
+		Iterable<String> composite = new CompositeListIterable<String>(c1, c2);
+		assertNotNull(composite.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/EmptyIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/EmptyIterableTests.java
new file mode 100644
index 0000000..07585f7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/EmptyIterableTests.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.EmptyIterable;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+
+@SuppressWarnings("nls")
+public class EmptyIterableTests extends TestCase {
+
+	public EmptyIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		for (String s : EmptyIterable.<String>instance()) {
+			fail("bogus element: " + s);
+		}
+	}
+
+	public void testToString() {
+		assertNotNull(EmptyIterable.instance().toString());
+	}
+
+	public void testSerialization() throws Exception {
+		Iterable<String> iterable = EmptyIterable.instance();
+		assertSame(iterable, TestTools.serialize(iterable));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/EmptyListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/EmptyListIterableTests.java
new file mode 100644
index 0000000..a41f9d2
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/EmptyListIterableTests.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.EmptyListIterable;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class EmptyListIterableTests extends TestCase {
+
+	public EmptyListIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		for (String s : EmptyListIterable.<String>instance()) {
+			fail("bogus element: " + s);
+		}
+	}
+
+	public void testToString() {
+		assertNotNull(EmptyListIterable.instance().toString());
+	}
+
+	public void testSerialization() throws Exception {
+		Iterable<String> iterable = EmptyListIterable.instance();
+		assertSame(iterable, TestTools.serialize(iterable));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/FilteringIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/FilteringIterableTests.java
new file mode 100644
index 0000000..0fbf46f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/FilteringIterableTests.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.iterable.FilteringIterable;
+
+@SuppressWarnings("nls")
+public class FilteringIterableTests extends TestCase {
+	private static final String PREFIX = "prefix";
+
+	public FilteringIterableTests(String name) {
+		super(name);
+	}
+
+	public void testAccept() {
+		int i = 0;
+		for (String s : this.buildIterable()) {
+			assertTrue(s.contains(PREFIX));
+			i++;
+		}
+		assertEquals(6, i);
+	}
+
+	public void testFilter() {
+		Filter<String> filter = this.buildFilter();
+		int i = 0;
+		for (String s : new FilteringIterable<String>(this.buildNestedIterable(), filter)) {
+			assertTrue(s.contains(PREFIX));
+			i++;
+		}
+		assertEquals(6, i);
+	}
+
+	public void testToString() {
+		assertNotNull(this.buildIterable().toString());
+	}
+
+	public void testMissingFilter() {
+		boolean exCaught = false;
+		Iterable<String> iterable = new FilteringIterable<String>(this.buildNestedIterable());
+		try {
+			Iterator<String> iterator = iterable.iterator();
+			fail("bogus iterator: " + iterator);
+		} catch (RuntimeException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	private Iterable<String> buildIterable() {
+		return this.buildFilteringIterable(this.buildNestedIterable());
+	}
+
+	private Iterable<String> buildFilteringIterable(Iterable<String> nestedIterable) {
+		return new FilteringIterable<String>(nestedIterable) {
+			@Override
+			protected boolean accept(String s) {
+				return s.startsWith(PREFIX);
+			}
+		};
+	}
+
+	private Filter<String> buildFilter() {
+		return new Filter<String>() {
+			@Override
+			public boolean accept(String s) {
+				return s.startsWith(PREFIX);
+			}
+		};
+	}
+
+	private Iterable<String> buildNestedIterable() {
+		Collection<String> c = new ArrayList<String>();
+		c.add(PREFIX + "1");
+		c.add(PREFIX + "2");
+		c.add(PREFIX + "3");
+		c.add("4");
+		c.add(PREFIX + "5");
+		c.add(PREFIX + "6");
+		c.add(PREFIX + "7");
+		c.add("8");
+		return c;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/GraphIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/GraphIterableTests.java
new file mode 100644
index 0000000..56318e8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/GraphIterableTests.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterable.GraphIterable;
+import org.eclipse.persistence.tools.utility.iterator.GraphIterator;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+
+@SuppressWarnings("nls")
+public class GraphIterableTests extends TestCase {
+	/** this will be populated with all the nodes created for the test */
+	Collection<GraphNode> nodes = new ArrayList<GraphNode>();
+
+	public GraphIterableTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testNeighbors1() {
+		for (GraphNode gn : this.buildGraphIterable1()) {
+			assertTrue(this.nodes.contains(gn));
+		}
+	}
+
+	private Iterable<GraphNode> buildGraphIterable1() {
+		return new GraphIterable<GraphNode>(this.buildGraphRoot()) {
+			@Override
+			public Iterator<GraphNode> neighbors(GraphNode next) {
+				return next.neighbors();
+			}
+		};
+	}
+
+	public void testNeighbors2() {
+		for (GraphNode gn : this.buildGraphIterable2()) {
+			assertTrue(this.nodes.contains(gn));
+		}
+	}
+
+	private Iterable<GraphNode> buildGraphIterable2() {
+		return new GraphIterable<GraphNode>(this.buildGraphRoot(), this.buildMisterRogers());
+	}
+
+	public void testNeighbors3() {
+		for (GraphNode gn : this.buildGraphIterable3()) {
+			assertTrue(this.nodes.contains(gn));
+		}
+	}
+
+	private Iterable<GraphNode> buildGraphIterable3() {
+		return new GraphIterable<GraphNode>(new GraphNode[] { this.buildGraphRoot() }) {
+			@Override
+			public Iterator<GraphNode> neighbors(GraphNode next) {
+				return next.neighbors();
+			}
+		};
+	}
+
+	public void testNeighbors4() {
+		for (GraphNode gn : this.buildGraphIterable4()) {
+			assertTrue(this.nodes.contains(gn));
+		}
+	}
+
+	private Iterable<GraphNode> buildGraphIterable4() {
+		return new GraphIterable<GraphNode>(new GraphNode[] { this.buildGraphRoot() }, this.buildMisterRogers());
+	}
+
+	public void testToString() {
+		assertNotNull(this.buildGraphIterable1().toString());
+	}
+
+	public void testMissingMisterRogers() {
+		boolean exCaught = false;
+		try {
+			for (GraphNode gn : new GraphIterable<GraphNode>(this.buildGraphRoot())) {
+				assertTrue(this.nodes.contains(gn));
+			}
+			fail();
+		} catch (RuntimeException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	private GraphIterator.MisterRogers<GraphNode> buildMisterRogers() {
+		return new GraphIterator.MisterRogers<GraphNode>() {
+			@Override
+			public Iterator<GraphNode> neighbors(GraphNode next) {
+				return next.neighbors();
+			}
+		};
+	}
+
+	private GraphNode buildGraphRoot() {
+		GraphNode ncNode = new GraphNode("North Carolina");
+		GraphNode vaNode = new GraphNode("Virginia");
+		GraphNode scNode = new GraphNode("South Carolina");
+		GraphNode gaNode = new GraphNode("Georgia");
+		GraphNode flNode = new GraphNode("Florida");
+		GraphNode alNode = new GraphNode("Alabama");
+		GraphNode msNode = new GraphNode("Mississippi");
+		GraphNode tnNode = new GraphNode("Tennessee");
+
+		ncNode.setNeighbors(new GraphNode[] { vaNode, scNode, gaNode, tnNode });
+		vaNode.setNeighbors(new GraphNode[] { ncNode, tnNode });
+		scNode.setNeighbors(new GraphNode[] { ncNode, gaNode });
+		gaNode.setNeighbors(new GraphNode[] { ncNode, scNode, flNode, alNode, tnNode });
+		flNode.setNeighbors(new GraphNode[] { gaNode });
+		alNode.setNeighbors(new GraphNode[] { gaNode, msNode, tnNode });
+		msNode.setNeighbors(new GraphNode[] { alNode, tnNode });
+		tnNode.setNeighbors(new GraphNode[] { vaNode, ncNode, gaNode, alNode, msNode });
+
+		return ncNode;
+	}
+
+	public class GraphNode {
+		private String name;
+
+		private Collection<GraphNode> neighbors = new ArrayList<GraphNode>();
+
+		public GraphNode(String name) {
+			super();
+			GraphIterableTests.this.nodes.add(this); // log node
+			this.name = name;
+		}
+
+		public String getName() {
+			return this.name;
+		}
+
+		void setNeighbors(GraphNode[] neighbors) {
+			this.neighbors = ListTools.list(neighbors);
+		}
+
+		public Iterator<GraphNode> neighbors() {
+			return this.neighbors.iterator();
+		}
+
+		public int neighborsSize() {
+			return this.neighbors.size();
+		}
+
+		@Override
+		public String toString() {
+			return "GraphNode(" + this.name + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/IterableToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/IterableToolsTests.java
new file mode 100644
index 0000000..176c317
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/IterableToolsTests.java
@@ -0,0 +1,367 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ClassTools;
+import org.eclipse.persistence.tools.utility.ReverseComparator;
+import org.eclipse.persistence.tools.utility.iterable.EmptyIterable;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.tests.ArrayToolsTests;
+
+@SuppressWarnings("nls")
+public class IterableToolsTests
+	extends TestCase
+{
+	public IterableToolsTests(String name) {
+		super(name);
+	}
+
+	public void testContainsIterableObject() {
+		Collection<String> c = this.buildStringList1();
+		Iterable<String> iterable = c;
+		assertTrue(IterableTools.contains(iterable, "one"));
+		assertFalse(IterableTools.contains(iterable, null));
+		c.add(null);
+		assertTrue(IterableTools.contains(iterable, null));
+	}
+
+	public void testContainsAllIterableCollection() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(IterableTools.containsAll(iterable, this.buildStringList1()));
+	}
+
+	public void testContainsAllIterableIntCollection() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(IterableTools.containsAll(iterable, 3, this.buildStringList1()));
+	}
+
+	public void testContainsAllIterableIterable() {
+		Iterable<String> iterable1 = this.buildStringList1();
+		Iterable<String> iterable2 = this.buildStringList1();
+		assertTrue(IterableTools.containsAll(iterable1, iterable2));
+	}
+
+	public void testContainsAllIterableIntIterable() {
+		Iterable<String> iterable1 = this.buildStringList1();
+		Iterable<String> iterable2 = this.buildStringList1();
+		assertTrue(IterableTools.containsAll(iterable1, 3, iterable2));
+	}
+
+	public void testContainsAllIterableIterator() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(IterableTools.containsAll(iterable, this.buildStringList1().iterator()));
+	}
+
+	public void testContainsAllIterableIntIterator() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(IterableTools.containsAll(iterable, 3, this.buildStringList1().iterator()));
+	}
+
+	public void testContainsAllIterableObjectArray() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(IterableTools.containsAll(iterable, this.buildObjectArray1()));
+		iterable = this.buildStringList2();
+		assertFalse(IterableTools.containsAll(iterable, this.buildObjectArray1()));
+	}
+
+	public void testContainsAllIterableIntObjectArray() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(IterableTools.containsAll(iterable, 3, this.buildObjectArray1()));
+		iterable = this.buildStringList2();
+		assertFalse(IterableTools.containsAll(iterable, 3, this.buildObjectArray1()));
+	}
+
+	public void testElementsAreDifferentIterableIterable() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("1000");
+		list1.add("2000");
+		list1.add("3000");
+		list1.add("4000");
+
+		List<String> list2 = new ArrayList<String>();
+
+		assertTrue(IterableTools.elementsAreDifferent(list1, list2));
+		assertFalse(IterableTools.elementsAreEqual(list1, list2));
+	}
+
+	public void testElementsAreEqualIterableIterable() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("1000");
+		list1.add("2000");
+		list1.add("3000");
+		list1.add("4000");
+
+		List<String> list2 = new ArrayList<String>();
+		for (int i = 0; i < list1.size(); i++) {
+			list2.add(String.valueOf((i + 1) * 1000));
+		}
+		assertFalse(IterableTools.elementsAreIdentical(list1, list2));
+		assertFalse(IterableTools.elementsAreDifferent(list1, list2));
+		assertTrue(IterableTools.elementsAreEqual(list1, list2));
+	}
+
+	public void testElementsAreIdenticalIterableIterable() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("0");
+		list1.add("1");
+		list1.add("2");
+		list1.add("3");
+		Iterable<String> iterable1 = list1;
+
+		List<String> list2 = new ArrayList<String>();
+		for (String s : list1) {
+			list2.add(s);
+		}
+		Iterable<String> iterable2 = list2;
+		assertTrue(IterableTools.elementsAreIdentical(iterable1, iterable2));
+		assertTrue(IterableTools.elementsAreEqual(iterable1, iterable2));
+	}
+
+	public void testElementsAreNotIdenticalIterableIterable() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("0");
+		list1.add("1");
+		list1.add("2");
+		list1.add("3");
+		Iterable<String> iterable1 = list1;
+
+		List<String> list2 = new ArrayList<String>();
+		for (String s : list1) {
+			list2.add(s);
+		}
+		Iterable<String> iterable2 = list2;
+		assertFalse(IterableTools.elementsAreNotIdentical(iterable1, iterable2));
+		assertTrue(IterableTools.elementsAreEqual(iterable1, iterable2));
+	}
+
+	public void testExecuteParmCommand() {
+		List<String> list = this.buildStringList1();
+		ArrayToolsTests.ConcatenateCommand command = new ArrayToolsTests.ConcatenateCommand();
+		IterableTools.execute(list, command);
+		assertEquals("zeroonetwo", command.string);
+	}
+
+	public void testExecuteInterruptibleParmCommand() throws Exception {
+		List<String> list = this.buildStringList1();
+		ArrayToolsTests.InterruptibleConcatenateCommand command = new ArrayToolsTests.InterruptibleConcatenateCommand();
+		IterableTools.execute(list, command);
+		assertEquals("zeroonetwo", command.string);
+	}
+
+	public void testGetIterableInt() {
+		List<String> list = this.buildStringList1();
+		Iterable<String> iterable = list;
+		String o = IterableTools.get(iterable, 1);
+		assertEquals("one", o);
+		list.add(null);
+		o = IterableTools.get(iterable, 3);
+		assertNull(o);
+	}
+
+	public void testHashCodeIterable1() {
+		Iterable<String> iterable = null;
+		assertEquals(0, IterableTools.hashCode(iterable));
+	}
+
+	public void testHashCodeIterable2() {
+		List<String> list = this.buildStringList1();
+		Iterable<String> iterable = list;
+		int hashCode = IterableTools.hashCode(iterable);
+		assertEquals(list.hashCode(), hashCode);
+
+		list.add(null);
+		hashCode = IterableTools.hashCode(iterable);
+		assertEquals(list.hashCode(), hashCode);
+	}
+
+	public void testIndexOfIterableObject_String() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertEquals(1, IterableTools.indexOf(iterable, "one"));
+	}
+
+	public void testIsEmptyIterable() {
+		assertFalse(IterableTools.isEmpty(buildObjectList1()));
+		assertTrue(IterableTools.isEmpty(EmptyIterable.instance()));
+	}
+
+	public void testIterableObjectArray() {
+		String[] strings = this.buildStringArray1();
+		int i = 0;
+		for (String string : IterableTools.iterable(strings)) {
+			assertEquals(strings[i++], string);
+		}
+	}
+
+	public void testLastIterable1() {
+		List<String> list = this.buildStringList1();
+		Iterable<String> iterable = list;
+		assertEquals("two", IterableTools.last(iterable));
+		list.add(null);
+		assertEquals(null, IterableTools.last(iterable));
+	}
+
+	public void testLastIterable2() {
+		Iterable<String> iterable = new ArrayList<String>();
+		boolean exCaught = false;
+		try {
+			IterableTools.last(iterable);
+			fail();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testLastIndexOfIterableObject() {
+		List<String> list = this.buildStringList1();
+		Iterable<String> iterable = list;
+		assertEquals(1, IterableTools.lastIndexOf(iterable, "one"));
+		list.add(null);
+		assertEquals(list.size() - 1, IterableTools.lastIndexOf(iterable, null));
+	}
+
+	public void testSizeIterable() {
+		Iterable<Object> iterable = this.buildObjectList1();
+		assertEquals(3, IterableTools.size(iterable));
+	}
+
+	public void testSortIterable() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("0");
+		list.add("2");
+		list.add("3");
+		list.add("1");
+
+		SortedSet<String> ss = new TreeSet<String>();
+		ss.addAll(list);
+
+		Iterable<String> iterable1 = list;
+		Iterable<String> iterable2 = IterableTools.<String>sort(iterable1);
+		assertTrue(IterableTools.elementsAreEqual(ss, iterable2));
+	}
+
+	public void testSortIterableInt() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("0");
+		list.add("2");
+		list.add("3");
+		list.add("1");
+
+		SortedSet<String> ss = new TreeSet<String>();
+		ss.addAll(list);
+
+		Iterable<String> iterable1 = list;
+		Iterable<String> iterable2 = IterableTools.<String>sort(iterable1, 77);
+		assertTrue(IterableTools.elementsAreEqual(ss, iterable2));
+	}
+
+	public void testSortIterableComparator() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("0");
+		list.add("2");
+		list.add("3");
+		list.add("1");
+
+		SortedSet<String> ss = new TreeSet<String>(new ReverseComparator<String>());
+		ss.addAll(list);
+
+		Iterable<String> iterable1 = list;
+		Iterable<String> iterable2 = IterableTools.<String>sort(iterable1, new ReverseComparator<String>());
+		assertTrue(IterableTools.elementsAreEqual(ss, iterable2));
+	}
+
+	public void testSortIterableComparatorInt() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("0");
+		list.add("2");
+		list.add("3");
+		list.add("1");
+
+		SortedSet<String> ss = new TreeSet<String>(new ReverseComparator<String>());
+		ss.addAll(list);
+
+		Iterable<String> iterable1 = list;
+		Iterable<String> iterable2 = IterableTools.<String>sort(iterable1, new ReverseComparator<String>(), 77);
+		assertTrue(IterableTools.elementsAreEqual(ss, iterable2));
+	}
+
+	public void testTransformIterableTransformer() {
+		List<String> list = Arrays.asList(new String[] { "zero", "one", "two" });
+		Iterable<String> actual = IterableTools.transform(list, ArrayToolsTests.UPPER_CASE_TRANSFORMER);
+		List<Object> expected = Arrays.asList(new Object[] { "ZERO", "ONE", "TWO" });
+		assertTrue(IterableTools.elementsAreEqual(expected, actual));
+	}
+
+	public void testConstructor() {
+		boolean exCaught = false;
+		try {
+			Object at = ClassTools.newInstance(IterableTools.class);
+			fail("bogus: " + at); //$NON-NLS-1$
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof InvocationTargetException) {
+				if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	private Object[] buildObjectArray1() {
+		return new Object[] { "zero", "one", "two" };
+	}
+
+	private String[] buildStringArray1() {
+		return new String[] { "zero", "one", "two" };
+	}
+
+	private List<String> buildStringList1() {
+		List<String> l = new ArrayList<String>();
+		this.addToCollection1(l);
+		return l;
+	}
+
+	private List<Object> buildObjectList1() {
+		List<Object> l = new ArrayList<Object>();
+		this.addToCollection1(l);
+		return l;
+	}
+
+	private List<String> buildStringList2() {
+		List<String> l = new ArrayList<String>();
+		this.addToCollection2(l);
+		return l;
+	}
+
+	private void addToCollection1(Collection<? super String> c) {
+		c.add("zero");
+		c.add("one");
+		c.add("two");
+	}
+
+	private void addToCollection2(Collection<? super String> c) {
+		c.add("three");
+		c.add("four");
+		c.add("five");
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/LiveCloneIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/LiveCloneIterableTests.java
new file mode 100644
index 0000000..d8e9bb5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/LiveCloneIterableTests.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.List;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.iterable.LiveCloneIterable;
+
+
+@SuppressWarnings("nls")
+public class LiveCloneIterableTests extends CloneIterableTests {
+
+	public LiveCloneIterableTests(String name) {
+		super(name);
+	}
+
+	@Override
+	public void testIterator() {
+		super.testIterator();
+		// iterable should now return only 3 strings (since it's "live")
+		int i = 0;
+		for (String s : this.iterable) {
+			assertEquals(String.valueOf(i++), s);
+		}
+		assertEquals(3, i);
+	}
+
+	@Override
+	public void testRemove() {
+		super.testRemove();
+		// "live" clone iterable will no longer contain the element removed from the
+		// original collection
+		assertFalse(IterableTools.contains(this.iterable, "three"));
+	}
+
+	@Override
+	public void testRemover() {
+		super.testRemover();
+		// "live" clone iterable will no longer contain the element removed from the
+		// original collection
+		assertFalse(IterableTools.contains(this.iterable, "three"));
+	}
+
+	@Override
+	Iterable<String> buildIterable(List<String> c) {
+		return new LiveCloneIterable<String>(c);
+	}
+
+	@Override
+	Iterable<String> buildRemovingIterable(final List<String> c) {
+		return new LiveCloneIterable<String>(c) {
+				@Override
+				protected void remove(String current) {
+					c.remove(current);
+				}
+			};
+	}
+
+	@Override
+	Iterable<String> buildIterableWithRemover(List<String> c) {
+		return new LiveCloneIterable<String>(c, this.buildRemover(c));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/LiveCloneListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/LiveCloneListIterableTests.java
new file mode 100644
index 0000000..091db70
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/LiveCloneListIterableTests.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.iterable.LiveCloneListIterable;
+
+
+@SuppressWarnings("nls")
+public class LiveCloneListIterableTests extends LiveCloneIterableTests {
+
+	public LiveCloneListIterableTests(String name) {
+		super(name);
+	}
+
+	public void testAdd() {
+		final List<String> collection = this.buildCollection();
+		this.iterable = this.buildRemovingIterable(collection);
+
+		String added = "xxxx";
+		assertFalse(IterableTools.contains(this.iterable, added));
+		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
+			if (iterator.next().equals("two")) {
+				iterator.add(added);
+			}
+		}
+		assertTrue(collection.contains(added));
+		// "live" clone iterable will contain the element added to the
+		// original collection
+		assertTrue(IterableTools.contains(this.iterable, added));
+	}
+
+	public void testMissingMutatorAdd() {
+		final List<String> collection = this.buildCollection();
+		this.iterable = this.buildIterable(collection);
+		assertNotNull(this.iterable.toString());
+
+		String added = "xxxx";
+		assertFalse(IterableTools.contains(this.iterable, added));
+		boolean exCaught = false;
+		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
+			if (iterator.next().equals("three")) {
+				try {
+					iterator.add(added);
+					fail();
+				} catch (RuntimeException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testSet() {
+		final List<String> collection = this.buildCollection();
+		this.iterable = this.buildRemovingIterable(collection);
+
+		String added = "xxxx";
+		assertFalse(IterableTools.contains(this.iterable, added));
+		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
+			if (iterator.next().equals("two")) {
+				iterator.set(added);
+			}
+		}
+		assertTrue(collection.contains(added));
+		assertFalse(collection.contains("two"));
+		// "live" clone iterable will contain the element added to the
+		// original collection
+		assertTrue(IterableTools.contains(this.iterable, added));
+		assertFalse(IterableTools.contains(this.iterable, "two"));
+	}
+
+	public void testMissingMutatorSet() {
+		final List<String> collection = this.buildCollection();
+		this.iterable = this.buildIterable(collection);
+		assertNotNull(this.iterable.toString());
+
+		String added = "xxxx";
+		assertFalse(IterableTools.contains(this.iterable, added));
+		boolean exCaught = false;
+		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
+			if (iterator.next().equals("three")) {
+				try {
+					iterator.set(added);
+					fail();
+				} catch (RuntimeException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	@Override
+	Iterable<String> buildIterable(List<String> c) {
+		return new LiveCloneListIterable<String>(c);
+	}
+
+	@Override
+	Iterable<String> buildRemovingIterable(final List<String> c) {
+		return new LiveCloneListIterable<String>(c) {
+				@Override
+				protected void add(int index, String element) {
+					c.add(index, element);
+				}
+				@Override
+				protected void remove(int index) {
+					c.remove(index);
+				}
+				@Override
+				protected void set(int index, String element) {
+					c.set(index, element);
+				}
+			};
+	}
+
+	@Override
+	Iterable<String> buildIterableWithRemover(List<String> c) {
+		return new LiveCloneListIterable<String>(c, this.buildMutator(c));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/PeekableIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/PeekableIterableTests.java
new file mode 100644
index 0000000..084e29e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/PeekableIterableTests.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
+import org.eclipse.persistence.tools.utility.iterable.PeekableIterable;
+import org.eclipse.persistence.tools.utility.iterator.PeekableIterator;
+
+
+@SuppressWarnings("nls")
+public class PeekableIterableTests extends TestCase {
+
+	public PeekableIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		PeekableIterable<String> iterable = this.buildIterable();
+		PeekableIterator<String> iterator = iterable.iterator();
+		assertEquals("one", iterator.peek());
+	}
+
+	public void testToString() {
+		assertNotNull(this.buildIterable().toString());
+	}
+
+	private PeekableIterable<String> buildIterable() {
+		return new PeekableIterable<String>(this.buildNestedIterable());
+	}
+
+	private Iterable<String> buildNestedIterable() {
+		return new ArrayIterable<String>(this.buildArray());
+	}
+
+	private String[] buildArray() {
+		return new String[] {"one", "two", "three"};
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/QueueIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/QueueIterableTests.java
new file mode 100644
index 0000000..90e3a68
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/QueueIterableTests.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.LinkedQueue;
+import org.eclipse.persistence.tools.utility.collection.Queue;
+import org.eclipse.persistence.tools.utility.iterable.QueueIterable;
+
+@SuppressWarnings("nls")
+public class QueueIterableTests extends TestCase {
+
+	public QueueIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		Iterable<String> iterable = this.buildIterable();
+		for (String s : iterable) {
+			assertNotNull(s);
+		}
+	}
+
+	public void testToString() {
+		assertNotNull(this.buildIterable().toString());
+	}
+
+	private Iterable<String> buildIterable() {
+		return new QueueIterable<String>(this.buildQueue());
+	}
+
+	private Queue<String> buildQueue() {
+		Queue<String> q = new LinkedQueue<String>();
+		q.enqueue("foo");
+		q.enqueue("bar");
+		q.enqueue("baz");
+		return q;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ReadOnlyCompositeListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ReadOnlyCompositeListIterableTests.java
new file mode 100644
index 0000000..5531a8b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ReadOnlyCompositeListIterableTests.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.ArrayList;
+import java.util.List;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ReadOnlyCompositeListIterable;
+
+@SuppressWarnings("nls")
+public class ReadOnlyCompositeListIterableTests extends TestCase {
+
+	public ReadOnlyCompositeListIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		List<String> c1 = new ArrayList<String>();
+		c1.add("0");
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+		ListIterable<String> li1 = new ListListIterable<String>(c1);
+
+		List<String> c2 = new ArrayList<String>();
+		c2.add("4");
+		c2.add("5");
+		c2.add("6");
+		c2.add("7");
+		ListIterable<String> li2 = new ListListIterable<String>(c2);
+
+		@SuppressWarnings("unchecked")
+		Iterable<String> composite = new ReadOnlyCompositeListIterable<String>(li1, li2);
+		int i = 0;
+		for (String s : composite) {
+			assertEquals(String.valueOf(i++), s);
+		}
+	}
+
+	public void testExtraElement1() {
+		List<String> c1 = new ArrayList<String>();
+		c1.add("0");
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+		ListIterable<String> li1 = new ListListIterable<String>(c1);
+
+		Iterable<String> composite = new ReadOnlyCompositeListIterable<String>(li1, "4");
+		int i = 0;
+		for (String s : composite) {
+			assertEquals(String.valueOf(i++), s);
+		}
+	}
+
+	public void testExtraElement2() {
+		List<String> c1 = new ArrayList<String>();
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+		ListIterable<String> li1 = new ListListIterable<String>(c1);
+
+		Iterable<String> composite = new ReadOnlyCompositeListIterable<String>("0", li1);
+		int i = 0;
+		for (String s : composite) {
+			assertEquals(String.valueOf(i++), s);
+		}
+	}
+
+	public void testCollectionOfIterables() {
+		List<String> c1 = new ArrayList<String>();
+		c1.add("0");
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+		ListIterable<String> li1 = new ListListIterable<String>(c1);
+
+		List<String> c2 = new ArrayList<String>();
+		c2.add("4");
+		c2.add("5");
+		c2.add("6");
+		c2.add("7");
+		ListIterable<String> li2 = new ListListIterable<String>(c2);
+
+		List<ListIterable<String>> collection = new ArrayList<ListIterable<String>>();
+		collection.add(li1);
+		collection.add(li2);
+		ListIterable<ListIterable<String>> li = new ListListIterable<ListIterable<String>>(collection);
+
+		Iterable<String> composite = new ReadOnlyCompositeListIterable<String>(li);
+		int i = 0;
+		for (String s : composite) {
+			assertEquals(String.valueOf(i++), s);
+		}
+	}
+
+	public void testToString() {
+		List<String> c1 = new ArrayList<String>();
+		c1.add("0");
+		c1.add("1");
+		c1.add("2");
+		c1.add("3");
+		ListIterable<String> li1 = new ListListIterable<String>(c1);
+
+		List<String> c2 = new ArrayList<String>();
+		c2.add("4");
+		c2.add("5");
+		c2.add("6");
+		c2.add("7");
+		ListIterable<String> li2 = new ListListIterable<String>(c2);
+
+		@SuppressWarnings("unchecked")
+		Iterable<String> composite = new ReadOnlyCompositeListIterable<String>(li1, li2);
+		assertNotNull(composite.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ReadOnlyIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ReadOnlyIterableTests.java
new file mode 100644
index 0000000..db2e3ba
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ReadOnlyIterableTests.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.Iterator;
+import java.util.Vector;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.ReadOnlyIterable;
+
+@SuppressWarnings("nls")
+public class ReadOnlyIterableTests extends TestCase {
+
+	public ReadOnlyIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		Iterator<String> nestedIterator = this.buildVector().iterator();
+		for (String s : this.buildReadOnlyIterable()) {
+			assertEquals(nestedIterator.next(), s);
+		}
+	}
+
+	public void testRemove() {
+		boolean exCaught = false;
+		for (Iterator<String> stream = this.buildReadOnlyIterable().iterator(); stream.hasNext();) {
+			if (stream.next().equals("three")) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testToString() {
+		assertNotNull(this.buildReadOnlyIterable().toString());
+	}
+
+	private Iterable<String> buildReadOnlyIterable() {
+		return new ReadOnlyIterable<String>(this.buildVector());
+	}
+
+	private Vector<String> buildVector() {
+		Vector<String> v = new Vector<String>();
+		v.addElement("one");
+		v.addElement("two");
+		v.addElement("three");
+		v.addElement("four");
+		v.addElement("five");
+		v.addElement("six");
+		v.addElement("seven");
+		v.addElement("eight");
+		return v;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ReadOnlyListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ReadOnlyListIterableTests.java
new file mode 100644
index 0000000..a574bbb
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/ReadOnlyListIterableTests.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.Iterator;
+import java.util.Vector;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ReadOnlyListIterable;
+
+@SuppressWarnings("nls")
+public class ReadOnlyListIterableTests extends TestCase {
+
+	public ReadOnlyListIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		Iterator<String> nestedIterator = this.buildVector().iterator();
+		for (String s : this.buildReadOnlyListIterable()) {
+			assertEquals(nestedIterator.next(), s);
+		}
+	}
+
+	public void testRemove() {
+		boolean exCaught = false;
+		for (Iterator<String> stream = this.buildReadOnlyListIterable().iterator(); stream.hasNext();) {
+			if (stream.next().equals("three")) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testToString() {
+		assertNotNull(this.buildReadOnlyListIterable().toString());
+	}
+
+	private Iterable<String> buildReadOnlyListIterable() {
+		return new ReadOnlyListIterable<String>(this.buildNestedListIterable());
+	}
+
+	private ListIterable<String> buildNestedListIterable() {
+		return new ListListIterable<String>(this.buildVector());
+	}
+
+	private Vector<String> buildVector() {
+		Vector<String> v = new Vector<String>();
+		v.addElement("one");
+		v.addElement("two");
+		v.addElement("three");
+		v.addElement("four");
+		v.addElement("five");
+		v.addElement("six");
+		v.addElement("seven");
+		v.addElement("eight");
+		return v;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SingleElementIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SingleElementIterableTests.java
new file mode 100644
index 0000000..ee8c5e0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SingleElementIterableTests.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.SingleElementIterable;
+
+@SuppressWarnings("nls")
+public class SingleElementIterableTests extends TestCase {
+
+	public SingleElementIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		for (String s : this.buildSingleElementIterable()) {
+			assertEquals(this.singleElement(), s);
+		}
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		Iterator<String> stream = this.buildSingleElementIterable().iterator();
+		String string = stream.next();
+		try {
+			string = stream.next();
+			fail("bogus element: " + string);
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemove() {
+		boolean exCaught = false;
+		for (Iterator<String> stream = this.buildSingleElementIterable().iterator(); stream.hasNext(); ) {
+			if (stream.next().equals(this.singleElement())) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	protected Iterable<String> buildSingleElementIterable() {
+		return new SingleElementIterable<String>(this.singleElement());
+	}
+
+	protected String singleElement() {
+		return "single element";
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SingleElementListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SingleElementListIterableTests.java
new file mode 100644
index 0000000..a5908d1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SingleElementListIterableTests.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.SingleElementListIterable;
+
+@SuppressWarnings("nls")
+public class SingleElementListIterableTests extends TestCase {
+
+	public SingleElementListIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		for (String s : this.buildSingleElementListIterable()) {
+			assertEquals(this.singleElement(), s);
+		}
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		Iterator<String> stream = this.buildSingleElementListIterable().iterator();
+		String string = stream.next();
+		try {
+			string = stream.next();
+			fail("bogus element: " + string);
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemove() {
+		boolean exCaught = false;
+		for (Iterator<String> stream = this.buildSingleElementListIterable().iterator(); stream.hasNext(); ) {
+			if (stream.next().equals(this.singleElement())) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	public void testToString() {
+		assertNotNull(this.buildSingleElementListIterable().toString());
+	}
+
+	protected Iterable<String> buildSingleElementListIterable() {
+		return new SingleElementListIterable<String>(this.singleElement());
+	}
+
+	protected String singleElement() {
+		return "single element";
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SnapshotCloneIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SnapshotCloneIterableTests.java
new file mode 100644
index 0000000..9c971d9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SnapshotCloneIterableTests.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.List;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.iterable.SnapshotCloneIterable;
+
+@SuppressWarnings("nls")
+public class SnapshotCloneIterableTests extends CloneIterableTests {
+
+	public SnapshotCloneIterableTests(String name) {
+		super(name);
+	}
+
+	@Override
+	public void testIterator() {
+		super.testIterator();
+		// "snapshot" iterable should still return 4 strings (since the original collection was cloned)
+		int i = 0;
+		for (String s : this.iterable) {
+			assertEquals(String.valueOf(i++), s);
+		}
+		assertEquals(4, i);
+	}
+
+	@Override
+	public void testRemove() {
+		super.testRemove();
+		// "snapshot" clone iterable will still contain the element removed from the
+		// original collection
+		assertTrue(IterableTools.contains(this.iterable, "three"));
+	}
+
+	@Override
+	public void testRemover() {
+		super.testRemover();
+		// "snapshot" clone iterable will still contain the element removed from the
+		// original collection
+		assertTrue(IterableTools.contains(this.iterable, "three"));
+	}
+
+	@Override
+	Iterable<String> buildIterable(List<String> c) {
+		return new SnapshotCloneIterable<String>(c);
+	}
+
+	@Override
+	Iterable<String> buildRemovingIterable(final List<String> c) {
+		return new SnapshotCloneIterable<String>(c) {
+				@Override
+				protected void remove(String current) {
+					c.remove(current);
+				}
+			};
+	}
+
+	@Override
+	Iterable<String> buildIterableWithRemover(List<String> c) {
+		return new SnapshotCloneIterable<String>(c, this.buildRemover(c));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SnapshotCloneListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SnapshotCloneListIterableTests.java
new file mode 100644
index 0000000..d05d2ad
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SnapshotCloneListIterableTests.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.iterable.SnapshotCloneListIterable;
+
+@SuppressWarnings("nls")
+public class SnapshotCloneListIterableTests extends SnapshotCloneIterableTests {
+
+	public SnapshotCloneListIterableTests(String name) {
+		super(name);
+	}
+
+	public void testAdd() {
+		final List<String> collection = this.buildCollection();
+		this.iterable = this.buildRemovingIterable(collection);
+
+		String added = "xxxx";
+		assertFalse(IterableTools.contains(this.iterable, added));
+		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
+			if (iterator.next().equals("two")) {
+				iterator.add(added);
+			}
+		}
+		assertTrue(collection.contains(added));
+		// "snapshot" clone iterable not will contain the element added to the
+		// original collection
+		assertFalse(IterableTools.contains(this.iterable, added));
+	}
+
+	public void testMissingMutatorAdd() {
+		final List<String> collection = this.buildCollection();
+		this.iterable = this.buildIterable(collection);
+		assertNotNull(this.iterable.toString());
+
+		String added = "xxxx";
+		assertFalse(IterableTools.contains(this.iterable, added));
+		boolean exCaught = false;
+		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
+			if (iterator.next().equals("three")) {
+				try {
+					iterator.add(added);
+					fail();
+				} catch (RuntimeException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testSet() {
+		final List<String> collection = this.buildCollection();
+		this.iterable = this.buildRemovingIterable(collection);
+
+		String added = "xxxx";
+		assertFalse(IterableTools.contains(this.iterable, added));
+		assertTrue(IterableTools.contains(this.iterable, "two"));
+		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
+			if (iterator.next().equals("two")) {
+				iterator.set(added);
+			}
+		}
+		assertTrue(collection.contains(added));
+		assertFalse(collection.contains("two"));
+		// "snapshot" clone iterable will not be changed
+		assertFalse(IterableTools.contains(this.iterable, added));
+		assertTrue(IterableTools.contains(this.iterable, "two"));
+	}
+
+	public void testMissingMutatorSet() {
+		final List<String> collection = this.buildCollection();
+		this.iterable = this.buildIterable(collection);
+		assertNotNull(this.iterable.toString());
+
+		String added = "xxxx";
+		assertFalse(IterableTools.contains(this.iterable, added));
+		boolean exCaught = false;
+		for (ListIterator<String> iterator = (ListIterator<String>) this.iterable.iterator(); iterator.hasNext(); ) {
+			if (iterator.next().equals("three")) {
+				try {
+					iterator.set(added);
+					fail();
+				} catch (RuntimeException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	@Override
+	Iterable<String> buildIterable(List<String> c) {
+		return new SnapshotCloneListIterable<String>(c);
+	}
+
+	@Override
+	Iterable<String> buildRemovingIterable(final List<String> c) {
+		return new SnapshotCloneListIterable<String>(c) {
+				@Override
+				protected void add(int index, String element) {
+					c.add(index, element);
+				}
+				@Override
+				protected void remove(int index) {
+					c.remove(index);
+				}
+				@Override
+				protected void set(int index, String element) {
+					c.set(index, element);
+				}
+			};
+	}
+
+	@Override
+	Iterable<String> buildIterableWithRemover(List<String> c) {
+		return new SnapshotCloneListIterable<String>(c, this.buildMutator(c));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/StackIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/StackIterableTests.java
new file mode 100644
index 0000000..0587918
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/StackIterableTests.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.Iterator;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.LinkedStack;
+import org.eclipse.persistence.tools.utility.collection.Stack;
+import org.eclipse.persistence.tools.utility.iterable.StackIterable;
+
+@SuppressWarnings("nls")
+public class StackIterableTests extends TestCase {
+
+	public StackIterableTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		Iterator<String> iterator = this.buildIterable().iterator();
+		assertEquals("three", iterator.next());
+		assertEquals("two", iterator.next());
+		assertEquals("one", iterator.next());
+	}
+
+	public void testToString() {
+		assertNotNull(this.buildIterable().toString());
+	}
+
+	private Iterable<String> buildIterable() {
+		return new StackIterable<String>(this.buildStack());
+	}
+
+	private Stack<String> buildStack() {
+		Stack<String> stack = new LinkedStack<String>();
+		stack.push("one");
+		stack.push("two");
+		stack.push("three");
+		return stack;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SuperIterableWrapperTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SuperIterableWrapperTests.java
new file mode 100644
index 0000000..0361487
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/SuperIterableWrapperTests.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.SuperIterableWrapper;
+
+@SuppressWarnings("nls")
+public class SuperIterableWrapperTests extends TestCase {
+
+	public SuperIterableWrapperTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("foo");
+		list.add("bar");
+		list.add("baz");
+		String concat = "";
+		for (String s : list) {
+			concat += s;
+		}
+		assertEquals("foobarbaz", concat);
+
+		Iterable<Object> iterable = new SuperIterableWrapper<Object>(list);
+		concat = "";
+		for (Object s : iterable) {
+			concat += s;
+		}
+		assertEquals("foobarbaz", concat);
+	}
+
+	public void testToString() {
+		Iterable<Object> iterable = new SuperIterableWrapper<Object>(Collections.emptyList());
+		assertNotNull(iterable.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/TransformationIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/TransformationIterableTests.java
new file mode 100644
index 0000000..c119986
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/TransformationIterableTests.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.TransformationIterable;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+@SuppressWarnings("nls")
+public class TransformationIterableTests extends TestCase {
+
+	public TransformationIterableTests(String name) {
+		super(name);
+	}
+
+	public void testTransform1() {
+		int i = 1;
+		for (Integer integer : this.buildIterable1()) {
+			assertEquals(i++, integer.intValue());
+		}
+	}
+
+	private Iterable<Integer> buildIterable1() {
+		return this.buildTransformationIterable1(this.buildNestedIterable());
+	}
+
+	private Iterable<Integer> buildTransformationIterable1(Iterable<String> nestedIterable) {
+		// transform each string into an integer with a value of the string's length
+		return new TransformationIterable<String, Integer>(nestedIterable) {
+			@Override
+			protected Integer transform(String next) {
+				return new Integer(next.length());
+			}
+		};
+	}
+
+	public void testTransform2() {
+		int i = 1;
+		for (Integer integer : this.buildIterable2()) {
+			assertEquals(i++, integer.intValue());
+		}
+	}
+
+	private Iterable<Integer> buildIterable2() {
+		return this.buildTransformationIterable2(this.buildNestedIterable());
+	}
+
+	private Iterable<Integer> buildTransformationIterable2(Iterable<String> nestedIterable) {
+		// transform each string into an integer with a value of the string's length
+		return new TransformationIterable<String, Integer>(nestedIterable, this.buildTransformer());
+	}
+
+	private Transformer<String, Integer> buildTransformer() {
+		// transform each string into an integer with a value of the string's length
+		return new Transformer<String, Integer>() {
+			@Override
+			public Integer transform(String next) {
+				return new Integer(next.length());
+			}
+		};
+	}
+
+	private Iterable<String> buildNestedIterable() {
+		Collection<String> c = new ArrayList<String>();
+		c.add("1");
+		c.add("22");
+		c.add("333");
+		c.add("4444");
+		c.add("55555");
+		c.add("666666");
+		c.add("7777777");
+		c.add("88888888");
+		return c;
+	}
+
+	public void testToString() {
+		assertNotNull(this.buildIterable1().toString());
+	}
+
+	public void testMissingTransformer() {
+		Iterable<Integer> iterable = new TransformationIterable<String, Integer>(this.buildNestedIterable());
+		boolean exCaught = false;
+		try {
+			int i = 1;
+			for (Integer integer : iterable) {
+				assertEquals(i++, integer.intValue());
+			}
+		} catch (RuntimeException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/TransformationListIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/TransformationListIterableTests.java
new file mode 100644
index 0000000..0734c8b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/TransformationListIterableTests.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.ArrayList;
+import java.util.List;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.TransformationListIterable;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+@SuppressWarnings("nls")
+public class TransformationListIterableTests extends TestCase {
+
+	public TransformationListIterableTests(String name) {
+		super(name);
+	}
+
+	public void testTransform1() {
+		int i = 1;
+		for (Integer integer : this.buildIterable1()) {
+			assertEquals(i++, integer.intValue());
+		}
+	}
+
+	private Iterable<Integer> buildIterable1() {
+		return this.buildTransformationListIterable1(this.buildNestedList());
+	}
+
+	private Iterable<Integer> buildTransformationListIterable1(List<String> nestedList) {
+		// transform each string into an integer with a value of the string's length
+		return new TransformationListIterable<String, Integer>(nestedList) {
+			@Override
+			protected Integer transform(String next) {
+				return new Integer(next.length());
+			}
+		};
+	}
+
+	public void testTransform2() {
+		int i = 1;
+		for (Integer integer : this.buildIterable2()) {
+			assertEquals(i++, integer.intValue());
+		}
+	}
+
+	private Iterable<Integer> buildIterable2() {
+		return this.buildTransformationListIterable2(this.buildNestedList());
+	}
+
+	private Iterable<Integer> buildTransformationListIterable2(List<String> nestedList) {
+		// transform each string into an integer with a value of the string's length
+		return new TransformationListIterable<String, Integer>(nestedList, this.buildTransformer());
+	}
+
+	private Transformer<String, Integer> buildTransformer() {
+		// transform each string into an integer with a value of the string's length
+		return new Transformer<String, Integer>() {
+			@Override
+			public Integer transform(String next) {
+				return new Integer(next.length());
+			}
+		};
+	}
+
+	private List<String> buildNestedList() {
+		List<String> c = new ArrayList<String>();
+		c.add("1");
+		c.add("22");
+		c.add("333");
+		c.add("4444");
+		c.add("55555");
+		c.add("666666");
+		c.add("7777777");
+		c.add("88888888");
+		return c;
+	}
+
+	public void testToString() {
+		assertNotNull(this.buildIterable1().toString());
+	}
+
+	public void testMissingTransformer() {
+		Iterable<Integer> iterable = new TransformationListIterable<String, Integer>(this.buildNestedList());
+		boolean exCaught = false;
+		try {
+			int i = 1;
+			for (Integer integer : iterable) {
+				assertEquals(i++, integer.intValue());
+			}
+		} catch (RuntimeException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/TreeIterableTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/TreeIterableTests.java
new file mode 100644
index 0000000..e50d164
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterable/TreeIterableTests.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+@SuppressWarnings("nls")
+public class TreeIterableTests extends TestCase {
+	/** this will be populated with all the nodes created for the test */
+	Collection<TreeNode> nodes = new ArrayList<TreeNode>();
+
+	public TreeIterableTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testIterator1() {
+		for (TreeNode tn : IterableTools.treeIterable(this.buildTree(), this.buildTransformer())) {
+			assertTrue(this.nodes.contains(tn));
+		}
+	}
+
+	public void testIterator2() {
+		for (TreeNode tn : IterableTools.treeIterable(new TreeNode[] { this.buildTree() }, this.buildTransformer())) {
+			assertTrue(this.nodes.contains(tn));
+		}
+	}
+
+	public void testToString() {
+		assertNotNull(IterableTools.treeIterable(this.buildTree(), this.buildTransformer()).toString());
+	}
+
+	private Transformer<TreeNode, Iterator<? extends TreeNode>> buildTransformer() {
+		return new Transformer<TreeNode, Iterator<? extends TreeNode>>() {
+			@Override
+			public Iterator<? extends TreeNode> transform(TreeNode next) {
+				return next.children();
+			}
+		};
+	}
+
+	private TreeNode buildTree() {
+		TreeNode root = new TreeNode("root");
+		TreeNode child1 = new TreeNode(root, "child 1");
+		@SuppressWarnings("unused")
+		TreeNode grandchild1A = new TreeNode(child1, "grandchild 1A");
+		TreeNode child2 = new TreeNode(root, "child 2");
+		@SuppressWarnings("unused")
+		TreeNode grandchild2A = new TreeNode(child2, "grandchild 2A");
+		TreeNode grandchild2B = new TreeNode(child2, "grandchild 2B");
+		@SuppressWarnings("unused")
+		TreeNode greatGrandchild2B1 = new TreeNode(grandchild2B, "great-grandchild 2B1");
+		@SuppressWarnings("unused")
+		TreeNode greatGrandchild2B2 = new TreeNode(grandchild2B, "great-grandchild 2B2");
+		TreeNode grandchild2C = new TreeNode(child2, "grandchild 2C");
+		@SuppressWarnings("unused")
+		TreeNode greatGrandchild2C1 = new TreeNode(grandchild2C, "great-grandchild 2C1");
+		@SuppressWarnings("unused")
+		TreeNode child3 = new TreeNode(root, "child 3");
+		return root;
+	}
+
+	public class TreeNode {
+		private String name;
+		private Collection<TreeNode> children = new ArrayList<TreeNode>();
+
+		public TreeNode(String name) {
+			super();
+			TreeIterableTests.this.nodes.add(this); // log node
+			this.name = name;
+		}
+
+		public TreeNode(TreeNode parent, String name) {
+			this(name);
+			parent.addChild(this);
+		}
+
+		public String getName() {
+			return this.name;
+		}
+
+		private void addChild(TreeNode child) {
+			this.children.add(child);
+		}
+
+		public Iterator<TreeNode> children() {
+			return this.children.iterator();
+		}
+
+		public int childrenSize() {
+			return this.children.size();
+		}
+
+		@Override
+		public String toString() {
+			return "TreeNode(" + this.name + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ArrayIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ArrayIteratorTests.java
new file mode 100644
index 0000000..97443a4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ArrayIteratorTests.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.ArrayIterator;
+
+@SuppressWarnings("nls")
+public class ArrayIteratorTests extends TestCase {
+
+	public ArrayIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testHasNext() {
+		int i = 0;
+		for (Iterator<String> stream = this.buildIterator(); stream.hasNext(); ) {
+			stream.next();
+			i++;
+		}
+		assertEquals(this.buildArray().length, i);
+	}
+
+	public void testNext() {
+		int i = 1;
+		for (Iterator<String> stream = this.buildIterator(); stream.hasNext(); ) {
+			assertEquals("bogus element", i++, Integer.parseInt(stream.next()));
+		}
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		Iterator<String> stream = this.buildIterator();
+		String string = null;
+		while (stream.hasNext()) {
+			string = stream.next();
+		}
+		try {
+			string = stream.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
+	}
+
+	public void testUnsupportedOperationException() {
+		boolean exCaught = false;
+		for (Iterator<String> stream = this.buildIterator(); stream.hasNext(); ) {
+			if (stream.next().equals("3")) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	public void testIllegalArgumentException() {
+		this.triggerIllegalArgumentException(-1, 1);
+		this.triggerIllegalArgumentException(8, 1);
+		this.triggerIllegalArgumentException(0, -1);
+		this.triggerIllegalArgumentException(0, 9);
+	}
+
+	public void testGenerics() {
+		Integer[] integers = new Integer[3];
+		integers[0] = new Integer(0);
+		integers[1] = new Integer(1);
+		integers[2] = new Integer(2);
+		int i = 0;
+		for (Iterator<Number> stream = this.buildGenericIterator(integers); stream.hasNext();) {
+			assertEquals(i++, stream.next().intValue());
+		}
+		assertEquals(integers.length, i);
+	}
+
+	Iterator<Number> buildGenericIterator(Integer[] integers) {
+		return new ArrayIterator<Number>(integers);
+	}
+
+	public void testVarargs() {
+		int i = 0;
+		for (Iterator<Number> stream = this.buildVarArgIterator(); stream.hasNext();) {
+			assertEquals(i++, stream.next().intValue());
+		}
+		assertEquals(3, i);
+	}
+
+	Iterator<Number> buildVarArgIterator() {
+		return new ArrayIterator<Number>(new Integer(0), new Integer(1), new Integer(2));
+	}
+
+	void triggerIllegalArgumentException(int start, int end) {
+		boolean exCaught = false;
+		Iterator<String> stream = null;
+		try {
+			stream = this.buildIterator(start, end);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue("IllegalArgumentException not thrown: " + stream, exCaught);
+	}
+
+	Iterator<String> buildIterator() {
+		return this.buildIterator(this.buildArray());
+	}
+
+	Iterator<String> buildIterator(String[] array) {
+		return new ArrayIterator<String>(array);
+	}
+
+	Iterator<String> buildIterator(int start, int end) {
+		return this.buildIterator(this.buildArray(), start, end);
+	}
+
+	Iterator<String> buildIterator(String[] array, int start, int end) {
+		return new ArrayIterator<String>(array, start, end);
+	}
+
+	String[] buildArray() {
+		return new String[] { "1", "2", "3", "4", "5", "6", "7", "8" };
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ArrayListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ArrayListIteratorTests.java
new file mode 100644
index 0000000..66e0dd5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ArrayListIteratorTests.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.Iterator;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.iterator.ArrayListIterator;
+
+@SuppressWarnings("nls")
+public class ArrayListIteratorTests extends ArrayIteratorTests {
+
+	public ArrayListIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testHasPrevious() {
+		ListIterator<String> stream = this.buildListIterator();
+		while (stream.hasNext()) {
+			stream.next();
+		}
+		int i = 0;
+		while (stream.hasPrevious()) {
+			stream.previous();
+			i++;
+		}
+		assertEquals(this.buildArray().length, i);
+	}
+
+	public void testPrevious() {
+		ListIterator<String> stream = this.buildListIterator();
+		while (stream.hasNext()) {
+			stream.next();
+		}
+		int i = this.buildArray().length;
+		while (stream.hasPrevious()) {
+			assertEquals("bogus element", i--, Integer.parseInt(stream.previous()));
+		}
+	}
+
+	public void testNextIndex() {
+		int i = 0;
+		ListIterator<String> stream = this.buildListIterator();
+		while (stream.hasNext()) {
+			assertEquals(i, stream.nextIndex());
+			stream.next();
+			i++;
+		}
+		assertEquals(i, stream.nextIndex());
+	}
+
+	public void testPreviousIndex() {
+		int i = 0;
+		ListIterator<String> stream = this.buildListIterator();
+		while (stream.hasNext()) {
+			assertEquals(i - 1, stream.previousIndex());
+			stream.next();
+			i++;
+		}
+		assertEquals(i - 1, stream.previousIndex());
+	}
+
+	@Override
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		ListIterator<String> stream = this.buildListIterator();
+		String string = null;
+		try {
+			string = stream.previous();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
+	}
+
+	public void testUnsupportedOperationExceptionAdd() {
+		boolean exCaught = false;
+		for (ListIterator<String> stream = this.buildListIterator(); stream.hasNext();) {
+			if (stream.next().equals("3")) {
+				try {
+					stream.add("3.5");
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	public void testUnsupportedOperationExceptionSet() {
+		boolean exCaught = false;
+		for (ListIterator<String> stream = this.buildListIterator(); stream.hasNext();) {
+			if (stream.next().equals("3")) {
+				try {
+					stream.set("three");
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	@Override
+	Iterator<Number> buildGenericIterator(Integer[] integers) {
+		return new ArrayListIterator<Number>(integers);
+	}
+
+	@Override
+	Iterator<Number> buildVarArgIterator() {
+		return new ArrayListIterator<Number>(new Integer(0), new Integer(1), new Integer(2));
+	}
+
+	private ListIterator<String> buildListIterator() {
+		return this.buildListIterator(this.buildArray());
+	}
+
+	private ListIterator<String> buildListIterator(String[] array) {
+		return new ArrayListIterator<String>(array);
+	}
+
+	@Override
+	Iterator<String> buildIterator(String[] array) {
+		return new ArrayListIterator<String>(array);
+	}
+
+	@Override
+	Iterator<String> buildIterator(String[] array, int start, int end) {
+		return new ArrayListIterator<String>(array, start, end);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ChainIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ChainIteratorTests.java
new file mode 100644
index 0000000..ee55f1e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ChainIteratorTests.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.AbstractCollection;
+import java.util.AbstractList;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.ChainIterator;
+
+@SuppressWarnings("nls")
+public class ChainIteratorTests extends TestCase {
+	private final static Class<?>[] VECTOR_HIERARCHY = { Vector.class, AbstractList.class, AbstractCollection.class, Object.class };
+
+	public ChainIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testHasNext() {
+		int i = 0;
+		for (Iterator<Class<?>> stream = this.buildIterator(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(VECTOR_HIERARCHY.length, i);
+	}
+
+	public void testInnerHasNext() {
+		int i = 0;
+		for (Iterator<Class<?>> stream = this.buildInnerIterator(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(VECTOR_HIERARCHY.length, i);
+	}
+
+	public void testNext() {
+		int i = 0;
+		for (Iterator<Class<?>> stream = this.buildIterator(); stream.hasNext(); i++) {
+			assertEquals("bogus link", VECTOR_HIERARCHY[i], stream.next());
+		}
+	}
+
+	public void testInnerNext() {
+		int i = 0;
+		for (Iterator<Class<?>> stream = this.buildInnerIterator(); stream.hasNext(); i++) {
+			assertEquals("bogus link", VECTOR_HIERARCHY[i], stream.next());
+		}
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		Iterator<Class<?>> stream = this.buildIterator();
+		Class<?> javaClass = null;
+		while (stream.hasNext()) {
+			javaClass = stream.next();
+		}
+		try {
+			javaClass = stream.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + javaClass, exCaught);
+	}
+
+	public void testUnsupportedOperationException() {
+		boolean exCaught = false;
+		for (Iterator<Class<?>> stream = this.buildIterator(); stream.hasNext();) {
+			if (stream.next() == AbstractCollection.class) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	private Iterator<Class<?>> buildIterator() {
+		return this.buildChainIterator(Vector.class, this.buildLinker());
+	}
+
+	private Iterator<Class<?>> buildInnerIterator() {
+		return this.buildInnerChainIterator(Vector.class);
+	}
+
+	private Iterator<Class<?>> buildChainIterator(Class<?> startLink, ChainIterator.Linker<Class<?>> linker) {
+		return new ChainIterator<Class<?>>(startLink, linker);
+	}
+
+	private ChainIterator.Linker<Class<?>> buildLinker() {
+		// chain up the class's hierarchy
+		return new ChainIterator.Linker<Class<?>>() {
+			@Override
+			public Class<?> nextLink(Class<?> currentLink) {
+				return currentLink.getSuperclass();
+			}
+		};
+	}
+
+	private Iterator<Class<?>> buildInnerChainIterator(Class<?> startLink) {
+		// chain up the class's hierarchy
+		return new ChainIterator<Class<?>>(startLink) {
+			@Override
+			protected Class<?> nextLink(Class<?> currentLink) {
+				return currentLink.getSuperclass();
+			}
+		};
+	}
+
+	public void testInvalidChainIterator() {
+		// missing method override
+		Iterator<Class<?>> iterator = new ChainIterator<Class<?>>(Vector.class);
+		boolean exCaught = false;
+		try {
+			Class<?> c = iterator.next();
+			fail("invalid class: " + c.getName());
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown", exCaught);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CloneIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CloneIteratorTests.java
new file mode 100644
index 0000000..c10add4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CloneIteratorTests.java
@@ -0,0 +1,231 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.tests.iterator;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.Collections;

+import java.util.Iterator;

+import java.util.NoSuchElementException;

+import org.eclipse.persistence.tools.utility.iterator.CloneIterator;

+import org.eclipse.persistence.tools.utility.tests.MultiThreadedTestCase;

+import org.eclipse.persistence.tools.utility.tests.TestTools;

+

+@SuppressWarnings("nls")

+public class CloneIteratorTests

+	extends MultiThreadedTestCase

+{

+	Collection<String> originalCollection;

+

+	private Collection<String> concurrentCollection;

+

+	public CloneIteratorTests(String name) {

+		super(name);

+	}

+

+	@Override

+	protected void setUp() throws Exception {

+		super.setUp();

+		this.originalCollection = this.buildCollection();

+	}

+

+	public void testHasNext() {

+		int originalSize = this.originalCollection.size();

+		int i = 0;

+		for (Iterator<String> stream = this.buildCloneIterator(); stream.hasNext();) {

+			stream.next();

+			// should allow concurrent modification

+			this.originalCollection.add("foo");

+			i++;

+		}

+		assertTrue(originalSize != this.originalCollection.size());

+		assertEquals(originalSize, i);

+	}

+

+	public void testNext() {

+		Iterator<String> nestedIterator = this.originalCollection.iterator();

+		for (Iterator<String> stream = this.buildCloneIterator(); stream.hasNext();) {

+			assertEquals("bogus element", nestedIterator.next(), stream.next());

+		}

+	}

+

+	public void testNoSuchElementException() {

+		boolean exCaught = false;

+		Iterator<String> stream = this.buildCloneIterator();

+		String string = null;

+		while (stream.hasNext()) {

+			string = stream.next();

+		}

+		try {

+			string = stream.next();

+		} catch (NoSuchElementException ex) {

+			exCaught = true;

+		}

+		assertTrue("NoSuchElementException not thrown: " + string, exCaught);

+	}

+

+	public void testRemoveDefault() {

+		boolean exCaught = false;

+		for (Iterator<String> stream = this.buildCloneIterator(); stream.hasNext();) {

+			if (stream.next().equals("three")) {

+				try {

+					stream.remove();

+				} catch (UnsupportedOperationException ex) {

+					exCaught = true;

+				}

+			}

+		}

+		assertTrue("UnsupportedOperationException not thrown", exCaught);

+	}

+

+	public void testRemoveEliminator() {

+		CloneIterator.Remover<String> eliminator = new CloneIterator.Remover<String>() {

+			@Override

+			public void remove(String element) {

+				CloneIteratorTests.this.originalCollection.remove(element);

+			}

+		};

+		this.verifyRemove(new CloneIterator<String>(this.originalCollection, eliminator));

+	}

+

+	/**

+	 * Test concurrent access: First build a clone iterator in a separate thread

+	 * that hangs momentarily during its construction; then modify the shared

+	 * collection in this thread. This would cause a

+	 * ConcurrentModificationException in the other thread if the clone iterator

+	 * were not synchronized on the original collection.

+	 */

+	public void testConcurrentAccess() throws Exception {

+		SlowCollection<String> slow = new SlowCollection<String>();

+		this.populateCollection(slow);

+		// using the unsynchronized collection will cause the test to fail

+		//		this.originalCollection = slow;

+		this.originalCollection = Collections.synchronizedCollection(slow);

+

+		this.concurrentCollection = new ArrayList<String>();

+		Thread thread = this.buildThread(this.buildRunnable());

+		thread.start();

+		while ( ! slow.hasStartedClone()) {

+			// wait for the other thread to start the clone...

+			Thread.yield();

+		}

+		// ...then sneak in an extra element

+		this.originalCollection.add("seventeen");

+		thread.join();

+		Collection<String> expected = new ArrayList<String>();

+		this.populateCollection(expected);

+		assertEquals(expected, this.concurrentCollection);

+	}

+

+	private Runnable buildRunnable() {

+		return new TestRunnable() {

+			@Override

+			protected void run_() throws Throwable {

+				CloneIteratorTests.this.loopWithCloneIterator();

+			}

+		};

+	}

+

+	/**

+	 * use a clone iterator to loop over the "slow" collection and copy its

+	 * contents to the concurrent collection

+	 */

+	void loopWithCloneIterator() {

+		for (Iterator<String> stream = this.buildCloneIterator(); stream.hasNext();) {

+			this.concurrentCollection.add(stream.next());

+		}

+	}

+

+	private void verifyRemove(Iterator<String> iterator) {

+		Object removed = "three";

+		assertTrue(this.originalCollection.contains(removed));

+		// try to remove before calling #next()

+		boolean exCaught = false;

+		try {

+			iterator.remove();

+		} catch (IllegalStateException ex) {

+			exCaught = true;

+		}

+		assertTrue("IllegalStateException not thrown", exCaught);

+		while (iterator.hasNext()) {

+			if (iterator.next().equals(removed)) {

+				iterator.remove();

+				// try to remove twice

+				exCaught = false;

+				try {

+					iterator.remove();

+				} catch (IllegalStateException ex) {

+					exCaught = true;

+				}

+				assertTrue("IllegalStateException not thrown", exCaught);

+			}

+		}

+		assertFalse(this.originalCollection.contains(removed));

+	}

+

+	private Iterator<String> buildCloneIterator() {

+		return this.buildCloneIterator(this.originalCollection);

+	}

+

+	private Iterator<String> buildCloneIterator(Collection<String> c) {

+		return new CloneIterator<String>(c);

+	}

+

+	private Collection<String> buildCollection() {

+		Collection<String> c = this.buildEmptyCollection();

+		this.populateCollection(c);

+		return c;

+	}

+

+	protected Collection<String> buildEmptyCollection() {

+		return new ArrayList<String>();

+	}

+

+	private void populateCollection(Collection<String> c) {

+		c.add("one");

+		c.add("two");

+		c.add("three");

+		c.add("four");

+		c.add("five");

+		c.add("six");

+		c.add("seven");

+		c.add("eight");

+	}

+

+	// ********** custom collection **********

+	static class SlowCollection<E> extends ArrayList<E> {

+		private static final long serialVersionUID = 1L;

+		private boolean hasStartedClone = false;

+

+		public SlowCollection() {

+			super();

+		}

+

+		@Override

+		public Object[] toArray() {

+			this.setHasStartedClone(true);

+			// take a little snooze before returning the array

+			TestTools.sleep(100);

+			return super.toArray();

+		}

+

+		synchronized void setHasStartedClone(boolean hasStartedClone) {

+			this.hasStartedClone = hasStartedClone;

+		}

+

+		synchronized boolean hasStartedClone() {

+			return this.hasStartedClone;

+		}

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CloneListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CloneListIteratorTests.java
new file mode 100644
index 0000000..4648698
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CloneListIteratorTests.java
@@ -0,0 +1,401 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.iterator.CloneListIterator;
+import org.eclipse.persistence.tools.utility.tests.MultiThreadedTestCase;
+
+@SuppressWarnings("nls")
+public class CloneListIteratorTests
+	extends MultiThreadedTestCase
+{
+	List<String> originalList;
+
+	private List<String> concurrentList;
+
+	public CloneListIteratorTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.originalList = this.buildList();
+	}
+
+	public void testHasNext() {
+		int originalSize = this.originalList.size();
+		int i = 0;
+		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
+			stream.next();
+			// should allow concurrent modification
+			this.originalList.add("foo");
+			i++;
+		}
+		assertTrue(originalSize != this.originalList.size());
+		assertEquals(originalSize, i);
+	}
+
+	public void testNext() {
+		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
+		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
+			assertEquals("bogus element", nestedListIterator.next(), stream.next());
+		}
+	}
+
+	public void testIndex() {
+		ListIterator<String> cloneListIterator = this.buildCloneListIterator();
+		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
+		for (int i = 0; i < 7; i++) {
+			nestedListIterator.next();
+			cloneListIterator.next();
+			assertEquals("bogus index", nestedListIterator.nextIndex(), cloneListIterator.nextIndex());
+			assertEquals("bogus index", nestedListIterator.previousIndex(), cloneListIterator.previousIndex());
+		}
+
+		for (int i = 0; i < 3; i++) {
+			nestedListIterator.previous();
+			cloneListIterator.previous();
+			assertEquals("bogus index", nestedListIterator.nextIndex(), cloneListIterator.nextIndex());
+			assertEquals("bogus index", nestedListIterator.previousIndex(), cloneListIterator.previousIndex());
+		}
+
+		while (nestedListIterator.hasNext()) {
+			nestedListIterator.next();
+			cloneListIterator.next();
+			assertEquals("bogus index", nestedListIterator.nextIndex(), cloneListIterator.nextIndex());
+			assertEquals("bogus index", nestedListIterator.previousIndex(), cloneListIterator.previousIndex());
+		}
+	}
+
+	public void testHasPrevious() {
+		int originalSize = this.originalList.size();
+		int i = 0;
+		ListIterator<String> stream = this.buildCloneListIterator();
+		while (stream.hasNext()) {
+			stream.next();
+			this.originalList.add("foo");
+			i++;
+		}
+		assertTrue(originalSize != this.originalList.size());
+		originalSize = this.originalList.size();
+		while (stream.hasPrevious()) {
+			stream.previous();
+			// should allow concurrent modification
+			this.originalList.add("bar");
+			i--;
+		}
+		assertTrue(originalSize != this.originalList.size());
+		assertEquals(0, i);
+	}
+
+	public void testPrevious() {
+		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
+		ListIterator<String> stream = this.buildCloneListIterator();
+		while (stream.hasNext()) {
+			nestedListIterator.next();
+			stream.next();
+		}
+		while (stream.hasPrevious()) {
+			assertEquals("bogus element", nestedListIterator.previous(), stream.previous());
+		}
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		ListIterator<String> stream = this.buildCloneListIterator();
+		String string = null;
+		while (stream.hasNext()) {
+			string = stream.next();
+		}
+		try {
+			string = stream.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
+
+		exCaught = false;
+		while (stream.hasPrevious()) {
+			string = stream.previous();
+		}
+		try {
+			string = stream.previous();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
+	}
+
+	public void testModifyDefault() {
+		boolean exCaught = false;
+		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
+			if (stream.next().equals("three")) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+
+		exCaught = false;
+		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
+			if (stream.next().equals("three")) {
+				try {
+					stream.add("three and a half");
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+
+		exCaught = false;
+		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
+			if (stream.next().equals("three")) {
+				try {
+					stream.set("another three");
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	public void testModifyMutatorNext() {
+		this.verifyModifyNext(new CloneListIterator<String>(this.originalList, this.buildMutator()));
+	}
+
+	public void testModifyMutatorPrevious() {
+		this.verifyModifyPrevious(new CloneListIterator<String>(this.originalList, this.buildMutator()));
+	}
+
+	private CloneListIterator.Mutator<String> buildMutator() {
+		return new CloneListIterator.Mutator<String>() {
+			@Override
+			public void add(int index, String o) {
+				CloneListIteratorTests.this.originalList.add(index, o);
+			}
+
+			@Override
+			public void remove(int index) {
+				CloneListIteratorTests.this.originalList.remove(index);
+			}
+
+			@Override
+			public void set(int index, String o) {
+				CloneListIteratorTests.this.originalList.set(index, o);
+			}
+		};
+	}
+
+	public void testModifySubclassNext() {
+		this.verifyModifyNext(this.buildSubclass());
+	}
+
+	public void testModifySubclassPrevious() {
+		this.verifyModifyPrevious(this.buildSubclass());
+	}
+
+	private ListIterator<String> buildSubclass() {
+		return new CloneListIterator<String>(this.originalList) {
+			@Override
+			protected void add(int currentIndex, String o) {
+				CloneListIteratorTests.this.originalList.add(currentIndex, o);
+			}
+
+			@Override
+			protected void remove(int currentIndex) {
+				CloneListIteratorTests.this.originalList.remove(currentIndex);
+			}
+
+			@Override
+			protected void set(int currentIndex, String o) {
+				CloneListIteratorTests.this.originalList.set(currentIndex, o);
+			}
+		};
+	}
+
+	private void verifyModifyNext(ListIterator<String> iterator) {
+		String removed = "three";
+		String addedAfter = "five";
+		String added = "five and a half";
+		String replaced = "seven";
+		String replacement = "another seven";
+		assertTrue(this.originalList.contains(removed));
+		assertTrue(this.originalList.contains(addedAfter));
+		assertTrue(this.originalList.contains(replaced));
+		// try to remove before calling #next()
+		boolean exCaught = false;
+		try {
+			iterator.remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+		while (iterator.hasNext()) {
+			String next = iterator.next();
+			if (next.equals(addedAfter)) {
+				iterator.add(added);
+			}
+			if (next.equals(removed)) {
+				iterator.remove();
+				// try to remove twice
+				exCaught = false;
+				try {
+					iterator.remove();
+				} catch (IllegalStateException ex) {
+					exCaught = true;
+				}
+				assertTrue(exCaught);
+			}
+			if (next.equals(replaced)) {
+				iterator.set(replacement);
+			}
+		}
+		assertTrue(this.originalList.contains(added));
+		assertFalse(this.originalList.contains(removed));
+		assertFalse(this.originalList.contains(replaced));
+		assertTrue(this.originalList.contains(replacement));
+	}
+
+	private void verifyModifyPrevious(ListIterator<String> iterator) {
+		String removed = "three";
+		String addedBefore = "five";
+		String added = "four and a half";
+		String replaced = "seven";
+		String replacement = "another seven";
+		assertTrue(this.originalList.contains(removed));
+		assertTrue(this.originalList.contains(addedBefore));
+		assertTrue(this.originalList.contains(replaced));
+		while (iterator.hasNext()) {
+			iterator.next();
+		}
+		while (iterator.hasPrevious()) {
+			Object previous = iterator.previous();
+			if (previous.equals(addedBefore)) {
+				iterator.add(added);
+			}
+			if (previous.equals(removed)) {
+				iterator.remove();
+				// try to remove twice
+				boolean exCaught = false;
+				try {
+					iterator.remove();
+				} catch (IllegalStateException ex) {
+					exCaught = true;
+				}
+				assertTrue("IllegalStateException not thrown", exCaught);
+			}
+			if (previous.equals(replaced)) {
+				iterator.set(replacement);
+			}
+		}
+		assertTrue(this.originalList.contains(added));
+		assertFalse(this.originalList.contains(removed));
+		assertFalse(this.originalList.contains(replaced));
+		assertTrue(this.originalList.contains(replacement));
+	}
+
+	private ListIterator<String> buildCloneListIterator() {
+		return this.buildCloneListIterator(this.originalList);
+	}
+
+	private ListIterator<String> buildCloneListIterator(List<String> list) {
+		return new CloneListIterator<String>(list);
+	}
+
+	private ListIterator<String> buildNestedListIterator() {
+		return this.originalList.listIterator();
+	}
+
+	private List<String> buildList() {
+		List<String> list = this.buildEmptyList();
+		this.populateList(list);
+		return list;
+	}
+
+	private void populateList(List<String> list) {
+		list.add("zero");
+		list.add("one");
+		list.add("two");
+		list.add("three");
+		list.add("four");
+		list.add("five");
+		list.add("six");
+		list.add("seven");
+		list.add("eight");
+		list.add("nine");
+	}
+
+	protected List<String> buildEmptyList() {
+		return new ArrayList<String>();
+	}
+
+	/**
+	 * Test concurrent access: First build a clone iterator in a separate thread
+	 * that hangs momentarily during its construction; then modify the shared
+	 * collection in this thread. This would cause a
+	 * ConcurrentModificationException in the other thread if the clone iterator
+	 * were not synchronized on the original collection.
+	 */
+	public void testConcurrentAccess() throws Exception {
+		CloneIteratorTests.SlowCollection<String> slow = new CloneIteratorTests.SlowCollection<String>();
+		this.populateList(slow);
+		// using the unsynchronized list will cause the test to fail
+		// this.originalList = slow;
+		this.originalList = Collections.synchronizedList(slow);
+
+		this.concurrentList = new ArrayList<String>();
+		Thread thread = this.buildThread(this.buildRunnable());
+		thread.start();
+		while ( ! slow.hasStartedClone()) {
+			// wait for the other thread to start the clone...
+			Thread.yield();
+		}
+		// ...then sneak in an extra element
+		this.originalList.add("seventeen");
+		thread.join();
+		List<String> expected = new ArrayList<String>();
+		this.populateList(expected);
+		assertEquals(expected, this.concurrentList);
+	}
+
+	private Runnable buildRunnable() {
+		return new TestRunnable() {
+			@Override
+			protected void run_() throws Throwable {
+				CloneListIteratorTests.this.loopWithCloneListIterator();
+			}
+		};
+	}
+
+	/**
+	 * use a clone iterator to loop over the "slow" collection and copy its
+	 * contents to the concurrent collection
+	 */
+	void loopWithCloneListIterator() {
+		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
+			this.concurrentList.add(stream.next());
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CommonUtilityIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CommonUtilityIteratorTests.java
new file mode 100644
index 0000000..a32f440
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CommonUtilityIteratorTests.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * decentralize test creation code
+ */
+public class CommonUtilityIteratorTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CommonUtilityIteratorTests.class.getPackage().getName());
+
+		suite.addTestSuite(ArrayIteratorTests.class);
+		suite.addTestSuite(ArrayListIteratorTests.class);
+		suite.addTestSuite(ChainIteratorTests.class);
+		suite.addTestSuite(CloneIteratorTests.class);
+		suite.addTestSuite(CloneListIteratorTests.class);
+		suite.addTestSuite(CompositeIteratorTests.class);
+		suite.addTestSuite(CompositeListIteratorTests.class);
+		suite.addTestSuite(EmptyIteratorTests.class);
+		suite.addTestSuite(EmptyListIteratorTests.class);
+		suite.addTestSuite(EnumerationIteratorTests.class);
+		suite.addTestSuite(FilteringIteratorTests.class);
+		suite.addTestSuite(GraphIteratorTests.class);
+		suite.addTestSuite(IteratorToolsTests.class);
+		suite.addTestSuite(PeekableIteratorTests.class);
+		suite.addTestSuite(ReadOnlyCompositeListIteratorTests.class);
+		suite.addTestSuite(ReadOnlyIteratorTests.class);
+		suite.addTestSuite(ReadOnlyListIteratorTests.class);
+		suite.addTestSuite(SimultaneousIteratorTests.class);
+		suite.addTestSuite(SimultaneousListIteratorTests.class);
+		suite.addTestSuite(SingleElementIteratorTests.class);
+		suite.addTestSuite(SingleElementListIteratorTests.class);
+		suite.addTestSuite(SuperIteratorWrapperTests.class);
+		suite.addTestSuite(SynchronizedIteratorTests.class);
+		suite.addTestSuite(SynchronizedListIteratorTests.class);
+		suite.addTestSuite(TransformationIteratorTests.class);
+		suite.addTestSuite(TransformationListIteratorTests.class);
+		suite.addTestSuite(TreeIteratorTests.class);
+
+		return suite;
+	}
+
+	private CommonUtilityIteratorTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CompositeIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CompositeIteratorTests.java
new file mode 100644
index 0000000..8cd1200
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CompositeIteratorTests.java
@@ -0,0 +1,354 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.CompositeIterator;
+
+@SuppressWarnings("nls")
+public class CompositeIteratorTests extends TestCase {
+
+	public CompositeIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testHasAnother() {
+		this.verifyHasAnother(this.buildCompositeIterator());
+	}
+
+	public void testHasAnother2() {
+		this.verifyHasAnother(this.buildCompositeIterator2());
+	}
+
+	public void testHasAnother3() {
+		this.verifyHasAnother(this.buildCompositeIterator3());
+	}
+
+	void verifyHasAnother(Iterator<String> stream) {
+		this.verifyHasAnother(8, stream);
+	}
+
+	void verifyHasAnother(int expected, Iterator<String> stream) {
+		int i = 0;
+		while (stream.hasNext()) {
+			stream.next();
+			i++;
+		}
+		assertEquals(expected, i);
+	}
+
+	public void testAnother() {
+		this.verifyAnother(this.buildCompositeIterator());
+	}
+
+	public void testAnother2() {
+		this.verifyAnother(this.buildCompositeIterator2());
+	}
+
+	public void testAnother3() {
+		this.verifyAnother(this.buildCompositeIterator3());
+	}
+
+	void verifyAnother(Iterator<String> stream) {
+		this.verifyAnother(1, stream);
+	}
+
+	void verifyAnother(int start, Iterator<String> stream) {
+		int index = start;
+		while (stream.hasNext()) {
+			assertEquals("bogus element", String.valueOf(index++), stream.next().substring(0, 1));
+		}
+	}
+
+	public void testRemove() {
+		this.verifyRemove();
+	}
+
+	protected void verifyRemove() {
+		List<String> list1 = this.buildList1();
+		Object lastElement1 = list1.get(list1.size() - 1);
+		List<String> list2 = this.buildList2();
+		List<String> list3 = this.buildList3();
+
+		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
+		list.add(list1.listIterator());
+		list.add(list2.listIterator());
+		list.add(list3.listIterator());
+
+		Iterator<String> stream = this.buildCompositeIterator(list.listIterator());
+		while (stream.hasNext()) {
+			Object next = stream.next();
+			if (next.equals("333")) {
+				stream.remove();
+			}
+			// test special case - where we are between iterators
+			if (next.equals(lastElement1)) {
+				// this will trigger the next iterator to be loaded
+				stream.hasNext();
+				// now try to remove from the previous iterator
+				stream.remove();
+			}
+		}
+		stream.remove();
+
+		assertEquals("nothing removed from collection 1", this.buildList1().size() - 2, list1.size());
+		assertFalse("element still in collection 1", list1.contains("333"));
+		assertFalse("last element still in collection 1", list1.contains(lastElement1));
+		assertTrue("wrong element removed from collection 1", list1.contains("22"));
+
+		assertEquals("nothing removed from collection 3", this.buildList3().size() - 1, list3.size());
+		assertFalse("element still in collection 3", list3.contains("88888888"));
+		assertTrue("wrong element removed from collection 3", list3.contains("666666"));
+	}
+
+	public void testSingleElement() {
+		String item = "0";
+		this.verifyHasAnother(9, this.buildCompositeIterator(item, this.buildCompositeIterator()));
+		this.verifyAnother(0, this.buildCompositeIterator(item, this.buildCompositeIterator()));
+	}
+
+	public void testNoSuchElementException() {
+		this.verifyNoSuchElementException(this.buildCompositeIterator());
+	}
+
+	void verifyNoSuchElementException(Iterator<String> stream) {
+		boolean exCaught = false;
+		String string = null;
+		while (stream.hasNext()) {
+			string = stream.next();
+		}
+		try {
+			string = stream.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
+	}
+
+	public void testUnsupportedOperationException() {
+		this.verifyUnsupportedOperationException(this.buildUnmodifiableCompositeIterator());
+	}
+
+	void verifyUnsupportedOperationException(Iterator<String> stream) {
+		boolean exCaught = false;
+		while (stream.hasNext()) {
+			Object string = stream.next();
+			if (string.equals("333")) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	public void testIllegalStateException() {
+		this.verifyIllegalStateException();
+	}
+
+	void verifyIllegalStateException() {
+		this.verifyIllegalStateException(this.buildCompositeIterator());
+	}
+
+	void verifyIllegalStateException(Iterator<String> stream) {
+		boolean exCaught = false;
+		try {
+			stream.remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue("IllegalStateException not thrown", exCaught);
+	}
+
+	public void testEmptyHasAnother1() {
+		this.verifyEmptyHasAnother(this.buildEmptyCompositeIterator1());
+	}
+
+	void verifyEmptyHasAnother(Iterator<String> stream) {
+		int i = 0;
+		while (stream.hasNext()) {
+			stream.next();
+			i++;
+		}
+		assertEquals(0, i);
+	}
+
+	public void testEmptyNoSuchElementException1() {
+		this.verifyNoSuchElementException(this.buildEmptyCompositeIterator1());
+	}
+
+	public void testEmptyIllegalStateException1() {
+		this.verifyEmptyIllegalStateException1();
+	}
+
+	void verifyEmptyIllegalStateException1() {
+		this.verifyIllegalStateException(this.buildEmptyCompositeIterator1());
+	}
+
+	public void testEmptyHasAnother2() {
+		this.verifyEmptyHasAnother(this.buildEmptyCompositeIterator2());
+	}
+
+	public void testEmptyNoSuchElementException2() {
+		this.verifyNoSuchElementException(this.buildEmptyCompositeIterator2());
+	}
+
+	public void testEmptyIllegalStateException2() {
+		this.verifyEmptyIllegalStateException2();
+	}
+
+	void verifyEmptyIllegalStateException2() {
+		this.verifyIllegalStateException(this.buildEmptyCompositeIterator2());
+	}
+
+	Iterator<String> buildCompositeIterator() {
+		return this.buildCompositeIterator(this.buildIterators());
+	}
+
+	Iterator<String> buildEmptyCompositeIterator1() {
+		return this.buildCompositeIterator(this.buildEmptyIterators1());
+	}
+
+	Iterator<String> buildEmptyCompositeIterator2() {
+		return this.buildCompositeIterator(this.buildEmptyIterators2());
+	}
+
+	Iterator<String> buildUnmodifiableCompositeIterator() {
+		return this.buildCompositeIterator(this.buildUnmodifiableIterators());
+	}
+
+	// leave unchecked so we can override in subclass
+	@SuppressWarnings("unchecked")
+	Iterator<String> buildCompositeIterator(@SuppressWarnings("rawtypes") Iterator iterators) {
+		return new CompositeIterator<String>(iterators);
+	}
+
+	// use vararg constructor
+	@SuppressWarnings("unchecked")
+	Iterator<String> buildCompositeIterator2() {
+		return new CompositeIterator<String>(this.buildIterator1(), this.buildIterator2(), this.buildIterator3());
+	}
+
+	// use vararg constructor
+	@SuppressWarnings("unchecked")
+	Iterator<String> buildCompositeIterator3() {
+		return new CompositeIterator<String>(new Iterator[] { this.buildIterator1(), this.buildIterator2(), this.buildIterator3() });
+	}
+
+	Iterator<String> buildCompositeIterator(String string, Iterator<String> iterator) {
+		return new CompositeIterator<String>(string, iterator);
+	}
+
+	ListIterator<Iterator<String>> buildIterators() {
+		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
+		list.add(this.buildIterator1());
+		list.add(this.buildIterator2());
+		list.add(this.buildIterator3());
+		return list.listIterator();
+	}
+
+	ListIterator<Iterator<String>> buildEmptyIterators1() {
+		return this.buildEmptyIteratorIterator();
+	}
+
+	ListIterator<Iterator<String>> buildEmptyIterators2() {
+		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
+		list.add(this.buildEmptyStringIterator());
+		list.add(this.buildEmptyStringIterator());
+		list.add(this.buildEmptyStringIterator());
+		return list.listIterator();
+	}
+
+	ListIterator<Iterator<String>> buildUnmodifiableIterators() {
+		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
+		list.add(this.buildUnmodifiableIterator1());
+		list.add(this.buildUnmodifiableIterator2());
+		list.add(this.buildUnmodifiableIterator3());
+		return list.listIterator();
+	}
+
+	ListIterator<String> buildIterator1() {
+		return this.buildList1().listIterator();
+	}
+
+	ListIterator<String> buildIterator2() {
+		return this.buildList2().listIterator();
+	}
+
+	ListIterator<String> buildIterator3() {
+		return this.buildList3().listIterator();
+	}
+
+	ListIterator<String> buildUnmodifiableIterator1() {
+		return this.buildUnmodifiableList1().listIterator();
+	}
+
+	ListIterator<String> buildUnmodifiableIterator2() {
+		return this.buildUnmodifiableList2().listIterator();
+	}
+
+	ListIterator<String> buildUnmodifiableIterator3() {
+		return this.buildUnmodifiableList3().listIterator();
+	}
+
+	ListIterator<Iterator<String>> buildEmptyIteratorIterator() {
+		return (new ArrayList<Iterator<String>>()).listIterator();
+	}
+
+	ListIterator<String> buildEmptyStringIterator() {
+		return (new ArrayList<String>()).listIterator();
+	}
+
+	List<String> buildList1() {
+		List<String> list = new ArrayList<String>();
+		list.add("1");
+		list.add("22");
+		list.add("333");
+		list.add("4444");
+		return list;
+	}
+
+	List<String> buildList2() {
+		return new ArrayList<String>();
+	}
+
+	List<String> buildList3() {
+		List<String> list = new ArrayList<String>();
+		list.add("55555");
+		list.add("666666");
+		list.add("7777777");
+		list.add("88888888");
+		return list;
+	}
+
+	List<String> buildUnmodifiableList1() {
+		return Collections.unmodifiableList(this.buildList1());
+	}
+
+	List<String> buildUnmodifiableList2() {
+		return Collections.unmodifiableList(this.buildList2());
+	}
+
+	List<String> buildUnmodifiableList3() {
+		return Collections.unmodifiableList(this.buildList3());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CompositeListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CompositeListIteratorTests.java
new file mode 100644
index 0000000..2726507
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/CompositeListIteratorTests.java
@@ -0,0 +1,334 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.CompositeListIterator;
+
+@SuppressWarnings("nls")
+public class CompositeListIteratorTests extends ReadOnlyCompositeListIteratorTests {
+
+	public CompositeListIteratorTests(String name) {
+		super(name);
+	}
+
+	@Override
+	public void testRemove() {
+		super.testRemove();
+		List<String> list1 = this.buildList1();
+		List<String> list2 = this.buildList2();
+		List<String> list3 = this.buildList3();
+		Object firstElement3 = list3.get(0);
+
+		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
+		list.add(list1.listIterator());
+		list.add(list2.listIterator());
+		list.add(list3.listIterator());
+
+		ListIterator<String> stream = (ListIterator<String>) this.buildCompositeIterator(list.listIterator());
+		// position to end of stream
+		while (stream.hasNext()) {
+			stream.next();
+		}
+		while (stream.hasPrevious()) {
+			Object previous = stream.previous();
+			if (previous.equals("333")) {
+				stream.remove();
+			}
+			// test special case - where we are between iterators
+			if (previous.equals(firstElement3)) {
+				// this will trigger the next iterator to be loaded
+				stream.hasPrevious();
+				// now try to remove from the previous iterator
+				stream.remove();
+			}
+		}
+		stream.remove();
+
+		assertEquals("nothing removed from collection 1", this.buildList1().size() - 2, list1.size());
+		assertFalse("element still in collection 1", list1.contains("1"));
+		assertFalse("element still in collection 1", list1.contains("333"));
+
+		assertEquals("nothing removed from collection 3", this.buildList3().size() - 1, list3.size());
+		assertFalse("first element still in collection 3", list3.contains(firstElement3));
+		assertTrue("wrong element removed from collection 3", list3.contains("666666"));
+	}
+
+	public void testAdd() {
+		List<String> list1 = this.buildList1();
+		Object lastElement1 = list1.get(list1.size() - 1);
+		List<String> list2 = this.buildList2();
+		List<String> list3 = this.buildList3();
+		Object firstElement3 = list3.get(0);
+
+		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
+		list.add(list1.listIterator());
+		list.add(list2.listIterator());
+		list.add(list3.listIterator());
+
+		ListIterator<String> stream = (ListIterator<String>) this.buildCompositeIterator(list.listIterator());
+		while (stream.hasNext()) {
+			Object next = stream.next();
+			if (next.equals("333")) {
+				stream.add("3.5");
+			}
+			// test special case - where we are between iterators
+			if (next.equals(lastElement1)) {
+				// this will trigger the next iterator to be loaded
+				stream.hasNext();
+				// now try to add to the iterator
+				stream.add("something in 3");
+			}
+		}
+		stream.add("finale");
+		boolean checkForFinale = true;
+		while (stream.hasPrevious()) {
+			Object previous = stream.previous();
+			if (checkForFinale) {
+				checkForFinale = false;
+				assertEquals("added element dropped", "finale", previous);
+			}
+			if (previous.equals("333")) {
+				stream.add("2.5");
+			}
+			// test special case - where we are between iterators
+			if (previous.equals(firstElement3)) {
+				// this will trigger the next iterator to be loaded
+				stream.hasPrevious();
+				// now try to remove from the previous iterator
+				stream.add("old start of 3");
+			}
+		}
+		stream.add("prelude");
+		assertEquals("added element dropped", "prelude", stream.previous());
+
+		assertEquals("elements not added to collection 1", this.buildList1().size() + 3, list1.size());
+		assertEquals("element not added to collection 1", "prelude", list1.get(0));
+		assertEquals("element not added to collection 1", "2.5", list1.get(3));
+		assertEquals("element not added to collection 1", "3.5", list1.get(5));
+
+		assertEquals("elements not added to collection 3", this.buildList3().size() + 3, list3.size());
+		assertEquals("element not added to collection 3", "something in 3", list3.get(0));
+		assertEquals("element not added to collection 3", "old start of 3", list3.get(1));
+		assertEquals("element not added to collection 3", "finale", list3.get(list3.size() - 1));
+
+		// add to the front
+		stream = (ListIterator<String>) this.buildCompositeIterator();
+		stream.add("blah");
+		assertFalse("added element should be placed BEFORE the \"cursor\"", stream.next().equals("blah"));
+
+		stream = (ListIterator<String>) this.buildCompositeIterator();
+		stream.add("blah");
+		assertTrue("added element should be placed BEFORE the \"cursor\"", stream.previous().equals("blah"));
+
+		stream = (ListIterator<String>) this.buildCompositeIterator();
+		while (stream.hasNext()) {
+			stream.next();
+		}
+		while (stream.hasPrevious()) {
+			stream.previous();
+		}
+		stream.add("blah");
+		assertFalse("added element should be placed BEFORE the \"cursor\"", stream.next().equals("blah"));
+
+		stream = (ListIterator<String>) this.buildCompositeIterator();
+		while (stream.hasNext()) {
+			stream.next();
+		}
+		while (stream.hasPrevious()) {
+			stream.previous();
+		}
+		stream.add("blah");
+		assertTrue("added element should be placed BEFORE the \"cursor\"", stream.previous().equals("blah"));
+
+		// add to the middle
+		stream = (ListIterator<String>) this.buildCompositeIterator();
+		stream.next();
+		stream.add("blah");
+		assertFalse("added element should be placed BEFORE the \"cursor\"", stream.next().equals("blah"));
+
+		stream = (ListIterator<String>) this.buildCompositeIterator();
+		stream.next();
+		stream.add("blah");
+		assertTrue("added element should be placed BEFORE the \"cursor\"", stream.previous().equals("blah"));
+
+		stream = (ListIterator<String>) this.buildCompositeIterator();
+		while (stream.hasNext()) {
+			stream.next();
+		}
+		stream.previous();
+		stream.add("blah");
+		assertFalse("added element should be placed BEFORE the \"cursor\"", stream.next().equals("blah"));
+
+		stream = (ListIterator<String>) this.buildCompositeIterator();
+		while (stream.hasNext()) {
+			stream.next();
+		}
+		stream.previous();
+		stream.add("blah");
+		assertTrue("added element should be placed BEFORE the \"cursor\"", stream.previous().equals("blah"));
+
+		// add to the end
+		stream = (ListIterator<String>) this.buildCompositeIterator();
+		while (stream.hasNext()) {
+			stream.next();
+		}
+		stream.add("blah");
+		assertFalse("added element should be placed BEFORE the \"cursor\"", stream.hasNext());
+
+		stream = (ListIterator<String>) this.buildCompositeIterator();
+		while (stream.hasNext()) {
+			stream.next();
+		}
+		stream.add("blah");
+		assertTrue("added element should be placed BEFORE the \"cursor\"", stream.previous().equals("blah"));
+	}
+
+	public void testSet() {
+		List<String> list1 = this.buildList1();
+		Object lastElement1 = list1.get(list1.size() - 1);
+		List<String> list2 = this.buildList2();
+		List<String> list3 = this.buildList3();
+		Object firstElement3 = list3.get(0);
+
+		List<Iterator<String>> list = new ArrayList<Iterator<String>>();
+		list.add(list1.listIterator());
+		list.add(list2.listIterator());
+		list.add(list3.listIterator());
+
+		ListIterator<String> stream = (ListIterator<String>) this.buildCompositeIterator(list.listIterator());
+		// position to end of stream
+		while (stream.hasNext()) {
+			Object next = stream.next();
+			if (next.equals("333")) {
+				stream.set("333a");
+			}
+			// test special case - where we are between iterators
+			if (next.equals(lastElement1)) {
+				// this will trigger the next iterator to be loaded
+				stream.hasNext();
+				// now try to remove from the previous iterator
+				stream.set("end of 1");
+			}
+		}
+		while (stream.hasPrevious()) {
+			Object previous = stream.previous();
+			if (previous.equals("22")) {
+				stream.set("22a");
+			}
+			// test special case - where we are between iterators
+			if (previous.equals(firstElement3)) {
+				// this will trigger the next iterator to be loaded
+				stream.hasPrevious();
+				// now try to remove from the previous iterator
+				stream.set("start of 3");
+			}
+		}
+
+		assertEquals("element(s) added to collection 1", this.buildList1().size(), list1.size());
+		assertEquals("element not set in collection 1", "22a", list1.get(1));
+		assertFalse("element not set in collection 1", list1.contains("22"));
+		assertEquals("element not set in collection 1", "333a", list1.get(2));
+		assertFalse("element not set in collection 1", list1.contains("333"));
+		assertEquals("element not set in collection 1", "end of 1", list1.get(list1.size() - 1));
+		assertFalse("element not set in collection 1", list1.contains(lastElement1));
+
+		assertEquals("element(s) added to collection 3", this.buildList3().size(), list3.size());
+		assertEquals("element not set in collection 3", "start of 3", list3.get(0));
+		assertFalse("element not set in collection 3", list3.contains(firstElement3));
+	}
+
+	@Override
+	public void testNextIndexPreviousIndex() {
+		int i = 0;
+		ListIterator<String> stream = (ListIterator<String>) this.buildCompositeIterator();
+		assertEquals(i, stream.nextIndex());
+		assertEquals(i - 1, stream.previousIndex());
+		while (stream.hasNext()) {
+			Object next = stream.next();
+			i++;
+			if (next.equals("333")) {
+				stream.remove();
+				i--;
+			}
+			if (next.equals("7777777")) {
+				stream.add("7.5");
+				i++;
+			}
+			assertEquals(i, stream.nextIndex());
+			assertEquals(i - 1, stream.previousIndex());
+		}
+		assertEquals("index is corrupt", 8, i);
+
+		assertEquals(i, stream.nextIndex());
+		assertEquals(i - 1, stream.previousIndex());
+		while (stream.hasPrevious()) {
+			Object previous = stream.previous();
+			i--;
+			if (previous.equals("666666")) {
+				stream.remove();
+				// removing a previous element, does not change the cursor
+			}
+			if (previous.equals("22")) {
+				stream.add("1.5");
+				i++;
+			}
+			assertEquals(i, stream.nextIndex());
+			assertEquals(i - 1, stream.previousIndex());
+		}
+		assertEquals("index is corrupt", 0, i);
+	}
+
+	@Override
+	public void testIllegalStateException() {
+		this.verifyIllegalStateException();
+	}
+
+	@Override
+	public void testEmptyIllegalStateException1() {
+		this.verifyEmptyIllegalStateException1();
+	}
+
+	@Override
+	public void testEmptyIllegalStateException2() {
+		this.verifyEmptyIllegalStateException2();
+	}
+
+	// unchecked so we can override the unchecked method in superclass
+	@Override
+	@SuppressWarnings("unchecked")
+	Iterator<String> buildCompositeIterator(@SuppressWarnings("rawtypes") Iterator iterators) {
+		return new CompositeListIterator<String>((ListIterator<ListIterator<String>>) iterators);
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	Iterator<String> buildCompositeIterator2() {
+		return new CompositeListIterator<String>(this.buildIterator1(), this.buildIterator2(), this.buildIterator3());
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	Iterator<String> buildCompositeIterator3() {
+		return new CompositeListIterator<String>(new ListIterator[] { this.buildIterator1(), this.buildIterator2(), this.buildIterator3() });
+	}
+
+	@Override
+	ListIterator<String> buildCompositeListIterator(String string, ListIterator<String> iterator) {
+		return new CompositeListIterator<String>(string, iterator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/EmptyIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/EmptyIteratorTests.java
new file mode 100644
index 0000000..44a6ddc
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/EmptyIteratorTests.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+
+@SuppressWarnings("nls")
+public class EmptyIteratorTests extends TestCase {
+
+	public EmptyIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testHasNext() {
+		int i = 0;
+		for (Iterator<Object> stream = EmptyIterator.instance(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(0, i);
+	}
+
+	public void testNext() {
+		for (Iterator<String> stream = EmptyIterator.instance(); stream.hasNext();) {
+			fail("bogus element: " + stream.next());
+		}
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		Iterator<Number> stream = EmptyIterator.instance();
+		Object element = null;
+		while (stream.hasNext()) {
+			element = stream.next();
+		}
+		try {
+			element = stream.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + element, exCaught);
+	}
+
+	public void testUnsupportedOperationException() {
+		boolean exCaught = false;
+		try {
+			EmptyIterator.instance().remove();
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/EmptyListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/EmptyListIteratorTests.java
new file mode 100644
index 0000000..372a855
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/EmptyListIteratorTests.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.EmptyListIterator;
+
+@SuppressWarnings("nls")
+public class EmptyListIteratorTests extends TestCase {
+
+	public EmptyListIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testHasNext() {
+		int i = 0;
+		for (ListIterator<Object> stream = EmptyListIterator.instance(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(0, i);
+	}
+
+	public void testNext() {
+		for (ListIterator<Object> stream = EmptyListIterator.instance(); stream.hasNext();) {
+			fail("bogus element: " + stream.next());
+		}
+	}
+
+	public void testNextIndex() {
+		ListIterator<Object> stream = EmptyListIterator.instance();
+		assertEquals(0, stream.nextIndex());
+	}
+
+	public void testHasPrevious() {
+		ListIterator<Object> stream = EmptyListIterator.instance();
+		int i = 0;
+		while (stream.hasPrevious()) {
+			stream.previous();
+			i++;
+		}
+		assertEquals(0, i);
+
+		while (stream.hasNext()) {
+			stream.next();
+		}
+		i = 0;
+		while (stream.hasPrevious()) {
+			stream.previous();
+			i++;
+		}
+		assertEquals(0, i);
+	}
+
+	public void testPrevious() {
+		ListIterator<Object> stream = EmptyListIterator.instance();
+		while (stream.hasPrevious()) {
+			fail("bogus element: " + stream.previous());
+		}
+		while (stream.hasNext()) {
+			stream.next();
+		}
+		while (stream.hasPrevious()) {
+			fail("bogus element: " + stream.previous());
+		}
+	}
+
+	public void testPreviousIndex() {
+		ListIterator<Object> stream = EmptyListIterator.instance();
+		assertEquals(-1, stream.previousIndex());
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		ListIterator<Object> stream = EmptyListIterator.instance();
+		Object element = null;
+		while (stream.hasNext()) {
+			element = stream.next();
+		}
+		try {
+			element = stream.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown (next): " + element, exCaught);
+		while (stream.hasPrevious()) {
+			element = stream.previous();
+		}
+		try {
+			element = stream.previous();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown (previous): " + element, exCaught);
+	}
+
+	public void testUnsupportedOperationException() {
+		boolean exCaught = false;
+		try {
+			EmptyListIterator.instance().remove();
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue("UnsupportedOperationException not thrown (remove)", exCaught);
+		try {
+			EmptyListIterator.instance().set(new Object());
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue("UnsupportedOperationException not thrown (set)", exCaught);
+		try {
+			EmptyListIterator.instance().add(new Object());
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue("UnsupportedOperationException not thrown (add)", exCaught);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/EnumerationIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/EnumerationIteratorTests.java
new file mode 100644
index 0000000..fd8ad04
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/EnumerationIteratorTests.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.EnumerationIterator;
+
+@SuppressWarnings("nls")
+public class EnumerationIteratorTests extends TestCase {
+
+	public EnumerationIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testHasNext() {
+		int i = 0;
+		for (Iterator<String> stream = this.buildIterator(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(this.buildVector().size(), i);
+	}
+
+	public void testHasNextUpcast() {
+		int i = 0;
+		for (Iterator<Object> stream = this.buildIteratorUpcast(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(this.buildVector().size(), i);
+	}
+
+	public void testNext() {
+		Enumeration<String> enumeration = this.buildEnumeration();
+		for (Iterator<String> stream = this.buildIterator(); stream.hasNext();) {
+			assertEquals("bogus element", enumeration.nextElement(), stream.next());
+		}
+	}
+
+	public void testNextUpcast() {
+		Enumeration<String> enumeration = this.buildEnumeration();
+		for (Iterator<Object> stream = this.buildIteratorUpcast(); stream.hasNext();) {
+			assertEquals("bogus element", enumeration.nextElement(), stream.next());
+		}
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		Iterator<String> stream = this.buildIterator();
+		String string = null;
+		while (stream.hasNext()) {
+			string = stream.next();
+		}
+		try {
+			string = stream.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
+	}
+
+	public void testUnsupportedOperationException() {
+		boolean exCaught = false;
+		for (Iterator<String> stream = this.buildIterator(); stream.hasNext();) {
+			if (stream.next().equals("three")) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	private Iterator<String> buildIterator() {
+		return this.buildIterator(this.buildEnumeration());
+	}
+
+	private Iterator<String> buildIterator(Enumeration<String> enumeration) {
+		return new EnumerationIterator<String>(enumeration);
+	}
+
+	private Enumeration<String> buildEnumeration() {
+		return this.buildVector().elements();
+	}
+
+	private Vector<String> buildVector() {
+		Vector<String> v = new Vector<String>();
+		v.addElement("one");
+		v.addElement("two");
+		v.addElement("three");
+		v.addElement("four");
+		v.addElement("five");
+		v.addElement("six");
+		v.addElement("seven");
+		v.addElement("eight");
+		return v;
+	}
+
+	private Iterator<Object> buildIteratorUpcast() {
+		return this.buildIteratorUpcast(this.buildEnumeration());
+	}
+
+	private Iterator<Object> buildIteratorUpcast(Enumeration<String> enumeration) {
+		return new EnumerationIterator<Object>(enumeration);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/FilteringIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/FilteringIteratorTests.java
new file mode 100644
index 0000000..bca8400
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/FilteringIteratorTests.java
@@ -0,0 +1,268 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.filter.SimpleFilter;
+import org.eclipse.persistence.tools.utility.iterator.FilteringIterator;
+
+@SuppressWarnings("nls")
+public class FilteringIteratorTests extends TestCase {
+
+	private static final String PREFIX = "prefix";
+
+	public FilteringIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testUnsupportedOperationException() {
+		boolean exCaught = false;
+		for (Iterator<String> stream = this.buildAcceptIterator(); stream.hasNext();) {
+			String string = stream.next();
+			if (string.equals(PREFIX + "3")) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		Iterator<String> stream = this.buildAcceptIterator();
+		String string = null;
+		while (stream.hasNext()) {
+			string = stream.next();
+		}
+		try {
+			string = stream.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
+	}
+
+	public void testAcceptHasNext() {
+		int i = 0;
+		for (Iterator<String> stream = this.buildAcceptIterator(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(6, i);
+	}
+
+	public void testAcceptNext() {
+		for (Iterator<String> stream = this.buildAcceptIterator(); stream.hasNext();) {
+			assertTrue("bogus accept", stream.next().startsWith(PREFIX));
+		}
+	}
+
+	public void testInnerHasNext() {
+		int i = 0;
+		for (Iterator<String> stream = this.buildInnerIterator(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(6, i);
+	}
+
+	public void testInnerNext() {
+		for (Iterator<String> stream = this.buildInnerIterator(); stream.hasNext();) {
+			assertTrue("bogus accept", stream.next().startsWith(PREFIX));
+		}
+	}
+
+	public void testRejectHasNext() {
+		int i = 0;
+		for (Iterator<String> stream = this.buildRejectIterator(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(2, i);
+	}
+
+	public void testRejectNext() {
+		for (Iterator<String> stream = this.buildRejectIterator(); stream.hasNext();) {
+			assertFalse("bogus reject", stream.next().startsWith(PREFIX));
+		}
+	}
+
+	public void testBothHasNext() {
+		// if both accept() and reject() are overridden, accept() is used
+		int i = 0;
+		for (Iterator<String> stream = this.buildBothIterator(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(6, i);
+	}
+
+	public void testLoadNext() {
+		// loadNext() used to cause a NPE when executing during the
+		// constructor because the "outer" class is not bound until completion
+		// of the constructor
+		for (Iterator<String> stream = this.buildInnerIterator2(); stream.hasNext();) {
+			assertTrue("bogus accept", stream.next().startsWith(PREFIX));
+		}
+	}
+
+	public void testFilterHasNext() {
+		int i = 0;
+		for (Iterator<String> stream = this.buildFilterIterator(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(6, i);
+	}
+
+	public void testFilterNext() {
+		for (Iterator<String> stream = this.buildFilterIterator(); stream.hasNext();) {
+			assertTrue("bogus accept", stream.next().startsWith(PREFIX));
+		}
+	}
+
+	private Iterator<String> buildFilteredIterator(Iterator<String> nestedIterator, Filter<String> filter) {
+		return new FilteringIterator<String>(nestedIterator, filter);
+	}
+
+	private Iterator<String> buildInnerFilteredIterator(Iterator<String> nestedIterator) {
+		return new FilteringIterator<String>(nestedIterator) {
+			@Override
+			protected boolean accept(String s) {
+				return s.startsWith(PREFIX);
+			}
+		};
+	}
+
+	String getPrefix() {
+		return PREFIX;
+	}
+
+	// this inner iterator will call the "outer" object
+	private Iterator<String> buildInnerFilteredIterator2(Iterator<String> nestedIterator) {
+		return new FilteringIterator<String>(nestedIterator) {
+			@Override
+			protected boolean accept(String s) {
+				return s.startsWith(FilteringIteratorTests.this.getPrefix());
+			}
+		};
+	}
+
+	private Iterator<String> buildNestedIterator() {
+		Collection<String> c = new ArrayList<String>();
+		c.add(PREFIX + "1");
+		c.add(PREFIX + "2");
+		c.add(PREFIX + "3");
+		c.add("4");
+		c.add(PREFIX + "5");
+		c.add(PREFIX + "6");
+		c.add(PREFIX + "7");
+		c.add("8");
+		return c.iterator();
+	}
+
+	private Iterator<String> buildAcceptIterator() {
+		return this.buildFilteredIterator(this.buildNestedIterator(), this.buildAcceptFilter(PREFIX));
+	}
+
+	private Iterator<String> buildInnerIterator() {
+		return this.buildInnerFilteredIterator(this.buildNestedIterator());
+	}
+
+	// this inner iterator will call the "outer" object
+	private Iterator<String> buildInnerIterator2() {
+		return this.buildInnerFilteredIterator2(this.buildNestedIterator());
+	}
+
+	private Iterator<String> buildFilterIterator() {
+		return this.buildFilteredIterator(this.buildNestedIterator(), this.buildFilterFilter(PREFIX));
+	}
+
+	private Filter<String> buildAcceptFilter(String prefix) {
+		return new SimpleFilter<String, String>(prefix) {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public boolean accept(String s) {
+				return s.startsWith(this.criterion);
+			}
+		};
+	}
+
+	private Iterator<String> buildRejectIterator() {
+		return this.buildFilteredIterator(this.buildNestedIterator(), this.buildRejectFilter(PREFIX));
+	}
+
+	private Filter<String> buildRejectFilter(String prefix) {
+		return new SimpleFilter<String, String>(prefix) {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public boolean reject(String s) {
+				return s.startsWith(this.criterion);
+			}
+		};
+	}
+
+	// use anonymous inner Filter
+	private Filter<String> buildFilterFilter(final String prefix) {
+		return new Filter<String>() {
+			@Override
+			public boolean accept(String s) {
+				return s.startsWith(prefix);
+			}
+		};
+	}
+
+	private Iterator<String> buildBothIterator() {
+		return this.buildFilteredIterator(this.buildNestedIterator(), this.buildBothFilter(PREFIX));
+	}
+
+	private Filter<String> buildBothFilter(String prefix) {
+		return new SimpleFilter<String, String>(prefix) {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public boolean reject(String s) {
+				return s.startsWith(this.criterion);
+			}
+
+			@Override
+			public boolean accept(String s) {
+				return s.startsWith(this.criterion);
+			}
+		};
+	}
+
+	public void testInvalidFilteringIterator() {
+		boolean exCaught = false;
+		try {
+			// missing method override
+			Iterator<String> iterator = new FilteringIterator<String>(this.buildNestedIterator());
+			String s = iterator.next();
+			fail("invalid string: " + s);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown", exCaught);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/GraphIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/GraphIteratorTests.java
new file mode 100644
index 0000000..18b10e4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/GraphIteratorTests.java
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.GraphIterator;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class GraphIteratorTests extends TestCase {
+	/** this will be populated with all the nodes created for the test */
+	Collection<GraphNode> nodes = new ArrayList<GraphNode>();
+
+	public GraphIteratorTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testHasNext1() {
+		this.verifyHasNext(this.buildGraphIterator1());
+	}
+
+	public void testHasNext2() {
+		this.verifyHasNext(this.buildGraphIterator2());
+	}
+
+	private void verifyHasNext(Iterator<GraphNode> iterator) {
+		int i = 0;
+		while (iterator.hasNext()) {
+			iterator.next();
+			i++;
+		}
+		assertEquals(this.nodes.size(), i);
+	}
+
+	public void testNext1() {
+		this.verifyNext(this.buildGraphIterator1());
+	}
+
+	public void testNext2() {
+		this.verifyNext(this.buildGraphIterator2());
+	}
+
+	private void verifyNext(Iterator<GraphNode> iterator) {
+		while (iterator.hasNext()) {
+			assertTrue("bogus element", this.nodes.contains(iterator.next()));
+		}
+	}
+
+	public void testNoSuchElementException1() {
+		this.verifyNoSuchElementException(this.buildGraphIterator1());
+	}
+
+	public void testNoSuchElementException2() {
+		this.verifyNoSuchElementException(this.buildGraphIterator2());
+	}
+
+	private void verifyNoSuchElementException(Iterator<GraphNode> iterator) {
+		boolean exCaught = false;
+		while (iterator.hasNext()) {
+			iterator.next();
+		}
+		try {
+			iterator.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown", exCaught);
+	}
+
+	public void testSize1() {
+		this.verifySize(this.buildGraphIterator1());
+	}
+
+	public void testSize2() {
+		this.verifySize(this.buildGraphIterator2());
+	}
+
+	private void verifySize(Iterator<GraphNode> iterator) {
+		int iteratorSize = IteratorTools.size(iterator);
+		int actualSize = this.nodes.size();
+		assertTrue("Too few items in iterator.", iteratorSize >= actualSize);
+		assertTrue("Too many items in iterator.", iteratorSize <= actualSize);
+	}
+
+	public void testInvalidGraphIterator() {
+		boolean exCaught = false;
+		try {
+			// missing method override
+			Iterator<GraphNode> iterator = new GraphIterator<GraphNode>(this.buildGraphRoot());
+			GraphNode gn = iterator.next();
+			fail("invalid graph node: " + gn);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown", exCaught);
+	}
+
+	/**
+	 * build a graph iterator with an explicit misterRogers
+	 */
+	private Iterator<GraphNode> buildGraphIterator1() {
+		return new GraphIterator<GraphNode>(this.buildGraphRoot(), this.buildMisterRogers());
+	}
+
+	private GraphIterator.MisterRogers<GraphNode> buildMisterRogers() {
+		return new GraphIterator.MisterRogers<GraphNode>() {
+			@Override
+			public Iterator<GraphNode> neighbors(GraphNode next) {
+				return next.neighbors();
+			}
+		};
+	}
+
+	/**
+	 * build a graph iterator with an override
+	 */
+	private Iterator<GraphNode> buildGraphIterator2() {
+		return new GraphIterator<GraphNode>(this.buildGraphRoot()) {
+			@Override
+			public Iterator<GraphNode> neighbors(GraphNode next) {
+				return next.neighbors();
+			}
+		};
+	}
+
+	private GraphNode buildGraphRoot() {
+		GraphNode ncNode = new GraphNode("North Carolina");
+		GraphNode vaNode = new GraphNode("Virginia");
+		GraphNode scNode = new GraphNode("South Carolina");
+		GraphNode gaNode = new GraphNode("Georgia");
+		GraphNode flNode = new GraphNode("Florida");
+		GraphNode alNode = new GraphNode("Alabama");
+		GraphNode msNode = new GraphNode("Mississippi");
+		GraphNode tnNode = new GraphNode("Tennessee");
+
+		ncNode.setNeighbors(new GraphNode[] { vaNode, scNode, gaNode, tnNode });
+		vaNode.setNeighbors(new GraphNode[] { ncNode, tnNode });
+		scNode.setNeighbors(new GraphNode[] { ncNode, gaNode });
+		gaNode.setNeighbors(new GraphNode[] { ncNode, scNode, flNode, alNode, tnNode });
+		flNode.setNeighbors(new GraphNode[] { gaNode });
+		alNode.setNeighbors(new GraphNode[] { gaNode, msNode, tnNode });
+		msNode.setNeighbors(new GraphNode[] { alNode, tnNode });
+		tnNode.setNeighbors(new GraphNode[] { vaNode, ncNode, gaNode, alNode, msNode });
+
+		return ncNode;
+	}
+
+	public class GraphNode {
+		private String name;
+
+		private Collection<GraphNode> neighbors = new ArrayList<GraphNode>();
+
+		public GraphNode(String name) {
+			super();
+			GraphIteratorTests.this.nodes.add(this); // log node
+			this.name = name;
+		}
+
+		public String getName() {
+			return this.name;
+		}
+
+		void setNeighbors(GraphNode[] neighbors) {
+			this.neighbors = ListTools.list(neighbors);
+		}
+
+		public Iterator<GraphNode> neighbors() {
+			return this.neighbors.iterator();
+		}
+
+		public int neighborsSize() {
+			return this.neighbors.size();
+		}
+
+		@Override
+		public String toString() {
+			return "GraphNode(" + this.name + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/IteratorToolsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/IteratorToolsTests.java
new file mode 100644
index 0000000..29b8882
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/IteratorToolsTests.java
@@ -0,0 +1,584 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ClassTools;
+import org.eclipse.persistence.tools.utility.ReverseComparator;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.tests.ArrayToolsTests;
+
+@SuppressWarnings("nls")
+public class IteratorToolsTests
+	extends TestCase
+{
+	public IteratorToolsTests(String name) {
+		super(name);
+	}
+
+
+	// ********** contains **********
+
+	public void testContainsIteratorObject_Object() {
+		Collection<Object> c = new HashBag<Object>();
+		c.add("zero");
+		c.add("one");
+		c.add("two");
+		c.add("three");
+		String one = "one";
+		assertTrue(IteratorTools.contains(c.iterator(), one));
+		assertFalse(IteratorTools.contains(c.iterator(), null));
+		c.add(null);
+		assertTrue(IteratorTools.contains(c.iterator(), null));
+	}
+
+	public void testContainsIteratorObject_String() {
+		Collection<String> c = this.buildStringList1();
+		assertTrue(IteratorTools.contains(c.iterator(), "one"));
+		assertFalse(IteratorTools.contains(c.iterator(), null));
+		c.add(null);
+		assertTrue(IteratorTools.contains(c.iterator(), null));
+	}
+
+
+	// ********** contains all **********
+
+	public void testContainsAllIteratorCollection_StringString() {
+		assertTrue(IteratorTools.containsAll(this.buildStringList1().iterator(), this.buildStringList1()));
+		assertFalse(IteratorTools.containsAll(this.buildStringList1().iterator(), this.buildStringList2()));
+	}
+
+	public void testContainsAllIteratorIntCollection() {
+		assertTrue(IteratorTools.containsAll(this.buildStringList1().iterator(), 5, this.buildStringList1()));
+		assertFalse(IteratorTools.containsAll(this.buildStringList1().iterator(), 5, this.buildStringList2()));
+	}
+
+	public void testContainsAllIteratorIntIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(IteratorTools.containsAll(this.buildStringList1().iterator(), 3, iterable));
+		iterable = this.buildStringList2();
+		assertFalse(IteratorTools.containsAll(this.buildStringList1().iterator(), 3, iterable));
+	}
+
+	public void testContainsAllIteratorIntIterator() {
+		assertTrue(IteratorTools.containsAll(this.buildStringList1().iterator(), 3, this.buildStringList1().iterator()));
+		assertFalse(IteratorTools.containsAll(this.buildStringList1().iterator(), 3, this.buildStringList2().iterator()));
+	}
+
+	public void testContainsAllIteratorIntObjectArray() {
+		assertTrue(IteratorTools.containsAll(this.buildStringList1().iterator(), 3, this.buildObjectArray1()));
+		assertFalse(IteratorTools.containsAll(this.buildStringList1().iterator(), 3, this.buildObjectArray2()));
+	}
+
+	public void testContainsAllIteratorIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(IteratorTools.containsAll(this.buildStringList1().iterator(), iterable));
+		iterable = this.buildStringList2();
+		assertFalse(IteratorTools.containsAll(this.buildStringList1().iterator(), iterable));
+	}
+
+	public void testContainsAllIteratorIterator_ObjectString() {
+		Collection<Object> c1 = new ArrayList<Object>();
+		c1.add("zero");
+		c1.add("one");
+		c1.add("two");
+		Collection<String> c2 = new ArrayList<String>();
+		c2.add("zero");
+		c2.add("one");
+		c2.add("two");
+		assertTrue(IteratorTools.containsAll(c1.iterator(), c2.iterator()));
+	}
+
+	public void testContainsAllIteratorIterator_StringString() {
+		assertTrue(IteratorTools.containsAll(this.buildStringList1().iterator(), this.buildStringList1().iterator()));
+		assertFalse(IteratorTools.containsAll(this.buildStringList1().iterator(), this.buildStringList2().iterator()));
+	}
+
+	public void testContainsAllIteratorObjectArray() {
+		assertTrue(IteratorTools.containsAll(this.buildStringList1().iterator(), this.buildObjectArray1()));
+		assertFalse(IteratorTools.containsAll(this.buildStringList1().iterator(), this.buildObjectArray2()));
+	}
+
+	public void testContainsAllIteratorCollection_ObjectString() {
+		Collection<Object> c1 = new ArrayList<Object>();
+		c1.add("zero");
+		c1.add("one");
+		c1.add("two");
+		Collection<String> c2 = new ArrayList<String>();
+		c2.add("zero");
+		c2.add("one");
+		c2.add("two");
+		assertTrue(IteratorTools.containsAll(c1.iterator(), c2));
+	}
+
+
+	// ********** elements are equal **********
+
+	public void testElementsAreDifferentIteratorIterator() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("1000");
+		list1.add("2000");
+		list1.add("3000");
+		list1.add("4000");
+
+		List<String> list2 = new ArrayList<String>();
+
+		assertTrue(IteratorTools.elementsAreDifferent(list1.iterator(), list2.iterator()));
+		assertFalse(IterableTools.elementsAreEqual(list1, list2));
+	}
+
+	public void testElementsAreEqualIteratorIterator() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("1000");
+		list1.add("2000");
+		list1.add("3000");
+		list1.add("4000");
+
+		List<String> list2 = new ArrayList<String>();
+		for (int i = 0; i < list1.size(); i++) {
+			list2.add(String.valueOf((i + 1) * 1000));
+		}
+		assertFalse(IteratorTools.elementsAreIdentical(list1.iterator(), list2.iterator()));
+		assertFalse(IteratorTools.elementsAreDifferent(list1.iterator(), list2.iterator()));
+		assertTrue(IteratorTools.elementsAreEqual(list1.iterator(), list2.iterator()));
+	}
+
+
+	// ********** elements are identical **********
+
+	public void testElementsAreIdenticalIteratorIterator() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("0");
+		list1.add("1");
+		list1.add("2");
+		list1.add("3");
+
+		List<String> list2 = new ArrayList<String>();
+		for (String s : list1) {
+			list2.add(s);
+		}
+		assertTrue(IteratorTools.elementsAreIdentical(list1.iterator(), list2.iterator()));
+		assertTrue(IteratorTools.elementsAreEqual(list1.iterator(), list2.iterator()));
+	}
+
+	public void testElementsAreIdenticalIteratorIterator_Not() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("0");
+		list1.add("1");
+		list1.add("2");
+		list1.add("3");
+
+		List<String> list2 = new ArrayList<String>();
+		for (String s : list1) {
+			list2.add(s);
+		}
+		list2.remove(0);
+		assertFalse(IteratorTools.elementsAreIdentical(list1.iterator(), list2.iterator()));
+		assertFalse(IteratorTools.elementsAreEqual(list1.iterator(), list2.iterator()));
+	}
+
+	public void testElementsAreIdenticalIteratorIterator_DifferentSizes() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("0");
+		list1.add("1");
+		list1.add("2");
+		list1.add("3");
+
+		List<String> list2 = new ArrayList<String>();
+		for (String s : list1) {
+			list2.add(s);
+		}
+		list2.remove(3);
+		assertFalse(IteratorTools.elementsAreIdentical(list1.iterator(), list2.iterator()));
+		assertFalse(IteratorTools.elementsAreEqual(list1.iterator(), list2.iterator()));
+	}
+
+	public void testElementsAreNotIdenticalIteratorIterator() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("0");
+		list1.add("1");
+		list1.add("2");
+		list1.add("3");
+
+		List<String> list2 = new ArrayList<String>();
+		for (String s : list1) {
+			list2.add(s);
+		}
+		assertFalse(IteratorTools.elementsAreNotIdentical(list1.iterator(), list2.iterator()));
+		assertTrue(IteratorTools.elementsAreEqual(list1.iterator(), list2.iterator()));
+	}
+
+	public void testElementsAreNotIdenticalIteratorIterator_Not() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("0");
+		list1.add("1");
+		list1.add("2");
+		list1.add("3");
+
+		List<String> list2 = new ArrayList<String>();
+		for (String s : list1) {
+			list2.add(s);
+		}
+		list2.remove(0);
+		assertTrue(IteratorTools.elementsAreNotIdentical(list1.iterator(), list2.iterator()));
+		assertFalse(IteratorTools.elementsAreEqual(list1.iterator(), list2.iterator()));
+	}
+
+	public void testElementsAreNotIdenticalIteratorIterator_DifferentSizes() {
+		List<String> list1 = new ArrayList<String>();
+		list1.add("0");
+		list1.add("1");
+		list1.add("2");
+		list1.add("3");
+
+		List<String> list2 = new ArrayList<String>();
+		for (String s : list1) {
+			list2.add(s);
+		}
+		list2.remove(3);
+		assertTrue(IteratorTools.elementsAreNotIdentical(list1.iterator(), list2.iterator()));
+		assertFalse(IteratorTools.elementsAreEqual(list1.iterator(), list2.iterator()));
+	}
+
+
+	// ********** execute **********
+
+	public void testExecuteParmCommand() {
+		List<String> list = this.buildStringList1();
+		ArrayToolsTests.ConcatenateCommand command = new ArrayToolsTests.ConcatenateCommand();
+		IteratorTools.execute(list.iterator(), command);
+		assertEquals("zeroonetwo", command.string);
+	}
+
+	public void testExecuteInterruptibleParmCommand() throws Exception {
+		List<String> list = this.buildStringList1();
+		ArrayToolsTests.InterruptibleConcatenateCommand command = new ArrayToolsTests.InterruptibleConcatenateCommand();
+		IteratorTools.execute(list.iterator(), command);
+		assertEquals("zeroonetwo", command.string);
+	}
+
+
+	// ********** get **********
+
+	public void testGetIteratorInt1() {
+		List<String> list = this.buildStringList1();
+		String o = IteratorTools.get(list.iterator(), 1);
+		assertEquals("one", o);
+		list.add(null);
+		o = IteratorTools.get(list.iterator(), list.size() - 1);
+		assertNull(o);
+	}
+
+	public void testGetIteratorInt2() {
+		List<String> list = this.buildStringList1();
+		boolean exCaught = false;
+		try {
+			IteratorTools.get(list.iterator(), list.size());
+			fail();
+		} catch (IndexOutOfBoundsException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+
+	// ********** index of **********
+
+	public void testIndexOfIteratorObject_String() {
+		List<String> list = this.buildStringList1();
+		assertEquals(1, IteratorTools.indexOf(list.iterator(), "one"));
+	}
+
+	public void testIndexOfIteratorObject_String_Not() {
+		List<String> list = this.buildStringList1();
+		assertEquals(-1, IteratorTools.indexOf(list.iterator(), null));
+		assertEquals(-1, IteratorTools.indexOf(list.iterator(), "shazam"));
+	}
+
+	public void testIndexOfIteratorObject_Null() {
+		List<String> list = this.buildStringList1();
+		list.add(null);
+		assertEquals(list.size() - 1, IteratorTools.indexOf(list.iterator(), null));
+	}
+
+	public void testIndexOfIteratorObject_Object() {
+		List<Object> list = new ArrayList<Object>();
+		list.add("0");
+		list.add("1");
+		list.add("2");
+		list.add("3");
+
+		String one = "1";
+		assertEquals(1, IteratorTools.indexOf(list.iterator(), one));
+		list.add(null);
+		assertEquals(list.size() - 1, IteratorTools.indexOf(list.iterator(), null));
+	}
+
+
+	// ********** is empty **********
+
+	public void testIsEmptyIterator() {
+		assertFalse(IteratorTools.isEmpty(buildObjectList1().iterator()));
+		assertTrue(IteratorTools.isEmpty(EmptyIterator.instance()));
+	}
+
+
+	// ********** iterable/iterator **********
+
+	public void testIteratorObjectArray() {
+		String[] a = this.buildStringArray1();
+		int i = 0;
+		for (Iterator<String> stream = IteratorTools.iterator(a); stream.hasNext(); i++) {
+			assertEquals(a[i], stream.next());
+		}
+	}
+
+
+	// ********** last **********
+
+	public void testLastIterator1() {
+		List<String> list = this.buildStringList1();
+		assertEquals("two", IteratorTools.last(list.iterator()));
+		list.add(null);
+		assertEquals(null, IteratorTools.last(list.iterator()));
+	}
+
+	public void testLastIterator2() {
+		List<String> list = new ArrayList<String>();
+		boolean exCaught = false;
+		try {
+			IteratorTools.last(list.iterator());
+			fail();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+
+	// ********** last index of **********
+
+	public void testLastIndexOfIteratorObject() {
+		List<String> list = this.buildStringList1();
+		assertEquals(1, IteratorTools.lastIndexOf(list.iterator(), "one"));
+		list.add(null);
+		assertEquals(list.size() - 1, IteratorTools.lastIndexOf(list.iterator(), null));
+	}
+
+	public void testLastIndexOfIteratorObject_Empty() {
+		assertEquals(-1, IteratorTools.lastIndexOf(EmptyIterator.instance(), "foo"));
+	}
+
+
+	// ********** list iterator **********
+
+	public void testListIteratorObjectArray() {
+		String[] a = this.buildStringArray1();
+		int i = 0;
+		for (ListIterator<String> stream = IteratorTools.listIterator(a); stream.hasNext(); i++) {
+			assertEquals(a[i], stream.next());
+		}
+	}
+
+	public void testListIteratorObjectArrayInt() {
+		String[] a = this.buildStringArray1();
+		int i = 1;
+		for (ListIterator<String> stream = IteratorTools.listIterator(a, 1); stream.hasNext(); i++) {
+			assertEquals(a[i], stream.next());
+		}
+	}
+
+
+	// ********** singleton iterator **********
+
+	public void testSingletonIterator_String() {
+		Iterator<String> stream = IteratorTools.singletonIterator("foo");
+		assertTrue(stream.hasNext());
+		assertEquals("foo", stream.next());
+	}
+
+	public void testSingletonIterator_Object() {
+		Iterator<Object> stream = IteratorTools.<Object>singletonIterator("foo");
+		assertTrue(stream.hasNext());
+		assertEquals("foo", stream.next());
+	}
+
+	public void testSingletonIterator_Cast() {
+		Iterator<Object> stream = IteratorTools.singletonIterator((Object) "foo");
+		assertTrue(stream.hasNext());
+		assertEquals("foo", stream.next());
+	}
+
+	public void testSingletonListIterator_String() {
+		ListIterator<String> stream = IteratorTools.singletonListIterator("foo");
+		assertTrue(stream.hasNext());
+		assertEquals("foo", stream.next());
+		assertFalse(stream.hasNext());
+		assertTrue(stream.hasPrevious());
+		assertEquals("foo", stream.previous());
+	}
+
+
+	// ********** size **********
+
+	public void testSizeIterator() {
+		assertEquals(3, IteratorTools.size(this.buildObjectList1().iterator()));
+	}
+
+
+	// ********** sort **********
+
+	public void testSortIterator() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("0");
+		list.add("2");
+		list.add("3");
+		list.add("1");
+
+		SortedSet<String> ss = new TreeSet<String>();
+		ss.addAll(list);
+
+		Iterator<String> iterator1 = list.iterator();
+		Iterator<String> iterator2 = IteratorTools.<String>sort(iterator1);
+		assertTrue(IteratorTools.elementsAreEqual(ss.iterator(), iterator2));
+	}
+
+	public void testSortIteratorInt() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("0");
+		list.add("2");
+		list.add("3");
+		list.add("1");
+
+		SortedSet<String> ss = new TreeSet<String>();
+		ss.addAll(list);
+
+		Iterator<String> iterator1 = list.iterator();
+		Iterator<String> iterator2 = IteratorTools.<String>sort(iterator1, 77);
+		assertTrue(IteratorTools.elementsAreEqual(ss.iterator(), iterator2));
+	}
+
+	public void testSortIteratorComparator() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("0");
+		list.add("2");
+		list.add("3");
+		list.add("1");
+
+		SortedSet<String> ss = new TreeSet<String>(new ReverseComparator<String>());
+		ss.addAll(list);
+
+		Iterator<String> iterator1 = list.iterator();
+		Iterator<String> iterator2 = IteratorTools.<String>sort(iterator1, new ReverseComparator<String>());
+		assertTrue(IteratorTools.elementsAreEqual(ss.iterator(), iterator2));
+	}
+
+	public void testSortIteratorComparatorInt() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("0");
+		list.add("2");
+		list.add("3");
+		list.add("1");
+
+		SortedSet<String> ss = new TreeSet<String>(new ReverseComparator<String>());
+		ss.addAll(list);
+
+		Iterator<String> iterator1 = list.iterator();
+		Iterator<String> iterator2 = IteratorTools.<String>sort(iterator1, new ReverseComparator<String>(), 77);
+		assertTrue(IteratorTools.elementsAreEqual(ss.iterator(), iterator2));
+	}
+
+	public void testConstructor() {
+		boolean exCaught = false;
+		try {
+			Object at = ClassTools.newInstance(IteratorTools.class);
+			fail("bogus: " + at); //$NON-NLS-1$
+		} catch (RuntimeException ex) {
+			if (ex.getCause() instanceof InvocationTargetException) {
+				if (ex.getCause().getCause() instanceof UnsupportedOperationException) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+
+	// ********** transform **********
+
+	public void testTransformIteratorTransformer() {
+		List<String> list = Arrays.asList(new String[] { "zero", "one", "two" });
+		Iterator<String> actual = IteratorTools.transform(list.iterator(), ArrayToolsTests.UPPER_CASE_TRANSFORMER);
+		Iterator<Object> expected = Arrays.asList(new Object[] { "ZERO", "ONE", "TWO" }).iterator();
+		assertTrue(IteratorTools.elementsAreEqual(expected, actual));
+	}
+
+
+	// ********** test harness **********
+
+	private Object[] buildObjectArray1() {
+		return new Object[] { "zero", "one", "two" };
+	}
+
+	private String[] buildStringArray1() {
+		return new String[] { "zero", "one", "two" };
+	}
+
+	private Object[] buildObjectArray2() {
+		return new Object[] { "three", "four", "five" };
+	}
+
+	private List<String> buildStringList1() {
+		List<String> l = new ArrayList<String>();
+		this.addToCollection1(l);
+		return l;
+	}
+
+	private List<Object> buildObjectList1() {
+		List<Object> l = new ArrayList<Object>();
+		this.addToCollection1(l);
+		return l;
+	}
+
+	private void addToCollection1(Collection<? super String> c) {
+		c.add("zero");
+		c.add("one");
+		c.add("two");
+	}
+
+	private List<String> buildStringList2() {
+		List<String> l = new ArrayList<String>();
+		this.addToCollection2(l);
+		return l;
+	}
+
+	private void addToCollection2(Collection<? super String> c) {
+		c.add("three");
+		c.add("four");
+		c.add("five");
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/PeekableIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/PeekableIteratorTests.java
new file mode 100644
index 0000000..f90e640
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/PeekableIteratorTests.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.PeekableIterator;
+
+@SuppressWarnings("nls")
+public class PeekableIteratorTests extends TestCase {
+
+	public PeekableIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testUnsupportedOperationException() {
+		boolean exCaught = false;
+		for (Iterator<String> stream = this.buildPeekableIterator(); stream.hasNext();) {
+			String string = stream.next();
+			if (string.equals("three")) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		Iterator<String> stream = this.buildPeekableIterator();
+		String string = null;
+		while (stream.hasNext()) {
+			string = stream.next();
+		}
+		try {
+			string = stream.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
+	}
+
+	public void testHasNext() {
+		int i = 0;
+		for (Iterator<String> stream = this.buildPeekableIterator(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(6, i);
+	}
+
+	public void testHasNextUpcast() {
+		int i = 0;
+		for (Iterator<Object> stream = this.buildPeekableIteratorUpcast(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(6, i);
+	}
+
+	public void testNext() {
+		Iterator<String> stream = this.buildPeekableIterator();
+		assertEquals("zero", stream.next());
+		assertEquals("one", stream.next());
+		assertEquals("two", stream.next());
+		assertEquals("three", stream.next());
+		assertEquals("four", stream.next());
+		assertEquals("five", stream.next());
+	}
+
+	public void testNextUpcast() {
+		Iterator<Object> stream = this.buildPeekableIteratorUpcast();
+		assertEquals("zero", stream.next());
+		assertEquals("one", stream.next());
+		assertEquals("two", stream.next());
+		assertEquals("three", stream.next());
+		assertEquals("four", stream.next());
+		assertEquals("five", stream.next());
+	}
+
+	public void testPeek() {
+		Object next = null;
+		for (PeekableIterator<String> stream = this.buildPeekableIterator(); stream.hasNext();) {
+			Object peek = stream.peek();
+			assertTrue("peek and next are prematurely identical", peek != next);
+			next = stream.next();
+			assertTrue("peek and next are not identical", peek == next);
+		}
+	}
+
+	public void testPeekUpcast() {
+		Object next = null;
+		for (PeekableIterator<Object> stream = this.buildPeekableIteratorUpcast(); stream.hasNext();) {
+			Object peek = stream.peek();
+			assertTrue("peek and next are prematurely identical", peek != next);
+			next = stream.next();
+			assertTrue("peek and next are not identical", peek == next);
+		}
+	}
+
+	private PeekableIterator<String> buildPeekableIterator() {
+		return this.buildPeekableIterator(this.buildNestedIterator());
+	}
+
+	private PeekableIterator<Object> buildPeekableIteratorUpcast() {
+		return this.buildPeekableIteratorUpcast(this.buildNestedIterator());
+	}
+
+	private PeekableIterator<String> buildPeekableIterator(Iterator<String> nestedIterator) {
+		return new PeekableIterator<String>(nestedIterator);
+	}
+
+	private PeekableIterator<Object> buildPeekableIteratorUpcast(Iterator<String> nestedIterator) {
+		return new PeekableIterator<Object>(nestedIterator);
+	}
+
+	private Iterator<String> buildNestedIterator() {
+		Collection<String> c = new ArrayList<String>();
+		c.add("zero");
+		c.add("one");
+		c.add("two");
+		c.add("three");
+		c.add("four");
+		c.add("five");
+		return c.iterator();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ReadOnlyCompositeListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ReadOnlyCompositeListIteratorTests.java
new file mode 100644
index 0000000..62c6e7f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ReadOnlyCompositeListIteratorTests.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyCompositeListIterator;
+
+
+@SuppressWarnings("nls")
+public class ReadOnlyCompositeListIteratorTests extends CompositeIteratorTests {
+
+	public ReadOnlyCompositeListIteratorTests(String name) {
+		super(name);
+	}
+
+	@Override
+	void verifyHasAnother(Iterator<String> stream) {
+		super.verifyHasAnother(stream);
+		ListIterator<String> stream2 = (ListIterator<String>) stream;
+		int i = 0;
+		while (stream2.hasPrevious()) {
+			stream2.previous();
+			i++;
+		}
+		assertEquals(8, i);
+	}
+
+	@Override
+	void verifyAnother(Iterator<String> stream) {
+		super.verifyAnother(stream);
+		int i = 8;
+		ListIterator<String> stream2 = (ListIterator<String>) stream;
+		while (stream2.hasPrevious()) {
+			assertEquals("bogus element", String.valueOf(i--), stream2.previous().substring(0, 1));
+		}
+	}
+
+	public void testNextIndexPreviousIndex() {
+		int i = 0;
+		ListIterator<String> stream = (ListIterator<String>) this.buildCompositeIterator();
+		assertEquals(i, stream.nextIndex());
+		assertEquals(i - 1, stream.previousIndex());
+		while (stream.hasNext()) {
+			stream.next();
+			i++;
+			assertEquals(i, stream.nextIndex());
+			assertEquals(i - 1, stream.previousIndex());
+		}
+		assertEquals("index is corrupt", 8, i);
+
+		assertEquals(i, stream.nextIndex());
+		assertEquals(i - 1, stream.previousIndex());
+		while (stream.hasPrevious()) {
+			stream.previous();
+			i--;
+			assertEquals(i, stream.nextIndex());
+			assertEquals(i - 1, stream.previousIndex());
+		}
+		assertEquals("index is corrupt", 0, i);
+	}
+
+	public void testPreviousIndex() {
+		// TODO
+	}
+
+	@Override
+	public void testRemove() {
+		// #remove() is not supported
+	}
+
+	@Override
+	public void testIllegalStateException() {
+		// #remove() is not supported
+	}
+
+	@Override
+	public void testEmptyIllegalStateException1() {
+		// #remove() is not supported
+	}
+
+	@Override
+	public void testEmptyIllegalStateException2() {
+		// #remove() is not supported
+	}
+
+	@Override
+	void verifyNoSuchElementException(Iterator<String> stream) {
+		super.verifyNoSuchElementException(stream);
+		ListIterator<String> stream2 = (ListIterator<String>) stream;
+		boolean exCaught = false;
+		String string = null;
+		while (stream2.hasPrevious()) {
+			string = stream2.previous();
+		}
+		try {
+			string = stream2.previous();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
+	}
+
+	@Override
+	void verifyUnsupportedOperationException(Iterator<String> stream) {
+		super.verifyUnsupportedOperationException(stream);
+		boolean exCaught = false;
+		ListIterator<String> stream2 = (ListIterator<String>) stream;
+		while (stream2.hasPrevious()) {
+			Object string = stream2.previous();
+			if (string.equals("333")) {
+				try {
+					stream2.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	@Override
+	void verifyIllegalStateException(Iterator<String> stream) {
+		super.verifyIllegalStateException(stream);
+		ListIterator<String> stream2 = (ListIterator<String>) stream;
+		boolean exCaught = false;
+		try {
+			stream2.set("junk");
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue("IllegalStateException not thrown", exCaught);
+	}
+
+	@Override
+	void verifyEmptyHasAnother(Iterator<String> stream) {
+		super.verifyEmptyHasAnother(stream);
+		ListIterator<String> stream2 = (ListIterator<String>) stream;
+		int i = 0;
+		while (stream2.hasPrevious()) {
+			stream2.previous();
+			i++;
+		}
+		assertEquals(0, i);
+	}
+
+	// unchecked so we can override the unchecked method in superclass
+	@Override
+	@SuppressWarnings("unchecked")
+	Iterator<String> buildCompositeIterator(@SuppressWarnings("rawtypes") Iterator iterators) {
+		return new ReadOnlyCompositeListIterator<String>((ListIterator<ListIterator<String>>) iterators);
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	Iterator<String> buildCompositeIterator2() {
+		return new ReadOnlyCompositeListIterator<String>(this.buildIterator1(), this.buildIterator2(), this.buildIterator3());
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	Iterator<String> buildCompositeIterator3() {
+		return new ReadOnlyCompositeListIterator<String>(new ListIterator[] { this.buildIterator1(), this.buildIterator2(), this.buildIterator3() });
+	}
+
+	Iterator<String> buildCompositeIterator(String string, ListIterator<String> iterator) {
+		return this.buildCompositeListIterator(string, iterator);
+	}
+
+	ListIterator<String> buildCompositeListIterator(String string, ListIterator<String> iterator) {
+		return new ReadOnlyCompositeListIterator<String>(string, iterator);
+	}
+
+	public void testVariedNestedIterators() {
+		List<Integer> integerList = new ArrayList<Integer>();
+		integerList.add(new Integer(42));
+		integerList.add(new Integer(42));
+		integerList.add(new Integer(111));
+		integerList.add(new Integer(77));
+
+		List<Float> floatList = new ArrayList<Float>();
+		floatList.add(new Float(42.42f));
+		floatList.add(new Float(22.22f));
+		floatList.add(new Float(111.111f));
+		floatList.add(new Float(77.77f));
+
+		List<List<? extends Number>> list = new ArrayList<List<? extends Number>>();
+		list.add(integerList);
+		list.add(floatList);
+		ListIterator<Number> li = new ReadOnlyCompositeListIterator<Number>(list);
+		while (li.hasNext()) {
+			assertTrue(li.next().intValue() > 0);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ReadOnlyIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ReadOnlyIteratorTests.java
new file mode 100644
index 0000000..4534352
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ReadOnlyIteratorTests.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyIterator;
+
+@SuppressWarnings("nls")
+public class ReadOnlyIteratorTests extends TestCase {
+
+	public ReadOnlyIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testHasNext() {
+		int i = 0;
+		for (Iterator<String> stream = this.buildReadOnlyIterator(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(this.buildVector().size(), i);
+	}
+
+	public void testHasNextUpcast() {
+		int i = 0;
+		for (Iterator<Object> stream = this.buildReadOnlyIteratorUpcast(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(this.buildVector().size(), i);
+	}
+
+	public void testNext() {
+		Iterator<String> nestedIterator = this.buildNestedIterator();
+		for (Iterator<String> stream = this.buildReadOnlyIterator(); stream.hasNext();) {
+			assertEquals("bogus element", nestedIterator.next(), stream.next());
+		}
+	}
+
+	public void testNextUpcast() {
+		Iterator<String> nestedIterator = this.buildNestedIterator();
+		for (Iterator<Object> stream = this.buildReadOnlyIteratorUpcast(); stream.hasNext();) {
+			assertEquals("bogus element", nestedIterator.next(), stream.next());
+		}
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		Iterator<String> stream = this.buildReadOnlyIterator();
+		String string = null;
+		while (stream.hasNext()) {
+			string = stream.next();
+		}
+		try {
+			string = stream.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
+	}
+
+	public void testRemove() {
+		boolean exCaught = false;
+		for (Iterator<String> stream = this.buildReadOnlyIterator(); stream.hasNext();) {
+			if (stream.next().equals("three")) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	private Iterator<String> buildReadOnlyIterator() {
+		return this.buildReadOnlyIterator(this.buildNestedIterator());
+	}
+
+	private Iterator<Object> buildReadOnlyIteratorUpcast() {
+		return this.buildReadOnlyIteratorUpcast(this.buildNestedIterator());
+	}
+
+	private Iterator<String> buildReadOnlyIterator(Iterator<String> nestedIterator) {
+		return new ReadOnlyIterator<String>(nestedIterator);
+	}
+
+	private Iterator<Object> buildReadOnlyIteratorUpcast(Iterator<String> nestedIterator) {
+		return new ReadOnlyIterator<Object>(nestedIterator);
+	}
+
+	private Iterator<String> buildNestedIterator() {
+		return this.buildVector().iterator();
+	}
+
+	private Vector<String> buildVector() {
+		Vector<String> v = new Vector<String>();
+		v.addElement("one");
+		v.addElement("two");
+		v.addElement("three");
+		v.addElement("four");
+		v.addElement("five");
+		v.addElement("six");
+		v.addElement("seven");
+		v.addElement("eight");
+		return v;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ReadOnlyListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ReadOnlyListIteratorTests.java
new file mode 100644
index 0000000..4e48b4e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/ReadOnlyListIteratorTests.java
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyListIterator;
+
+@SuppressWarnings("nls")
+public class ReadOnlyListIteratorTests extends TestCase {
+
+	public ReadOnlyListIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testHasNextAndHasPrevious() {
+		int i = 0;
+		ListIterator<String> stream = this.buildReadOnlyListIterator();
+		while (stream.hasNext()) {
+			stream.next();
+			i++;
+		}
+		assertEquals(this.buildList().size(), i);
+
+		while (stream.hasPrevious()) {
+			stream.previous();
+			i--;
+		}
+		assertEquals(0, i);
+	}
+
+	public void testHasNextAndHasPreviousUpcast() {
+		int i = 0;
+		ListIterator<Object> stream = this.buildReadOnlyListIteratorUpcast();
+		while (stream.hasNext()) {
+			stream.next();
+			i++;
+		}
+		assertEquals(this.buildList().size(), i);
+
+		while (stream.hasPrevious()) {
+			stream.previous();
+			i--;
+		}
+		assertEquals(0, i);
+	}
+
+	public void testNextAndPrevious() {
+		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
+		ListIterator<String> stream = this.buildReadOnlyListIterator();
+		while (stream.hasNext()) {
+			assertEquals("bogus element", nestedListIterator.next(), stream.next());
+		}
+		while (stream.hasPrevious()) {
+			assertEquals("bogus element", nestedListIterator.previous(), stream.previous());
+		}
+	}
+
+	public void testNextAndPreviousUpcast() {
+		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
+		ListIterator<Object> stream = this.buildReadOnlyListIteratorUpcast();
+		while (stream.hasNext()) {
+			assertEquals("bogus element", nestedListIterator.next(), stream.next());
+		}
+		while (stream.hasPrevious()) {
+			assertEquals("bogus element", nestedListIterator.previous(), stream.previous());
+		}
+	}
+
+	public void testNextIndexAndPreviousIndex() {
+		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
+		ListIterator<String> stream = this.buildReadOnlyListIterator();
+		while (stream.hasNext()) {
+			assertEquals("bogus index", nestedListIterator.nextIndex(), stream.nextIndex());
+			nestedListIterator.next();
+			stream.next();
+		}
+		assertEquals("bogus index", this.buildList().size(), stream.nextIndex());
+		while (stream.hasPrevious()) {
+			assertEquals("bogus element", nestedListIterator.previousIndex(), stream.previousIndex());
+			nestedListIterator.previous();
+			stream.previous();
+		}
+		assertEquals("bogus index", -1, stream.previousIndex());
+	}
+
+	public void testNextIndexAndPreviousIndexUpcast() {
+		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
+		ListIterator<Object> stream = this.buildReadOnlyListIteratorUpcast();
+		while (stream.hasNext()) {
+			assertEquals("bogus index", nestedListIterator.nextIndex(), stream.nextIndex());
+			nestedListIterator.next();
+			stream.next();
+		}
+		assertEquals("bogus index", this.buildList().size(), stream.nextIndex());
+		while (stream.hasPrevious()) {
+			assertEquals("bogus element", nestedListIterator.previousIndex(), stream.previousIndex());
+			nestedListIterator.previous();
+			stream.previous();
+		}
+		assertEquals("bogus index", -1, stream.previousIndex());
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		ListIterator<String> stream = this.buildReadOnlyListIterator();
+		String string = null;
+		while (stream.hasNext()) {
+			string = stream.next();
+		}
+		try {
+			string = stream.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
+	}
+
+	public void testRemove() {
+		boolean exCaught = false;
+		for (ListIterator<String> stream = this.buildReadOnlyListIterator(); stream.hasNext();) {
+			if (stream.next().equals("three")) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	public void testSet() {
+		boolean exCaught = false;
+		for (ListIterator<String> stream = this.buildReadOnlyListIterator(); stream.hasNext();) {
+			if (stream.next().equals("three")) {
+				try {
+					stream.set("bogus");
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	public void testAdd() {
+		boolean exCaught = false;
+		for (ListIterator<String> stream = this.buildReadOnlyListIterator(); stream.hasNext();) {
+			if (stream.next().equals("three")) {
+				try {
+					stream.add("bogus");
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	private ListIterator<String> buildReadOnlyListIterator() {
+		return this.buildReadOnlyListIterator(this.buildNestedListIterator());
+	}
+
+	private ListIterator<Object> buildReadOnlyListIteratorUpcast() {
+		return this.buildReadOnlyListIteratorUpcast(this.buildNestedListIterator());
+	}
+
+	private ListIterator<String> buildReadOnlyListIterator(ListIterator<String> nestedListIterator) {
+		return new ReadOnlyListIterator<String>(nestedListIterator);
+	}
+
+	private ListIterator<Object> buildReadOnlyListIteratorUpcast(ListIterator<String> nestedListIterator) {
+		return new ReadOnlyListIterator<Object>(nestedListIterator);
+	}
+
+	private ListIterator<String> buildNestedListIterator() {
+		return this.buildList().listIterator();
+	}
+
+	private List<String> buildList() {
+		List<String> l = new ArrayList<String>();
+		l.add("one");
+		l.add("two");
+		l.add("three");
+		l.add("four");
+		l.add("five");
+		l.add("six");
+		l.add("seven");
+		l.add("eight");
+		return l;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SimultaneousIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SimultaneousIteratorTests.java
new file mode 100644
index 0000000..c53f70c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SimultaneousIteratorTests.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.SimultaneousIterator;
+
+@SuppressWarnings("nls")
+public class SimultaneousIteratorTests
+	extends TestCase
+{
+	public SimultaneousIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testConstructor() {
+		boolean exCaught = false;
+		try {
+			Iterator<List<String>> iterator = this.buildIterator((Iterable<ListIterator<String>>) null);
+			fail("bogus iterator: " + iterator);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testHasNext() {
+		int i = 0;
+		for (Iterator<List<String>> stream = this.buildIterator(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(this.buildList2().size(), i);
+	}
+
+	public void testHasNextEmpty() {
+		Iterator<List<String>> iterator = this.buildIterator(Collections.<ListIterator<String>>emptyList());
+		assertFalse(iterator.hasNext());
+	}
+
+	public void testNext() {
+		Iterator<List<String>> stream = this.buildIterator();
+		List<String> next = stream.next();
+		assertEquals("1", next.get(0));
+		assertEquals("one", next.get(1));
+
+		next = stream.next();
+		assertEquals("2", next.get(0));
+		assertEquals("two", next.get(1));
+
+		next = stream.next();
+		assertEquals("3", next.get(0));
+		assertEquals("three", next.get(1));
+
+		next = stream.next();
+		assertEquals("4", next.get(0));
+		assertEquals("four", next.get(1));
+
+		next = stream.next();
+		assertEquals("5", next.get(0));
+		assertEquals("five", next.get(1));
+
+		next = stream.next();
+		assertEquals("6", next.get(0));
+		assertEquals("six", next.get(1));
+
+		next = stream.next();
+		assertEquals("7", next.get(0));
+		assertEquals("seven", next.get(1));
+	}
+
+	public void testNextEmpty() {
+		Iterator<List<String>> iterator = this.buildIterator(Collections.<ListIterator<String>>emptyList());
+		boolean exCaught = false;
+		try {
+			List<String> next = iterator.next();
+			fail("bogus element: " + next);
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemove() {
+		List<String> list1 = this.buildList1();
+		List<String> list2 = this.buildList2();
+		assertTrue(list1.contains("2"));
+		assertTrue(list2.contains("two"));
+
+		Iterator<List<String>> stream = this.buildIterator(list1, list2);
+		List<String> next = stream.next();
+		assertEquals("1", next.get(0));
+		assertEquals("one", next.get(1));
+
+		next = stream.next();
+		assertEquals("2", next.get(0));
+		assertEquals("two", next.get(1));
+
+		stream.remove();
+		assertFalse(list1.contains("2"));
+		assertFalse(list1.contains("two"));
+	}
+
+	public void testRemoveEmpty() {
+		Iterator<List<String>> iterator = this.buildIterator(Collections.<ListIterator<String>>emptyList());
+		boolean exCaught = false;
+		try {
+			iterator.remove();
+			fail("bogus iterator: " + iterator);
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	private List<String> buildList1() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("1");
+		list.add("2");
+		list.add("3");
+		list.add("4");
+		list.add("5");
+		list.add("6");
+		list.add("7");
+		list.add("8");
+		return list;
+	}
+
+	private List<String> buildList2() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("one");
+		list.add("two");
+		list.add("three");
+		list.add("four");
+		list.add("five");
+		list.add("six");
+		list.add("seven");
+		return list;
+	}
+
+	protected Iterator<List<String>> buildIterator() {
+		return this.buildIterator(this.buildList1(), this.buildList2());
+	}
+
+	@SuppressWarnings("unchecked")
+	protected Iterator<List<String>> buildIterator(List<String> list1, List<String> list2) {
+		return this.buildIterator(list1.listIterator(), list2.listIterator());
+	}
+
+	protected Iterator<List<String>> buildIterator(ListIterator<String>... iterators) {
+		return new SimultaneousIterator<String>(iterators);
+	}
+
+	protected Iterator<List<String>> buildIterator(Iterable<ListIterator<String>> iterators) {
+		return new SimultaneousIterator<String>(iterators);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SimultaneousListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SimultaneousListIteratorTests.java
new file mode 100644
index 0000000..1ce89e2
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SimultaneousListIteratorTests.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.SimultaneousListIterator;
+
+public class SimultaneousListIteratorTests
+	extends SimultaneousIteratorTests
+{
+	public SimultaneousListIteratorTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected Iterator<List<String>> buildIterator(ListIterator<String>... iterators) {
+		return new SimultaneousListIterator<String>(iterators);
+	}
+
+	@Override
+	protected Iterator<List<String>> buildIterator(Iterable<ListIterator<String>> iterators) {
+		return new SimultaneousListIterator<String>(iterators);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SingleElementIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SingleElementIteratorTests.java
new file mode 100644
index 0000000..53c574a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SingleElementIteratorTests.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.SingleElementIterator;
+
+@SuppressWarnings("nls")
+public class SingleElementIteratorTests extends TestCase {
+
+	public SingleElementIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testHasNext() {
+		int i = 0;
+		for (Iterator<String> stream = this.buildSingleElementIterator(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(1, i);
+	}
+
+	public void testNext() {
+		for (Iterator<String> stream = this.buildSingleElementIterator(); stream.hasNext();) {
+			assertEquals("bogus element", this.singleElement(), stream.next());
+		}
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		Iterator<String> stream = this.buildSingleElementIterator();
+		String string = stream.next();
+		try {
+			string = stream.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
+	}
+
+	public void testRemove() {
+		boolean exCaught = false;
+		for (Iterator<String> stream = this.buildSingleElementIterator(); stream.hasNext();) {
+			if (stream.next().equals(this.singleElement())) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	protected Iterator<String> buildSingleElementIterator() {
+		return new SingleElementIterator<String>(this.singleElement());
+	}
+
+	protected String singleElement() {
+		return "single element";
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SingleElementListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SingleElementListIteratorTests.java
new file mode 100644
index 0000000..26939d0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SingleElementListIteratorTests.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.Iterator;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.SingleElementListIterator;
+
+@SuppressWarnings("nls")
+public class SingleElementListIteratorTests extends SingleElementIteratorTests {
+
+	public SingleElementListIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testNextIndex() {
+		ListIterator<String> stream = this.buildSingleElementListIterator();
+		while (stream.hasNext()) {
+			assertEquals("bogus index", 0, stream.nextIndex());
+			stream.next();
+		}
+		assertEquals("bogus index", 1, stream.nextIndex());
+	}
+
+	public void testHasPrevious() {
+		int i = 0;
+		ListIterator<String> stream = this.buildSingleElementListIterator();
+		while (stream.hasNext()) {
+			stream.next();
+			i++;
+		}
+		assertEquals(1, i);
+
+		while (stream.hasPrevious()) {
+			stream.previous();
+			i++;
+		}
+		assertEquals(2, i);
+	}
+
+	public void testPrevious() {
+		ListIterator<String> stream = this.buildSingleElementListIterator();
+
+		while (stream.hasNext()) {
+			assertEquals("bogus element", this.singleElement(), stream.next());
+		}
+
+		while (stream.hasPrevious()) {
+			assertEquals("bogus element", this.singleElement(), stream.previous());
+		}
+	}
+
+	public void testPreviousIndex() {
+		ListIterator<String> stream = this.buildSingleElementListIterator();
+
+		while (stream.hasNext()) {
+			assertEquals("bogus index", 0, stream.nextIndex());
+			stream.next();
+		}
+
+		while (stream.hasPrevious()) {
+			assertEquals("bogus index", 0, stream.previousIndex());
+			stream.previous();
+		}
+
+		assertEquals("bogus index", -1, stream.previousIndex());
+	}
+
+	public void testAdd() {
+		boolean exCaught = false;
+		ListIterator<String> stream = this.buildSingleElementListIterator();
+
+		try {
+			stream.add("foo");
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	public void testSet() {
+		boolean exCaught = false;
+		for (ListIterator<String> stream = this.buildSingleElementListIterator(); stream.hasNext();) {
+			if (stream.next().equals(this.singleElement())) {
+				try {
+					stream.set("foo");
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	@Override
+	protected Iterator<String> buildSingleElementIterator() {
+		return new SingleElementListIterator<String>(this.singleElement());
+	}
+
+	protected ListIterator<String> buildSingleElementListIterator() {
+		return (ListIterator<String>) this.buildSingleElementIterator();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SuperIteratorWrapperTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SuperIteratorWrapperTests.java
new file mode 100644
index 0000000..33adc67
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SuperIteratorWrapperTests.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.SuperIteratorWrapper;
+
+@SuppressWarnings("nls")
+public class SuperIteratorWrapperTests extends TestCase {
+
+	public SuperIteratorWrapperTests(String name) {
+		super(name);
+	}
+
+	public void testIterator() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("foo");
+		list.add("bar");
+		list.add("baz");
+		String concat = "";
+		for (Iterator<String> stream = list.iterator(); stream.hasNext(); ) {
+			concat += stream.next();
+		}
+		assertEquals("foobarbaz", concat);
+
+		Iterator<Object> iterator = new SuperIteratorWrapper<Object>(list);
+		concat = "";
+		while (iterator.hasNext()) {
+			Object next = iterator.next();
+			if (next.equals("bar")) {
+				iterator.remove();
+			} else {
+				concat += next;
+			}
+		}
+		assertEquals("foobaz", concat);
+		assertEquals(2, list.size());
+		assertFalse(list.contains("bar"));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SynchronizedIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SynchronizedIteratorTests.java
new file mode 100644
index 0000000..af6bb67
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SynchronizedIteratorTests.java
@@ -0,0 +1,319 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterator.SynchronizedIterator;
+import org.eclipse.persistence.tools.utility.tests.MultiThreadedTestCase;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+
+@SuppressWarnings("nls")
+public class SynchronizedIteratorTests
+	extends MultiThreadedTestCase
+{
+	public SynchronizedIteratorTests(String name) {
+		super(name);
+	}
+
+	/**
+	 * test that an unsynchronized iterator will produce corrupt output;
+	 * thread 1 will read the first element from the iterator
+	 * and then sleep for a bit, allowing thread 2 to sneak in and
+	 * read the same element from the iterator
+	 */
+	public void testUnsynchronizedNext() throws Exception {
+		TestIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
+
+		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		NextTestRunnable<String> runnable2 = new NextTestRunnable<String>(iterator);
+		Thread thread2 = this.buildThread(runnable2);
+		iterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// both threads should have read the same element from the iterator :-(
+		assertEquals("foo", runnable1.next);
+		assertEquals("foo", runnable2.next);
+	}
+
+	/**
+	 * test that a synchronized iterator will produce valid output;
+	 * thread 1 will read the first element from the iterator
+	 * and then sleep for a bit, but thread 2 will be locked out and
+	 * wait to read the second element from the iterator
+	 */
+	public void testSynchronizedNext() throws Exception {
+		TestIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
+		Iterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+
+		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		NextTestRunnable<String> runnable2 = new NextTestRunnable<String>(iterator);
+		Thread thread2 = this.buildThread(runnable2);
+		nestedIterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// the threads should have read the correct elements from the iterator :-)
+		assertEquals("foo", runnable1.next);
+		assertEquals("bar", runnable2.next);
+	}
+
+	public void testUnsynchronizedHasNext() throws Exception {
+		TestIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
+		iterator.next();
+		iterator.next();
+
+		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		HasNextTestRunnable<String> runnable2 = new HasNextTestRunnable<String>(iterator);
+		Thread thread2 = this.buildThread(runnable2);
+		iterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// thread 1 will have the last element,
+		// but thread 2 will think there are more elements on the iterator :-(
+		assertEquals("baz", runnable1.next);
+		assertEquals(true, runnable2.hasNext);
+	}
+
+	public void testSynchronizedHasNext() throws Exception {
+		TestIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
+		Iterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+		iterator.next();
+		iterator.next();
+
+		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		HasNextTestRunnable<String> runnable2 = new HasNextTestRunnable<String>(iterator);
+		Thread thread2 = this.buildThread(runnable2);
+		nestedIterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// thread 1 will have the last element,
+		// and thread 2 will think there are no more elements on the iterator :-)
+		assertEquals("baz", runnable1.next);
+		assertEquals(false, runnable2.hasNext);
+	}
+
+	public void testUnsynchronizedRemove() throws Exception {
+		TestIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
+		iterator.next();
+
+		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		RemoveTestRunnable<String> runnable2 = new RemoveTestRunnable<String>(iterator);
+		Thread thread2 = this.buildThread(runnable2);
+		iterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// the wrong element was removed :-(
+		assertEquals("bar", runnable1.next);
+		assertFalse(iterator.list.contains("foo"));
+		assertTrue(iterator.list.contains("bar"));
+		assertTrue(iterator.list.contains("baz"));
+	}
+
+	public void testSynchronizedRemove() throws Exception {
+		TestIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
+		Iterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+		iterator.next();
+
+		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		RemoveTestRunnable<String> runnable2 = new RemoveTestRunnable<String>(iterator);
+		Thread thread2 = this.buildThread(runnable2);
+		nestedIterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// the correct element was removed :-)
+		assertEquals("bar", runnable1.next);
+		assertTrue(nestedIterator.list.contains("foo"));
+		assertFalse(nestedIterator.list.contains("bar"));
+		assertTrue(nestedIterator.list.contains("baz"));
+	}
+
+	TestIterator<String> buildTestIterator(long delay) {
+		return new TestIterator<String>(delay, this.buildArray());
+	}
+
+	String[] buildArray() {
+		return new String[] {"foo", "bar", "baz"};
+	}
+
+	Iterator<String> buildSynchronizedIterator(Iterator<String> nestedIterator) {
+		return new SynchronizedIterator<String>(nestedIterator);
+	}
+
+
+	/**
+	 * next runnable
+	 */
+	class NextTestRunnable<E> implements Runnable {
+		final Iterator<E> iterator;
+		E next;
+
+		NextTestRunnable(Iterator<E> iterator) {
+			super();
+			this.iterator = iterator;
+		}
+
+		@Override
+		public void run() {
+			this.next = this.iterator.next();
+		}
+
+	}
+
+	/**
+	 * has next runnable
+	 */
+	class HasNextTestRunnable<E> implements Runnable {
+		final Iterator<E> iterator;
+		boolean hasNext;
+
+		HasNextTestRunnable(Iterator<E> iterator) {
+			super();
+			this.iterator = iterator;
+		}
+
+		@Override
+		public void run() {
+			this.hasNext = this.iterator.hasNext();
+		}
+
+	}
+
+	/**
+	 * remove runnable
+	 */
+	class RemoveTestRunnable<E> implements Runnable {
+		final Iterator<E> iterator;
+
+		RemoveTestRunnable(Iterator<E> iterator) {
+			super();
+			this.iterator = iterator;
+		}
+
+		@Override
+		public void run() {
+			this.iterator.remove();
+		}
+
+	}
+
+	/**
+	 * Test iterator: If {@link #next()} is called while executing on the
+	 * {@link #slowThread}, the iterator will delay for the configured time.
+	 */
+	static class TestIterator<E> implements Iterator<E> {
+		final long delay;
+		final ArrayList<E> list = new ArrayList<E>();
+		int nextIndex = 0;
+		int lastIndex = -1;
+		Thread slowThread;
+
+		TestIterator(long delay, E... array) {
+			super();
+			this.delay = delay;
+			CollectionTools.addAll(this.list, array);
+		}
+
+		@Override
+		public boolean hasNext() {
+			return this.nextIndex != this.list.size();
+		}
+
+		@Override
+		public E next() {
+			if (this.hasNext()) {
+				E next = this.list.get(this.nextIndex);
+				if (Thread.currentThread() == this.slowThread) {
+					TestTools.sleep(this.delay);
+				}
+				this.lastIndex = this.nextIndex++;
+				return next;
+			}
+			throw new NoSuchElementException();
+		}
+
+		@Override
+		public void remove() {
+			if (this.lastIndex == -1) {
+				throw new IllegalStateException();
+			}
+			this.list.remove(this.lastIndex);
+			if (this.lastIndex < this.nextIndex) {  // check necessary for ListIterator
+				this.nextIndex--;
+			}
+			this.lastIndex = -1;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SynchronizedListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SynchronizedListIteratorTests.java
new file mode 100644
index 0000000..1b05c46
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/SynchronizedListIteratorTests.java
@@ -0,0 +1,531 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.Iterator;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.iterator.SynchronizedListIterator;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class SynchronizedListIteratorTests
+	extends SynchronizedIteratorTests
+{
+	public SynchronizedListIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testUnsynchronizedPrevious() throws Exception {
+		TestListIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
+		iterator.next();
+		iterator.next();
+
+		PreviousTestRunnable<String> runnable1 = new PreviousTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		PreviousTestRunnable<String> runnable2 = new PreviousTestRunnable<String>(iterator);
+		Thread thread2 = this.buildThread(runnable2);
+		iterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// both threads should have read the same element from the iterator :-(
+		assertEquals("bar", runnable1.previous);
+		assertEquals("bar", runnable2.previous);
+	}
+
+	public void testSynchronizedPrevious() throws Exception {
+		TestListIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
+		ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+		iterator.next();
+		iterator.next();
+
+		PreviousTestRunnable<String> runnable1 = new PreviousTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		PreviousTestRunnable<String> runnable2 = new PreviousTestRunnable<String>(iterator);
+		Thread thread2 = this.buildThread(runnable2);
+		nestedIterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// the threads should have read the correct elements from the iterator :-)
+		assertEquals("bar", runnable1.previous);
+		assertEquals("foo", runnable2.previous);
+	}
+
+	public void testUnsynchronizedHasPrevious() throws Exception {
+		TestListIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
+		iterator.next();
+
+		PreviousTestRunnable<String> runnable1 = new PreviousTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		HasPreviousTestRunnable<String> runnable2 = new HasPreviousTestRunnable<String>(iterator);
+		Thread thread2 = this.buildThread(runnable2);
+		iterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// thread 1 will have the first element,
+		// but thread 2 will think there are more "previous" elements on the iterator :-(
+		assertEquals("foo", runnable1.previous);
+		assertEquals(true, runnable2.hasPrevious);
+	}
+
+	public void testSynchronizedHasPrevious() throws Exception {
+		TestListIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
+		ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+		iterator.next();
+
+		PreviousTestRunnable<String> runnable1 = new PreviousTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		HasPreviousTestRunnable<String> runnable2 = new HasPreviousTestRunnable<String>(iterator);
+		Thread thread2 = this.buildThread(runnable2);
+		nestedIterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// thread 1 will have the first element,
+		// and thread 2 will think there are no more "previous" elements on the iterator :-)
+		assertEquals("foo", runnable1.previous);
+		assertEquals(false, runnable2.hasPrevious);
+	}
+
+	public void testUnsynchronizedNextIndex() throws Exception {
+		TestListIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
+
+		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		NextIndexTestRunnable<String> runnable2 = new NextIndexTestRunnable<String>(iterator);
+		Thread thread2 = this.buildThread(runnable2);
+		iterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// thread 1 will have the first element,
+		// but thread 2 will think the next index is still 0 :-(
+		assertEquals("foo", runnable1.next);
+		assertEquals(0, runnable2.nextIndex);
+	}
+
+	public void testSynchronizedNextIndex() throws Exception {
+		TestListIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
+		ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+
+		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		NextIndexTestRunnable<String> runnable2 = new NextIndexTestRunnable<String>(iterator);
+		Thread thread2 = this.buildThread(runnable2);
+		nestedIterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// thread 1 will have the first element,
+		// and thread 2 will think the next index is 1 :-)
+		assertEquals("foo", runnable1.next);
+		assertEquals(1, runnable2.nextIndex);
+	}
+
+	public void testUnsynchronizedPreviousIndex() throws Exception {
+		TestListIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
+		iterator.next();
+
+		PreviousTestRunnable<String> runnable1 = new PreviousTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		PreviousIndexTestRunnable<String> runnable2 = new PreviousIndexTestRunnable<String>(iterator);
+		Thread thread2 = this.buildThread(runnable2);
+		iterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// thread 1 will have the first element,
+		// but thread 2 will think the next index is still 0 :-(
+		assertEquals("foo", runnable1.previous);
+		assertEquals(0, runnable2.previousIndex);
+	}
+
+	public void testSynchronizedPreviousIndex() throws Exception {
+		TestListIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
+		ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+		iterator.next();
+
+		PreviousTestRunnable<String> runnable1 = new PreviousTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		PreviousIndexTestRunnable<String> runnable2 = new PreviousIndexTestRunnable<String>(iterator);
+		Thread thread2 = this.buildThread(runnable2);
+		nestedIterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// thread 1 will have the first element,
+		// and thread 2 will think the next index is -1 :-)
+		assertEquals("foo", runnable1.previous);
+		assertEquals(-1, runnable2.previousIndex);
+	}
+
+	public void testUnsynchronizedSet() throws Exception {
+		TestListIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
+		iterator.next();
+
+		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		SetTestRunnable<String> runnable2 = new SetTestRunnable<String>(iterator, "xxx");
+		Thread thread2 = this.buildThread(runnable2);
+		iterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// the wrong element was set :-(
+		assertEquals("bar", runnable1.next);
+		assertFalse(iterator.list.contains("foo"));
+		assertTrue(iterator.list.contains("xxx"));
+		assertTrue(iterator.list.contains("bar"));
+		assertTrue(iterator.list.contains("baz"));
+	}
+
+	public void testSynchronizedSet() throws Exception {
+		TestListIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
+		ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+		iterator.next();
+
+		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		SetTestRunnable<String> runnable2 = new SetTestRunnable<String>(iterator, "xxx");
+		Thread thread2 = this.buildThread(runnable2);
+		nestedIterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// the right element was set :-)
+		assertEquals("bar", runnable1.next);
+		assertTrue(nestedIterator.list.contains("foo"));
+		assertFalse(nestedIterator.list.contains("bar"));
+		assertTrue(nestedIterator.list.contains("xxx"));
+		assertTrue(nestedIterator.list.contains("baz"));
+	}
+
+	public void testUnsynchronizedAdd() throws Exception {
+		TestListIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
+		iterator.next();
+
+		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		AddTestRunnable<String> runnable2 = new AddTestRunnable<String>(iterator, "xxx");
+		Thread thread2 = this.buildThread(runnable2);
+		iterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// the element was added at the wrong index :-(
+		assertEquals("bar", runnable1.next);
+		assertTrue(iterator.list.contains("foo"));
+		assertEquals(0, iterator.list.indexOf("xxx"));
+		assertTrue(iterator.list.contains("xxx"));
+		assertTrue(iterator.list.contains("bar"));
+		assertTrue(iterator.list.contains("baz"));
+	}
+
+	public void testSynchronizedAdd() throws Exception {
+		TestListIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
+		ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+		iterator.next();
+
+		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
+		Thread thread1 = this.buildThread(runnable1);
+		AddTestRunnable<String> runnable2 = new AddTestRunnable<String>(iterator, "xxx");
+		Thread thread2 = this.buildThread(runnable2);
+		nestedIterator.slowThread = thread1;
+
+		thread1.start();
+
+		// allow thread 1 to read the first element and get bogged down
+		this.sleep(TICK);
+		thread2.start();
+
+		// wait for the threads to finish
+		thread1.join();
+		thread2.join();
+
+		// the element was added at the correct index :-)
+		assertEquals("bar", runnable1.next);
+		assertTrue(nestedIterator.list.contains("foo"));
+		assertEquals(1, nestedIterator.list.indexOf("xxx"));
+		assertTrue(nestedIterator.list.contains("xxx"));
+		assertTrue(nestedIterator.list.contains("bar"));
+		assertTrue(nestedIterator.list.contains("baz"));
+	}
+
+	@Override
+	ListIterator<String> buildSynchronizedIterator(Iterator<String> nestedIterator) {
+		return new SynchronizedListIterator<String>((ListIterator<String>) nestedIterator);
+	}
+
+	@Override
+	TestListIterator<String> buildTestIterator(long delay) {
+		return new TestListIterator<String>(delay, this.buildArray());
+	}
+
+	/**
+	 * previous runnable
+	 */
+	class PreviousTestRunnable<E> implements Runnable {
+		final ListIterator<E> iterator;
+		E previous;
+
+		PreviousTestRunnable(ListIterator<E> iterator) {
+			super();
+			this.iterator = iterator;
+		}
+
+		@Override
+		public void run() {
+			this.previous = this.iterator.previous();
+		}
+	}
+
+	/**
+	 * has previous runnable
+	 */
+	class HasPreviousTestRunnable<E> implements Runnable {
+		final ListIterator<E> iterator;
+		boolean hasPrevious;
+
+		HasPreviousTestRunnable(ListIterator<E> iterator) {
+			super();
+			this.iterator = iterator;
+		}
+
+		@Override
+		public void run() {
+			this.hasPrevious = this.iterator.hasPrevious();
+		}
+	}
+
+	/**
+	 * next index runnable
+	 */
+	class NextIndexTestRunnable<E> implements Runnable {
+		final ListIterator<E> iterator;
+		int nextIndex;
+
+		NextIndexTestRunnable(ListIterator<E> iterator) {
+			super();
+			this.iterator = iterator;
+		}
+
+		@Override
+		public void run() {
+			this.nextIndex = this.iterator.nextIndex();
+		}
+	}
+
+	/**
+	 * previous index runnable
+	 */
+	class PreviousIndexTestRunnable<E> implements Runnable {
+		final ListIterator<E> iterator;
+		int previousIndex;
+
+		PreviousIndexTestRunnable(ListIterator<E> iterator) {
+			super();
+			this.iterator = iterator;
+		}
+
+		@Override
+		public void run() {
+			this.previousIndex = this.iterator.previousIndex();
+		}
+	}
+
+	/**
+	 * set runnable
+	 */
+	class SetTestRunnable<E> implements Runnable {
+		final ListIterator<E> iterator;
+		final E element;
+
+		SetTestRunnable(ListIterator<E> iterator, E element) {
+			super();
+			this.iterator = iterator;
+			this.element = element;
+		}
+
+		@Override
+		public void run() {
+			this.iterator.set(this.element);
+		}
+	}
+
+	/**
+	 * add runnable
+	 */
+	class AddTestRunnable<E> implements Runnable {
+		final ListIterator<E> iterator;
+		final E element;
+
+		AddTestRunnable(ListIterator<E> iterator, E element) {
+			super();
+			this.iterator = iterator;
+			this.element = element;
+		}
+
+		@Override
+		public void run() {
+			this.iterator.add(this.element);
+		}
+	}
+
+	/**
+	 * Test iterator: If {@link #next()} or {@link #previous()} is called
+	 * while executing on the {@link #slowThread}, the iterator will delay
+	 * for the configured time.
+	 */
+	static class TestListIterator<E> extends TestIterator<E> implements ListIterator<E> {
+
+		TestListIterator(long delay, E... array) {
+			super(delay, array);
+		}
+
+		@Override
+		public int nextIndex() {
+			return this.nextIndex;
+		}
+
+		@Override
+		public boolean hasPrevious() {
+			return this.nextIndex != 0;
+		}
+
+		@Override
+		public E previous() {
+			if (this.hasPrevious()) {
+				E previous = this.list.get(this.previousIndex());
+				if (Thread.currentThread() == this.slowThread) {
+					TestTools.sleep(this.delay);
+				}
+				this.nextIndex--;
+				this.lastIndex = this.nextIndex;
+				return previous;
+			}
+			throw new NoSuchElementException();
+		}
+
+		@Override
+		public int previousIndex() {
+			return this.nextIndex - 1;
+		}
+
+		@Override
+		public void set(E e) {
+			if (this.lastIndex == -1) {
+				throw new IllegalStateException();
+			}
+			this.list.set(this.lastIndex, e);
+		}
+
+		@Override
+		public void add(E e) {
+			this.list.add(this.lastIndex, e);
+			this.lastIndex++;
+			this.lastIndex = -1;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/TransformationIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/TransformationIteratorTests.java
new file mode 100644
index 0000000..745b497
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/TransformationIteratorTests.java
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+@SuppressWarnings("nls")
+public class TransformationIteratorTests extends TestCase {
+
+	public TransformationIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testHasNext() {
+		int i = 0;
+		for (Iterator<Integer> stream = this.buildIterator(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(8, i);
+	}
+
+	public void testHasNextUpcast() {
+		int i = 0;
+		for (Iterator<Object> stream = this.buildIteratorUpcast(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(8, i);
+	}
+
+	public void testInnerHasNext() {
+		int i = 0;
+		for (Iterator<Integer> stream = this.buildInnerIterator(); stream.hasNext();) {
+			stream.next();
+			i++;
+		}
+		assertEquals(8, i);
+	}
+
+	public void testNext() {
+		int i = 0;
+		for (Iterator<Integer> stream = this.buildIterator(); stream.hasNext();) {
+			assertEquals("bogus transformation", ++i, stream.next().intValue());
+		}
+	}
+
+	public void testNextUpcast() {
+		int i = 0;
+		for (Iterator<Object> stream = this.buildIteratorUpcast(); stream.hasNext();) {
+			assertEquals("bogus transformation", ++i, ((Integer) stream.next()).intValue());
+		}
+	}
+
+	public void testInnerNext() {
+		int i = 0;
+		for (Iterator<Integer> stream = this.buildInnerIterator(); stream.hasNext();) {
+			assertEquals("bogus transformation", ++i, stream.next().intValue());
+		}
+	}
+
+	public void testRemove() {
+		Collection<String> c = this.buildCollection();
+		for (Iterator<Integer> stream = this.buildInnerTransformationIterator(c.iterator()); stream.hasNext();) {
+			if (stream.next().intValue() == 3) {
+				stream.remove();
+			}
+		}
+		assertEquals("nothing removed", this.buildCollection().size() - 1, c.size());
+		assertFalse("element still in collection", c.contains("333"));
+		assertTrue("wrong element removed", c.contains("22"));
+	}
+
+	public void testInnerRemove() {
+		Collection<String> c = this.buildCollection();
+		for (Iterator<Integer> stream = this.buildTransformationIterator(c.iterator(), this.buildTransformer()); stream.hasNext();) {
+			if (stream.next().intValue() == 3) {
+				stream.remove();
+			}
+		}
+		assertEquals("nothing removed", this.buildCollection().size() - 1, c.size());
+		assertFalse("element still in collection", c.contains("333"));
+		assertTrue("wrong element removed", c.contains("22"));
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		Iterator<Integer> stream = this.buildIterator();
+		Integer integer = null;
+		while (stream.hasNext()) {
+			integer = stream.next();
+		}
+		try {
+			integer = stream.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + integer, exCaught);
+	}
+
+	public void testUnsupportedOperationException() {
+		boolean exCaught = false;
+		for (Iterator<Integer> stream = this.buildUnmodifiableIterator(); stream.hasNext();) {
+			int i = stream.next().intValue();
+			if (i == 3) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	public void testIllegalStateException() {
+		boolean exCaught = false;
+		try {
+			this.buildIterator().remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue("IllegalStateException not thrown", exCaught);
+	}
+
+	private Iterator<Integer> buildIterator() {
+		return this.buildTransformationIterator(this.buildNestedIterator(), this.buildTransformer());
+	}
+
+	private Iterator<Object> buildIteratorUpcast() {
+		return this.buildTransformationIteratorUpcast(this.buildNestedIterator(), this.buildTransformerUpcast());
+	}
+
+	private Iterator<Integer> buildInnerIterator() {
+		return this.buildInnerTransformationIterator(this.buildNestedIterator());
+	}
+
+	private Iterator<Integer> buildUnmodifiableIterator() {
+		return this.buildTransformationIterator(this.buildUnmodifiableNestedIterator(), this.buildTransformer());
+	}
+
+	private Iterator<Integer> buildTransformationIterator(Iterator<String> nestedIterator, Transformer<String, Integer> transformer) {
+		return new TransformationIterator<String, Integer>(nestedIterator, transformer);
+	}
+
+	private Iterator<Object> buildTransformationIteratorUpcast(Iterator<String> nestedIterator, Transformer<Object, Integer> transformer) {
+		return new TransformationIterator<Object, Object>(nestedIterator, transformer);
+	}
+
+	private Transformer<String, Integer> buildTransformer() {
+		// transform each string into an integer with a value of the string's length
+		return new Transformer<String, Integer>() {
+			@Override
+			public Integer transform(String next) {
+				return new Integer(next.length());
+			}
+		};
+	}
+
+	private Transformer<Object, Integer> buildTransformerUpcast() {
+		// transform each string into an integer with a value of the string's length
+		return new Transformer<Object, Integer>() {
+			@Override
+			public Integer transform(Object next) {
+				return new Integer(((String) next).length());
+			}
+		};
+	}
+
+	private Iterator<Integer> buildInnerTransformationIterator(Iterator<String> nestedIterator) {
+		// transform each string into an integer with a value of the string's length
+		return new TransformationIterator<String, Integer>(nestedIterator) {
+			@Override
+			protected Integer transform(String next) {
+				return new Integer(next.length());
+			}
+		};
+	}
+
+	private Iterator<String> buildNestedIterator() {
+		return this.buildCollection().iterator();
+	}
+
+	private Iterator<String> buildUnmodifiableNestedIterator() {
+		return this.buildUnmodifiableCollection().iterator();
+	}
+
+	private Collection<String> buildCollection() {
+		Collection<String> c = new ArrayList<String>();
+		c.add("1");
+		c.add("22");
+		c.add("333");
+		c.add("4444");
+		c.add("55555");
+		c.add("666666");
+		c.add("7777777");
+		c.add("88888888");
+		return c;
+	}
+
+	private Collection<String> buildUnmodifiableCollection() {
+		return Collections.unmodifiableCollection(this.buildCollection());
+	}
+
+	public void testInvalidTransformationIterator() {
+		// missing method override
+		Iterator<Integer> iterator = new TransformationIterator<String, Integer>(this.buildCollection().iterator());
+		boolean exCaught = false;
+		try {
+			Integer integer = iterator.next();
+			fail("invalid integer: " + integer);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown", exCaught);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/TransformationListIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/TransformationListIteratorTests.java
new file mode 100644
index 0000000..2e54521
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/TransformationListIteratorTests.java
@@ -0,0 +1,327 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.TransformationListIterator;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+@SuppressWarnings("nls")
+public class TransformationListIteratorTests extends TestCase {
+
+	public TransformationListIteratorTests(String name) {
+		super(name);
+	}
+
+	public void testHasNextAndHasPrevious() {
+		int i = 0;
+		ListIterator<Integer> stream = this.buildIterator();
+
+		while (stream.hasNext()) {
+			stream.next();
+			i++;
+		}
+		assertEquals(8, i);
+
+		while (stream.hasPrevious()) {
+			stream.previous();
+			i--;
+		}
+		assertEquals(0, i);
+	}
+
+	public void testHasNextAndHasPreviousUpcast() {
+		int i = 0;
+		ListIterator<Object> stream = this.buildIteratorUpcast();
+
+		while (stream.hasNext()) {
+			stream.next();
+			i++;
+		}
+		assertEquals(8, i);
+
+		while (stream.hasPrevious()) {
+			stream.previous();
+			i--;
+		}
+		assertEquals(0, i);
+	}
+
+	public void testInnerHasNextAndHasPrevious() {
+		int i = 0;
+		ListIterator<Integer> stream = this.buildInnerIterator();
+
+		while (stream.hasNext()) {
+			stream.next();
+			i++;
+		}
+		assertEquals(8, i);
+
+		while (stream.hasPrevious()) {
+			stream.previous();
+			i--;
+		}
+		assertEquals(0, i);
+	}
+
+	public void testNextAndPrevious() {
+		int i = 0;
+		ListIterator<Integer> stream = this.buildIterator();
+
+		while (stream.hasNext()) {
+			assertEquals(++i, stream.next().intValue());
+		}
+
+		++i;
+
+		while (stream.hasPrevious()) {
+			assertEquals(--i, stream.previous().intValue());
+		}
+	}
+
+	public void testInnerNextAndPrevious() {
+		int i = 0;
+		ListIterator<Integer> stream = this.buildInnerIterator();
+
+		while (stream.hasNext()) {
+			assertEquals(++i, stream.next().intValue());
+		}
+
+		++i;
+
+		while (stream.hasPrevious()) {
+			assertEquals(--i, stream.previous().intValue());
+		}
+	}
+
+	public void testNextIndexAndPreviousIndex() {
+		int i = -1;
+		ListIterator<Integer> stream = this.buildIterator();
+
+		while (stream.hasNext()) {
+			assertEquals(++i, stream.nextIndex());
+			stream.next();
+		}
+
+		++i;
+
+		while (stream.hasPrevious()) {
+			assertEquals(--i, stream.previousIndex());
+			stream.previous();
+		}
+	}
+
+	public void testInnerNextIndexAndPreviousIndex() {
+		int i = -1;
+		ListIterator<Integer> stream = this.buildInnerIterator();
+
+		while (stream.hasNext()) {
+			assertEquals(++i, stream.nextIndex());
+			stream.next();
+		}
+
+		++i;
+
+		while (stream.hasPrevious()) {
+			assertEquals(--i, stream.previousIndex());
+			stream.previous();
+		}
+	}
+
+	public void testRemove() {
+		List<String> l = this.buildList();
+		for (ListIterator<Integer> stream = this.buildInnerTransformationListIterator(l.listIterator()); stream.hasNext();) {
+			if (stream.next().intValue() == 3) {
+				stream.remove();
+			}
+		}
+		assertEquals("nothing removed", this.buildList().size() - 1, l.size());
+		assertFalse("element still in list", l.contains("333"));
+		assertTrue("wrong element removed", l.contains("22"));
+	}
+
+	public void testInnerRemove() {
+		List<String> l = this.buildList();
+		for (ListIterator<Integer> stream = this.buildTransformationListIterator(l.listIterator(), this.buildTransformer()); stream.hasNext();) {
+			if (stream.next().intValue() == 3) {
+				stream.remove();
+			}
+		}
+		assertEquals("nothing removed", this.buildList().size() - 1, l.size());
+		assertFalse("element still in list", l.contains("333"));
+		assertTrue("wrong element removed", l.contains("22"));
+	}
+
+	public void testUnsupportedOperationExceptionOnAdd() {
+		ListIterator<Integer> stream = this.buildIterator();
+		boolean exCaught = false;
+		try {
+			stream.add(new Integer(0));
+			fail("exception not thrown");
+		} catch (UnsupportedOperationException e) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testUnsupportedOperationExceptionOnSet() {
+		ListIterator<Integer> stream = this.buildIterator();
+		boolean exCaught = false;
+		try {
+			stream.set(new Integer(0));
+			fail("exception not thrown");
+		} catch (UnsupportedOperationException e) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testNoSuchElementException() {
+		boolean exCaught = false;
+		ListIterator<Integer> stream = this.buildIterator();
+		Integer integer = null;
+		while (stream.hasNext()) {
+			integer = stream.next();
+		}
+		try {
+			integer = stream.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + integer, exCaught);
+	}
+
+	public void testUnsupportedOperationException() {
+		boolean exCaught = false;
+		for (Iterator<Integer> stream = this.buildUnmodifiableIterator(); stream.hasNext();) {
+			int i = stream.next().intValue();
+			if (i == 3) {
+				try {
+					stream.remove();
+				} catch (UnsupportedOperationException ex) {
+					exCaught = true;
+				}
+			}
+		}
+		assertTrue("UnsupportedOperationException not thrown", exCaught);
+	}
+
+	public void testIllegalStateException() {
+		boolean exCaught = false;
+		try {
+			this.buildIterator().remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue("IllegalStateException not thrown", exCaught);
+	}
+
+	private ListIterator<Integer> buildIterator() {
+		return this.buildTransformationListIterator(this.buildNestedIterator(), this.buildTransformer());
+	}
+
+	private ListIterator<Object> buildIteratorUpcast() {
+		return this.buildTransformationListIteratorUpcast(this.buildNestedIterator(), this.buildTransformerUpcast());
+	}
+
+	private ListIterator<Integer> buildInnerIterator() {
+		return this.buildInnerTransformationListIterator(this.buildNestedIterator());
+	}
+
+	private ListIterator<Integer> buildUnmodifiableIterator() {
+		return this.buildTransformationListIterator(this.buildUnmodifiableNestedIterator(), this.buildTransformer());
+	}
+
+	private ListIterator<Integer> buildTransformationListIterator(ListIterator<String> nestedIterator, Transformer<String, Integer> transformer) {
+		return new TransformationListIterator<String, Integer>(nestedIterator, transformer);
+	}
+
+	private ListIterator<Object> buildTransformationListIteratorUpcast(ListIterator<String> nestedIterator, Transformer<Object, Integer> transformer) {
+		return new TransformationListIterator<Object, Object>(nestedIterator, transformer);
+	}
+
+	private Transformer<String, Integer> buildTransformer() {
+		// transform each string into an integer with a value of the string's length
+		return new Transformer<String, Integer>() {
+			@Override
+			public Integer transform(String next) {
+				return new Integer(next.length());
+			}
+		};
+	}
+
+	private Transformer<Object, Integer> buildTransformerUpcast() {
+		// transform each string into an integer with a value of the string's length
+		return new Transformer<Object, Integer>() {
+			@Override
+			public Integer transform(Object next) {
+				return new Integer(((String) next).length());
+			}
+		};
+	}
+
+	private ListIterator<Integer> buildInnerTransformationListIterator(ListIterator<String> nestedIterator) {
+		// transform each string into an integer with a value of the string's length
+		return new TransformationListIterator<String, Integer>(nestedIterator) {
+			@Override
+			protected Integer transform(String next) {
+				return new Integer(next.length());
+			}
+		};
+	}
+
+	private ListIterator<String> buildNestedIterator() {
+		return this.buildList().listIterator();
+	}
+
+	private ListIterator<String> buildUnmodifiableNestedIterator() {
+		return this.buildUnmodifiableList().listIterator();
+	}
+
+	private List<String> buildList() {
+		List<String> l = new ArrayList<String>();
+		l.add("1");
+		l.add("22");
+		l.add("333");
+		l.add("4444");
+		l.add("55555");
+		l.add("666666");
+		l.add("7777777");
+		l.add("88888888");
+		return l;
+	}
+
+	private List<String> buildUnmodifiableList() {
+		return Collections.unmodifiableList(this.buildList());
+	}
+
+	public void testInvalidTransformationListIterator() {
+		// missing method override
+		Iterator<Integer> iterator = new TransformationListIterator<String, Integer>(this.buildList().listIterator());
+		boolean exCaught = false;
+		try {
+			Integer integer = iterator.next();
+			fail("invalid integer: " + integer);
+		} catch (UnsupportedOperationException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown", exCaught);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/TreeIteratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/TreeIteratorTests.java
new file mode 100644
index 0000000..03939dd
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/iterator/TreeIteratorTests.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.iterator;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+@SuppressWarnings("nls")
+public class TreeIteratorTests extends TestCase {
+	/** this will be populated with all the nodes created for the test */
+	Collection<TreeNode> nodes = new ArrayList<TreeNode>();
+
+	public TreeIteratorTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testHasNext() {
+		Iterator<TreeNode> iterator = this.buildTreeIterator();
+		int i = 0;
+		while (iterator.hasNext()) {
+			iterator.next();
+			i++;
+		}
+		assertEquals(this.nodes.size(), i);
+	}
+
+	public void testNext() {
+		Iterator<TreeNode> iterator = this.buildTreeIterator();
+		while (iterator.hasNext()) {
+			assertTrue("bogus element", this.nodes.contains(iterator.next()));
+		}
+	}
+
+	public void testNoSuchElementException() {
+		Iterator<TreeNode> iterator = this.buildTreeIterator();
+		boolean exCaught = false;
+		while (iterator.hasNext()) {
+			iterator.next();
+		}
+		try {
+			iterator.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown", exCaught);
+	}
+
+	public void testRemove() {
+		Iterator<TreeNode> iterator = this.buildTreeIterator();
+		String parentName = "child 2";
+		String childName = "grandchild 2A";
+		int startSize = this.childrenSize(parentName);
+		while (iterator.hasNext()) {
+			TreeNode node = iterator.next();
+			if (node.getName().equals(childName)) {
+				iterator.remove();
+			}
+		}
+		int endSize = this.childrenSize(parentName);
+		assertEquals(startSize - 1, endSize);
+	}
+
+	private int childrenSize(String nodeName) {
+		for (Iterator<TreeNode> stream = this.nodes.iterator(); stream.hasNext();) {
+			TreeNode node = stream.next();
+			if (node.getName().equals(nodeName)) {
+				return node.childrenSize();
+			}
+		}
+		throw new IllegalArgumentException(nodeName);
+	}
+
+	/**
+	 * build a tree iterator with an explicit midwife
+	 */
+	private Iterator<TreeNode> buildTreeIterator() {
+		return IteratorTools.treeIterator(this.buildTree(), this.buildTransformer());
+	}
+
+	private Transformer<TreeNode, Iterator<? extends TreeNode>> buildTransformer() {
+		return new Transformer<TreeNode, Iterator<? extends TreeNode>>() {
+			@Override
+			public Iterator<? extends TreeNode> transform(TreeNode node) {
+				return node.children();
+			}
+		};
+	}
+
+	private TreeNode buildTree() {
+		TreeNode root = new TreeNode("root");
+		TreeNode child1 = new TreeNode(root, "child 1");
+		@SuppressWarnings("unused")
+		TreeNode grandchild1A = new TreeNode(child1, "grandchild 1A");
+		TreeNode child2 = new TreeNode(root, "child 2");
+		@SuppressWarnings("unused")
+		TreeNode grandchild2A = new TreeNode(child2, "grandchild 2A");
+		TreeNode grandchild2B = new TreeNode(child2, "grandchild 2B");
+		@SuppressWarnings("unused")
+		TreeNode greatGrandchild2B1 = new TreeNode(grandchild2B, "great-grandchild 2B1");
+		@SuppressWarnings("unused")
+		TreeNode greatGrandchild2B2 = new TreeNode(grandchild2B, "great-grandchild 2B2");
+		TreeNode grandchild2C = new TreeNode(child2, "grandchild 2C");
+		@SuppressWarnings("unused")
+		TreeNode greatGrandchild2C1 = new TreeNode(grandchild2C, "great-grandchild 2C1");
+		@SuppressWarnings("unused")
+		TreeNode child3 = new TreeNode(root, "child 3");
+		return root;
+	}
+
+	private class TreeNode {
+		private String name;
+		private Collection<TreeNode> children = new ArrayList<TreeNode>();
+
+		public TreeNode(String name) {
+			super();
+			TreeIteratorTests.this.nodes.add(this); // log node
+			this.name = name;
+		}
+
+		public TreeNode(TreeNode parent, String name) {
+			this(name);
+			parent.addChild(this);
+		}
+
+		public String getName() {
+			return this.name;
+		}
+
+		private void addChild(TreeNode child) {
+			this.children.add(child);
+		}
+
+		public Iterator<TreeNode> children() {
+			return this.children.iterator();
+		}
+
+		public int childrenSize() {
+			return this.children.size();
+		}
+
+		@Override
+		public String toString() {
+			return "TreeNode(" + this.name + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/jdbc/CommonUtilityJDBCTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/jdbc/CommonUtilityJDBCTests.java
new file mode 100644
index 0000000..b71cd42
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/jdbc/CommonUtilityJDBCTests.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.jdbc;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CommonUtilityJDBCTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CommonUtilityJDBCTests.class.getPackage().getName());
+
+		suite.addTestSuite(JDBCTypeTests.class);
+
+		return suite;
+	}
+
+	private CommonUtilityJDBCTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/jdbc/JDBCTypeTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/jdbc/JDBCTypeTests.java
new file mode 100644
index 0000000..60c3659
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/jdbc/JDBCTypeTests.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.jdbc;
+
+import java.sql.Types;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.jdbc.JDBCType;
+
+@SuppressWarnings("nls")
+public class JDBCTypeTests extends TestCase {
+
+	public JDBCTypeTests(String name) {
+		super(name);
+	}
+
+	public void testTypesSize() {
+		assertEquals(Types.class.getDeclaredFields().length, JDBCType.types().length);
+	}
+
+	public void testName() {
+		JDBCType jdbcType;
+		jdbcType = JDBCType.type(Types.VARCHAR);
+		assertEquals("VARCHAR", jdbcType.name());
+
+		jdbcType = JDBCType.type(Types.INTEGER);
+		assertEquals("INTEGER", jdbcType.name());
+	}
+
+	public void testCode() {
+		JDBCType jdbcType;
+		jdbcType = JDBCType.type(Types.VARCHAR);
+		assertEquals(Types.VARCHAR, jdbcType.code());
+
+		jdbcType = JDBCType.type(Types.INTEGER);
+		assertEquals(Types.INTEGER, jdbcType.code());
+	}
+
+	public void testInvalidTypeCode() throws Exception {
+		boolean exCaught = false;
+		try {
+			JDBCType jdbcType = JDBCType.type(55);
+			fail("invalid JDBCType: " + jdbcType);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testInvalidTypeName() throws Exception {
+		boolean exCaught = false;
+		try {
+			JDBCType jdbcType = JDBCType.type("VARCHAR2");
+			fail("invalid JDBCType: " + jdbcType);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/ChangeSupportTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/ChangeSupportTests.java
new file mode 100644
index 0000000..72ff2ed
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/ChangeSupportTests.java
@@ -0,0 +1,4205 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.HashSet;
+import java.util.List;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.ListenerList;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.SystemTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.ChangeSupport;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class ChangeSupportTests
+	extends TestCase
+{
+	TestModel testModel;
+	static final String TEST_TO_STRING = "this is a test";
+
+	ChangeListener changeListener = new Adapter();
+
+	StateChangeEvent stateChangeEvent;
+	boolean stateChangedCalled = false;
+
+	PropertyChangeEvent propertyChangeEvent;
+	boolean propertyChangeCalled = false;
+	static final String PROPERTY_NAME = "propertyName";
+	static final Object OLD_OBJECT_VALUE = new Object();
+	static final Object NEW_OBJECT_VALUE = new Object();
+	static final Integer OLD_INT_VALUE = new Integer(27);
+	static final Boolean OLD_BOOLEAN_VALUE = Boolean.TRUE;
+	static final Integer NEW_INT_VALUE = new Integer(42);
+	static final Boolean NEW_BOOLEAN_VALUE = Boolean.FALSE;
+
+	CollectionEvent collectionEvent;
+	boolean itemsAddedCollectionCalled = false;
+	boolean itemsRemovedCollectionCalled = false;
+	boolean collectionChangedCalled = false;
+	boolean collectionClearedCalled = false;
+	static final String COLLECTION_NAME = "collectionName";
+	static final Object ADDED_OBJECT_VALUE = new Object();
+	static final Object ADDED_OBJECT_VALUE_2 = new Object();
+	static final Object REMOVED_OBJECT_VALUE = new Object();
+	static final int TARGET_INDEX = 7;
+	static final int SOURCE_INDEX = 22;
+
+	ListEvent listEvent;
+	boolean itemsAddedListCalled = false;
+	boolean itemsRemovedListCalled = false;
+	boolean itemsReplacedListCalled = false;
+	boolean itemsMovedListCalled = false;
+	boolean listChangedCalled = false;
+	boolean listClearedCalled = false;
+	static final String LIST_NAME = "listName";
+	static final int ADD_INDEX = 3;
+	static final int REMOVE_INDEX = 5;
+	static final int REPLACE_INDEX = 2;
+
+
+	public ChangeSupportTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.testModel = new TestModel();
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+
+	// ********** general tests **********
+
+	public void testNullSource() {
+		boolean exCaught = false;
+		try {
+			ChangeSupport cs = new ChangeSupport(null);
+			fail("bogus change support: " + cs);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	// ********** state change tests **********
+
+	public void testFireStateChange() {
+		this.stateChangeEvent = null;
+		this.stateChangedCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireStateChange();
+		assertNotNull(this.stateChangeEvent);
+		assertEquals(this.testModel, this.stateChangeEvent.getSource());
+		assertTrue(this.stateChangedCalled);
+	}
+
+	public void testHasAnyStateChangeListeners() {
+		assertTrue(this.testModel.hasNoStateChangeListeners());
+		this.testModel.addChangeListener(this.changeListener);
+		assertTrue(this.testModel.hasAnyStateChangeListeners());
+		this.testModel.removeChangeListener(this.changeListener);
+		assertTrue(this.testModel.hasNoStateChangeListeners());
+	}
+
+	public void testHasAnyStateChangeListenersDuplicate() {
+		assertTrue(this.testModel.hasNoStateChangeListeners());
+		this.testModel.addChangeListener(this.changeListener);
+		boolean exCaught = false;
+		try {
+			this.testModel.addChangeListener(this.changeListener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+		assertTrue(this.testModel.hasAnyStateChangeListeners());
+		this.testModel.removeChangeListener(this.changeListener);
+		assertTrue(this.testModel.hasNoStateChangeListeners());
+
+		exCaught = false;
+		try {
+			this.testModel.removeChangeListener(this.changeListener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(this.testModel.hasNoStateChangeListeners());
+	}
+
+	public void testAddNullStateListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.addStateChangeListener(null);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveBogusStateListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.removeChangeListener(this.changeListener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addPropertyChangeListener("foo", this.changeListener);
+		exCaught = false;
+		try {
+			this.testModel.removeChangeListener(this.changeListener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addChangeListener(this.changeListener);
+		exCaught = false;
+		try {
+			this.testModel.removeStateChangeListener(new Adapter());
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		exCaught = false;
+		try {
+			this.testModel.removeStateChangeListener(new StateChangeAdapter());
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+
+	// ********** property change tests **********
+
+	public void testFirePropertyChangedEvent() {
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedEvent();
+		this.verifyPropertyChangeEvent(OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedEvent();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedEvent();
+		this.verifyPropertyChangeEvent(OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedEvent();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+	}
+
+	public void testFirePropertyChangedEventNoChange() {
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedEventNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedEventNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedEventNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedEventNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+	}
+
+	public void testFirePropertyChangedObjectObject() {
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedObjectObject();
+		this.verifyPropertyChangeEvent(OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedObjectObject();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedObjectObject();
+		this.verifyPropertyChangeEvent(OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedObjectObject();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+	}
+
+	public void testFirePropertyChangedObjectObjectNoChange() {
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedObjectObjectNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedObjectObjectNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedObjectObjectNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedObjectObjectNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+	}
+
+	public void testFirePropertyChangedObject() {
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedObject();
+		this.verifyPropertyChangeEvent(null, NEW_OBJECT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedObject();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedObject();
+		this.verifyPropertyChangeEvent(null, NEW_OBJECT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedObject();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+	}
+
+	public void testFirePropertyChangedObjectNoChange() {
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedObjectNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedObjectNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedObjectNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedObjectNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+	}
+
+	public void testFirePropertyChangedIntInt() {
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedIntInt();
+		this.verifyPropertyChangeEvent(OLD_INT_VALUE, NEW_INT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedIntInt();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedIntInt();
+		this.verifyPropertyChangeEvent(OLD_INT_VALUE, NEW_INT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedIntInt();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+	}
+
+	public void testFirePropertyChangedIntIntNoChange() {
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedIntIntNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedIntIntNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedIntIntNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedIntIntNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+	}
+
+	public void testFirePropertyChangedBooleanBoolean() {
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedBooleanBoolean();
+		this.verifyPropertyChangeEvent(OLD_BOOLEAN_VALUE, NEW_BOOLEAN_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedBooleanBoolean();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedBooleanBoolean();
+		this.verifyPropertyChangeEvent(OLD_BOOLEAN_VALUE, NEW_BOOLEAN_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedBooleanBoolean();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+	}
+
+	public void testFirePropertyChangedBooleanBooleanNoChange() {
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedBooleanBooleanNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFirePropertyChangedBooleanBooleanNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedBooleanBooleanNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		this.testModel.testFirePropertyChangedBooleanBooleanNoChange();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+	}
+
+	public void testHasAnyPropertyChangeListeners() {
+		assertTrue(this.testModel.hasNoPropertyChangeListeners(PROPERTY_NAME));
+		this.testModel.addChangeListener(this.changeListener);
+		assertTrue(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+		this.testModel.removeChangeListener(this.changeListener);
+		assertTrue(this.testModel.hasNoPropertyChangeListeners(PROPERTY_NAME));
+
+		assertTrue(this.testModel.hasNoPropertyChangeListeners(PROPERTY_NAME));
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		assertTrue(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this.changeListener);
+		assertTrue(this.testModel.hasNoPropertyChangeListeners(PROPERTY_NAME));
+	}
+
+	public void testAddNullPropertyListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.addChangeListener(null);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddNullPropertyListenerName() {
+		boolean exCaught = false;
+		try {
+			this.testModel.addPropertyChangeListener("foo", null);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveBogusPropertyListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.removePropertyChangeListener("foo", new PropertyChangeAdapter());
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addCollectionChangeListener("foo", this.changeListener);
+		exCaught = false;
+		try {
+			this.testModel.removePropertyChangeListener("foo", this.changeListener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addPropertyChangeListener("foo", this.changeListener);
+		exCaught = false;
+		try {
+			this.testModel.removePropertyChangeListener("foo", new PropertyChangeAdapter());
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		exCaught = false;
+		try {
+			this.testModel.removePropertyChangeListener("foo", new PropertyChangeAdapter());
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	private void verifyPropertyChangeEvent(Object oldValue, Object newValue) {
+		this.verifyPropertyChangeEvent(this.testModel, oldValue, newValue);
+	}
+
+	private void verifyPropertyChangeEvent(Object source, Object oldValue, Object newValue) {
+		assertNotNull(this.propertyChangeEvent);
+		assertEquals(source, this.propertyChangeEvent.getSource());
+		assertEquals(PROPERTY_NAME, this.propertyChangeEvent.getPropertyName());
+		assertEquals(oldValue, this.propertyChangeEvent.getOldValue());
+		assertEquals(newValue, this.propertyChangeEvent.getNewValue());
+	}
+
+
+	// ********** collection change tests **********
+
+	public void testFireItemsAddedCollectionEvent() {
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedCollectionEvent();
+		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedCollectionEvent();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedCollectionEvent();
+		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedCollectionEvent();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+	}
+
+	public void testFireItemsAddedCollectionEventNoChange() {
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedCollectionEventNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedCollectionEventNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedCollectionEventNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedCollectionEventNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+	}
+
+	public void testFireItemsAddedCollection() {
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedCollection();
+		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedCollection();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedCollection();
+		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedCollection();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+	}
+
+	public void testFireItemsAddedCollectionNoChange() {
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedCollectionNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedCollectionNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedCollectionNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedCollectionNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+	}
+
+	public void testFireItemAddedCollection() {
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemAddedCollection();
+		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemAddedCollection();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemAddedCollection();
+		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemAddedCollection();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+	}
+
+	public void testFireItemsRemovedCollectionEvent() {
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedCollectionEvent();
+		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedCollectionEvent();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedCollectionEvent();
+		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedCollectionEvent();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	public void testFireItemsRemovedCollectionEventNoChange() {
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedCollectionEventNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedCollectionEventNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedCollectionEventNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedCollectionEventNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	public void testFireItemsRemovedCollection() {
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedCollection();
+		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedCollection();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedCollection();
+		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedCollection();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	public void testFireItemsRemovedCollectionNoChange() {
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedCollectionNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedCollectionNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedCollectionNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedCollectionNoChange();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	public void testFireItemRemovedCollection() {
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemRemovedCollection();
+		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemRemovedCollection();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemRemovedCollection();
+		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireItemRemovedCollection();
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	public void testFireCollectionCleared() {
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireCollectionCleared();
+		this.verifyCollectionEvent(null);
+		assertTrue(this.collectionClearedCalled);
+
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireCollectionCleared();
+		assertNull(this.collectionEvent);
+		assertFalse(this.collectionClearedCalled);
+
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireCollectionCleared();
+		this.verifyCollectionEvent(null);
+		assertTrue(this.collectionClearedCalled);
+
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireCollectionCleared();
+		assertNull(this.collectionEvent);
+		assertFalse(this.collectionClearedCalled);
+	}
+
+	public void testFireCollectionChangedEvent() {
+		this.collectionEvent = null;
+		this.collectionChangedCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireCollectionChangedEvent();
+		this.verifyCollectionEvent(null);
+		assertTrue(this.collectionChangedCalled);
+
+		this.collectionEvent = null;
+		this.collectionChangedCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireCollectionChangedEvent();
+		assertNull(this.collectionEvent);
+		assertFalse(this.collectionChangedCalled);
+
+		this.collectionEvent = null;
+		this.collectionChangedCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireCollectionChangedEvent();
+		this.verifyCollectionEvent(null);
+		assertTrue(this.collectionChangedCalled);
+
+		this.collectionEvent = null;
+		this.collectionChangedCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireCollectionChangedEvent();
+		assertNull(this.collectionEvent);
+		assertFalse(this.collectionChangedCalled);
+	}
+
+	public void testFireCollectionChanged() {
+		this.collectionEvent = null;
+		this.collectionChangedCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireCollectionChanged();
+		this.verifyCollectionEvent(null);
+		assertTrue(this.collectionChangedCalled);
+
+		this.collectionEvent = null;
+		this.collectionChangedCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireCollectionChanged();
+		assertNull(this.collectionEvent);
+		assertFalse(this.collectionChangedCalled);
+
+		this.collectionEvent = null;
+		this.collectionChangedCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireCollectionChanged();
+		this.verifyCollectionEvent(null);
+		assertTrue(this.collectionChangedCalled);
+
+		this.collectionEvent = null;
+		this.collectionChangedCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		this.testModel.testFireCollectionChanged();
+		assertNull(this.collectionEvent);
+		assertFalse(this.collectionChangedCalled);
+	}
+
+	public void testAddItemToCollection() {
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertTrue(this.testModel.testAddItemToCollection());
+		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertTrue(this.testModel.testAddItemToCollection());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testAddItemToCollection());
+		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testAddItemToCollection());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+	}
+
+	public void testAddItemToCollectionNoChange() {
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertFalse(this.testModel.testAddItemToCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertFalse(this.testModel.testAddItemToCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testAddItemToCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testAddItemToCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+	}
+
+	public void testAddItemsToCollection() {
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertTrue(this.testModel.testAddItemsToCollection());
+		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertTrue(this.testModel.testAddItemsToCollection());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testAddItemsToCollection());
+		this.verifyCollectionEvent(ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testAddItemsToCollection());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+	}
+
+	public void testAddItemsToCollectionNoChange() {
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertFalse(this.testModel.testAddItemsToCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertFalse(this.testModel.testAddItemsToCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testAddItemsToCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testAddItemsToCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+	}
+
+	public void testAddItemsToCollectionMixed() {
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertTrue(this.testModel.testAddItemsToCollectionMixed());
+		this.verifyCollectionEvent(ADDED_OBJECT_VALUE_2);
+		assertTrue(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertTrue(this.testModel.testAddItemsToCollectionMixed());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testAddItemsToCollectionMixed());
+		this.verifyCollectionEvent(ADDED_OBJECT_VALUE_2);
+		assertTrue(this.itemsAddedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testAddItemsToCollectionMixed());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+	}
+
+	public void testRemoveItemFromCollection() {
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertTrue(this.testModel.testRemoveItemFromCollection());
+		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertTrue(this.testModel.testRemoveItemFromCollection());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testRemoveItemFromCollection());
+		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testRemoveItemFromCollection());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	public void testRemoveItemFromCollectionNoChange() {
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertFalse(this.testModel.testRemoveItemFromCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertFalse(this.testModel.testRemoveItemFromCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testRemoveItemFromCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testRemoveItemFromCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	public void testRemoveItemsFromCollection() {
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertTrue(this.testModel.testRemoveItemsFromCollection());
+		this.verifyCollectionChangeEvent2(REMOVED_OBJECT_VALUE, "foo", "bar");
+		assertTrue(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertTrue(this.testModel.testRemoveItemsFromCollection());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testRemoveItemsFromCollection());
+		this.verifyCollectionChangeEvent2(REMOVED_OBJECT_VALUE, "foo", "bar");
+		assertTrue(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testRemoveItemsFromCollection());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	public void testRemoveItemsFromCollectionNoChange1() {
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange1());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange1());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange1());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange1());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	public void testRemoveItemsFromCollectionNoChange2() {
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange2());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange2());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange2());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange2());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	public void testRemoveItemsFromCollectionNoChange3() {
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange3());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange3());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange3());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testRemoveItemsFromCollectionNoChange3());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	public void testRetainItemsInCollection1() {
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertTrue(this.testModel.testRetainItemsInCollection1());
+		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertTrue(this.testModel.testRetainItemsInCollection1());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testRetainItemsInCollection1());
+		this.verifyCollectionEvent(REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testRetainItemsInCollection1());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	// collection cleared...
+	public void testRetainItemsInCollection2() {
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertTrue(this.testModel.testRetainItemsInCollection2());
+		this.verifyCollectionEvent(null);
+		assertTrue(this.collectionClearedCalled);
+
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertTrue(this.testModel.testRetainItemsInCollection2());
+		assertNull(this.collectionEvent);
+		assertFalse(this.collectionClearedCalled);
+
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testRetainItemsInCollection2());
+		this.verifyCollectionEvent(null);
+		assertTrue(this.collectionClearedCalled);
+
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testRetainItemsInCollection2());
+		assertNull(this.collectionEvent);
+		assertFalse(this.collectionClearedCalled);
+	}
+
+	public void testRetainItemsInCollectionNoChange1() {
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertFalse(this.testModel.testRetainItemsInCollectionNoChange1());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertFalse(this.testModel.testRetainItemsInCollectionNoChange1());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testRetainItemsInCollectionNoChange1());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testRetainItemsInCollectionNoChange1());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	public void testRetainItemsInCollectionNoChange2() {
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertFalse(this.testModel.testRetainItemsInCollectionNoChange2());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertFalse(this.testModel.testRetainItemsInCollectionNoChange2());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testRetainItemsInCollectionNoChange2());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testRetainItemsInCollectionNoChange2());
+		assertNull(this.collectionEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	public void testClearCollection() {
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertTrue(this.testModel.testClearCollection());
+		this.verifyCollectionEvent(null);
+		assertTrue(this.collectionClearedCalled);
+
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertTrue(this.testModel.testClearCollection());
+		assertNull(this.collectionEvent);
+		assertFalse(this.collectionClearedCalled);
+
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testClearCollection());
+		this.verifyCollectionEvent(null);
+		assertTrue(this.collectionClearedCalled);
+
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.testClearCollection());
+		assertNull(this.collectionEvent);
+		assertFalse(this.collectionClearedCalled);
+	}
+
+	public void testClearCollectionNoChange() {
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		assertFalse(this.testModel.testClearCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.collectionClearedCalled);
+
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		assertFalse(this.testModel.testClearCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.collectionClearedCalled);
+
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testClearCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.collectionClearedCalled);
+
+		this.collectionEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertFalse(this.testModel.testClearCollectionNoChange());
+		assertNull(this.collectionEvent);
+		assertFalse(this.collectionClearedCalled);
+	}
+
+	public void testSynchronizeCollection1() {
+		CollectionSynchListener csl = new CollectionSynchListener();
+		this.testModel.addChangeListener(csl);
+		assertTrue(this.testModel.testSynchronizeCollection1());
+		assertTrue(csl.itemsAdded);
+		assertTrue(csl.itemsRemoved);
+		assertFalse(csl.collectionChanged);
+		assertFalse(csl.collectionCleared);
+		assertEquals(2, csl.addedItems.size());
+		assertTrue(CollectionTools.containsAll(csl.addedItems, new Object[] {"joo", "jar"}));
+		assertEquals(2, csl.removedItems.size());
+		assertTrue(CollectionTools.containsAll(csl.removedItems, new Object[] {"foo", "bar"}));
+	}
+
+	public void testSynchronizeCollection2() {
+		CollectionSynchListener csl = new CollectionSynchListener();
+		this.testModel.addChangeListener(csl);
+		assertTrue(this.testModel.testSynchronizeCollection2());
+		assertFalse(csl.itemsAdded);
+		assertFalse(csl.itemsRemoved);
+		assertFalse(csl.collectionChanged);
+		assertTrue(csl.collectionCleared);
+		assertTrue(csl.addedItems.isEmpty());
+		assertTrue(csl.removedItems.isEmpty());
+	}
+
+	public void testSynchronizeCollection3() {
+		CollectionSynchListener csl = new CollectionSynchListener();
+		this.testModel.addChangeListener(csl);
+		assertTrue(this.testModel.testSynchronizeCollection3());
+		assertTrue(csl.itemsAdded);
+		assertFalse(csl.itemsRemoved);
+		assertFalse(csl.collectionChanged);
+		assertFalse(csl.collectionCleared);
+		assertEquals(3, csl.addedItems.size());
+		assertTrue(CollectionTools.containsAll(csl.addedItems, new Object[] {"joo", "jar", "baz"}));
+		assertTrue(csl.removedItems.isEmpty());
+	}
+
+	class CollectionSynchListener extends ChangeAdapter {
+		boolean itemsAdded = false;
+		boolean itemsRemoved = false;
+		boolean collectionChanged = false;
+		boolean collectionCleared = false;
+		Collection<Object> addedItems = new ArrayList<Object>();
+		Collection<Object> removedItems = new ArrayList<Object>();
+		@Override
+		public void collectionChanged(CollectionChangeEvent event) {
+			this.collectionChanged = true;
+		}
+		@Override
+		public void collectionCleared(CollectionClearEvent event) {
+			this.collectionCleared = true;
+		}
+		@Override
+		public void itemsAdded(CollectionAddEvent event) {
+			this.itemsAdded = true;
+			CollectionTools.addAll(this.addedItems, event.getItems());
+		}
+		@Override
+		public void itemsRemoved(CollectionRemoveEvent event) {
+			this.itemsRemoved = true;
+			CollectionTools.addAll(this.removedItems, event.getItems());
+		}
+	}
+
+	public void testHasAnyCollectionChangeListeners() {
+		assertTrue(this.testModel.hasNoCollectionChangeListeners(COLLECTION_NAME));
+		this.testModel.addChangeListener(this.changeListener);
+		assertTrue(this.testModel.hasAnyCollectionChangeListeners(COLLECTION_NAME));
+		this.testModel.removeChangeListener(this.changeListener);
+		assertTrue(this.testModel.hasNoCollectionChangeListeners(COLLECTION_NAME));
+
+		assertTrue(this.testModel.hasNoCollectionChangeListeners(COLLECTION_NAME));
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.hasAnyCollectionChangeListeners(COLLECTION_NAME));
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this.changeListener);
+		assertTrue(this.testModel.hasNoCollectionChangeListeners(COLLECTION_NAME));
+	}
+
+	public void testAddNullCollectionListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.addCollectionChangeListener("foo", null);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveBogusCollectionListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.removeCollectionChangeListener("foo", this.changeListener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addPropertyChangeListener("foo", this.changeListener);
+		exCaught = false;
+		try {
+			this.testModel.removeCollectionChangeListener("foo", this.changeListener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addCollectionChangeListener("foo", this.changeListener);
+		exCaught = false;
+		try {
+			this.testModel.removeCollectionChangeListener("foo", new CollectionChangeAdapter());
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		exCaught = false;
+		try {
+			this.testModel.removeCollectionChangeListener("foo", new CollectionChangeAdapter());
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	private void verifyCollectionEvent(Object item) {
+		assertNotNull(this.collectionEvent);
+		assertEquals(this.testModel, this.collectionEvent.getSource());
+		assertEquals(COLLECTION_NAME, this.collectionEvent.getCollectionName());
+		if (item != null) {
+			assertEquals(item, this.getCollectionEventItems().iterator().next());
+		}
+	}
+
+	private Iterable<?> getCollectionEventItems() {
+		if (this.collectionEvent instanceof CollectionAddEvent) {
+			return ((CollectionAddEvent) this.collectionEvent).getItems();
+		} else if (this.collectionEvent instanceof CollectionRemoveEvent) {
+			return ((CollectionRemoveEvent) this.collectionEvent).getItems();
+		}
+		throw new IllegalStateException();
+	}
+
+	private void verifyCollectionChangeEvent2(Object... items) {
+		assertNotNull(this.collectionEvent);
+		assertEquals(this.testModel, this.collectionEvent.getSource());
+		assertEquals(COLLECTION_NAME, this.collectionEvent.getCollectionName());
+		assertEquals(items.length, this.getCollectionEventItemsSize());
+		for (Object item : items) {
+			assertTrue(IterableTools.contains(this.getCollectionEventItems(), item));
+		}
+	}
+
+	private int getCollectionEventItemsSize() {
+		if (this.collectionEvent instanceof CollectionAddEvent) {
+			return ((CollectionAddEvent) this.collectionEvent).getItemsSize();
+		} else if (this.collectionEvent instanceof CollectionRemoveEvent) {
+			return ((CollectionRemoveEvent) this.collectionEvent).getItemsSize();
+		}
+		throw new IllegalStateException();
+	}
+
+
+	// ********** list change tests **********
+
+	public void testFireItemsAddedListEvent() {
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedListEvent();
+		this.verifyListAddEvent(ADD_INDEX, ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedListEvent();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedListEvent();
+		this.verifyListAddEvent(ADD_INDEX, ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedListEvent();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+	}
+
+	public void testFireItemsAddedListEventNoChange() {
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+	}
+
+	public void testFireItemsAddedList() {
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedList();
+		this.verifyListAddEvent(ADD_INDEX, ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedList();
+		this.verifyListAddEvent(ADD_INDEX, ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+	}
+
+	public void testFireItemsAddedListNoChange() {
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsAddedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsAddedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+	}
+
+	public void testFireItemAddedList() {
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemAddedList();
+		this.verifyListAddEvent(ADD_INDEX, ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemAddedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemAddedList();
+		this.verifyListAddEvent(ADD_INDEX, ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemAddedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+	}
+
+	public void testFireItemsRemovedListEvent() {
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedListEvent();
+		this.verifyListRemoveEvent(REMOVE_INDEX, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedListEvent();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedListEvent();
+		this.verifyListRemoveEvent(REMOVE_INDEX, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedListEvent();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+	}
+
+	public void testFireItemsRemovedListEventNoChange() {
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+	}
+
+	public void testFireItemsRemovedList() {
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedList();
+		this.verifyListRemoveEvent(REMOVE_INDEX, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedList();
+		this.verifyListRemoveEvent(REMOVE_INDEX, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+	}
+
+	public void testFireItemsRemovedListNoChange() {
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsRemovedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsRemovedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+	}
+
+	public void testFireItemRemovedList() {
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemRemovedList();
+		this.verifyListRemoveEvent(REMOVE_INDEX, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemRemovedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemRemovedList();
+		this.verifyListRemoveEvent(REMOVE_INDEX, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemRemovedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+	}
+
+	public void testFireItemsReplacedListEvent() {
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsReplacedListEvent();
+		this.verifyListReplaceEvent(REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsReplacedListEvent();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsReplacedListEvent();
+		this.verifyListReplaceEvent(REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsReplacedListEvent();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+	}
+
+	public void testFireItemsReplacedListEventNoChange() {
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsReplacedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsReplacedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsReplacedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsReplacedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+	}
+
+	public void testFireItemsReplacedList() {
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsReplacedList();
+		this.verifyListReplaceEvent(REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsReplacedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsReplacedList();
+		this.verifyListReplaceEvent(REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsReplacedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+	}
+
+	public void testFireItemsReplacedListNoChange() {
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsReplacedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsReplacedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsReplacedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsReplacedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+	}
+
+	public void testFireItemReplacedList() {
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemReplacedList();
+		this.verifyListReplaceEvent(REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemReplacedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemReplacedList();
+		this.verifyListReplaceEvent(REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemReplacedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+	}
+
+	public void testFireItemsMovedListEvent() {
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsMovedListEvent();
+		this.verifyListMoveEvent(TARGET_INDEX, SOURCE_INDEX);
+		assertTrue(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsMovedListEvent();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsMovedListEvent();
+		this.verifyListMoveEvent(TARGET_INDEX, SOURCE_INDEX);
+		assertTrue(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsMovedListEvent();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+	}
+
+	public void testFireItemsMovedListEventNoChange() {
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsMovedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsMovedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsMovedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsMovedListEventNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+	}
+
+	public void testFireItemsMovedList() {
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsMovedList();
+		this.verifyListMoveEvent(TARGET_INDEX, SOURCE_INDEX);
+		assertTrue(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsMovedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsMovedList();
+		this.verifyListMoveEvent(TARGET_INDEX, SOURCE_INDEX);
+		assertTrue(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsMovedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+	}
+
+	public void testFireItemsMovedListNoChange() {
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemsMovedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemsMovedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsMovedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemsMovedListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+	}
+
+	public void testFireItemMovedList() {
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireItemMovedList();
+		this.verifyListMoveEvent(TARGET_INDEX, SOURCE_INDEX);
+		assertTrue(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireItemMovedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemMovedList();
+		this.verifyListMoveEvent(TARGET_INDEX, SOURCE_INDEX);
+		assertTrue(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireItemMovedList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+	}
+
+	public void testFireListClearedEvent() {
+		this.listEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireListClearedEvent();
+		this.verifyListClearEvent();
+		assertTrue(this.listClearedCalled);
+
+		this.listEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireListClearedEvent();
+		assertNull(this.listEvent);
+		assertFalse(this.listClearedCalled);
+
+		this.listEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireListClearedEvent();
+		this.verifyListClearEvent();
+		assertTrue(this.listClearedCalled);
+
+		this.listEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireListClearedEvent();
+		assertNull(this.listEvent);
+		assertFalse(this.listClearedCalled);
+	}
+
+	public void testFireListCleared() {
+		this.listEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireListCleared();
+		this.verifyListClearEvent();
+		assertTrue(this.listClearedCalled);
+
+		this.listEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireListCleared();
+		assertNull(this.listEvent);
+		assertFalse(this.listClearedCalled);
+
+		this.listEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireListCleared();
+		this.verifyListClearEvent();
+		assertTrue(this.listClearedCalled);
+
+		this.listEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireListCleared();
+		assertNull(this.listEvent);
+		assertFalse(this.listClearedCalled);
+	}
+
+	public void testFireListChangedEvent() {
+		this.listEvent = null;
+		this.listChangedCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireListChangedEvent();
+		this.verifyListChangeEvent();
+		assertTrue(this.listChangedCalled);
+
+		this.listEvent = null;
+		this.listChangedCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireListChangedEvent();
+		assertNull(this.listEvent);
+		assertFalse(this.listChangedCalled);
+
+		this.listEvent = null;
+		this.listChangedCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireListChangedEvent();
+		this.verifyListChangeEvent();
+		assertTrue(this.listChangedCalled);
+
+		this.listEvent = null;
+		this.listChangedCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireListChangedEvent();
+		assertNull(this.listEvent);
+		assertFalse(this.listChangedCalled);
+	}
+
+	public void testFireListChanged() {
+		this.listEvent = null;
+		this.listChangedCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testFireListChanged();
+		this.verifyListChangeEvent();
+		assertTrue(this.listChangedCalled);
+
+		this.listEvent = null;
+		this.listChangedCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testFireListChanged();
+		assertNull(this.listEvent);
+		assertFalse(this.listChangedCalled);
+
+		this.listEvent = null;
+		this.listChangedCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireListChanged();
+		this.verifyListChangeEvent();
+		assertTrue(this.listChangedCalled);
+
+		this.listEvent = null;
+		this.listChangedCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testFireListChanged();
+		assertNull(this.listEvent);
+		assertFalse(this.listChangedCalled);
+	}
+
+	public void testAddItemToListIndex() {
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testAddItemToListIndex();
+		this.verifyListAddEvent(2, "joo");
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testAddItemToListIndex();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testAddItemToListIndex();
+		this.verifyListAddEvent(2, "joo");
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testAddItemToListIndex();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+	}
+
+	public void testAddItemToList() {
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testAddItemToList();
+		this.verifyListAddEvent(3, "joo");
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testAddItemToList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testAddItemToList();
+		this.verifyListAddEvent(3, "joo");
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testAddItemToList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+	}
+
+	public void testAddItemsToListIndex() {
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testAddItemsToListIndex();
+		this.verifyListAddEvent(2, "joo");
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testAddItemsToListIndex();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testAddItemsToListIndex();
+		this.verifyListAddEvent(2, "joo");
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testAddItemsToListIndex();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+	}
+
+	public void testAddItemsToListIndexNoChange() {
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testAddItemsToListIndexNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testAddItemsToListIndexNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testAddItemsToListIndexNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testAddItemsToListIndexNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+	}
+
+	public void testAddItemsToList() {
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testAddItemsToList();
+		this.verifyListAddEvent(3, "joo");
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testAddItemsToList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testAddItemsToList();
+		this.verifyListAddEvent(3, "joo");
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testAddItemsToList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+	}
+
+	public void testAddItemsToListNoChange() {
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testAddItemsToListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testAddItemsToListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testAddItemsToListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testAddItemsToListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsAddedListCalled);
+	}
+
+	public void testRemoveItemFromListIndex() {
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testRemoveItemFromListIndex();
+		this.verifyListRemoveEvent(1, "bar");
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testRemoveItemFromListIndex();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testRemoveItemFromListIndex();
+		this.verifyListRemoveEvent(1, "bar");
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testRemoveItemFromListIndex();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+	}
+
+	public void testRemoveItemFromList() {
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testRemoveItemFromList();
+		this.verifyListRemoveEvent(1, "bar");
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testRemoveItemFromList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testRemoveItemFromList();
+		this.verifyListRemoveEvent(1, "bar");
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testRemoveItemFromList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+	}
+
+	public void testRemoveItemsFromListIndex() {
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testRemoveItemsFromListIndex();
+		this.verifyListRemoveEvent(1, "bar");
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testRemoveItemsFromListIndex();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testRemoveItemsFromListIndex();
+		this.verifyListRemoveEvent(1, "bar");
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testRemoveItemsFromListIndex();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+	}
+
+	public void testRemoveItemsFromListIndexNoChange() {
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testRemoveItemsFromListIndexNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testRemoveItemsFromListIndexNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testRemoveItemsFromListIndexNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testRemoveItemsFromListIndexNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+	}
+
+	public void testRemoveItemsFromList() {
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testRemoveItemsFromList();
+		this.verifyListRemoveEvent(1, "bar");
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testRemoveItemsFromList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testRemoveItemsFromList();
+		this.verifyListRemoveEvent(1, "bar");
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testRemoveItemsFromList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+	}
+
+	public void testRemoveItemsFromListNoChange() {
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testRemoveItemsFromListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testRemoveItemsFromListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testRemoveItemsFromListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testRemoveItemsFromListNoChange();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+	}
+
+	public void testRetainItemsInList() {
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testRetainItemsInList();
+		this.verifyListRemoveEvent(0, "foo");
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testRetainItemsInList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testRetainItemsInList();
+		this.verifyListRemoveEvent(0, "foo");
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testRetainItemsInList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsRemovedListCalled);
+	}
+
+	public void testReplaceItemInList() {
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testReplaceItemInList();
+		this.verifyListReplaceEvent(1, "xxx", "bar");
+		assertTrue(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testReplaceItemInList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testReplaceItemInList();
+		this.verifyListReplaceEvent(1, "xxx", "bar");
+		assertTrue(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testReplaceItemInList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+	}
+
+	public void testSetItemsInList() {
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testSetItemsInList();
+		this.verifyListReplaceEvent(1, "xxx", "bar");
+		assertTrue(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testSetItemsInList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testSetItemsInList();
+		this.verifyListReplaceEvent(1, "xxx", "bar");
+		assertTrue(this.itemsReplacedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testSetItemsInList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+	}
+
+	public void testMoveItemsInList() {
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testMoveItemsInList();
+		this.verifyListMoveEvent(2, 4, 2);
+		assertTrue(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testMoveItemsInList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testMoveItemsInList();
+		this.verifyListMoveEvent(2, 4, 2);
+		assertTrue(this.itemsMovedListCalled);
+
+		this.listEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testMoveItemsInList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsMovedListCalled);
+	}
+
+	public void testClearList() {
+		this.listEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testClearList();
+		this.verifyListClearEvent();
+		assertTrue(this.listClearedCalled);
+
+		this.listEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testClearList();
+		assertNull(this.listEvent);
+		assertFalse(this.listClearedCalled);
+
+		this.listEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testClearList();
+		this.verifyListClearEvent();
+		assertTrue(this.listClearedCalled);
+
+		this.listEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testClearList();
+		assertNull(this.listEvent);
+		assertFalse(this.listClearedCalled);
+	}
+
+	public void testSynchronizeList() {
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addChangeListener(this.changeListener);
+		this.testModel.testSynchronizeList();
+		assertNotNull(this.listEvent);
+		assertTrue(this.itemsReplacedListCalled);
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeChangeListener(this.changeListener);
+		this.testModel.testSynchronizeList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testSynchronizeList();
+		assertNotNull(this.listEvent);
+		assertTrue(this.itemsReplacedListCalled);
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		this.testModel.testSynchronizeList();
+		assertNull(this.listEvent);
+		assertFalse(this.itemsReplacedListCalled);
+		assertFalse(this.itemsRemovedListCalled);
+	}
+
+	public void testHasAnyListChangeListeners() {
+		assertTrue(this.testModel.hasNoListChangeListeners(LIST_NAME));
+		this.testModel.addChangeListener(this.changeListener);
+		assertTrue(this.testModel.hasAnyListChangeListeners(LIST_NAME));
+		this.testModel.removeChangeListener(this.changeListener);
+		assertTrue(this.testModel.hasNoListChangeListeners(LIST_NAME));
+
+		assertTrue(this.testModel.hasNoListChangeListeners(LIST_NAME));
+		this.testModel.addListChangeListener(LIST_NAME, this.changeListener);
+		assertTrue(this.testModel.hasAnyListChangeListeners(LIST_NAME));
+		this.testModel.removeListChangeListener(LIST_NAME, this.changeListener);
+		assertTrue(this.testModel.hasNoListChangeListeners(LIST_NAME));
+	}
+
+	public void testAddNullListListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.addListChangeListener("foo", null);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveBogusListListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.removeListChangeListener("foo", this.changeListener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addPropertyChangeListener("foo", this.changeListener);
+		exCaught = false;
+		try {
+			this.testModel.removeListChangeListener("foo", this.changeListener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addListChangeListener("foo", this.changeListener);
+		exCaught = false;
+		try {
+			this.testModel.removeListChangeListener("foo", new ListChangeAdapter());
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		exCaught = false;
+		try {
+			this.testModel.removeListChangeListener("foo", new ListChangeAdapter());
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	private void verifyListAddEvent(int index, Object item) {
+		assertNotNull(this.listEvent);
+		assertEquals(this.testModel, this.listEvent.getSource());
+		assertEquals(LIST_NAME, this.listEvent.getListName());
+		assertEquals(index, ((ListAddEvent) this.listEvent).getIndex());
+		assertEquals(item, ((ListAddEvent) this.listEvent).getItems().iterator().next());
+	}
+
+	private void verifyListRemoveEvent(int index, Object item) {
+		assertNotNull(this.listEvent);
+		assertEquals(this.testModel, this.listEvent.getSource());
+		assertEquals(LIST_NAME, this.listEvent.getListName());
+		assertEquals(index, ((ListRemoveEvent) this.listEvent).getIndex());
+		assertEquals(item, ((ListRemoveEvent) this.listEvent).getItems().iterator().next());
+	}
+
+	private void verifyListReplaceEvent(int index, Object newItem, Object oldItem) {
+		assertNotNull(this.listEvent);
+		assertEquals(this.testModel, this.listEvent.getSource());
+		assertEquals(LIST_NAME, this.listEvent.getListName());
+		assertEquals(index, ((ListReplaceEvent) this.listEvent).getIndex());
+		assertEquals(newItem, ((ListReplaceEvent) this.listEvent).getNewItems().iterator().next());
+		assertEquals(oldItem, ((ListReplaceEvent) this.listEvent).getOldItems().iterator().next());
+	}
+
+	private void verifyListMoveEvent(int targetIndex, int sourceIndex) {
+		this.verifyListMoveEvent(targetIndex, sourceIndex, 1);
+	}
+
+	private void verifyListMoveEvent(int targetIndex, int sourceIndex, int length) {
+		assertNotNull(this.listEvent);
+		assertEquals(this.testModel, this.listEvent.getSource());
+		assertEquals(LIST_NAME, this.listEvent.getListName());
+		assertEquals(targetIndex, ((ListMoveEvent) this.listEvent).getTargetIndex());
+		assertEquals(sourceIndex, ((ListMoveEvent) this.listEvent).getSourceIndex());
+		assertEquals(length, ((ListMoveEvent) this.listEvent).getLength());
+	}
+
+	private void verifyListClearEvent() {
+		assertNotNull(this.listEvent);
+		assertEquals(this.testModel, this.listEvent.getSource());
+		assertEquals(LIST_NAME, this.listEvent.getListName());
+		assertEquals(ListClearEvent.class, this.listEvent.getClass());
+	}
+
+	private void verifyListChangeEvent() {
+		assertNotNull(this.listEvent);
+		assertEquals(this.testModel, this.listEvent.getSource());
+		assertEquals(LIST_NAME, this.listEvent.getListName());
+		assertEquals(ListChangeEvent.class, this.listEvent.getClass());
+	}
+
+
+	// ********** convenience method tests **********
+
+	public void testElementsAreEqual() {
+		Collection<String> c1 = new ArrayList<String>();
+		c1.add("foo");
+		c1.add("bar");
+		c1.add("baz");
+		Collection<String> c2 = new ArrayList<String>();
+		c2.add("foo");
+		c2.add("bar");
+		c2.add("baz");
+		assertTrue(this.testModel.testElementsAreEqual(c1, c2));
+	}
+
+	public void testElementsAreDifferent() {
+		Collection<String> c1 = new ArrayList<String>();
+		c1.add("foo");
+		c1.add("bar");
+		c1.add("baz");
+		Collection<String> c2 = new ArrayList<String>();
+		c2.add("baz");
+		c2.add("bar");
+		c2.add("foo");
+		assertTrue(this.testModel.testElementsAreDifferent(c1, c2));
+	}
+
+
+	// ********** AbstractModel tests **********
+
+	public void testAbstractModelValuesAreEqual1() {
+		assertTrue(this.testModel.testValuesAreEqual(null, null));
+	}
+
+	public void testAbstractModelValuesAreEqual2() {
+		assertTrue(this.testModel.testValuesAreEqual("foo", "foo"));
+	}
+
+	public void testAbstractModelValuesAreEqual3() {
+		assertFalse(this.testModel.testValuesAreEqual("foo", null));
+	}
+
+	public void testAbstractModelValuesAreEqual4() {
+		assertFalse(this.testModel.testValuesAreEqual(null, "foo"));
+	}
+
+	public void testAbstractModelValuesAreEqual5() {
+		assertFalse(this.testModel.testValuesAreEqual("bar", "foo"));
+	}
+
+	public void testAbstractModelValuesAreDifferent1() {
+		assertFalse(this.testModel.testValuesAreDifferent(null, null));
+	}
+
+	public void testAbstractModelValuesAreDifferent2() {
+		assertFalse(this.testModel.testValuesAreDifferent("foo", "foo"));
+	}
+
+	public void testAbstractModelValuesAreDifferent3() {
+		assertTrue(this.testModel.testValuesAreDifferent("foo", null));
+	}
+
+	public void testAbstractModelValuesAreDifferent4() {
+		assertTrue(this.testModel.testValuesAreDifferent(null, "foo"));
+	}
+
+	public void testAbstractModelValuesAreDifferent5() {
+		assertTrue(this.testModel.testValuesAreDifferent("bar", "foo"));
+	}
+
+	public void testAbstractModelAttributeValueHasChanged1() {
+		assertFalse(this.testModel.testAttributeValueHasChanged(null, null));
+	}
+
+	public void testAbstractModelAttributeValueHasChanged2() {
+		assertFalse(this.testModel.testAttributeValueHasChanged("foo", "foo"));
+	}
+
+	public void testAbstractModelAttributeValueHasChanged3() {
+		assertTrue(this.testModel.testAttributeValueHasChanged("foo", null));
+	}
+
+	public void testAbstractModelAttributeValueHasChanged4() {
+		assertTrue(this.testModel.testAttributeValueHasChanged(null, "foo"));
+	}
+
+	public void testAbstractModelAttributeValueHasChanged5() {
+		assertTrue(this.testModel.testAttributeValueHasChanged("bar", "foo"));
+	}
+
+	public void testAbstractModelAttributeValueHasNotChanged1() {
+		assertTrue(this.testModel.testAttributeValueHasNotChanged(null, null));
+	}
+
+	public void testAbstractModelAttributeValueHasNotChanged2() {
+		assertTrue(this.testModel.testAttributeValueHasNotChanged("foo", "foo"));
+	}
+
+	public void testAbstractModelAttributeValueHasNotChanged3() {
+		assertFalse(this.testModel.testAttributeValueHasNotChanged("foo", null));
+	}
+
+	public void testAbstractModelAttributeValueHasNotChanged4() {
+		assertFalse(this.testModel.testAttributeValueHasNotChanged(null, "foo"));
+	}
+
+	public void testAbstractModelAttributeValueHasNotChanged5() {
+		assertFalse(this.testModel.testAttributeValueHasNotChanged("bar", "foo"));
+	}
+
+	public void testAbstractModelClone() {
+		assertFalse(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+		this.testModel.addChangeListener(this.changeListener);
+		assertTrue(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+
+		// verify that the clone does not have any listeners
+		TestModel clone = this.testModel.clone();
+		assertFalse(clone.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+		clone.addChangeListener(this.changeListener);
+		assertTrue(clone.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+		// check original
+		assertTrue(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+
+		// now test events fired by original
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.testFirePropertyChangedObjectObject();
+		this.verifyPropertyChangeEvent(OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		// now test events fired by clone
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		clone.testFirePropertyChangedObjectObject();
+		this.verifyPropertyChangeEvent(clone, OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+	}
+
+	public void testAbstractModelToString() {
+		assertTrue(this.testModel.toString().contains('(' + TEST_TO_STRING + ')'));
+	}
+
+
+	// ********** listener implementations **********
+
+	class Adapter implements ChangeListener {
+		@Override
+		public void stateChanged(StateChangeEvent e) {
+			ChangeSupportTests.this.stateChangedCalled = true;
+			ChangeSupportTests.this.stateChangeEvent = e;
+		}
+
+		@Override
+		public void propertyChanged(PropertyChangeEvent e) {
+			ChangeSupportTests.this.propertyChangeCalled = true;
+			ChangeSupportTests.this.propertyChangeEvent = e;
+		}
+
+
+		@Override
+		public void itemsAdded(CollectionAddEvent e) {
+			ChangeSupportTests.this.itemsAddedCollectionCalled = true;
+			ChangeSupportTests.this.collectionEvent = e;
+		}
+		@Override
+		public void itemsRemoved(CollectionRemoveEvent e) {
+			ChangeSupportTests.this.itemsRemovedCollectionCalled = true;
+			ChangeSupportTests.this.collectionEvent = e;
+		}
+		@Override
+		public void collectionCleared(CollectionClearEvent e) {
+			ChangeSupportTests.this.collectionClearedCalled = true;
+			ChangeSupportTests.this.collectionEvent = e;
+		}
+		@Override
+		public void collectionChanged(CollectionChangeEvent e) {
+			ChangeSupportTests.this.collectionChangedCalled = true;
+			ChangeSupportTests.this.collectionEvent = e;
+		}
+
+		@Override
+		public void itemsAdded(ListAddEvent e) {
+			ChangeSupportTests.this.itemsAddedListCalled = true;
+			ChangeSupportTests.this.listEvent = e;
+		}
+		@Override
+		public void itemsRemoved(ListRemoveEvent e) {
+			ChangeSupportTests.this.itemsRemovedListCalled = true;
+			ChangeSupportTests.this.listEvent = e;
+		}
+		@Override
+		public void itemsReplaced(ListReplaceEvent e) {
+			ChangeSupportTests.this.itemsReplacedListCalled = true;
+			ChangeSupportTests.this.listEvent = e;
+		}
+		@Override
+		public void itemsMoved(ListMoveEvent e) {
+			ChangeSupportTests.this.itemsMovedListCalled = true;
+			ChangeSupportTests.this.listEvent = e;
+		}
+		@Override
+		public void listCleared(ListClearEvent e) {
+			ChangeSupportTests.this.listClearedCalled = true;
+			ChangeSupportTests.this.listEvent = e;
+		}
+		@Override
+		public void listChanged(ListChangeEvent e) {
+			ChangeSupportTests.this.listChangedCalled = true;
+			ChangeSupportTests.this.listEvent = e;
+		}
+	}
+
+
+	// ********** inner class **********
+
+	private static class TestModel extends AbstractModel implements Cloneable {
+		TestModel() {
+			super();
+		}
+
+		// ***** state
+		public void testFireStateChange() {
+			this.fireStateChanged();
+		}
+
+		// ***** property
+		public void testFirePropertyChangedEvent() {
+			this.firePropertyChanged(new PropertyChangeEvent(this, PROPERTY_NAME, OLD_OBJECT_VALUE, NEW_OBJECT_VALUE));
+		}
+
+		public void testFirePropertyChangedEventNoChange() {
+			this.firePropertyChanged(new PropertyChangeEvent(this, PROPERTY_NAME, OLD_OBJECT_VALUE, OLD_OBJECT_VALUE));
+		}
+
+		public void testFirePropertyChangedObjectObject() {
+			this.firePropertyChanged(PROPERTY_NAME, OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
+		}
+
+		public void testFirePropertyChangedObjectObjectNoChange() {
+			this.firePropertyChanged(PROPERTY_NAME, OLD_OBJECT_VALUE, OLD_OBJECT_VALUE);
+		}
+
+		public void testFirePropertyChangedObject() {
+			this.firePropertyChanged(PROPERTY_NAME, NEW_OBJECT_VALUE);
+		}
+
+		public void testFirePropertyChangedObjectNoChange() {
+			this.firePropertyChanged(PROPERTY_NAME, null);
+		}
+
+		public void testFirePropertyChangedIntInt() {
+			this.firePropertyChanged(PROPERTY_NAME, OLD_INT_VALUE.intValue(), NEW_INT_VALUE.intValue());
+		}
+
+		public void testFirePropertyChangedIntIntNoChange() {
+			this.firePropertyChanged(PROPERTY_NAME, OLD_INT_VALUE.intValue(), OLD_INT_VALUE.intValue());
+		}
+
+		public void testFirePropertyChangedBooleanBoolean() {
+			this.firePropertyChanged(PROPERTY_NAME, OLD_BOOLEAN_VALUE.booleanValue(), NEW_BOOLEAN_VALUE.booleanValue());
+		}
+
+		public void testFirePropertyChangedBooleanBooleanNoChange() {
+			this.firePropertyChanged(PROPERTY_NAME, OLD_BOOLEAN_VALUE.booleanValue(), OLD_BOOLEAN_VALUE.booleanValue());
+		}
+
+		// ***** collection
+		public void testFireItemsAddedCollectionEvent() {
+			this.fireItemsAdded(new CollectionAddEvent(this, COLLECTION_NAME, ADDED_OBJECT_VALUE));
+		}
+
+		public void testFireItemsAddedCollectionEventNoChange() {
+			this.fireItemsAdded(new CollectionAddEvent(this, COLLECTION_NAME, Collections.emptySet()));
+		}
+
+		public void testFireItemsAddedCollection() {
+			this.fireItemsAdded(COLLECTION_NAME, Collections.singleton(ADDED_OBJECT_VALUE));
+		}
+
+		public void testFireItemsAddedCollectionNoChange() {
+			this.fireItemsAdded(COLLECTION_NAME, Collections.emptySet());
+		}
+
+		public void testFireItemAddedCollection() {
+			this.fireItemAdded(COLLECTION_NAME, ADDED_OBJECT_VALUE);
+		}
+
+		public void testFireItemsRemovedCollectionEvent() {
+			this.fireItemsRemoved(new CollectionRemoveEvent(this, COLLECTION_NAME, REMOVED_OBJECT_VALUE));
+		}
+
+		public void testFireItemsRemovedCollectionEventNoChange() {
+			this.fireItemsRemoved(new CollectionRemoveEvent(this, COLLECTION_NAME, Collections.emptySet()));
+		}
+
+		public void testFireItemsRemovedCollection() {
+			this.fireItemsRemoved(COLLECTION_NAME, Collections.singleton(REMOVED_OBJECT_VALUE));
+		}
+
+		public void testFireItemsRemovedCollectionNoChange() {
+			this.fireItemsRemoved(COLLECTION_NAME, Collections.emptySet());
+		}
+
+		public void testFireItemRemovedCollection() {
+			this.fireItemRemoved(COLLECTION_NAME, REMOVED_OBJECT_VALUE);
+		}
+
+		public void testFireCollectionCleared() {
+			this.fireCollectionCleared(COLLECTION_NAME);
+		}
+
+		public void testFireCollectionChangedEvent() {
+			this.fireCollectionChanged(new CollectionChangeEvent(this, COLLECTION_NAME, Collections.emptySet()));
+		}
+
+		public void testFireCollectionChanged() {
+			this.fireCollectionChanged(COLLECTION_NAME, Collections.emptySet());
+		}
+
+		public boolean testAddItemToCollection() {
+			return this.addItemToCollection(ADDED_OBJECT_VALUE, new ArrayList<Object>(), COLLECTION_NAME);
+		}
+
+		public boolean testAddItemToCollectionNoChange() {
+			Collection<Object> collection = new HashSet<Object>();
+			collection.add(ADDED_OBJECT_VALUE);
+			return this.addItemToCollection(ADDED_OBJECT_VALUE, collection, COLLECTION_NAME);
+		}
+
+		public boolean testAddItemsToCollection() {
+			return this.addItemsToCollection(Collections.singleton(ADDED_OBJECT_VALUE), new ArrayList<Object>(), COLLECTION_NAME);
+		}
+
+		public boolean testAddItemsToCollectionNoChange() {
+			Collection<Object> collection = new HashSet<Object>();
+			collection.add(ADDED_OBJECT_VALUE);
+			return this.addItemsToCollection(Collections.singleton(ADDED_OBJECT_VALUE), collection, COLLECTION_NAME);
+		}
+
+		public boolean testAddItemsToCollectionMixed() {
+			Collection<Object> collection = new HashSet<Object>();
+			collection.add(ADDED_OBJECT_VALUE);
+			return this.addItemsToCollection(new Object[] {ADDED_OBJECT_VALUE, ADDED_OBJECT_VALUE_2}, collection, COLLECTION_NAME);
+		}
+
+		public boolean testRemoveItemFromCollection() {
+			Collection<Object> collection = new HashSet<Object>();
+			collection.add(REMOVED_OBJECT_VALUE);
+			return this.removeItemFromCollection(REMOVED_OBJECT_VALUE, collection, COLLECTION_NAME);
+		}
+
+		public boolean testRemoveItemFromCollectionNoChange() {
+			Collection<Object> collection = new HashSet<Object>();
+			collection.add(REMOVED_OBJECT_VALUE);
+			return this.removeItemFromCollection("foo", collection, COLLECTION_NAME);
+		}
+
+		public boolean testRemoveItemsFromCollection() {
+			Collection<Object> collection = new HashSet<Object>();
+			collection.add(REMOVED_OBJECT_VALUE);
+			collection.add("foo");
+			collection.add("bar");
+			return this.removeItemsFromCollection(new Object[] {"foo", "bar", REMOVED_OBJECT_VALUE}, collection, COLLECTION_NAME);
+		}
+
+		public boolean testRemoveItemsFromCollectionNoChange1() {
+			Collection<Object> collection = new HashSet<Object>();
+			collection.add(REMOVED_OBJECT_VALUE);
+			return this.removeItemsFromCollection(Collections.emptySet(), collection, COLLECTION_NAME);
+		}
+
+		public boolean testRemoveItemsFromCollectionNoChange2() {
+			Collection<Object> collection = new HashSet<Object>();
+			return this.removeItemsFromCollection(Collections.singleton("foo"), collection, COLLECTION_NAME);
+		}
+
+		public boolean testRemoveItemsFromCollectionNoChange3() {
+			Collection<Object> collection = new HashSet<Object>();
+			collection.add(REMOVED_OBJECT_VALUE);
+			return this.removeItemsFromCollection(Collections.singleton("foo"), collection, COLLECTION_NAME);
+		}
+
+		public boolean testRetainItemsInCollection1() {
+			Collection<Object> collection = new HashSet<Object>();
+			collection.add(REMOVED_OBJECT_VALUE);
+			collection.add("foo");
+			collection.add("bar");
+			return this.retainItemsInCollection(new Object[] {"foo", "bar"}, collection, COLLECTION_NAME);
+		}
+
+		public boolean testRetainItemsInCollection2() {
+			Collection<Object> collection = new HashSet<Object>();
+			collection.add(REMOVED_OBJECT_VALUE);
+			collection.add("foo");
+			collection.add("bar");
+			return this.retainItemsInCollection(Collections.emptySet(), collection, COLLECTION_NAME);
+		}
+
+		public boolean testRetainItemsInCollectionNoChange1() {
+			Collection<Object> collection = new HashSet<Object>();
+			return this.retainItemsInCollection(new Object[] {"foo", "bar"}, collection, COLLECTION_NAME);
+		}
+
+		public boolean testRetainItemsInCollectionNoChange2() {
+			Collection<Object> collection = new HashSet<Object>();
+			collection.add(REMOVED_OBJECT_VALUE);
+			collection.add("foo");
+			collection.add("bar");
+			return this.retainItemsInCollection(new Object[] {"foo", "bar", REMOVED_OBJECT_VALUE}, collection, COLLECTION_NAME);
+		}
+
+		public boolean testClearCollection() {
+			Collection<Object> collection = new HashSet<Object>();
+			collection.add(REMOVED_OBJECT_VALUE);
+			collection.add("foo");
+			collection.add("bar");
+			return this.clearCollection(collection, COLLECTION_NAME);
+		}
+
+		public boolean testClearCollectionNoChange() {
+			Collection<Object> collection = new HashSet<Object>();
+			return this.clearCollection(collection, COLLECTION_NAME);
+		}
+
+		public boolean testSynchronizeCollection1() {
+			Collection<Object> collection = new HashSet<Object>();
+			collection.add("foo");
+			collection.add("bar");
+			collection.add("baz");
+			Collection<Object> newCollection = new HashSet<Object>();
+			newCollection.add("joo");
+			newCollection.add("jar");
+			newCollection.add("baz");
+			boolean result = this.synchronizeCollection(newCollection, collection, COLLECTION_NAME);
+			assertEquals(newCollection, collection);
+			return result;
+		}
+
+		public boolean testSynchronizeCollection2() {
+			Collection<Object> collection = new HashSet<Object>();
+			collection.add("foo");
+			collection.add("bar");
+			collection.add("baz");
+			Collection<Object> newCollection = new HashSet<Object>();
+			boolean result = this.synchronizeCollection(newCollection, collection, COLLECTION_NAME);
+			assertEquals(newCollection, collection);
+			return result;
+		}
+
+		public boolean testSynchronizeCollection3() {
+			Collection<Object> collection = new HashSet<Object>();
+			Collection<Object> newCollection = new HashSet<Object>();
+			newCollection.add("joo");
+			newCollection.add("jar");
+			newCollection.add("baz");
+			boolean result = this.synchronizeCollection(newCollection, collection, COLLECTION_NAME);
+			assertEquals(newCollection, collection);
+			return result;
+		}
+
+		// ***** list
+		public void testFireItemsAddedListEvent() {
+			this.fireItemsAdded(new ListAddEvent(this, LIST_NAME, ADD_INDEX, ADDED_OBJECT_VALUE));
+		}
+
+		public void testFireItemsAddedListEventNoChange() {
+			this.fireItemsAdded(new ListAddEvent(this, LIST_NAME, ADD_INDEX, Collections.emptyList()));
+		}
+
+		public void testFireItemsAddedList() {
+			this.fireItemsAdded(LIST_NAME, ADD_INDEX, Collections.singletonList(ADDED_OBJECT_VALUE));
+		}
+
+		public void testFireItemsAddedListNoChange() {
+			this.fireItemsAdded(LIST_NAME, ADD_INDEX, Collections.emptyList());
+		}
+
+		public void testFireItemAddedList() {
+			this.fireItemAdded(LIST_NAME, ADD_INDEX, ADDED_OBJECT_VALUE);
+		}
+
+		public void testFireItemsRemovedListEvent() {
+			this.fireItemsRemoved(new ListRemoveEvent(this, LIST_NAME, REMOVE_INDEX, REMOVED_OBJECT_VALUE));
+		}
+
+		public void testFireItemsRemovedListEventNoChange() {
+			this.fireItemsRemoved(new ListRemoveEvent(this, LIST_NAME, REMOVE_INDEX, Collections.emptyList()));
+		}
+
+		public void testFireItemsRemovedList() {
+			this.fireItemsRemoved(LIST_NAME, REMOVE_INDEX, Collections.singletonList(REMOVED_OBJECT_VALUE));
+		}
+
+		public void testFireItemsRemovedListNoChange() {
+			this.fireItemsRemoved(LIST_NAME, REMOVE_INDEX, Collections.emptyList());
+		}
+
+		public void testFireItemRemovedList() {
+			this.fireItemRemoved(LIST_NAME, REMOVE_INDEX, REMOVED_OBJECT_VALUE);
+		}
+
+		public void testFireItemsReplacedListEvent() {
+			this.fireItemsReplaced(new ListReplaceEvent(this, LIST_NAME, REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE));
+		}
+
+		public void testFireItemsReplacedListEventNoChange() {
+			this.fireItemsReplaced(new ListReplaceEvent(this, LIST_NAME, REPLACE_INDEX, Collections.emptyList(), Collections.emptyList()));
+		}
+
+		public void testFireItemsReplacedList() {
+			this.fireItemsReplaced(LIST_NAME, REPLACE_INDEX, Collections.singletonList(ADDED_OBJECT_VALUE), Collections.singletonList(REMOVED_OBJECT_VALUE));
+		}
+
+		public void testFireItemsReplacedListNoChange() {
+			this.fireItemsReplaced(LIST_NAME, REPLACE_INDEX, Collections.emptyList(), Collections.emptyList());
+		}
+
+		public void testFireItemReplacedList() {
+			this.fireItemReplaced(LIST_NAME, REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
+		}
+
+		public void testFireItemsMovedListEvent() {
+			this.fireItemsMoved(new ListMoveEvent(this, LIST_NAME, TARGET_INDEX, SOURCE_INDEX, 1));
+		}
+
+		public void testFireItemsMovedListEventNoChange() {
+			this.fireItemsMoved(new ListMoveEvent(this, LIST_NAME, SOURCE_INDEX, SOURCE_INDEX, 1));
+		}
+
+		public void testFireItemsMovedList() {
+			this.fireItemsMoved(LIST_NAME, TARGET_INDEX, SOURCE_INDEX, 1);
+		}
+
+		public void testFireItemsMovedListNoChange() {
+			this.fireItemsMoved(LIST_NAME, SOURCE_INDEX, SOURCE_INDEX, 1);
+		}
+
+		public void testFireItemMovedList() {
+			this.fireItemMoved(LIST_NAME, TARGET_INDEX, SOURCE_INDEX);
+		}
+
+		public void testFireListClearedEvent() {
+			this.fireListCleared(new ListClearEvent(this, LIST_NAME));
+		}
+
+		public void testFireListCleared() {
+			this.fireListCleared(LIST_NAME);
+		}
+
+		public void testFireListChangedEvent() {
+			this.fireListChanged(new ListChangeEvent(this, LIST_NAME, Collections.emptyList()));
+		}
+
+		public void testFireListChanged() {
+			this.fireListChanged(LIST_NAME, Collections.emptyList());
+		}
+
+		public void testAddItemToListIndex() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.addItemToList(2, "joo", list, LIST_NAME);
+		}
+
+		public void testAddItemToList() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.addItemToList("joo", list, LIST_NAME);
+		}
+
+		public void testAddItemsToListIndex() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.addItemsToList(2, Collections.singletonList("joo"), list, LIST_NAME);
+		}
+
+		public void testAddItemsToListIndexNoChange() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.addItemsToList(2, Collections.<String>emptyList(), list, LIST_NAME);
+		}
+
+		public void testAddItemsToList() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.addItemsToList(Collections.singletonList("joo"), list, LIST_NAME);
+		}
+
+		public void testAddItemsToListNoChange() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.addItemsToList(Collections.<String>emptyList(), list, LIST_NAME);
+		}
+
+		public void testRemoveItemFromListIndex() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.removeItemFromList(1, list, LIST_NAME);
+		}
+
+		public void testRemoveItemFromList() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.removeItemFromList("bar", list, LIST_NAME);
+		}
+
+		public void testRemoveItemsFromListIndex() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.removeItemsFromList(1, 1, list, LIST_NAME);
+		}
+
+		public void testRemoveItemsFromListIndexNoChange() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.removeItemsFromList(2, 0, list, LIST_NAME);
+		}
+
+		public void testRemoveItemsFromList() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.removeItemsFromList(Collections.singletonList("bar"), list, LIST_NAME);
+		}
+
+		public void testRemoveItemsFromListNoChange() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.addItemsToList(Collections.<String>emptyList(), list, LIST_NAME);
+		}
+
+		public void testRetainItemsInList() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.retainItemsInList(new String[] {"bar", "baz"}, list, LIST_NAME);
+		}
+
+		public void testReplaceItemInList() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.replaceItemInList("bar", "xxx", list, LIST_NAME);
+		}
+
+		public void testSetItemsInList() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.setItemsInList(1, new String[] {"xxx"}, list, LIST_NAME);
+		}
+
+		public void testMoveItemsInList() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			list.add("xxx");
+			list.add("yyy");
+			list.add("zzz");
+			this.moveItemsInList(2, 4, 2, list, LIST_NAME);
+		}
+
+		public void testClearList() {
+			List<String> list = new ArrayList<String>();
+			list.add("foo");
+			list.add("bar");
+			list.add("baz");
+			this.clearList(list, LIST_NAME);
+		}
+
+		public void testSynchronizeList() {
+			List<String> oldList = new ArrayList<String>();
+			oldList.add("foo");
+			oldList.add("bar");
+			oldList.add("baz");
+			oldList.add("xxx");
+			oldList.add("yyy");
+			oldList.add("zzz");
+			List<String> newList = new ArrayList<String>();
+			newList.add("foo");
+			newList.add("ppp");
+			newList.add("baz");
+			newList.add("xxx");
+			newList.add("qqq");
+			this.synchronizeList(newList, oldList, LIST_NAME);
+			assertEquals(newList, oldList);
+		}
+
+		public boolean testAttributeValueHasChanged(Object value1, Object value2) {
+			return this.attributeValueHasChanged(value1, value2);
+		}
+
+		public boolean testAttributeValueHasNotChanged(Object value1, Object value2) {
+			return this.attributeValueHasNotChanged(value1, value2);
+		}
+
+		// ***** misc
+		@Override
+		public TestModel clone() {
+			try {
+				return (TestModel) super.clone();
+			} catch (CloneNotSupportedException ex) {
+				throw new InternalError();
+			}
+		}
+
+		public boolean testValuesAreDifferent(Object value1, Object value2) {
+			return this.valuesAreDifferent(value1, value2);
+		}
+
+		public boolean testValuesAreEqual(Object value1, Object value2) {
+			return this.valuesAreEqual(value1, value2);
+		}
+
+		public boolean testElementsAreDifferent(Iterable<?> iterable1, Iterable<?> iterable2) {
+			return this.getChangeSupport().elementsAreDifferent(iterable1, iterable2);
+		}
+
+		public boolean testElementsAreEqual(Iterable<?> iterable1, Iterable<?> iterable2) {
+			return this.getChangeSupport().elementsAreEqual(iterable1, iterable2);
+		}
+
+		@Override
+		public void toString(StringBuilder sb) {
+			sb.append(TEST_TO_STRING);
+		}
+
+	}
+
+
+	// ********** serialization test **********
+	public void testSerialization() throws java.io.IOException, ClassNotFoundException {
+		if (SystemTools.jvmIsSun()) {
+			// This test doesn't pass in the Eclipse build environment (Linux/IBM JVM) for some reason
+			this.verifySerialization();
+		}
+	}
+
+	private void verifySerialization() throws java.io.IOException, ClassNotFoundException {
+		LocalModel model1 = new LocalModel();
+		Foo foo1 = new Foo();
+		Bar bar1 = new Bar();
+		Joo joo1 = new Joo();
+		Jar jar1 = new Jar();
+		model1.addStateChangeListener(foo1);
+		model1.addStateChangeListener(bar1);
+		model1.addListChangeListener("foo", joo1);
+		model1.addListChangeListener("foo", jar1);
+
+		Iterable<EventListener> listeners1 = this.getListeners(model1, StateChangeListener.class, null);
+		Object[] listenersArray1 = ArrayTools.array(listeners1);
+		assertEquals(2, listenersArray1.length);
+		// the order of these could change...
+		assertEquals(Foo.class, listenersArray1[0].getClass());
+		assertEquals(Bar.class, listenersArray1[1].getClass());
+
+		listeners1 = this.getListeners(model1, ListChangeListener.class, "foo");
+		listenersArray1 = ArrayTools.array(listeners1);
+		assertEquals(2, listenersArray1.length);
+		// the order of these could change...
+		assertEquals(Joo.class, listenersArray1[0].getClass());
+		assertEquals(Jar.class, listenersArray1[1].getClass());
+
+		LocalModel model2 = TestTools.serialize(model1);
+
+		Iterable<EventListener> listeners2 = this.getListeners(model2, StateChangeListener.class, null);
+		Object[] listenersArray2 = ArrayTools.array(listeners2);
+		assertEquals(1, listenersArray2.length);
+		assertEquals(Foo.class, listenersArray2[0].getClass());
+
+		listeners2 = this.getListeners(model2, ListChangeListener.class, "foo");
+		listenersArray2 = ArrayTools.array(listeners2);
+		assertEquals(1, listenersArray2.length);
+		assertEquals(Joo.class, listenersArray2[0].getClass());
+	}
+
+	private Iterable<EventListener> getListeners(LocalModel model, Class<? extends EventListener> listenerClass, String aspectName) {
+		return this.getListenerList(model, listenerClass, aspectName).getListeners();
+	}
+
+	@SuppressWarnings("unchecked")
+	private ListenerList<EventListener> getListenerList(LocalModel model, Class<? extends EventListener> listenerClass, String aspectName) {
+		ChangeSupport changeSupport = (ChangeSupport) ObjectTools.get(model, "changeSupport");
+		return (ListenerList<EventListener>) ObjectTools.execute(changeSupport, "getListenerList_", new Class<?>[] {Class.class, String.class}, new Object[] {listenerClass, aspectName});
+	}
+
+	// we have to manually handle 'changeSupport' since AbstractModel is not Serializable
+	/* CU private */ static class LocalModel
+		extends AbstractModel
+		implements Serializable
+	{
+		private static final long serialVersionUID = 1L;
+		LocalModel() {
+			super();
+		}
+		private synchronized void writeObject(ObjectOutputStream s) throws IOException {
+			s.defaultWriteObject();
+			s.writeObject(this.changeSupport);
+	    }
+		private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
+			s.defaultReadObject();
+			this.changeSupport = (ChangeSupport) s.readObject();
+		}
+	}
+
+	/* CU private */ static class Foo
+		implements Serializable, StateChangeListener
+	{
+		private static final long serialVersionUID = 1L;
+		Foo() {
+			super();
+		}
+		@Override
+		public void stateChanged(StateChangeEvent event) {
+			// do nothing
+		}
+	}
+
+	/* CU private */ static class Bar
+		implements StateChangeListener
+	{
+		Bar() {
+			super();
+		}
+		@Override
+		public void stateChanged(StateChangeEvent event) {
+			// do nothing
+		}
+	}
+
+	/* CU private */ static class Joo
+		extends ListChangeAdapter
+		implements Serializable
+	{
+		private static final long serialVersionUID = 1L;
+		Joo() {
+			super();
+		}
+	}
+
+	/* CU private */ static class Jar
+		extends ListChangeAdapter
+	{
+		Jar() {
+			super();
+		}
+	}
+
+
+	// ********** bug(?) test **********
+
+	private static final String ISE_MESSAGE = "this object is no longer listening to localA";
+
+	/**
+	 * Test the following situation:
+	 * 	- both B and C are listening to A
+	 * 	- C is also listening to B
+	 * 	- when B receives an event from A, it will fire an event to C
+	 * 	- when C receives an event from B, it will STOP listening to A
+	 * 	- the event from B to C may be preceded or followed (depending on
+	 * 		the hash positions of listeners) by an event from A to C:
+	 * 		- if the A to C event comes first, no problem
+	 * 		- but if the A to B event comes first, the A to C event should NOT happen
+	 */
+	public void testIndirectRemoveStateListener() {
+		this.verifyIndirectRemoveListener(
+			new NotifyCommand() {
+				@Override
+				public void notifyListeners(LocalA localA) {
+					localA.notifyStateListeners();
+				}
+			}
+		);
+	}
+
+	public void testIndirectRemovePropertyListener() {
+		this.verifyIndirectRemoveListener(
+			new NotifyCommand() {
+				@Override
+				public void notifyListeners(LocalA localA) {
+					localA.notifyPropertyListeners();
+				}
+			}
+		);
+	}
+
+	public void testIndirectRemoveCollectionListener() {
+		this.verifyIndirectRemoveListener(
+			new NotifyCommand() {
+				@Override
+				public void notifyListeners(LocalA localA) {
+					localA.notifyCollectionListeners();
+				}
+			}
+		);
+	}
+
+	public void testIndirectRemoveListListener() {
+		this.verifyIndirectRemoveListener(
+			new NotifyCommand() {
+				@Override
+				public void notifyListeners(LocalA localA) {
+					localA.notifyListListeners();
+				}
+			}
+		);
+	}
+
+	public void verifyIndirectRemoveListener(NotifyCommand command) {
+		LocalA localA = new LocalA();
+		LocalB localB = new LocalB(localA);
+
+		// build a bunch of LocalCs so at least one of them is notified AFTER the LocalB;
+		// using 1000 seemed to fail very consistently before ChangeSupport was fixed
+		LocalC[] localCs = new LocalC[1000];
+		for (int i = localCs.length; i-- > 0; ) {
+			localCs[i] = new LocalC(localA, localB);
+		}
+
+		boolean exCaught = false;
+		try {
+			command.notifyListeners(localA);
+		} catch (IllegalStateException ex) {
+			if (ex.getMessage() == ISE_MESSAGE) {
+				exCaught = true;
+			} else {
+				throw ex;
+			}
+		}
+		assertFalse(exCaught);
+
+		for (int i = localCs.length; i-- > 0; ) {
+			assertFalse(localCs[i].isListeningToLocalA());
+		}
+	}
+
+	private interface NotifyCommand {
+		void notifyListeners(LocalA localA);
+	}
+
+	/**
+	 * This object simply fires a state change event. Both LocalB and LocalC
+	 * will be listeners.
+	 */
+	private static class LocalA extends AbstractModel {
+		LocalA() {
+			super();
+		}
+		void notifyStateListeners() {
+			this.fireStateChanged();
+		}
+		void notifyPropertyListeners() {
+			this.firePropertyChanged("foo", 1, 2);
+		}
+		void notifyCollectionListeners() {
+			this.fireCollectionChanged("foo", Collections.emptySet());
+		}
+		void notifyListListeners() {
+			this.fireListChanged("foo", Collections.emptyList());
+		}
+	}
+
+	/**
+	 * This object will fire state change events whenever it receives
+	 * a state change event from localA.
+	 */
+	private static class LocalB
+		extends AbstractModel
+		implements ChangeListener
+	{
+		LocalB(LocalA localA) {
+			super();
+			localA.addChangeListener(this);
+		}
+
+		@Override
+		public void stateChanged(StateChangeEvent e) {
+			this.fireStateChanged();
+		}
+
+		@Override
+		public void propertyChanged(PropertyChangeEvent evt) {
+			this.firePropertyChanged("bar", 1, 2);
+		}
+
+		@Override
+		public void collectionChanged(CollectionChangeEvent e) {
+			this.fireCollectionChanged("bar", Collections.emptySet());
+		}
+		@Override
+		public void collectionCleared(CollectionClearEvent e) {/*ignore*/}
+		@Override
+		public void itemsAdded(CollectionAddEvent e) {/*ignore*/}
+		@Override
+		public void itemsRemoved(CollectionRemoveEvent e) {/*ignore*/}
+
+		@Override
+		public void listChanged(ListChangeEvent e) {
+			this.fireListChanged("bar", Collections.emptyList());
+		}
+		@Override
+		public void listCleared(ListClearEvent e) {/*ignore*/}
+		@Override
+		public void itemsAdded(ListAddEvent e) {/*ignore*/}
+		@Override
+		public void itemsRemoved(ListRemoveEvent e) {/*ignore*/}
+		@Override
+		public void itemsReplaced(ListReplaceEvent e) {/*ignore*/}
+		@Override
+		public void itemsMoved(ListMoveEvent e) {/*ignore*/}
+
+	}
+
+	/**
+	 * This object will listen to two other objects, localA and localB.
+	 * If this object receives notification from localB, it will stop listening to
+	 * localA. If this object receives notification from localA, it will check to
+	 * see whether it still listening to localA. If this object is no longer
+	 * listening to localA, it will complain about receiving the event and
+	 * throw an exception.
+	 */
+	private static class LocalC
+		extends AbstractModel
+		implements ChangeListener
+	{
+		private LocalA localA;
+		private LocalB localB;
+		private boolean listeningToLocalA;
+
+		LocalC(LocalA localA, LocalB localB) {
+			super();
+			this.localA = localA;
+			this.localB = localB;
+
+			localA.addChangeListener(this);
+			this.listeningToLocalA = true;
+
+			localB.addChangeListener(this);
+		}
+		boolean isListeningToLocalA() {
+			return this.listeningToLocalA;
+		}
+
+		@Override
+		public void stateChanged(StateChangeEvent e) {
+			Object source = e.getSource();
+			if (source == this.localA) {
+				if ( ! this.listeningToLocalA) {
+					throw new IllegalStateException(ISE_MESSAGE);
+				}
+			} else if (source == this.localB) {
+				this.localA.removeChangeListener(this);
+				this.listeningToLocalA = false;
+			} else {
+				throw new IllegalStateException("bogus event source: " + source);
+			}
+		}
+
+		@Override
+		public void propertyChanged(PropertyChangeEvent e) {
+			Object source = e.getSource();
+			if (source == this.localA) {
+				if ( ! this.listeningToLocalA) {
+					throw new IllegalStateException(ISE_MESSAGE);
+				}
+			} else if (source == this.localB) {
+				this.localA.removeChangeListener(this);
+				this.listeningToLocalA = false;
+			} else {
+				throw new IllegalStateException("bogus event source: " + source);
+			}
+		}
+
+		@Override
+		public void collectionChanged(CollectionChangeEvent e) {
+			Object source = e.getSource();
+			if (source == this.localA) {
+				if ( ! this.listeningToLocalA) {
+					throw new IllegalStateException(ISE_MESSAGE);
+				}
+			} else if (source == this.localB) {
+				this.localA.removeChangeListener(this);
+				this.listeningToLocalA = false;
+			} else {
+				throw new IllegalStateException("bogus event source: " + source);
+			}
+		}
+		@Override
+		public void collectionCleared(CollectionClearEvent e) {/*ignore*/}
+		@Override
+		public void itemsAdded(CollectionAddEvent e) {/*ignore*/}
+		@Override
+		public void itemsRemoved(CollectionRemoveEvent e) {/*ignore*/}
+
+		@Override
+		public void listChanged(ListChangeEvent e) {
+			Object source = e.getSource();
+			if (source == this.localA) {
+				if ( ! this.listeningToLocalA) {
+					throw new IllegalStateException(ISE_MESSAGE);
+				}
+			} else if (source == this.localB) {
+				this.localA.removeChangeListener(this);
+				this.listeningToLocalA = false;
+			} else {
+				throw new IllegalStateException("bogus event source: " + source);
+			}
+		}
+		@Override
+		public void listCleared(ListClearEvent e) {/*ignore*/}
+		@Override
+		public void itemsAdded(ListAddEvent e) {/*ignore*/}
+		@Override
+		public void itemsRemoved(ListRemoveEvent e) {/*ignore*/}
+		@Override
+		public void itemsReplaced(ListReplaceEvent e) {/*ignore*/}
+		@Override
+		public void itemsMoved(ListMoveEvent e) {/*ignore*/}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/CommonUtilityModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/CommonUtilityModelTests.java
new file mode 100644
index 0000000..c1cf081
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/CommonUtilityModelTests.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.eclipse.persistence.tools.utility.tests.model.listener.UtilityModelListenerTests;
+import org.eclipse.persistence.tools.utility.tests.model.value.UtilityModelValueTests;
+
+public class CommonUtilityModelTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CommonUtilityModelTests.class.getPackage().getName());
+
+		suite.addTest(UtilityModelListenerTests.suite());
+		suite.addTest(UtilityModelValueTests.suite());
+
+		suite.addTestSuite(ChangeSupportTests.class);
+		suite.addTestSuite(NewEventTests.class);
+		suite.addTestSuite(SingleAspectChangeSupportTests.class);
+
+		return suite;
+	}
+
+	private CommonUtilityModelTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/Displayable.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/Displayable.java
new file mode 100644
index 0000000..d990942
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/Displayable.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model;
+
+import javax.swing.Icon;
+import org.eclipse.persistence.tools.utility.model.Model;
+
+/**
+ * Used by general-purpose UI models and renderers to cast
+ * application model objects to something displayable.
+ */
+@SuppressWarnings("nls")
+public interface Displayable
+	extends Model
+{
+	/**
+	 * Return a string that can be used to identify the model
+	 * in a textual UI setting (typically the object's name).
+	 * When the display string changes, the model should fire
+	 * the appropriate change notification:<pre>
+	 *     this.firePropertyChanged(DISPLAY_STRING_PROPERTY, oldDisplayString, this.displayString);
+	 * </pre>
+	 */
+	String displayString();
+		String DISPLAY_STRING_PROPERTY = "displayString";
+
+	/**
+	 * Return an icon that can be used to identify the model
+	 * in a UI component that supports icons (the icon can be null).
+	 * When the icon changes, the model should fire
+	 * the appropriate change notification:<pre>
+	 *     this.firePropertyChanged(ICON_PROPERTY, oldIcon, this.icon);
+	 * </pre>
+	 */
+	Icon icon();
+		String ICON_PROPERTY = "icon";
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/NewEventTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/NewEventTests.java
new file mode 100644
index 0000000..2b547e3
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/NewEventTests.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model;
+
+import java.util.EventListener;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ListenerList;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.ChangeSupport;
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.ChangeEvent;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+/**
+ * test what it takes to add a new type of event to
+ * model and change support
+ */
+public class NewEventTests extends TestCase {
+	private Foo foo;
+
+	public NewEventTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.foo = new Foo();
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testHasNoFooChangeListeners() {
+		assertTrue(this.foo.hasNoFooChangeListeners());
+		LocalListener listener = new LocalListener();
+		this.foo.addFooChangeListener(listener);
+		assertFalse(this.foo.hasNoFooChangeListeners());
+		this.foo.removeFooChangeListener(listener);
+		assertTrue(this.foo.hasNoFooChangeListeners());
+	}
+
+	public void testHasAnyFooChangeListeners() {
+		assertFalse(this.foo.hasAnyFooChangeListeners());
+		LocalListener listener = new LocalListener();
+		this.foo.addFooChangeListener(listener);
+		assertTrue(this.foo.hasAnyFooChangeListeners());
+		this.foo.removeFooChangeListener(listener);
+		assertFalse(this.foo.hasAnyFooChangeListeners());
+	}
+
+	public void testFireFooChangeEvent() {
+		LocalListener listener = new LocalListener();
+		assertFalse(listener.receivedFooEvent);
+		this.foo.addFooChangeListener(listener);
+		this.foo.foo();
+		assertTrue(listener.receivedFooEvent);
+	}
+
+
+	// ********** harness classes **********
+
+	class Foo extends AbstractFooModel {
+		Foo() {
+			super();
+		}
+		void foo() {
+			this.fireFooChangeEvent();
+		}
+	}
+
+	class LocalListener implements FooChangeListener {
+		boolean receivedFooEvent = false;
+		LocalListener() {
+			super();
+		}
+		@Override
+		public void fooChanged(FooChangeEvent event) {
+			this.receivedFooEvent = true;
+		}
+	}
+
+	interface FooModel extends Model {
+		void addFooChangeListener(FooChangeListener listener);
+		void removeFooChangeListener(FooChangeListener listener);
+	}
+
+	interface FooChangeListener extends EventListener {
+		void fooChanged(FooChangeEvent event);
+	}
+
+	static class FooChangeEvent
+		extends ChangeEvent
+	{
+		private static final long serialVersionUID = 1L;
+		public FooChangeEvent(FooModel source) {
+			super(source);
+		}
+		public FooChangeEvent clone(Model newSource) {
+			return new FooChangeEvent((FooModel) newSource);
+		}
+	}
+
+	static class AbstractFooModel
+		extends AbstractModel
+		implements FooModel
+	{
+		@Override
+		protected synchronized FooChangeSupport getChangeSupport() {
+			return (FooChangeSupport) super.getChangeSupport();
+		}
+		@Override
+		protected ChangeSupport buildChangeSupport() {
+			return new FooChangeSupport(this);
+		}
+		@Override
+		public void addFooChangeListener(FooChangeListener listener) {
+			this.getChangeSupport().addFooChangeListener(listener);
+		}
+		@Override
+		public void removeFooChangeListener(FooChangeListener listener) {
+			this.getChangeSupport().removeFooChangeListener(listener);
+		}
+		protected void fireFooChangeEvent() {
+			this.getChangeSupport().fireFooChanged();
+		}
+		public boolean hasAnyFooChangeListeners() {
+			return this.getChangeSupport().hasAnyFooChangeListeners();
+		}
+		public boolean hasNoFooChangeListeners() {
+			return ! this.hasAnyFooChangeListeners();
+		}
+	}
+
+	static class FooChangeSupport
+		extends ChangeSupport
+	{
+		private static final long serialVersionUID = 1L;
+		FooChangeSupport(FooModel source) {
+			super(source);
+		}
+		protected static final Class<FooChangeListener> FOO_CHANGE_LISTENER_CLASS = FooChangeListener.class;
+		void addFooChangeListener(FooChangeListener listener) {
+			this.addListener(FOO_CHANGE_LISTENER_CLASS, listener);
+		}
+		void removeFooChangeListener(FooChangeListener listener) {
+			this.removeListener(FOO_CHANGE_LISTENER_CLASS, listener);
+		}
+		public boolean hasAnyFooChangeListeners() {
+			return this.hasAnyListeners(FOO_CHANGE_LISTENER_CLASS);
+		}
+		private ListenerList<FooChangeListener> getFooChangeListenerList() {
+			return this.getListenerList(FOO_CHANGE_LISTENER_CLASS);
+		}
+		private Iterable<FooChangeListener> getFooChangeListeners() {
+			ListenerList<FooChangeListener> listenerList = this.getFooChangeListenerList();
+			return (listenerList == null) ? null : listenerList.getListeners();
+		}
+		private boolean hasFooChangeListener(FooChangeListener listener) {
+			return IterableTools.contains(this.getFooChangeListeners(), listener);
+		}
+		public void fireFooChanged() {
+			Iterable<FooChangeListener> listeners = this.getFooChangeListeners();
+			if (listeners != null) {
+				FooChangeEvent event = null;
+				for (FooChangeListener listener : listeners) {
+					if (this.hasFooChangeListener(listener)) {
+						if (event == null) {
+							// here's the reason for the duplicate code...
+							event = new FooChangeEvent((FooModel) this.source);
+						}
+						listener.fooChanged(event);
+					}
+				}
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/SimpleDisplayable.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/SimpleDisplayable.java
new file mode 100644
index 0000000..6efa650
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/SimpleDisplayable.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model;
+
+import javax.swing.Icon;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+
+/**
+ * This implementation of {@link Displayable} converts any {@link Object}
+ * to a {@link Displayable}. Subclass it to override {@link #displayString()} and
+ * {@link #icon()} if necessary. Change notification will be fired if the
+ * object is changed.
+ * <p>
+ * This can be used for {@link String}s - the display string
+ * will simply be the string itself.
+ */
+public class SimpleDisplayable
+	extends AbstractModel
+	implements Displayable
+{
+	/** The object to be converted to a displayable. */
+	protected Object object;
+
+
+	/**
+	 * Construct a displayable for the specified object.
+	 */
+	public SimpleDisplayable(Object object) {
+		super();
+		this.object = object;
+	}
+
+	public SimpleDisplayable(boolean b) {
+		this(Boolean.valueOf(b));
+	}
+
+	public SimpleDisplayable(char c) {
+		this(Character.valueOf(c));
+	}
+
+	public SimpleDisplayable(byte b) {
+		this(Byte.valueOf(b));
+	}
+
+	public SimpleDisplayable(short s) {
+		this(Short.valueOf(s));
+	}
+
+	public SimpleDisplayable(int i) {
+		this(Integer.valueOf(i));
+	}
+
+	public SimpleDisplayable(long l) {
+		this(Long.valueOf(l));
+	}
+
+	public SimpleDisplayable(float f) {
+		this(Float.valueOf(f));
+	}
+
+	public SimpleDisplayable(double d) {
+		this(Double.valueOf(d));
+	}
+
+
+	// ********** Displayable implementation **********
+
+	@Override
+	public String displayString() {
+		return this.object.toString();
+	}
+
+	@Override
+	public Icon icon() {
+		return null;
+	}
+
+
+	// ********** accessors **********
+
+	public Object getObject() {
+		return this.object;
+	}
+
+	public void setObject(Object object) {
+		String oldDisplayString = this.displayString();
+		Icon oldIcon = this.icon();
+		this.object = object;
+		this.firePropertyChanged(DISPLAY_STRING_PROPERTY, oldDisplayString, this.displayString());
+		this.firePropertyChanged(ICON_PROPERTY, oldIcon, this.icon());
+	}
+
+	public boolean getBoolean() {
+		return ((Boolean) this.object).booleanValue();
+	}
+
+	public void setBoolean(boolean b) {
+		this.setObject(Boolean.valueOf(b));
+	}
+
+	public char getChar() {
+		return ((Character) this.object).charValue();
+	}
+
+	public void setChar(char c) {
+		this.setObject(Character.valueOf(c));
+	}
+
+	public byte getByte() {
+		return ((Byte) this.object).byteValue();
+	}
+
+	public void setByte(byte b) {
+		this.setObject(Byte.valueOf(b));
+	}
+
+	public short getShort() {
+		return ((Short) this.object).shortValue();
+	}
+
+	public void setShort(short s) {
+		this.setObject(Short.valueOf(s));
+	}
+
+	public int getInt() {
+		return ((Integer) this.object).intValue();
+	}
+
+	public void setInt(int i) {
+		this.setObject(Integer.valueOf(i));
+	}
+
+	public long getLong() {
+		return ((Long) this.object).longValue();
+	}
+
+	public void setLong(long l) {
+		this.setObject(Long.valueOf(l));
+	}
+
+	public float getFloat() {
+		return ((Float) this.object).floatValue();
+	}
+
+	public void setFloat(float f) {
+		this.setObject(Float.valueOf(f));
+	}
+
+	public double getDouble() {
+		return ((Double) this.object).doubleValue();
+	}
+
+	public void setDouble(double d) {
+		this.setObject(Double.valueOf(d));
+	}
+
+
+	// ********** override methods **********
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.object);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/SingleAspectChangeSupportTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/SingleAspectChangeSupportTests.java
new file mode 100644
index 0000000..d5d00a5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/SingleAspectChangeSupportTests.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.ChangeSupport;
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.SingleAspectChangeSupport;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
+
+@SuppressWarnings("nls")
+public class SingleAspectChangeSupportTests extends TestCase {
+
+	public SingleAspectChangeSupportTests(String name) {
+		super(name);
+	}
+
+	public void testAddPropertyChangeListenerInvalidClass() {
+		Model model = new StateTestModel();
+		boolean exCaught = false;
+		PropertyChangeListener listener = new PropertyChangeAdapter();
+		try {
+			model.addPropertyChangeListener("foo", listener);
+			fail("bogus listener: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddPropertyChangeListenerInvalidAspect() {
+		Model model = new PropertyTestModel();
+		boolean exCaught = false;
+		PropertyChangeListener listener = new PropertyChangeAdapter();
+		try {
+			model.addPropertyChangeListener("bar", listener);
+			fail("bogus listener: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddCollectionChangeListenerInvalidClass() {
+		Model model = new StateTestModel();
+		boolean exCaught = false;
+		CollectionChangeListener listener = new CollectionChangeAdapter();
+		try {
+			model.addCollectionChangeListener("foo", listener);
+			fail("bogus listener: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddCollectionChangeListenerInvalidAspect() {
+		Model model = new CollectionTestModel();
+		boolean exCaught = false;
+		CollectionChangeListener listener = new CollectionChangeAdapter();
+		try {
+			model.addCollectionChangeListener("bar", listener);
+			fail("bogus listener: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddListChangeListenerInvalidClass() {
+		Model model = new StateTestModel();
+		boolean exCaught = false;
+		ListChangeListener listener = new ListChangeAdapter();
+		try {
+			model.addListChangeListener("foo", listener);
+			fail("bogus listener: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddListChangeListenerInvalidAspect() {
+		Model model = new ListTestModel();
+		boolean exCaught = false;
+		ListChangeListener listener = new ListChangeAdapter();
+		try {
+			model.addListChangeListener("bar", listener);
+			fail("bogus listener: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+
+	// ********** test models **********
+
+	static class StateTestModel extends AbstractModel {
+		StateTestModel() {
+			super();
+		}
+		@Override
+		protected ChangeSupport buildChangeSupport() {
+			return new SingleAspectChangeSupport(this, StateChangeListener.class, null);
+		}
+	}
+
+	static class PropertyTestModel extends AbstractModel {
+		PropertyTestModel() {
+			super();
+		}
+		@Override
+		protected ChangeSupport buildChangeSupport() {
+			return new SingleAspectChangeSupport(this, PropertyChangeListener.class, "foo");
+		}
+	}
+
+	static class CollectionTestModel extends AbstractModel {
+		CollectionTestModel() {
+			super();
+		}
+		@Override
+		protected ChangeSupport buildChangeSupport() {
+			return new SingleAspectChangeSupport(this, CollectionChangeListener.class, "foo");
+		}
+	}
+
+	static class ListTestModel extends AbstractModel {
+		ListTestModel() {
+			super();
+		}
+		@Override
+		protected ChangeSupport buildChangeSupport() {
+			return new SingleAspectChangeSupport(this, ListChangeListener.class, "foo");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/ReflectiveCollectionChangeListenerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/ReflectiveCollectionChangeListenerTests.java
new file mode 100644
index 0000000..6aa4345
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/ReflectiveCollectionChangeListenerTests.java
@@ -0,0 +1,332 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.listener;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterator.CloneIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ReflectiveChangeListener;
+
+@SuppressWarnings("nls")
+public class ReflectiveCollectionChangeListenerTests extends TestCase {
+
+	public ReflectiveCollectionChangeListenerTests(String name) {
+		super(name);
+	}
+
+	private CollectionChangeListener buildZeroArgumentListener(Object target) {
+		return ReflectiveChangeListener.buildCollectionChangeListener(target, "itemAddedZeroArgument", "itemRemovedZeroArgument", "collectionClearedZeroArgument", "collectionChangedZeroArgument");
+	}
+
+	private CollectionChangeListener buildSingleArgumentListener(Object target) {
+		return ReflectiveChangeListener.buildCollectionChangeListener(target, "itemAddedSingleArgument", "itemRemovedSingleArgument", "collectionClearedSingleArgument", "collectionChangedSingleArgument");
+	}
+
+	public void testItemAddedZeroArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildZeroArgumentListener(target));
+		testModel.addString(string);
+		assertTrue(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testItemAddedSingleArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildSingleArgumentListener(target));
+		testModel.addString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertTrue(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testItemRemovedZeroArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildZeroArgumentListener(target));
+		testModel.removeString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertTrue(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testItemRemovedSingleArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildSingleArgumentListener(target));
+		testModel.removeString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertTrue(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testCollectionClearedZeroArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildZeroArgumentListener(target));
+		testModel.clearStrings();
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertTrue(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testCollectionClearedSingleArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildSingleArgumentListener(target));
+		testModel.clearStrings();
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertTrue(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testCollectionChangedZeroArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildZeroArgumentListener(target));
+		testModel.replaceStrings(new String[] {"bar", "baz"});
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertTrue(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testCollectionChangedSingleArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildSingleArgumentListener(target));
+		testModel.replaceStrings(new String[] {"bar", "baz"});
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertTrue(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testBogusDoubleArgument1() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		boolean exCaught = false;
+		try {
+			CollectionChangeListener listener = ReflectiveChangeListener.buildCollectionChangeListener(target, "collectionChangedDoubleArgument");
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getCause().getClass() == NoSuchMethodException.class) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testBogusDoubleArgument2() throws Exception {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		Method method = ObjectTools.method(target, "collectionChangedDoubleArgument", new Class[] {CollectionChangeEvent.class, Object.class});
+		boolean exCaught = false;
+		try {
+			CollectionChangeListener listener = ReflectiveChangeListener.buildCollectionChangeListener(target, method);
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getMessage().equals(method.toString())) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testListenerMismatch() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		// build a COLLECTION change listener and hack it so we
+		// can add it as a LIST change listener
+		Object listener = ReflectiveChangeListener.buildCollectionChangeListener(target, "collectionEventSingleArgument");
+		testModel.addListChangeListener("bogus list", (ListChangeListener) listener);
+
+		boolean exCaught = false;
+		try {
+			testModel.changeList();
+			fail("listener mismatch: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+
+	class TestModel extends AbstractModel {
+		private Collection<String> strings = new ArrayList<String>();
+			public static final String STRINGS_COLLECTION = "strings";
+		TestModel() {
+			super();
+		}
+		Iterator<String> strings() {
+			return new CloneIterator<String>(this.strings, new CloneIterator.Remover<String>() {
+				@Override
+				public void remove(String s) {
+					TestModel.this.removeString(s);
+				}
+			});
+		}
+		void addString(String string) {
+			this.addItemToCollection(string, this.strings, STRINGS_COLLECTION);
+		}
+		void removeString(String string) {
+			this.removeItemFromCollection(string, this.strings, STRINGS_COLLECTION);
+		}
+		void clearStrings() {
+			this.clearCollection(this.strings, STRINGS_COLLECTION);
+		}
+		void replaceStrings(String[] newStrings) {
+			this.strings.clear();
+			CollectionTools.addAll(this.strings, newStrings);
+			this.fireCollectionChanged(STRINGS_COLLECTION, this.strings);
+		}
+		void changeList() {
+			this.fireListChanged("bogus list", Collections.emptyList());
+		}
+	}
+
+	class Target {
+		TestModel testModel;
+		String collectionName;
+		String string;
+		boolean itemAddedZeroArgumentFlag = false;
+		boolean itemAddedSingleArgumentFlag = false;
+		boolean itemRemovedZeroArgumentFlag = false;
+		boolean itemRemovedSingleArgumentFlag = false;
+		boolean collectionClearedZeroArgumentFlag = false;
+		boolean collectionClearedSingleArgumentFlag = false;
+		boolean collectionChangedZeroArgumentFlag = false;
+		boolean collectionChangedSingleArgumentFlag = false;
+		boolean collectionEventSingleArgumentFlag = false;
+		Target(TestModel testModel, String collectionName, String string) {
+			super();
+			this.testModel = testModel;
+			this.collectionName = collectionName;
+			this.string = string;
+		}
+		void itemAddedZeroArgument() {
+			this.itemAddedZeroArgumentFlag = true;
+		}
+		void itemAddedSingleArgument(CollectionAddEvent e) {
+			this.itemAddedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.collectionName, e.getCollectionName());
+			assertEquals(this.string, e.getItems().iterator().next());
+		}
+		void itemRemovedZeroArgument() {
+			this.itemRemovedZeroArgumentFlag = true;
+		}
+		void itemRemovedSingleArgument(CollectionRemoveEvent e) {
+			this.itemRemovedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.collectionName, e.getCollectionName());
+			assertEquals(this.string, e.getItems().iterator().next());
+		}
+		void collectionClearedZeroArgument() {
+			this.collectionClearedZeroArgumentFlag = true;
+		}
+		void collectionClearedSingleArgument(CollectionClearEvent e) {
+			this.collectionClearedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.collectionName, e.getCollectionName());
+		}
+		void collectionChangedZeroArgument() {
+			this.collectionChangedZeroArgumentFlag = true;
+		}
+		void collectionChangedSingleArgument(CollectionChangeEvent e) {
+			this.collectionChangedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.collectionName, e.getCollectionName());
+		}
+		void collectionEventSingleArgument(CollectionEvent e) {
+			this.collectionEventSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.collectionName, e.getCollectionName());
+		}
+		void collectionChangedDoubleArgument(CollectionChangeEvent e, Object o) {
+			fail("bogus event: " + e + " object: " + o);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/ReflectiveListChangeListenerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/ReflectiveListChangeListenerTests.java
new file mode 100644
index 0000000..5bd5ece
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/ReflectiveListChangeListenerTests.java
@@ -0,0 +1,499 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.listener;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.ListIterator;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterator.CloneListIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ReflectiveChangeListener;
+
+@SuppressWarnings("nls")
+public class ReflectiveListChangeListenerTests extends TestCase {
+
+	public ReflectiveListChangeListenerTests(String name) {
+		super(name);
+	}
+
+	private ListChangeListener buildZeroArgumentListener(Object target) {
+		return ReflectiveChangeListener.buildListChangeListener(target, "itemAddedZeroArgument", "itemRemovedZeroArgument", "itemReplacedZeroArgument", "itemMovedZeroArgument", "listClearedZeroArgument", "listChangedZeroArgument");
+	}
+
+	private ListChangeListener buildSingleArgumentListener(Object target) {
+		return ReflectiveChangeListener.buildListChangeListener(target, "itemAddedSingleArgument", "itemRemovedSingleArgument", "itemReplacedSingleArgument", "itemMovedSingleArgument", "listClearedSingleArgument", "listChangedSingleArgument");
+	}
+
+	public void testItemAddedZeroArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
+		testModel.addString(string);
+		assertTrue(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemAddedSingleArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
+		testModel.addString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertTrue(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemRemovedZeroArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
+		testModel.removeString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertTrue(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemRemovedSingleArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
+		testModel.removeString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertTrue(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemReplacedZeroArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String oldString = "foo";
+		String newString = "bar";
+		testModel.addString(oldString);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, newString, 0, oldString);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
+		testModel.replaceString(oldString, newString);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertTrue(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemReplacedSingleArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String oldString = "foo";
+		String newString = "bar";
+		testModel.addString(oldString);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, newString, 0, oldString);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
+		testModel.replaceString(oldString, newString);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertTrue(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemMovedZeroArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		testModel.addString("zero");
+		testModel.addString("one");
+		testModel.addString("two");
+		testModel.addString("three");
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, 0, 2);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
+		testModel.moveString(0, 2);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertTrue(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemMovedSingleArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		testModel.addString("zero");
+		testModel.addString("one");
+		testModel.addString("two");
+		testModel.addString("three");
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, 0, 2);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
+		testModel.moveString(0, 2);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertTrue(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testListClearedZeroArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
+		testModel.clearStrings();
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertTrue(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testListClearedSingleArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
+		testModel.clearStrings();
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertTrue(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testListChangedZeroArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
+		testModel.replaceAllStrings(new String[] {"bar", "baz"});
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertTrue(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testListChangedSingleArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
+		testModel.replaceAllStrings(new String[] {"bar", "baz"});
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertTrue(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testBogusDoubleArgument1() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		boolean exCaught = false;
+		try {
+			ListChangeListener listener = ReflectiveChangeListener.buildListChangeListener(target, "listChangedDoubleArgument");
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getCause().getClass() == NoSuchMethodException.class) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testBogusDoubleArgument2() throws Exception {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		Method method = ObjectTools.method(target, "listChangedDoubleArgument", new Class[] {ListChangeEvent.class, Object.class});
+		boolean exCaught = false;
+		try {
+			ListChangeListener listener = ReflectiveChangeListener.buildListChangeListener(target, method);
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getMessage().equals(method.toString())) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testListenerMismatch() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		// build a LIST change listener and hack it so we
+		// can add it as a COLLECTION change listener
+		Object listener = ReflectiveChangeListener.buildListChangeListener(target, "listEventSingleArgument");
+		testModel.addCollectionChangeListener("bogus collection", (CollectionChangeListener) listener);
+
+		boolean exCaught = false;
+		try {
+			testModel.changeCollection();
+			fail("listener mismatch: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+
+	class TestModel extends AbstractModel {
+		private List<String> strings = new ArrayList<String>();
+			public static final String STRINGS_LIST = "strings";
+		TestModel() {
+			super();
+		}
+		ListIterator<String> strings() {
+			return new CloneListIterator<String>(this.strings);
+		}
+		void addString(String string) {
+			this.addItemToList(string, this.strings, STRINGS_LIST);
+		}
+		void removeString(String string) {
+			this.removeItemFromList(this.strings.indexOf(string), this.strings, STRINGS_LIST);
+		}
+		void replaceString(String oldString, String newString) {
+			this.setItemInList(this.strings.indexOf(oldString), newString, this.strings, STRINGS_LIST);
+		}
+		void moveString(int targetIndex, int sourceIndex) {
+			this.moveItemInList(targetIndex, sourceIndex, this.strings, STRINGS_LIST);
+		}
+		void clearStrings() {
+			this.clearList(this.strings, STRINGS_LIST);
+		}
+		void replaceAllStrings(String[] newStrings) {
+			this.strings.clear();
+			CollectionTools.addAll(this.strings, newStrings);
+			this.fireListChanged(STRINGS_LIST, this.strings);
+		}
+		void changeCollection() {
+			this.fireCollectionChanged("bogus collection", Collections.emptySet());
+		}
+	}
+
+	class Target {
+		TestModel testModel;
+		String listName;
+		String string;
+		int index;
+		String replacedString;
+		int sourceIndex;
+		boolean itemAddedZeroArgumentFlag = false;
+		boolean itemAddedSingleArgumentFlag = false;
+		boolean itemRemovedZeroArgumentFlag = false;
+		boolean itemRemovedSingleArgumentFlag = false;
+		boolean itemReplacedZeroArgumentFlag = false;
+		boolean itemReplacedSingleArgumentFlag = false;
+		boolean itemMovedZeroArgumentFlag = false;
+		boolean itemMovedSingleArgumentFlag = false;
+		boolean listClearedZeroArgumentFlag = false;
+		boolean listClearedSingleArgumentFlag = false;
+		boolean listChangedZeroArgumentFlag = false;
+		boolean listChangedSingleArgumentFlag = false;
+		boolean listEventSingleArgumentFlag = false;
+		Target(TestModel testModel, String listName, String string, int index) {
+			super();
+			this.testModel = testModel;
+			this.listName = listName;
+			this.string = string;
+			this.index = index;
+		}
+		Target(TestModel testModel, String listName, String string, int index, String replacedString) {
+			this(testModel, listName, string, index);
+			this.replacedString = replacedString;
+		}
+		Target(TestModel testModel, String listName, int targetIndex, int sourceIndex) {
+			super();
+			this.testModel = testModel;
+			this.listName = listName;
+			this.index = targetIndex;
+			this.sourceIndex = sourceIndex;
+		}
+		void itemAddedZeroArgument() {
+			this.itemAddedZeroArgumentFlag = true;
+		}
+		void itemAddedSingleArgument(ListAddEvent e) {
+			this.itemAddedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.listName, e.getListName());
+			assertEquals(this.string, e.getItems().iterator().next());
+			assertEquals(this.index, e.getIndex());
+		}
+		void itemRemovedZeroArgument() {
+			this.itemRemovedZeroArgumentFlag = true;
+		}
+		void itemRemovedSingleArgument(ListRemoveEvent e) {
+			this.itemRemovedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.listName, e.getListName());
+			assertEquals(this.string, e.getItems().iterator().next());
+			assertEquals(this.index, e.getIndex());
+		}
+		void itemReplacedZeroArgument() {
+			this.itemReplacedZeroArgumentFlag = true;
+		}
+		void itemReplacedSingleArgument(ListReplaceEvent e) {
+			this.itemReplacedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.listName, e.getListName());
+			assertEquals(this.string, e.getNewItems().iterator().next());
+			assertEquals(this.replacedString, e.getOldItems().iterator().next());
+			assertEquals(this.index, e.getIndex());
+		}
+		void itemMovedZeroArgument() {
+			this.itemMovedZeroArgumentFlag = true;
+		}
+		void itemMovedSingleArgument(ListMoveEvent e) {
+			this.itemMovedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.listName, e.getListName());
+			assertEquals(this.index, e.getTargetIndex());
+			assertEquals(this.sourceIndex, e.getSourceIndex());
+		}
+		void listChangedZeroArgument() {
+			this.listChangedZeroArgumentFlag = true;
+		}
+		void listClearedSingleArgument(ListClearEvent e) {
+			this.listClearedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.listName, e.getListName());
+		}
+		void listClearedZeroArgument() {
+			this.listClearedZeroArgumentFlag = true;
+		}
+		void listChangedSingleArgument(ListChangeEvent e) {
+			this.listChangedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.listName, e.getListName());
+		}
+		void listChangedDoubleArgument(ListChangeEvent e, Object o) {
+			fail("bogus event: " + e + " - object: " + o);
+		}
+		void listEventSingleArgument(ListEvent e) {
+			this.listEventSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.listName, e.getListName());
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/ReflectivePropertyChangeListenerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/ReflectivePropertyChangeListenerTests.java
new file mode 100644
index 0000000..7dd59f9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/ReflectivePropertyChangeListenerTests.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.listener;
+
+import java.lang.reflect.Method;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ReflectiveChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
+
+@SuppressWarnings("nls")
+public class ReflectivePropertyChangeListenerTests extends TestCase {
+
+	public ReflectivePropertyChangeListenerTests(String name) {
+		super(name);
+	}
+
+	public void testZeroArgumentNamedProperty() {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		testModel.addPropertyChangeListener(TestModel.VALUE_PROPERTY, ReflectiveChangeListener.buildPropertyChangeListener(target, "propertyChangedZeroArgument"));
+		testModel.setValue(99);
+		assertTrue(target.zeroArgumentFlag);
+		assertFalse(target.singleArgumentFlag);
+	}
+
+	/**
+	 * test method that has more general method parameter type
+	 */
+	public void testSingleArgument2() throws Exception {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		Method method = ObjectTools.method(target, "propertyChangedSingleArgument2", new Class[] {Object.class});
+		testModel.addPropertyChangeListener(TestModel.VALUE_PROPERTY, ReflectiveChangeListener.buildPropertyChangeListener(target, method));
+		testModel.setValue(99);
+		assertFalse(target.zeroArgumentFlag);
+		assertTrue(target.singleArgumentFlag);
+	}
+
+	public void testSingleArgumentNamedProperty() {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		testModel.addPropertyChangeListener(TestModel.VALUE_PROPERTY, ReflectiveChangeListener.buildPropertyChangeListener(target, "propertyChangedSingleArgument"));
+		testModel.setValue(99);
+		assertFalse(target.zeroArgumentFlag);
+		assertTrue(target.singleArgumentFlag);
+	}
+
+	/**
+	 * test method that has more general method parameter type
+	 */
+	public void testSingleArgumentNamedProperty2() throws Exception {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		Method method = ObjectTools.method(target, "propertyChangedSingleArgument2", new Class[] {Object.class});
+		testModel.addPropertyChangeListener(TestModel.VALUE_PROPERTY, ReflectiveChangeListener.buildPropertyChangeListener(target, method));
+		testModel.setValue(99);
+		assertFalse(target.zeroArgumentFlag);
+		assertTrue(target.singleArgumentFlag);
+	}
+
+	public void testListenerMismatch() {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		// build a PROPERTY change listener and hack it so we
+		// can add it as a STATE change listener
+		Object listener = ReflectiveChangeListener.buildPropertyChangeListener(target, "propertyChangedSingleArgument");
+		testModel.addStateChangeListener((StateChangeListener) listener);
+
+		boolean exCaught = false;
+		try {
+			testModel.setValue(99);
+			fail("listener mismatch: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testBogusDoubleArgument1() {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		boolean exCaught = false;
+		try {
+			PropertyChangeListener listener = ReflectiveChangeListener.buildPropertyChangeListener(target, "stateChangedDoubleArgument");
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getCause().getClass() == NoSuchMethodException.class) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testBogusDoubleArgument2() throws Exception {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		Method method = ObjectTools.method(target, "propertyChangedDoubleArgument", new Class[] {PropertyChangeEvent.class, Object.class});
+		boolean exCaught = false;
+		try {
+			PropertyChangeListener listener = ReflectiveChangeListener.buildPropertyChangeListener(target, method);
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getMessage().equals(method.toString())) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+
+	class TestModel extends AbstractModel {
+		private int value = 0;
+			public static final String VALUE_PROPERTY = "value";
+		TestModel(int value) {
+			super();
+			this.value = value;
+		}
+		void setValue(int value) {
+			int old = this.value;
+			this.value = value;
+			this.firePropertyChanged(VALUE_PROPERTY, old, value);
+			if (old != value) {
+				this.fireStateChanged();
+			}
+		}
+	}
+
+	class Target {
+		TestModel testModel;
+		String propertyName;
+		Object oldValue;
+		Object newValue;
+		boolean zeroArgumentFlag = false;
+		boolean singleArgumentFlag = false;
+		Target(TestModel testModel, String propertyName, int oldValue, int newValue) {
+			super();
+			this.testModel = testModel;
+			this.propertyName = propertyName;
+			this.oldValue = new Integer(oldValue);
+			this.newValue = new Integer(newValue);
+		}
+		void propertyChangedZeroArgument() {
+			this.zeroArgumentFlag = true;
+		}
+		void propertyChangedSingleArgument(PropertyChangeEvent e) {
+			this.singleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.propertyName, e.getPropertyName());
+			assertEquals(this.oldValue, e.getOldValue());
+			assertEquals(this.newValue, e.getNewValue());
+		}
+		void propertyChangedSingleArgument2(Object o) {
+			PropertyChangeEvent e = (PropertyChangeEvent) o;
+			this.singleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.propertyName, e.getPropertyName());
+			assertEquals(this.oldValue, e.getOldValue());
+			assertEquals(this.newValue, e.getNewValue());
+		}
+		void propertyChangedDoubleArgument(PropertyChangeEvent e, Object o) {
+			fail("bogus event: " + e + " - object: " + o);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/ReflectiveStateChangeListenerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/ReflectiveStateChangeListenerTests.java
new file mode 100644
index 0000000..19c61d4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/ReflectiveStateChangeListenerTests.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.listener;
+
+import java.lang.reflect.Method;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ReflectiveChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
+
+@SuppressWarnings("nls")
+public class ReflectiveStateChangeListenerTests extends TestCase {
+
+	public ReflectiveStateChangeListenerTests(String name) {
+		super(name);
+	}
+
+	public void testZeroArgument() {
+		TestModel testModel = new TestModel();
+		Target target = new Target(testModel);
+		testModel.addStateChangeListener(ReflectiveChangeListener.buildStateChangeListener(target, "stateChangedZeroArgument"));
+		testModel.changeState();
+		assertTrue(target.zeroArgumentFlag);
+		assertFalse(target.singleArgumentFlag);
+	}
+
+	public void testSingleArgument() {
+		TestModel testModel = new TestModel();
+		Target target = new Target(testModel);
+		testModel.addStateChangeListener(ReflectiveChangeListener.buildStateChangeListener(target, "stateChangedSingleArgument"));
+		testModel.changeState();
+		assertFalse(target.zeroArgumentFlag);
+		assertTrue(target.singleArgumentFlag);
+	}
+
+	/**
+	 * test method that has more general method parameter type
+	 */
+	public void testSingleArgument2() throws Exception {
+		TestModel testModel = new TestModel();
+		Target target = new Target(testModel);
+		Method method = ObjectTools.method(target, "stateChangedSingleArgument2", new Class[] {Object.class});
+		testModel.addStateChangeListener(ReflectiveChangeListener.buildStateChangeListener(target, method));
+		testModel.changeState();
+		assertFalse(target.zeroArgumentFlag);
+		assertTrue(target.singleArgumentFlag);
+	}
+
+	public void testListenerMismatch() {
+		TestModel testModel = new TestModel();
+		Target target = new Target(testModel);
+		// build a STATE change listener and hack it so we
+		// can add it as a PROPERTY change listener
+		Object listener = ReflectiveChangeListener.buildStateChangeListener(target, "stateChangedSingleArgument");
+		testModel.addPropertyChangeListener("value", (PropertyChangeListener) listener);
+
+		boolean exCaught = false;
+		try {
+			testModel.changeProperty();
+			fail("listener mismatch: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testBogusDoubleArgument1() {
+		TestModel testModel = new TestModel();
+		Target target = new Target(testModel);
+		boolean exCaught = false;
+		try {
+			StateChangeListener listener = ReflectiveChangeListener.buildStateChangeListener(target, "stateChangedDoubleArgument");
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getCause().getClass() == NoSuchMethodException.class) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testBogusDoubleArgument2() throws Exception {
+		TestModel testModel = new TestModel();
+		Target target = new Target(testModel);
+		Method method = ObjectTools.method(target, "stateChangedDoubleArgument", new Class[] {StateChangeEvent.class, Object.class});
+		boolean exCaught = false;
+		try {
+			StateChangeListener listener = ReflectiveChangeListener.buildStateChangeListener(target, method);
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getMessage().equals(method.toString())) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+
+	class TestModel extends AbstractModel {
+		TestModel() {
+			super();
+		}
+		void changeState() {
+			this.fireStateChanged();
+		}
+		void changeProperty() {
+			this.firePropertyChanged("value", 55, 42);
+		}
+	}
+
+	class Target {
+		TestModel testModel;
+		boolean zeroArgumentFlag = false;
+		boolean singleArgumentFlag = false;
+		Target(TestModel testModel) {
+			super();
+			this.testModel = testModel;
+		}
+		void stateChangedZeroArgument() {
+			this.zeroArgumentFlag = true;
+		}
+		void stateChangedSingleArgument(StateChangeEvent e) {
+			this.singleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+		}
+		void stateChangedSingleArgument2(Object e) {
+			this.singleArgumentFlag = true;
+			assertSame(this.testModel, ((StateChangeEvent) e).getSource());
+		}
+		void stateChangedDoubleArgument(StateChangeEvent e, Object o) {
+			fail("bogus event: " + e + " - object: " + o);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/UtilityModelListenerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/UtilityModelListenerTests.java
new file mode 100644
index 0000000..94d4f84
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/listener/UtilityModelListenerTests.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.listener;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class UtilityModelListenerTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(UtilityModelListenerTests.class.getPackage().getName());
+
+		suite.addTestSuite(ReflectiveCollectionChangeListenerTests.class);
+		suite.addTestSuite(ReflectiveListChangeListenerTests.class);
+		suite.addTestSuite(ReflectivePropertyChangeListenerTests.class);
+		suite.addTestSuite(ReflectiveStateChangeListenerTests.class);
+
+		return suite;
+	}
+
+	private UtilityModelListenerTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/BufferedModifiablePropertyValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/BufferedModifiablePropertyValueModelTests.java
new file mode 100644
index 0000000..bf4c35d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/BufferedModifiablePropertyValueModelTests.java
@@ -0,0 +1,508 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.Date;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.BufferedModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class BufferedModifiablePropertyValueModelTests
+	extends TestCase
+{
+	private Employee employee;
+	private ModifiablePropertyValueModel<Employee> employeeHolder;
+	PropertyChangeEvent employeeEvent;
+
+	private ModifiablePropertyValueModel<Integer> idAdapter;
+	private ModifiablePropertyValueModel<String> nameAdapter;
+	private ModifiablePropertyValueModel<Date> hireDateAdapter;
+	PropertyChangeEvent adapterEvent;
+
+	private BufferedModifiablePropertyValueModel.Trigger trigger;
+	private BufferedModifiablePropertyValueModel<Integer> bufferedIDHolder;
+	private BufferedModifiablePropertyValueModel<String> bufferedNameHolder;
+	private BufferedModifiablePropertyValueModel<Date> bufferedHireDateHolder;
+	PropertyChangeEvent bufferedEvent;
+
+	public BufferedModifiablePropertyValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+
+		this.employee = new Employee(17, "Freddy", new Date());
+		this.employeeHolder = new SimplePropertyValueModel<Employee>(this.employee);
+
+		this.trigger = new BufferedModifiablePropertyValueModel.Trigger();
+
+		this.idAdapter = this.buildIDAdapter(this.employeeHolder);
+		this.bufferedIDHolder = new BufferedModifiablePropertyValueModel<Integer>(this.idAdapter, this.trigger);
+
+		this.nameAdapter = this.buildNameAdapter(this.employeeHolder);
+		this.bufferedNameHolder = new BufferedModifiablePropertyValueModel<String>(this.nameAdapter, this.trigger);
+
+		this.hireDateAdapter = this.buildHireDateAdapter(this.employeeHolder);
+		this.bufferedHireDateHolder = new BufferedModifiablePropertyValueModel<Date>(this.hireDateAdapter, this.trigger);
+	}
+
+	private ModifiablePropertyValueModel<Integer> buildIDAdapter(PropertyValueModel<Employee> eHolder) {
+		return new PropertyAspectAdapter<Employee, Integer>(eHolder, Employee.ID_PROPERTY) {
+			@Override
+			protected Integer buildValue_() {
+				return new Integer(this.subject.getID());
+			}
+			@Override
+			protected void setValue_(Integer value) {
+				this.subject.setID(value.intValue());
+			}
+		};
+	}
+
+	private ModifiablePropertyValueModel<String> buildNameAdapter(PropertyValueModel<Employee> eHolder) {
+		return new PropertyAspectAdapter<Employee, String>(eHolder, Employee.NAME_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getName();
+			}
+			@Override
+			protected void setValue_(String value) {
+				this.subject.setName(value);
+			}
+		};
+	}
+
+	private ModifiablePropertyValueModel<Date> buildHireDateAdapter(PropertyValueModel<Employee> eHolder) {
+		return new PropertyAspectAdapter<Employee, Date>(eHolder, Employee.HIRE_DATE_PROPERTY) {
+			@Override
+			protected Date buildValue_() {
+				return this.subject.getHireDate();
+			}
+			@Override
+			protected void setValue_(Date value) {
+				this.subject.setHireDate(value);
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testGetValue() {
+		PropertyChangeListener bufferedListener = this.buildBufferedListener();
+		this.bufferedIDHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+		this.bufferedNameHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+		this.bufferedHireDateHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+
+		assertEquals(new Integer(17), this.idAdapter.getValue());
+		assertEquals(new Integer(17), this.bufferedIDHolder.getValue());
+
+		assertEquals("Freddy", this.employee.getName());
+		assertEquals("Freddy", this.nameAdapter.getValue());
+		assertEquals("Freddy", this.bufferedNameHolder.getValue());
+
+		Date temp = this.employee.getHireDate();
+		assertEquals(temp, this.employee.getHireDate());
+		assertEquals(temp, this.hireDateAdapter.getValue());
+		assertEquals(temp, this.bufferedHireDateHolder.getValue());
+
+		this.bufferedIDHolder.setValue(new Integer(323));
+		assertEquals(17, this.employee.getID());
+		assertEquals(new Integer(17), this.idAdapter.getValue());
+		assertEquals(new Integer(323), this.bufferedIDHolder.getValue());
+
+		this.bufferedNameHolder.setValue("Ripley");
+		assertEquals("Freddy", this.employee.getName());
+		assertEquals("Freddy", this.nameAdapter.getValue());
+		assertEquals("Ripley", this.bufferedNameHolder.getValue());
+
+		this.bufferedHireDateHolder.setValue(null);
+		assertEquals(temp, this.employee.getHireDate());
+		assertEquals(temp, this.hireDateAdapter.getValue());
+		assertEquals(null, this.bufferedHireDateHolder.getValue());
+	}
+
+	public void testTriggerAccept() {
+		PropertyChangeListener bufferedListener = this.buildBufferedListener();
+		this.bufferedIDHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+		this.bufferedNameHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+		this.bufferedHireDateHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+
+		this.bufferedIDHolder.setValue(new Integer(323));
+		assertEquals(17, this.employee.getID());
+		assertEquals(new Integer(17), this.idAdapter.getValue());
+		assertEquals(new Integer(323), this.bufferedIDHolder.getValue());
+
+		this.bufferedNameHolder.setValue("Ripley");
+		assertEquals("Freddy", this.employee.getName());
+		assertEquals("Freddy", this.nameAdapter.getValue());
+		assertEquals("Ripley", this.bufferedNameHolder.getValue());
+
+		Date temp = this.employee.getHireDate();
+		this.bufferedHireDateHolder.setValue(null);
+		assertEquals(temp, this.employee.getHireDate());
+		assertEquals(temp, this.hireDateAdapter.getValue());
+		assertEquals(null, this.bufferedHireDateHolder.getValue());
+
+		this.trigger.accept();
+
+		assertEquals(323, this.employee.getID());
+		assertEquals(new Integer(323), this.idAdapter.getValue());
+		assertEquals(new Integer(323), this.bufferedIDHolder.getValue());
+
+		assertEquals("Ripley", this.employee.getName());
+		assertEquals("Ripley", this.nameAdapter.getValue());
+		assertEquals("Ripley", this.bufferedNameHolder.getValue());
+
+		assertEquals(null, this.employee.getHireDate());
+		assertEquals(null, this.hireDateAdapter.getValue());
+		assertEquals(null, this.bufferedHireDateHolder.getValue());
+	}
+
+	public void testTriggerReset() {
+		PropertyChangeListener bufferedListener = this.buildBufferedListener();
+		this.bufferedIDHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+		this.bufferedNameHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+		this.bufferedHireDateHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+
+		this.bufferedIDHolder.setValue(new Integer(323));
+		assertEquals(17, this.employee.getID());
+		assertEquals(new Integer(17), this.idAdapter.getValue());
+		assertEquals(new Integer(323), this.bufferedIDHolder.getValue());
+
+		this.bufferedNameHolder.setValue("Ripley");
+		assertEquals("Freddy", this.employee.getName());
+		assertEquals("Freddy", this.nameAdapter.getValue());
+		assertEquals("Ripley", this.bufferedNameHolder.getValue());
+
+		Date temp = this.employee.getHireDate();
+		this.bufferedHireDateHolder.setValue(null);
+		assertEquals(temp, this.employee.getHireDate());
+		assertEquals(temp, this.hireDateAdapter.getValue());
+		assertEquals(null, this.bufferedHireDateHolder.getValue());
+
+		this.trigger.reset();
+
+		assertEquals(17, this.employee.getID());
+		assertEquals(new Integer(17), this.idAdapter.getValue());
+		assertEquals(new Integer(17), this.bufferedIDHolder.getValue());
+
+		assertEquals("Freddy", this.employee.getName());
+		assertEquals("Freddy", this.nameAdapter.getValue());
+		assertEquals("Freddy", this.bufferedNameHolder.getValue());
+
+		assertEquals(temp, this.employee.getHireDate());
+		assertEquals(temp, this.hireDateAdapter.getValue());
+		assertEquals(temp, this.bufferedHireDateHolder.getValue());
+	}
+
+	public void testLazyListening() {
+		assertTrue(((AbstractModel) this.bufferedIDHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.bufferedNameHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.bufferedHireDateHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		assertTrue(((AbstractModel) this.idAdapter).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.nameAdapter).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.hireDateAdapter).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		assertTrue(this.employee.hasNoPropertyChangeListeners(Employee.ID_PROPERTY));
+		assertTrue(this.employee.hasNoPropertyChangeListeners(Employee.NAME_PROPERTY));
+		assertTrue(this.employee.hasNoPropertyChangeListeners(Employee.HIRE_DATE_PROPERTY));
+
+		PropertyChangeListener bufferedListener = this.buildBufferedListener();
+		this.bufferedIDHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+		this.bufferedNameHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+		this.bufferedHireDateHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+
+		assertTrue(((AbstractModel) this.bufferedIDHolder).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.bufferedNameHolder).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.bufferedHireDateHolder).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		assertTrue(((AbstractModel) this.idAdapter).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.nameAdapter).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.hireDateAdapter).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		assertTrue(this.employee.hasAnyPropertyChangeListeners(Employee.ID_PROPERTY));
+		assertTrue(this.employee.hasAnyPropertyChangeListeners(Employee.NAME_PROPERTY));
+		assertTrue(this.employee.hasAnyPropertyChangeListeners(Employee.HIRE_DATE_PROPERTY));
+
+		this.bufferedIDHolder.removePropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+		this.bufferedNameHolder.removePropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+		this.bufferedHireDateHolder.removePropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+
+		assertTrue(((AbstractModel) this.bufferedIDHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.bufferedNameHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.bufferedHireDateHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		assertTrue(((AbstractModel) this.idAdapter).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.nameAdapter).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.hireDateAdapter).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		assertTrue(this.employee.hasNoPropertyChangeListeners(Employee.ID_PROPERTY));
+		assertTrue(this.employee.hasNoPropertyChangeListeners(Employee.NAME_PROPERTY));
+		assertTrue(this.employee.hasNoPropertyChangeListeners(Employee.HIRE_DATE_PROPERTY));
+	}
+
+	public void testPropertyChange1() {
+		PropertyChangeListener bufferedListener = this.buildBufferedListener();
+		this.bufferedNameHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+
+		PropertyChangeListener adapterListener = this.buildAdapterListener();
+		this.nameAdapter.addPropertyChangeListener(PropertyValueModel.VALUE, adapterListener);
+
+		PropertyChangeListener employeeListener = this.buildEmployeeListener();
+		this.employee.addPropertyChangeListener(Employee.NAME_PROPERTY, employeeListener);
+
+		this.verifyPropertyChanges();
+	}
+
+	public void testPropertyChange2() {
+		ChangeListener bufferedListener = this.buildBufferedListener();
+		this.bufferedNameHolder.addChangeListener(bufferedListener);
+
+		ChangeListener adapterListener = this.buildAdapterListener();
+		this.nameAdapter.addChangeListener(adapterListener);
+
+		ChangeListener employeeListener = this.buildEmployeeListener();
+		this.employee.addChangeListener(employeeListener);
+
+		this.verifyPropertyChanges();
+	}
+
+	private void verifyPropertyChanges() {
+		this.bufferedEvent = null;
+		this.adapterEvent = null;
+		this.employeeEvent = null;
+		this.bufferedNameHolder.setValue("Ripley");
+		this.verifyEvent(this.bufferedEvent, this.bufferedNameHolder, PropertyValueModel.VALUE, "Freddy", "Ripley");
+		assertNull(this.adapterEvent);
+		assertNull(this.employeeEvent);
+
+		this.bufferedEvent = null;
+		this.adapterEvent = null;
+		this.employeeEvent = null;
+		this.bufferedNameHolder.setValue("Charlie");
+		this.verifyEvent(this.bufferedEvent, this.bufferedNameHolder, PropertyValueModel.VALUE, "Ripley", "Charlie");
+		assertNull(this.adapterEvent);
+		assertNull(this.employeeEvent);
+
+		this.bufferedEvent = null;
+		this.adapterEvent = null;
+		this.employeeEvent = null;
+		this.trigger.accept();
+		assertNull(this.bufferedEvent);
+		this.verifyEvent(this.adapterEvent, this.nameAdapter, PropertyValueModel.VALUE, "Freddy", "Charlie");
+		this.verifyEvent(this.employeeEvent, this.employee, Employee.NAME_PROPERTY, "Freddy", "Charlie");
+
+		this.bufferedEvent = null;
+		this.adapterEvent = null;
+		this.employeeEvent = null;
+		this.bufferedNameHolder.setValue("Jason");
+		this.verifyEvent(this.bufferedEvent, this.bufferedNameHolder, PropertyValueModel.VALUE, "Charlie", "Jason");
+		assertNull(this.adapterEvent);
+		assertNull(this.employeeEvent);
+
+		this.bufferedEvent = null;
+		this.adapterEvent = null;
+		this.employeeEvent = null;
+		this.trigger.reset();
+		this.verifyEvent(this.bufferedEvent, this.bufferedNameHolder, PropertyValueModel.VALUE, "Jason", "Charlie");
+		assertNull(this.adapterEvent);
+		assertNull(this.employeeEvent);
+	}
+
+	/**
+	 * changing the value should trigger buffering
+	 */
+	public void testBuffering1() {
+		PropertyChangeListener bufferedListener = this.buildBufferedListener();
+		this.bufferedNameHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+
+		this.bufferedNameHolder.setValue("Ripley");
+		assertEquals("Freddy", this.nameAdapter.getValue());
+		assertEquals("Ripley", this.bufferedNameHolder.getValue());
+		assertTrue(this.bufferedNameHolder.isBuffering());
+	}
+
+	/**
+	 * setting to the same value should not trigger buffering (?)
+	 */
+	public void testBuffering2() {
+		PropertyChangeListener bufferedListener = this.buildBufferedListener();
+		this.bufferedNameHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+
+		this.bufferedNameHolder.setValue("Freddy");
+		assertEquals("Freddy", this.bufferedNameHolder.getValue());
+		assertEquals("Freddy", this.nameAdapter.getValue());
+		assertFalse(this.bufferedNameHolder.isBuffering());
+	}
+
+	/**
+	 * setting to the original value should not trigger buffering (?)
+	 */
+	public void testBuffering3() {
+		PropertyChangeListener bufferedListener = this.buildBufferedListener();
+		this.bufferedNameHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+
+		this.bufferedNameHolder.setValue("Ripley");
+		assertEquals("Freddy", this.nameAdapter.getValue());
+		assertEquals("Ripley", this.bufferedNameHolder.getValue());
+		assertTrue(this.bufferedNameHolder.isBuffering());
+
+		this.bufferedNameHolder.setValue("Freddy");
+		assertEquals("Freddy", this.nameAdapter.getValue());
+		assertEquals("Freddy", this.bufferedNameHolder.getValue());
+		assertFalse(this.bufferedNameHolder.isBuffering());
+	}
+
+	/**
+	 * back-door changes are ignored - "Last One In Wins"
+	 */
+	public void testChangeConflict1() {
+		PropertyChangeListener bufferedListener = this.buildBufferedListener();
+		this.bufferedNameHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+
+		this.bufferedNameHolder.setValue("Ripley");
+		assertEquals("Freddy", this.employee.getName());
+		assertEquals("Freddy", this.nameAdapter.getValue());
+		assertEquals("Ripley", this.bufferedNameHolder.getValue());
+
+		this.nameAdapter.setValue("Jason");
+		assertEquals("Jason", this.employee.getName());
+		assertEquals("Jason", this.nameAdapter.getValue());
+		assertEquals("Ripley", this.bufferedNameHolder.getValue());
+
+		this.trigger.accept();
+		// "Jason" is dropped on the floor...
+		assertEquals("Ripley", this.employee.getName());
+		assertEquals("Ripley", this.nameAdapter.getValue());
+		assertEquals("Ripley", this.bufferedNameHolder.getValue());
+	}
+
+	/**
+	 * back-door changes can de-activate buffering (?)
+	 */
+	public void testChangeConflict2() {
+		PropertyChangeListener bufferedListener = this.buildBufferedListener();
+		this.bufferedNameHolder.addPropertyChangeListener(PropertyValueModel.VALUE, bufferedListener);
+
+		this.bufferedNameHolder.setValue("Ripley");
+		assertEquals("Freddy", this.employee.getName());
+		assertEquals("Freddy", this.nameAdapter.getValue());
+		assertEquals("Ripley", this.bufferedNameHolder.getValue());
+		assertTrue(this.bufferedNameHolder.isBuffering());
+
+		this.nameAdapter.setValue("Ripley");
+		assertEquals("Ripley", this.employee.getName());
+		assertEquals("Ripley", this.nameAdapter.getValue());
+		assertEquals("Ripley", this.bufferedNameHolder.getValue());
+		assertFalse(this.bufferedNameHolder.isBuffering());
+	}
+
+	private ChangeListener buildBufferedListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				BufferedModifiablePropertyValueModelTests.this.bufferedEvent = e;
+			}
+		};
+	}
+
+	private ChangeListener buildAdapterListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				BufferedModifiablePropertyValueModelTests.this.adapterEvent = e;
+			}
+		};
+	}
+
+	private ChangeListener buildEmployeeListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				BufferedModifiablePropertyValueModelTests.this.employeeEvent = e;
+			}
+		};
+	}
+
+	private void verifyEvent(PropertyChangeEvent event, Object source, String propertyName, Object oldValue, Object newValue) {
+		assertEquals(source, event.getSource());
+		assertEquals(propertyName, event.getPropertyName());
+		assertEquals(oldValue, event.getOldValue());
+		assertEquals(newValue, event.getNewValue());
+	}
+
+
+	// ********** inner class **********
+
+	class Employee extends AbstractModel {
+		private int id;
+			public static final String ID_PROPERTY = "id";
+		private String name;
+			public static final String NAME_PROPERTY = "name";
+		private Date hireDate;
+			public static final String HIRE_DATE_PROPERTY = "hireDate";
+
+		Employee(int id, String name, Date hireDate) {
+			super();
+			this.id = id;
+			this.name = name;
+			this.hireDate = hireDate;
+		}
+		int getID() {
+			return this.id;
+		}
+		void setID(int id) {
+			int old = this.id;
+			this.id = id;
+			this.firePropertyChanged(ID_PROPERTY, old, id);
+		}
+		String getName() {
+			return this.name;
+		}
+		void setName(String name) {
+			Object old = this.name;
+			this.name = name;
+			this.firePropertyChanged(NAME_PROPERTY, old, name);
+		}
+		Date getHireDate() {
+			return this.hireDate;
+		}
+		void setHireDate(Date hireDate) {
+			Object old = this.hireDate;
+			this.hireDate = hireDate;
+			this.firePropertyChanged(HIRE_DATE_PROPERTY, old, hireDate);
+		}
+		@Override
+		public void toString(StringBuilder sb) {
+			sb.append(this.name);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CachingTransformationPropertyValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CachingTransformationPropertyValueModelTests.java
new file mode 100644
index 0000000..1102dc5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CachingTransformationPropertyValueModelTests.java
@@ -0,0 +1,243 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.TransformationPropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+@SuppressWarnings("nls")
+public class CachingTransformationPropertyValueModelTests extends TestCase {
+	private ModifiablePropertyValueModel<Person> objectHolder;
+	PropertyChangeEvent event;
+
+	private PropertyValueModel<Person> transformationObjectHolder;
+	PropertyChangeEvent transformationEvent;
+
+	public CachingTransformationPropertyValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.objectHolder = new SimplePropertyValueModel<Person>(new Person("Karen", "Peggy", null));
+		this.transformationObjectHolder = new TransformationPropertyValueModel<Person, Person>(this.objectHolder, this.buildTransformer());
+	}
+
+	private Transformer<Person, Person> buildTransformer() {
+		return new Transformer<Person, Person>() {
+			@Override
+			public Person transform(Person p) {
+				return (p == null) ? null : p.getParent();
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testValue() {
+		ChangeListener listener = this.buildTransformationChangeListener();
+		this.transformationObjectHolder.addChangeListener(listener);
+
+		Person person = this.objectHolder.getValue();
+		assertEquals("Karen", person.getName());
+		Person parent = this.transformationObjectHolder.getValue();
+		assertEquals(person.getParent().getName(), parent.getName());
+		assertNotSame(person.getParent(), this.transformationObjectHolder.getValue());
+		assertEquals(parent, this.transformationObjectHolder.getValue());
+
+		Person person1 = new Person("Matt", "Mitch", null);
+		this.objectHolder.setValue(person1);
+		Person parent2 = this.transformationObjectHolder.getValue();
+		assertEquals(person1.getParent().getName(), parent2.getName());
+		assertNotSame(person1.getParent(), this.transformationObjectHolder.getValue());
+		assertEquals(parent2, this.transformationObjectHolder.getValue());
+
+
+		this.objectHolder.setValue(null);
+		assertNull(this.objectHolder.getValue());
+		assertNull(this.transformationObjectHolder.getValue());
+
+		Person person3 = new Person("Karen", "Peggy", null);
+		this.objectHolder.setValue(person3);
+		assertEquals("Karen", person3.getName());
+		Person parent3 = this.transformationObjectHolder.getValue();
+		assertEquals(person3.getParent().getName(), parent3.getName());
+		assertNotSame(person3.getParent(), this.transformationObjectHolder.getValue());
+		assertEquals(parent3, this.transformationObjectHolder.getValue());
+	}
+
+	public void testLazyListening() {
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		ChangeListener listener = this.buildTransformationChangeListener();
+		this.transformationObjectHolder.addChangeListener(listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.transformationObjectHolder.removeChangeListener(listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.transformationObjectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.transformationObjectHolder.removePropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	public void testPropertyChange1() {
+		this.objectHolder.addChangeListener(this.buildChangeListener());
+		this.transformationObjectHolder.addChangeListener(this.buildTransformationChangeListener());
+		this.verifyPropertyChanges();
+	}
+
+	public void testPropertyChange2() {
+		this.objectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildListener());
+		this.transformationObjectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildTransformationListener());
+		this.verifyPropertyChanges();
+	}
+
+	private void verifyPropertyChanges() {
+		this.event = null;
+		this.transformationEvent = null;
+		Person karen = this.objectHolder.getValue();
+		Person peggyParent = this.transformationObjectHolder.getValue();
+		Person peggy = new Person("Peggy", "Marian", null);
+		this.objectHolder.setValue(peggy);
+		Person marianParent = this.transformationObjectHolder.getValue();
+		this.verifyEvent(this.event, this.objectHolder, karen, peggy);
+		this.verifyEvent(this.transformationEvent, this.transformationObjectHolder, peggyParent, marianParent);
+
+		this.event = null;
+		this.transformationEvent = null;
+		Person matt = new Person("Matt", "Mitch", null);
+		this.objectHolder.setValue(matt);
+		Person mitchParent = this.transformationObjectHolder.getValue();
+		this.verifyEvent(this.event, this.objectHolder, peggy, matt);
+		this.verifyEvent(this.transformationEvent, this.transformationObjectHolder, marianParent, mitchParent);
+
+		this.event = null;
+		this.transformationEvent = null;
+		this.objectHolder.setValue(null);
+		this.verifyEvent(this.event, this.objectHolder, matt, null);
+		this.verifyEvent(this.transformationEvent, this.transformationObjectHolder, mitchParent, null);
+
+		this.event = null;
+		this.transformationEvent = null;
+		this.objectHolder.setValue(matt);
+		mitchParent = this.transformationObjectHolder.getValue();
+		this.verifyEvent(this.event, this.objectHolder, null, matt);
+		this.verifyEvent(this.transformationEvent, this.transformationObjectHolder, null, mitchParent);
+	}
+
+	private PropertyChangeListener buildListener() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				CachingTransformationPropertyValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	private PropertyChangeListener buildTransformationListener() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				CachingTransformationPropertyValueModelTests.this.transformationEvent = e;
+			}
+		};
+	}
+
+	private ChangeListener buildChangeListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				CachingTransformationPropertyValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	private ChangeListener buildTransformationChangeListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				CachingTransformationPropertyValueModelTests.this.transformationEvent = e;
+			}
+		};
+	}
+
+	private void verifyEvent(PropertyChangeEvent e, Object source, Object oldValue, Object newValue) {
+		assertEquals(source, e.getSource());
+		assertEquals(PropertyValueModel.VALUE, e.getPropertyName());
+		assertEquals(oldValue, e.getOldValue());
+		assertEquals(newValue, e.getNewValue());
+	}
+
+
+	class Person
+		extends AbstractModel
+	{
+		private String name;
+			public static final String NAME_PROPERTY = "name";
+
+		private String parentName;
+			public static final String PARENT_NAME_PROPERTY = "parentName";
+
+		private Person child;
+
+		public Person(String name, String parentName, Person child) {
+			this.name = name;
+			this.parentName = parentName;
+			this.child = child;
+		}
+
+		public String getName() {
+			return this.name;
+		}
+
+		public void setName(String newName) {
+			String oldName = this.name;
+			this.name = newName;
+			firePropertyChanged(NAME_PROPERTY, oldName, newName);
+		}
+
+		public Person getParent() {
+			return new Person(this.parentName, null, this);
+		}
+
+		public String getParentName() {
+			return this.parentName;
+		}
+
+		public void setParentName(String newParentName) {
+			String oldParentName = this.parentName;
+			this.parentName = newParentName;
+			firePropertyChanged(PARENT_NAME_PROPERTY, oldParentName, newParentName);
+		}
+
+		public Person getChild() {
+			return this.child;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CollectionAspectAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CollectionAspectAdapterTests.java
new file mode 100644
index 0000000..9c98c39
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CollectionAspectAdapterTests.java
@@ -0,0 +1,377 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CollectionAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class CollectionAspectAdapterTests extends TestCase {
+	private TestSubject subject1;
+	private ModifiablePropertyValueModel<TestSubject> subjectHolder1;
+	private LocalCollectionAspectAdapter aa1;
+	private CollectionEvent event1;
+	private CollectionChangeListener listener1;
+	private String event1Type;
+
+	private static final String ADD = "add";
+	private static final String REMOVE = "remove";
+	private static final String CHANGE = "change";
+	private static final String CLEAR = "clear";
+
+	private TestSubject subject2;
+
+	public CollectionAspectAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.subject1 = new TestSubject();
+		this.subject1.addNames(this.subject1Names());
+		this.subject1.addDescriptions(this.subject1Descriptions());
+		this.subjectHolder1 = new SimplePropertyValueModel<TestSubject>(this.subject1);
+		this.aa1 = this.buildAspectAdapter(this.subjectHolder1);
+		this.listener1 = this.buildValueChangeListener1();
+		this.aa1.addCollectionChangeListener(CollectionValueModel.VALUES, this.listener1);
+		this.event1 = null;
+		this.event1Type = null;
+
+		this.subject2 = new TestSubject();
+		this.subject2.addNames(this.subject2Names());
+		this.subject2.addDescriptions(this.subject2Descriptions());
+	}
+
+	private Collection<String> subject1Names() {
+		Collection<String> result = new HashBag<String>();
+		result.add("foo");
+		result.add("bar");
+		return result;
+	}
+
+	private Collection<String> subject1Descriptions() {
+		Collection<String> result = new HashBag<String>();
+		result.add("this.subject1 description1");
+		result.add("this.subject1 description2");
+		return result;
+	}
+
+	private Collection<String> subject2Names() {
+		Collection<String> result = new HashBag<String>();
+		result.add("baz");
+		result.add("bam");
+		return result;
+	}
+
+	private Collection<String> subject2Descriptions() {
+		Collection<String> result = new HashBag<String>();
+		result.add("this.subject2 description1");
+		result.add("this.subject2 description2");
+		return result;
+	}
+
+	private LocalCollectionAspectAdapter buildAspectAdapter(PropertyValueModel<TestSubject> subjectHolder) {
+		return new LocalCollectionAspectAdapter(subjectHolder);
+	}
+
+	private CollectionChangeListener buildValueChangeListener1() {
+		return new CollectionChangeListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {
+				CollectionAspectAdapterTests.this.value1Changed(e, ADD);
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {
+				CollectionAspectAdapterTests.this.value1Changed(e, REMOVE);
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent e) {
+				CollectionAspectAdapterTests.this.value1Changed(e, CLEAR);
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent e) {
+				CollectionAspectAdapterTests.this.value1Changed(e, CHANGE);
+			}
+		};
+	}
+
+	void value1Changed(CollectionEvent e, String eventType) {
+		this.event1 = e;
+		this.event1Type = eventType;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testSubjectHolder() {
+		assertEquals(this.subject1Names(), CollectionTools.bag(this.aa1.iterator()));
+		assertNull(this.event1);
+
+		this.subjectHolder1.setValue(this.subject2);
+		assertNotNull(this.event1);
+		assertEquals(this.event1Type, CHANGE);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(CollectionValueModel.VALUES, this.event1.getCollectionName());
+		assertEquals(this.subject2Names(), CollectionTools.bag(this.aa1.iterator()));
+
+		this.event1 = null;
+		this.event1Type = null;
+		this.subjectHolder1.setValue(null);
+		assertNotNull(this.event1);
+		assertEquals(this.event1Type, CHANGE);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(CollectionValueModel.VALUES, this.event1.getCollectionName());
+		assertFalse(this.aa1.iterator().hasNext());
+
+		this.event1 = null;
+		this.event1Type = null;
+		this.subjectHolder1.setValue(this.subject1);
+		assertNotNull(this.event1);
+		assertEquals(this.event1Type, CHANGE);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(CollectionValueModel.VALUES, this.event1.getCollectionName());
+		assertEquals(this.subject1Names(), CollectionTools.bag(this.aa1.iterator()));
+	}
+
+	public void testAdd() {
+		assertEquals(this.subject1Names(), CollectionTools.bag(this.aa1.iterator()));
+		assertNull(this.event1);
+
+		this.subject1.addName("jam");
+		assertNotNull(this.event1);
+		assertEquals(this.event1Type, ADD);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(CollectionValueModel.VALUES, this.event1.getCollectionName());
+		assertEquals("jam", ((CollectionAddEvent) this.event1).getItems().iterator().next());
+		Collection<String> namesPlus = this.subject1Names();
+		namesPlus.add("jam");
+		assertEquals(namesPlus, CollectionTools.bag(this.aa1.iterator()));
+
+		this.event1 = null;
+		this.event1Type = null;
+		this.aa1.addAll(Collections.singleton("jaz"));
+		assertNotNull(this.event1);
+		assertEquals(this.event1Type, ADD);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(CollectionValueModel.VALUES, this.event1.getCollectionName());
+		assertEquals("jaz", ((CollectionAddEvent) this.event1).getItems().iterator().next());
+		namesPlus.add("jaz");
+		assertEquals(namesPlus, CollectionTools.bag(this.aa1.iterator()));
+	}
+
+	public void testRemove() {
+		assertEquals(this.subject1Names(), CollectionTools.bag(this.aa1.iterator()));
+		assertNull(this.event1);
+
+		this.subject1.removeName("foo");
+		assertNotNull(this.event1);
+		assertEquals(this.event1Type, REMOVE);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(CollectionValueModel.VALUES, this.event1.getCollectionName());
+		assertEquals("foo", ((CollectionRemoveEvent) this.event1).getItems().iterator().next());
+		Collection<String> namesMinus = this.subject1Names();
+		namesMinus.remove("foo");
+		assertEquals(namesMinus, CollectionTools.bag(this.aa1.iterator()));
+
+		this.event1 = null;
+		this.event1Type = null;
+		this.aa1.removeAll(Collections.singleton("bar"));
+		assertNotNull(this.event1);
+		assertEquals(this.event1Type, REMOVE);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(CollectionValueModel.VALUES, this.event1.getCollectionName());
+		assertEquals("bar", ((CollectionRemoveEvent) this.event1).getItems().iterator().next());
+		namesMinus.remove("bar");
+		assertEquals(namesMinus, CollectionTools.bag(this.aa1.iterator()));
+	}
+
+	public void testCollectionChange() {
+		assertEquals(this.subject1Names(), CollectionTools.bag(this.aa1.iterator()));
+		assertNull(this.event1);
+
+		this.subject1.addTwoNames("jam", "jaz");
+		assertNotNull(this.event1);
+		assertEquals(this.event1Type, CHANGE);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(CollectionValueModel.VALUES, this.event1.getCollectionName());
+		Collection<String> namesPlus2 = this.subject1Names();
+		namesPlus2.add("jam");
+		namesPlus2.add("jaz");
+		assertEquals(namesPlus2, CollectionTools.bag(this.aa1.iterator()));
+	}
+
+	public void testIterator() {
+		assertEquals(this.subject1Names(), CollectionTools.bag(this.subject1.names()));
+		assertEquals(this.subject1Names(), CollectionTools.bag(this.aa1.iterator()));
+	}
+
+	public void testSize() {
+		assertEquals(this.subject1Names().size(), IteratorTools.size(this.subject1.names()));
+		assertEquals(this.subject1Names().size(), IteratorTools.size(this.aa1.iterator()));
+	}
+
+	public void testHasListeners() {
+		assertTrue(this.aa1.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		assertTrue(this.subject1.hasAnyCollectionChangeListeners(TestSubject.NAMES_COLLECTION));
+		this.aa1.removeCollectionChangeListener(CollectionValueModel.VALUES, this.listener1);
+		assertFalse(this.subject1.hasAnyCollectionChangeListeners(TestSubject.NAMES_COLLECTION));
+		assertFalse(this.aa1.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+
+		ChangeListener listener2 = new ChangeAdapter();
+		this.aa1.addChangeListener(listener2);
+		assertTrue(this.aa1.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		assertTrue(this.subject1.hasAnyCollectionChangeListeners(TestSubject.NAMES_COLLECTION));
+		this.aa1.removeChangeListener(listener2);
+		assertFalse(this.subject1.hasAnyCollectionChangeListeners(TestSubject.NAMES_COLLECTION));
+		assertFalse(this.aa1.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+	}
+
+
+	// ********** inner class **********
+
+	private class TestSubject extends AbstractModel {
+		private Collection<String> names;
+		public static final String NAMES_COLLECTION = "names";
+		private Collection<String> descriptions;
+		public static final String DESCRIPTIONS_COLLECTION = "descriptions";
+
+		public TestSubject() {
+			this.names = new HashBag<String>();
+			this.descriptions = new HashBag<String>();
+		}
+		public Iterator<String> names() {
+			return new ReadOnlyIterator<String>(this.names);
+		}
+		public void addName(String name) {
+			if (this.names.add(name)) {
+				this.fireItemAdded(NAMES_COLLECTION, name);
+			}
+		}
+		public void addNames(Iterator<String> newNames) {
+			while (newNames.hasNext()) {
+				this.addName(newNames.next());
+			}
+		}
+		public void addNames(Collection<String> newNames) {
+			this.addNames(newNames.iterator());
+		}
+		public void addTwoNames(String name1, String name2) {
+			if (this.names.add(name1) | this.names.add(name2)) {
+				this.fireCollectionChanged(NAMES_COLLECTION, this.names);
+			}
+		}
+		public void removeName(String name) {
+			if (this.names.remove(name)) {
+				this.fireItemRemoved(NAMES_COLLECTION, name);
+			}
+		}
+		public Iterator<String> descriptions() {
+			return new ReadOnlyIterator<String>(this.descriptions);
+		}
+		public void addDescription(String description) {
+			if (this.descriptions.add(description)) {
+				this.fireItemAdded(DESCRIPTIONS_COLLECTION, description);
+			}
+		}
+		public void addDescriptions(Iterator<String> newDescriptions) {
+			while (newDescriptions.hasNext()) {
+				this.addDescription(newDescriptions.next());
+			}
+		}
+		public void addDescriptions(Collection<String> newDescriptions) {
+			this.addDescriptions(newDescriptions.iterator());
+		}
+		public void removeDescription(String description) {
+			if (this.descriptions.remove(description)) {
+				this.fireItemRemoved(DESCRIPTIONS_COLLECTION, description);
+			}
+		}
+	}
+
+	// this is not a typical aspect adapter - the value is determined by the aspect name
+	private class LocalCollectionAspectAdapter extends CollectionAspectAdapter<TestSubject, String> {
+
+		LocalCollectionAspectAdapter(PropertyValueModel<TestSubject> subjectHolder) {
+			super(subjectHolder, TestSubject.NAMES_COLLECTION);
+		}
+
+		@Override
+		protected Iterator<String> iterator_() {
+			if (this.aspectNames[0] == TestSubject.NAMES_COLLECTION) {
+				return this.subject.names();
+			}
+			if (this.aspectNames[0] == TestSubject.DESCRIPTIONS_COLLECTION) {
+				return this.subject.descriptions();
+			}
+			throw new IllegalStateException("invalid aspect name: " + this.aspectNames[0]);
+		}
+
+		public void add(String item) {
+			if (this.aspectNames[0] == TestSubject.NAMES_COLLECTION) {
+				this.subject.addName(item);
+			} else if (this.aspectNames[0] == TestSubject.DESCRIPTIONS_COLLECTION) {
+				this.subject.addDescription(item);
+			} else {
+				throw new IllegalStateException("invalid aspect name: " + this.aspectNames[0]);
+			}
+		}
+
+		public void addAll(Collection<String> items) {
+			for (Iterator<String> stream = items.iterator(); stream.hasNext(); ) {
+				this.add(stream.next());
+			}
+		}
+
+		public void remove(Object item) {
+			if (this.aspectNames[0] == TestSubject.NAMES_COLLECTION) {
+				this.subject.removeName((String) item);
+			} else if (this.aspectNames[0] == TestSubject.DESCRIPTIONS_COLLECTION) {
+				this.subject.removeDescription((String) item);
+			} else {
+				throw new IllegalStateException("invalid aspect name: " + this.aspectNames[0]);
+			}
+		}
+
+		public void removeAll(Collection<String> items) {
+			for (Iterator<String> stream = items.iterator(); stream.hasNext(); ) {
+				this.remove(stream.next());
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CollectionListValueModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CollectionListValueModelAdapterTests.java
new file mode 100644
index 0000000..0c5e1d9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CollectionListValueModelAdapterTests.java
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.Collection;
+import java.util.List;
+import javax.swing.JList;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CollectionListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.ListModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class CollectionListValueModelAdapterTests extends TestCase {
+	private ListValueModel<String> adapter;
+	private SimpleCollectionValueModel<String> wrappedCollectionHolder;
+	private Collection<String> wrappedCollection;
+
+	public CollectionListValueModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.wrappedCollection = new HashBag<String>();
+		this.wrappedCollectionHolder = new SimpleCollectionValueModel<String>(this.wrappedCollection);
+		this.adapter = new CollectionListValueModelAdapter<String>(this.wrappedCollectionHolder);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testIterator() {
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {/* OK */}
+		});
+		this.wrappedCollectionHolder.add("foo");
+		this.wrappedCollectionHolder.add("bar");
+		this.wrappedCollectionHolder.add("baz");
+		Collection<String> adapterCollection = this.adapterCollection();
+		assertEquals(3, adapterCollection.size());
+		assertEquals(this.wrappedCollection, adapterCollection);
+	}
+
+	private Collection<String> adapterCollection() {
+		return CollectionTools.collection(this.adapter.iterator());
+	}
+
+	public void testStaleValue() {
+		ListChangeListener listener = new TestListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {/* OK */}
+		};
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		this.wrappedCollectionHolder.add("foo");
+		this.wrappedCollectionHolder.add("bar");
+		this.wrappedCollectionHolder.add("baz");
+		Collection<String> adapterCollection = this.adapterCollection();
+		assertEquals(3, adapterCollection.size());
+		assertEquals(this.wrappedCollection, adapterCollection);
+
+		this.adapter.removeListChangeListener(ListValueModel.LIST_VALUES, listener);
+		adapterCollection = this.adapterCollection();
+		assertEquals(0, adapterCollection.size());
+		assertEquals(new HashBag<String>(), adapterCollection);
+
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		adapterCollection = this.adapterCollection();
+		assertEquals(3, adapterCollection.size());
+		assertEquals(this.wrappedCollection, adapterCollection);
+	}
+
+	public void testAdd() {
+		List<String> synchList = new CoordinatedList<String>(this.adapter);
+		Bag<String> synchCollection = new CoordinatedBag<String>(this.wrappedCollectionHolder);
+		this.wrappedCollectionHolder.add("foo");
+		assertTrue(this.wrappedCollection.contains("foo"));
+		this.wrappedCollectionHolder.add("bar");
+		this.wrappedCollectionHolder.add("baz");
+		this.wrappedCollectionHolder.add("joo");
+		this.wrappedCollectionHolder.add("jar");
+		this.wrappedCollectionHolder.add("jaz");
+		assertEquals(6, this.wrappedCollection.size());
+
+		Collection<String> adapterCollection = this.adapterCollection();
+		assertEquals(this.wrappedCollection, adapterCollection);
+		assertEquals(this.wrappedCollection, CollectionTools.collection(synchList.iterator()));
+		assertEquals(this.wrappedCollection, synchCollection);
+	}
+
+	public void testRemove() {
+		List<String> synchList = new CoordinatedList<String>(this.adapter);
+		Bag<String> synchCollection = new CoordinatedBag<String>(this.wrappedCollectionHolder);
+		this.wrappedCollectionHolder.add("foo");
+		this.wrappedCollectionHolder.add("bar");
+		this.wrappedCollectionHolder.add("baz");
+		this.wrappedCollectionHolder.add("joo");
+		this.wrappedCollectionHolder.add("jar");
+		this.wrappedCollectionHolder.add("jaz");
+		assertTrue(this.wrappedCollection.contains("jaz"));
+		this.wrappedCollectionHolder.remove("jaz");
+		assertFalse(this.wrappedCollection.contains("jaz"));
+		this.wrappedCollectionHolder.remove("foo");
+		assertFalse(this.wrappedCollection.contains("foo"));
+		assertEquals(4, this.wrappedCollection.size());
+
+		Collection<String> adapterCollection = this.adapterCollection();
+		assertEquals(this.wrappedCollection, adapterCollection);
+		assertEquals(this.wrappedCollection, CollectionTools.collection(synchList.iterator()));
+		assertEquals(this.wrappedCollection, synchCollection);
+	}
+
+	public void testListSynch() {
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {/* OK */}
+			@Override
+			public void itemsRemoved(ListRemoveEvent e) {/* OK */}
+		});
+		this.wrappedCollectionHolder.add("foo");
+		this.wrappedCollectionHolder.add("bar");
+		this.wrappedCollectionHolder.add("baz");
+		this.wrappedCollectionHolder.add("joo");
+		this.wrappedCollectionHolder.add("jar");
+		this.wrappedCollectionHolder.add("jaz");
+		this.wrappedCollectionHolder.remove("jaz");
+		assertFalse(this.wrappedCollection.contains("jaz"));
+		this.wrappedCollectionHolder.remove("foo");
+		assertFalse(this.wrappedCollection.contains("foo"));
+		assertEquals(4, this.wrappedCollection.size());
+
+		Collection<String> adapterCollection = this.adapterCollection();
+		assertEquals(this.wrappedCollection, adapterCollection);
+	}
+
+	public void testHasListeners() {
+		assertFalse(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		CoordinatedList<String> synchList = new CoordinatedList<String>(this.adapter);
+		assertTrue(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		this.adapter.removeListChangeListener(ListValueModel.LIST_VALUES, synchList);
+		assertFalse(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		ChangeListener cl = new ChangeAdapter();
+		this.adapter.addChangeListener(cl);
+		assertTrue(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		this.adapter.removeChangeListener(cl);
+		assertFalse(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	public void testCollectionChangedToEmpty() {
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListChangeListener() {
+			@Override
+			public void listCleared(ListClearEvent e) {/* OK */}
+			@Override
+			public void itemsAdded(ListAddEvent e) {/* OK */}
+		});
+		this.wrappedCollectionHolder.add("foo");
+		this.wrappedCollectionHolder.add("bar");
+		this.wrappedCollectionHolder.add("baz");
+		JList jList = new JList(new ListModelAdapter(this.adapter));
+		this.wrappedCollectionHolder.setValues(new HashBag<String>());
+		assertEquals(0, jList.getModel().getSize());
+	}
+
+	public void testCollectionChangedFromEmpty() {
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {/* OK */}
+			@Override
+			public void itemsRemoved(ListRemoveEvent e) {/* OK */}
+		});
+		JList jList = new JList(new ListModelAdapter(this.adapter));
+
+		HashBag<String> bag = new HashBag<String>();
+		bag.add("foo");
+		bag.add("bar");
+		this.wrappedCollectionHolder.setValues(bag);
+		assertEquals(2, jList.getModel().getSize());
+	}
+
+	public void testCollectionChangedFromEmptyToEmpty() {
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {/* OK */}
+			@Override
+			public void itemsRemoved(ListRemoveEvent e) {/* OK */}
+		});
+		JList jList = new JList(new ListModelAdapter(this.adapter));
+
+		HashBag<String> bag = new HashBag<String>();
+		this.wrappedCollectionHolder.setValues(bag);
+		assertEquals(0, jList.getModel().getSize());
+	}
+
+
+	class TestListChangeListener implements ListChangeListener {
+		@Override
+		public void itemsAdded(ListAddEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsRemoved(ListRemoveEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsReplaced(ListReplaceEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsMoved(ListMoveEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void listCleared(ListClearEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void listChanged(ListChangeEvent e) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CollectionPropertyValueModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CollectionPropertyValueModelAdapterTests.java
new file mode 100644
index 0000000..fb10cdb
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CollectionPropertyValueModelAdapterTests.java
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.Collection;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CollectionPropertyValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class CollectionPropertyValueModelAdapterTests extends TestCase {
+	private ModifiablePropertyValueModel<Boolean> adapter;
+	private SimpleCollectionValueModel<String> wrappedCollectionHolder;
+	PropertyChangeEvent event;
+
+	public CollectionPropertyValueModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.wrappedCollectionHolder = new SimpleCollectionValueModel<String>();
+		this.adapter = new LocalAdapter(this.wrappedCollectionHolder, "666");
+		this.event = null;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	private boolean booleanValue() {
+		return this.adapter.getValue().booleanValue();
+	}
+
+	private Collection<String> wrappedCollection() {
+		return CollectionTools.collection(this.wrappedCollectionHolder.iterator());
+	}
+
+	public void testValue() {
+		this.adapter.addPropertyChangeListener(PropertyValueModel.VALUE, new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {/* OK */}
+		});
+		assertFalse(this.booleanValue());
+		assertFalse(this.wrappedCollection().contains("666"));
+
+		this.wrappedCollectionHolder.add("111");
+		assertFalse(this.booleanValue());
+
+		this.wrappedCollectionHolder.add("222");
+		assertFalse(this.booleanValue());
+
+		this.wrappedCollectionHolder.add("666");
+		assertTrue(this.booleanValue());
+		assertTrue(this.wrappedCollection().contains("666"));
+
+		this.wrappedCollectionHolder.remove("666");
+		assertFalse(this.booleanValue());
+		assertFalse(this.wrappedCollection().contains("666"));
+
+		this.wrappedCollectionHolder.add("666");
+		assertTrue(this.booleanValue());
+		assertTrue(this.wrappedCollection().contains("666"));
+
+		this.wrappedCollectionHolder.clear();
+		assertFalse(this.booleanValue());
+		assertFalse(this.wrappedCollection().contains("666"));
+	}
+
+	public void testSetValue() {
+		this.adapter.addPropertyChangeListener(PropertyValueModel.VALUE, new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {/* OK */}
+		});
+		assertFalse(this.booleanValue());
+		assertFalse(this.wrappedCollection().contains("666"));
+
+		this.adapter.setValue(Boolean.TRUE);
+		assertTrue(this.booleanValue());
+		assertTrue(this.wrappedCollection().contains("666"));
+
+		this.adapter.setValue(Boolean.FALSE);
+		assertFalse(this.booleanValue());
+		assertFalse(this.wrappedCollection().contains("666"));
+	}
+
+	public void testEventFiring() {
+		this.adapter.addPropertyChangeListener(PropertyValueModel.VALUE, new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				CollectionPropertyValueModelAdapterTests.this.event = e;
+			}
+		});
+		assertNull(this.event);
+
+		this.wrappedCollectionHolder.add("111");
+		assertNull(this.event);
+
+		this.wrappedCollectionHolder.add("222");
+		assertNull(this.event);
+
+		this.wrappedCollectionHolder.add("666");
+		this.verifyEvent(false, true);
+
+		this.wrappedCollectionHolder.remove("666");
+		this.verifyEvent(true, false);
+
+		this.wrappedCollectionHolder.add("666");
+		this.verifyEvent(false, true);
+
+		this.wrappedCollectionHolder.clear();
+		this.verifyEvent(true, false);
+	}
+
+	private void verifyEvent(boolean oldValue, boolean newValue) {
+		assertEquals(this.adapter, this.event.getSource());
+		assertEquals(Boolean.valueOf(oldValue), this.event.getOldValue());
+		assertEquals(Boolean.valueOf(newValue), this.event.getNewValue());
+		this.event = null;
+	}
+
+	public void testStaleValue() {
+		PropertyChangeListener listener = new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {/* OK */}
+		};
+		this.adapter.addPropertyChangeListener(PropertyValueModel.VALUE, listener);
+		this.wrappedCollectionHolder.add("666");
+		assertTrue(this.booleanValue());
+		assertTrue(this.wrappedCollection().contains("666"));
+
+		this.adapter.removePropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertFalse(this.booleanValue());
+		assertTrue(this.wrappedCollection().contains("666"));
+
+		this.adapter.addPropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(this.booleanValue());
+		assertTrue(this.wrappedCollection().contains("666"));
+	}
+
+	public void testHasListeners() {
+		assertFalse(((AbstractModel) this.adapter).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertFalse(((AbstractModel) this.wrappedCollectionHolder).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+
+		ChangeListener listener = new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {/* OK */}
+		};
+		this.adapter.addPropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(((AbstractModel) this.adapter).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.wrappedCollectionHolder).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+
+		this.adapter.removePropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertFalse(((AbstractModel) this.adapter).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertFalse(((AbstractModel) this.wrappedCollectionHolder).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+
+		this.adapter.addChangeListener(listener);
+		assertTrue(((AbstractModel) this.adapter).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.wrappedCollectionHolder).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+
+		this.adapter.removeChangeListener(listener);
+		assertFalse(((AbstractModel) this.adapter).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertFalse(((AbstractModel) this.wrappedCollectionHolder).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+	}
+
+
+	// ********** member class **********
+
+	/**
+	 * the value is true if the wrapped collection contains the specified item,
+	 * otherwise the value is false
+	 */
+	static class LocalAdapter
+		extends CollectionPropertyValueModelAdapter<Boolean, String>
+		implements ModifiablePropertyValueModel<Boolean>
+	{
+		private String item;
+
+		LocalAdapter(CollectionValueModel<String> collectionHolder, String item) {
+			super(collectionHolder);
+			this.item = item;
+		}
+
+		// ********** CollectionPropertyValueModelAdapter implementation **********
+		/**
+		 * always return a Boolean
+		 */
+		@Override
+		public Boolean getValue() {
+			Boolean result = super.getValue();
+			return (result == null) ? Boolean.FALSE : result;
+		}
+		@Override
+		@SuppressWarnings("unchecked")
+		public void setValue(Boolean value) {
+			if (this.booleanValue()) {
+				if ( ! this.booleanValueOf(value)) {
+					// the value is changing from true to false
+					((SimpleCollectionValueModel<String>) this.collectionModel).remove(this.item);
+				}
+			} else {
+				if (this.booleanValueOf(value)) {
+					// the value is changing from false to true
+					((SimpleCollectionValueModel<String>) this.collectionModel).add(this.item);
+				}
+			}
+		}
+		@Override
+		protected Boolean buildValue() {
+			return Boolean.valueOf(IteratorTools.contains(this.collectionModel.iterator(), this.item));
+		}
+
+		// ********** internal methods **********
+		private boolean booleanValue() {
+			return this.booleanValueOf(this.value);
+		}
+		private boolean booleanValueOf(Object b) {
+			return (b == null) ? false : ((Boolean) b).booleanValue();
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CompositeBooleanPropertyValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CompositeBooleanPropertyValueModelTests.java
new file mode 100644
index 0000000..75e57da
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CompositeBooleanPropertyValueModelTests.java
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.CompositeBooleanPropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+public class CompositeBooleanPropertyValueModelTests extends TestCase {
+
+	private SimplePropertyValueModel<Boolean> pvm1;
+	private ModifiablePropertyValueModel<Boolean> pvm2;
+	private ModifiablePropertyValueModel<Boolean> pvm3;
+	private ModifiablePropertyValueModel<Boolean> pvm4;
+	private Collection<ModifiablePropertyValueModel<Boolean>> collection;
+	private SimpleCollectionValueModel<ModifiablePropertyValueModel<Boolean>> cvm;
+	private PropertyValueModel<Boolean> compositePVM;
+	PropertyChangeEvent event;
+
+
+	public CompositeBooleanPropertyValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.pvm1 = new SimplePropertyValueModel<Boolean>(Boolean.TRUE);
+		this.pvm2 = new SimplePropertyValueModel<Boolean>(Boolean.TRUE);
+		this.pvm3 = new SimplePropertyValueModel<Boolean>(Boolean.TRUE);
+		this.pvm4 = new SimplePropertyValueModel<Boolean>(Boolean.TRUE);
+		this.collection = new ArrayList<ModifiablePropertyValueModel<Boolean>>();
+		this.collection.add(this.pvm1);
+		this.collection.add(this.pvm2);
+		this.collection.add(this.pvm3);
+		this.collection.add(this.pvm4);
+		this.cvm = new SimpleCollectionValueModel<ModifiablePropertyValueModel<Boolean>>(this.collection);
+
+		this.compositePVM = this.buildCompositePVM(cvm);
+	}
+
+	private PropertyValueModel<Boolean> buildCompositePVM(CollectionValueModel<ModifiablePropertyValueModel<Boolean>> pvms) {
+		return CompositeBooleanPropertyValueModel.and(pvms);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testGetValue() {
+		assertNull(this.compositePVM.getValue());
+		ChangeListener listener = this.buildListener();
+		this.compositePVM.addChangeListener(listener);
+		assertTrue(this.compositePVM.getValue().booleanValue());
+	}
+
+	public void testValueAndListeners1() {
+		assertNull(this.compositePVM.getValue());
+		ChangeListener listener = this.buildListener();
+		this.compositePVM.addChangeListener(listener);
+		assertTrue(this.compositePVM.getValue().booleanValue());
+		this.compositePVM.removeChangeListener(listener);
+		assertNull(this.compositePVM.getValue());
+	}
+
+	public void testValueAndListeners2() {
+		assertNull(this.compositePVM.getValue());
+		ChangeListener listener = this.buildListener();
+		this.compositePVM.addPropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(this.compositePVM.getValue().booleanValue());
+		this.compositePVM.removePropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertNull(this.compositePVM.getValue());
+	}
+
+	public void testPropertyChange1() {
+		this.compositePVM.addChangeListener(this.buildListener());
+		this.verifyPropertyChange();
+	}
+
+	public void testPropertyChange2() {
+		this.compositePVM.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildListener());
+		this.verifyPropertyChange();
+	}
+
+	private void verifyPropertyChange() {
+		this.event = null;
+		this.pvm1.setValue(Boolean.FALSE);
+		this.verifyEvent(true, false);
+
+		this.event = null;
+		this.pvm2.setValue(Boolean.FALSE);
+		assertNull(this.event);  // no change
+
+		this.event = null;
+		this.pvm2.setValue(Boolean.TRUE);
+		assertNull(this.event);  // no change
+
+		this.event = null;
+		this.pvm1.setValue(Boolean.TRUE);
+		this.verifyEvent(false, true);
+
+		this.event = null;
+		this.pvm4.setValue(Boolean.FALSE);
+		this.verifyEvent(true, false);
+	}
+
+	public void testCollectionChange1() {
+		this.compositePVM.addChangeListener(this.buildListener());
+		this.verifyCollectionChange();
+	}
+
+	public void testCollectionChange2() {
+		this.compositePVM.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildListener());
+		this.verifyCollectionChange();
+	}
+
+	private void verifyCollectionChange() {
+		this.event = null;
+		ModifiablePropertyValueModel<Boolean> pvm = new SimplePropertyValueModel<Boolean>(Boolean.FALSE);
+		this.cvm.add(pvm);
+		this.verifyEvent(true, false);
+
+		this.event = null;
+		this.cvm.remove(pvm);
+		this.verifyEvent(false, true);
+
+		this.event = null;
+		this.cvm.clear();
+		this.verifyEvent(Boolean.TRUE, null);
+
+		Collection<ModifiablePropertyValueModel<Boolean>> c2 = new ArrayList<ModifiablePropertyValueModel<Boolean>>();
+		c2.add(this.pvm1);
+		c2.add(this.pvm2);
+		this.event = null;
+		this.cvm.setValues(c2);
+		this.verifyEvent(null, Boolean.TRUE);
+	}
+
+	public void testLazyListening1() {
+		assertFalse(this.pvm1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		ChangeListener listener = this.buildListener();
+
+		this.compositePVM.addChangeListener(listener);
+		assertTrue(this.pvm1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.compositePVM.removeChangeListener(listener);
+		assertFalse(this.pvm1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	public void testLazyListening2() {
+		assertFalse(this.pvm1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		ChangeListener listener = this.buildListener();
+
+		this.compositePVM.addPropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(this.pvm1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.compositePVM.removePropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertFalse(this.pvm1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	private ChangeListener buildListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				CompositeBooleanPropertyValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	private void verifyEvent(boolean oldValue, boolean newValue) {
+		this.verifyEvent(Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
+	}
+
+	private void verifyEvent(Boolean oldValue, Boolean newValue) {
+		assertEquals(this.compositePVM, this.event.getSource());
+		assertEquals(PropertyValueModel.VALUE, this.event.getPropertyName());
+		assertEquals(oldValue, this.event.getOldValue());
+		assertEquals(newValue, this.event.getNewValue());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CompositeCollectionValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CompositeCollectionValueModelTests.java
new file mode 100644
index 0000000..84e07fb
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CompositeCollectionValueModelTests.java
@@ -0,0 +1,398 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterator.CompositeIterator;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.value.CollectionAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.CompositeCollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+import org.eclipse.persistence.tools.utility.transformer.TransformerAdapter;
+
+@SuppressWarnings("nls")
+public class CompositeCollectionValueModelTests extends TestCase {
+	private Neighborhood neighborhood;
+	private ModifiablePropertyValueModel<Neighborhood> neighborhoodHolder;
+
+	public CompositeCollectionValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.neighborhood = new Neighborhood("Hanna-Barbera");
+		this.neighborhoodHolder = new SimplePropertyValueModel<Neighborhood>(this.neighborhood);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testSynch() {
+		this.verifySynch(this.buildAllMembersComposite(this.neighborhoodHolder));
+	}
+
+	private void verifySynch(CollectionValueModel<Member> compositeCVM) {
+		assertEquals(0, IteratorTools.size(compositeCVM.iterator()));
+		Bag<Family> familiesSynch = new CoordinatedBag<Family>(this.buildFamiliesAspectAdapter(this.neighborhoodHolder));
+		Bag<Member> membersSynch = new CoordinatedBag<Member>(compositeCVM);
+		this.populateNeighborhood(this.neighborhood);
+
+		Family jetsons = this.neighborhood.familyNamed("Jetson");
+
+		assertEquals(3, familiesSynch.size());
+		assertEquals(12, IteratorTools.size(this.neighborhood.allMembers()));
+		assertEquals(12, membersSynch.size());
+		assertEquals(CollectionTools.bag(this.neighborhood.allMembers()), membersSynch);
+		assertEquals(membersSynch, CollectionTools.bag(compositeCVM.iterator()));
+
+		jetsons.removeMember(jetsons.memberNamed("Astro"));
+		assertEquals(3, familiesSynch.size());
+		assertEquals(11, IteratorTools.size(this.neighborhood.allMembers()));
+		assertEquals(11, membersSynch.size());
+		assertEquals(CollectionTools.bag(this.neighborhood.allMembers()), membersSynch);
+		assertEquals(membersSynch, CollectionTools.bag(compositeCVM.iterator()));
+
+		jetsons.removeMember(jetsons.memberNamed("Judy"));
+		assertEquals(3, familiesSynch.size());
+		assertEquals(10, IteratorTools.size(this.neighborhood.allMembers()));
+		assertEquals(10, membersSynch.size());
+		assertEquals(CollectionTools.bag(this.neighborhood.allMembers()), membersSynch);
+		assertEquals(membersSynch, CollectionTools.bag(compositeCVM.iterator()));
+
+		jetsons.addMember("Fido");
+		assertEquals(3, familiesSynch.size());
+		assertEquals(11, IteratorTools.size(this.neighborhood.allMembers()));
+		assertEquals(11, membersSynch.size());
+		assertEquals(CollectionTools.bag(this.neighborhood.allMembers()), membersSynch);
+		assertEquals(membersSynch, CollectionTools.bag(compositeCVM.iterator()));
+
+		this.neighborhood.removeFamily(jetsons);
+		assertEquals(2, familiesSynch.size());
+		assertEquals(7, IteratorTools.size(this.neighborhood.allMembers()));
+		assertEquals(7, membersSynch.size());
+		assertEquals(CollectionTools.bag(this.neighborhood.allMembers()), membersSynch);
+		assertEquals(membersSynch, CollectionTools.bag(compositeCVM.iterator()));
+
+		Family bears = this.neighborhood.addFamily("Bear");
+			bears.addMember("Yogi");
+		assertEquals(3, familiesSynch.size());
+		assertEquals(8, IteratorTools.size(this.neighborhood.allMembers()));
+		assertEquals(8, membersSynch.size());
+		assertEquals(CollectionTools.bag(this.neighborhood.allMembers()), membersSynch);
+		assertEquals(membersSynch, CollectionTools.bag(compositeCVM.iterator()));
+
+		bears.addMember("Boo-Boo");
+		assertEquals(3, familiesSynch.size());
+		assertEquals(9, IteratorTools.size(this.neighborhood.allMembers()));
+		assertEquals(9, membersSynch.size());
+		assertEquals(CollectionTools.bag(this.neighborhood.allMembers()), membersSynch);
+		assertEquals(membersSynch, CollectionTools.bag(compositeCVM.iterator()));
+
+		Neighborhood n2 = new Neighborhood("Hanna-Barbera 2");
+		this.neighborhoodHolder.setValue(n2);
+		this.populateNeighborhood(n2);
+		assertEquals(3, familiesSynch.size());
+		assertEquals(12, IteratorTools.size(n2.allMembers()));
+		assertEquals(12, membersSynch.size());
+		assertEquals(CollectionTools.bag(n2.allMembers()), membersSynch);
+		assertEquals(membersSynch, CollectionTools.bag(compositeCVM.iterator()));
+	}
+
+	public void testNoTransformer() {
+		SimpleCollectionValueModel<String> subCVM1 = new SimpleCollectionValueModel<String>();
+		SimpleCollectionValueModel<String> subCVM2 = new SimpleCollectionValueModel<String>();
+		Collection<CollectionValueModel<String>> collection = new ArrayList<CollectionValueModel<String>>();
+		collection.add(subCVM1);
+		collection.add(subCVM2);
+		Bag<String> synchBag = new CoordinatedBag<String>(CompositeCollectionValueModel.forModels(collection));
+
+		assertEquals(0, synchBag.size());
+
+		subCVM1.add("foo");
+		subCVM1.add("bar");
+		subCVM1.add("baz");
+		assertEquals(3, synchBag.size());
+		assertTrue(synchBag.contains("foo"));
+
+		subCVM2.add("joo");
+		subCVM2.add("jar");
+		subCVM2.add("jaz");
+		assertEquals(6, synchBag.size());
+		assertTrue(synchBag.contains("foo"));
+		assertTrue(synchBag.contains("jaz"));
+
+		subCVM1.remove("baz");
+		assertEquals(5, synchBag.size());
+		assertFalse(synchBag.contains("baz"));
+	}
+
+	public void testDuplicateItem() {
+		Bag<Member> synchBag = new CoordinatedBag<Member>(this.buildAllMembersComposite(this.neighborhoodHolder));
+		this.populateNeighborhood(this.neighborhood);
+		boolean exCaught = false;
+		try {
+			this.neighborhood.addFamily(this.neighborhood.familyNamed("Jetson"));
+		} catch (IllegalStateException ex) {
+			if (ex.getMessage().indexOf("duplicate component") != -1) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+		assertEquals(12, synchBag.size());
+	}
+
+	public void testHasListeners() {
+		CompositeCollectionValueModel<Family, Member> compositeCVM = this.buildAllMembersComposite(this.neighborhoodHolder);
+		CoordinatedBag<Member> synchBag = new CoordinatedBag<Member>(compositeCVM);
+		this.populateNeighborhood(this.neighborhood);
+		Family jetsons = this.neighborhood.familyNamed("Jetson");
+
+		assertTrue(compositeCVM.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		assertTrue(jetsons.hasAnyCollectionChangeListeners(Family.MEMBERS_COLLECTION));
+
+		compositeCVM.removeCollectionChangeListener(CollectionValueModel.VALUES, synchBag);
+		assertFalse(compositeCVM.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		assertFalse(jetsons.hasAnyCollectionChangeListeners(Family.MEMBERS_COLLECTION));
+
+		compositeCVM.addCollectionChangeListener(CollectionValueModel.VALUES, synchBag);
+		assertTrue(compositeCVM.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		assertTrue(jetsons.hasAnyCollectionChangeListeners(Family.MEMBERS_COLLECTION));
+	}
+
+	private void populateNeighborhood(Neighborhood n) {
+		Family family1 = n.addFamily("Flintstone");
+			family1.addMember("Fred");
+			family1.addMember("Wilma");
+			family1.addMember("Pebbles");
+			family1.addMember("Dino");
+		Family family2 = n.addFamily("Rubble");
+			family2.addMember("Barney");
+			family2.addMember("Betty");
+			family2.addMember("Bamm-Bamm");
+		Family family3 = n.addFamily("Jetson");
+			family3.addMember("George");
+			family3.addMember("Jane");
+			family3.addMember("Judy");
+			family3.addMember("Elroy");
+			family3.addMember("Astro");
+	}
+
+	private CollectionValueModel<Family> buildFamiliesAspectAdapter(PropertyValueModel<Neighborhood> communeHolder) {
+		return new CollectionAspectAdapter<Neighborhood, Family>(communeHolder, Neighborhood.FAMILIES_COLLECTION) {
+			@Override
+			protected Iterator<Family> iterator_() {
+				return this.subject.families();
+			}
+		};
+	}
+
+	CollectionValueModel<Member> buildMembersAdapter(Family family) {
+		return new CollectionAspectAdapter<Family, Member>(Family.MEMBERS_COLLECTION, family) {
+			@Override
+			protected Iterator<Member> iterator_() {
+				return this.subject.members();
+			}
+		};
+	}
+
+	private CompositeCollectionValueModel<Family, Member> buildAllMembersComposite(PropertyValueModel<Neighborhood> communeHolder) {
+		// build a custom Transformer
+		return new CompositeCollectionValueModel<Family, Member>(this.buildFamiliesAspectAdapter(communeHolder), this.buildTransformer());
+	}
+
+	private Transformer<Family, CollectionValueModel<Member>> buildTransformer() {
+		return new TransformerAdapter<Family, CollectionValueModel<Member>>() {
+			@Override
+			public CollectionValueModel<Member> transform(Family family) {
+				return CompositeCollectionValueModelTests.this.buildMembersAdapter(family);
+			}
+		};
+	}
+
+
+	// ********** inner classes **********
+
+	/**
+	 * inner class
+	 */
+	public class Neighborhood extends AbstractModel {
+		private String name;
+			public static final String NAME_PROPERTY = "name";
+		private Collection<Family> families = new ArrayList<Family>();
+			public static final String FAMILIES_COLLECTION = "families";
+
+		public Neighborhood(String name) {
+			super();
+			this.name = name;
+		}
+
+		public String getName() {
+			return this.name;
+		}
+
+		public void setName(String name) {
+			Object old = this.name;
+			this.name = name;
+			this.firePropertyChanged(NAME_PROPERTY, old, name);
+		}
+
+		public Iterator<Family> families() {
+			return this.families.iterator();
+		}
+
+		public Family addFamily(String familyName) {
+			return this.addFamily(new Family(familyName));
+		}
+
+		// backdoor to allow duplicates
+		public Family addFamily(Family family) {
+			this.addItemToCollection(family, this.families, FAMILIES_COLLECTION);
+			return family;
+		}
+
+		public void removeFamily(Family family) {
+			this.removeItemFromCollection(family, this.families, FAMILIES_COLLECTION);
+		}
+
+		public Family familyNamed(String familyName) {
+			for (Family family : this.families) {
+				if (family.getName().equals(familyName)) {
+					return family;
+				}
+			}
+			throw new IllegalArgumentException(familyName);
+		}
+
+		public Iterator<Member> allMembers() {
+			return new CompositeIterator<Member>(this.membersIterators());
+		}
+
+		private Iterator<Iterator<Member>> membersIterators() {
+			return new TransformationIterator<Family, Iterator<Member>>(this.families()) {
+				@Override
+				protected Iterator<Member> transform(Family family) {
+					return family.members();
+				}
+			};
+		}
+
+		public Member memberNamed(String familyName, String memberName) {
+			return this.familyNamed(familyName).memberNamed(memberName);
+		}
+
+		@Override
+		public void toString(StringBuilder sb) {
+			sb.append(this.name);
+		}
+	}
+
+	/**
+	 * inner class
+	 */
+	public class Family extends AbstractModel {
+		private String name;
+			public static final String NAME_PROPERTY = "name";
+		private Collection<Member> members = new ArrayList<Member>();
+			public static final String MEMBERS_COLLECTION = "members";
+
+		public Family(String name) {
+			super();
+			this.name = name;
+		}
+
+		public String getName() {
+			return this.name;
+		}
+
+		public void setName(String name) {
+			Object old = this.name;
+			this.name = name;
+			this.firePropertyChanged(NAME_PROPERTY, old, name);
+		}
+
+		public Iterator<Member> members() {
+			return this.members.iterator();
+		}
+
+		public Member addMember(String memberName) {
+			Member member = new Member(memberName);
+			this.addItemToCollection(member, this.members, MEMBERS_COLLECTION);
+			return member;
+		}
+
+		public void removeMember(Member member) {
+			this.removeItemFromCollection(member, this.members, MEMBERS_COLLECTION);
+		}
+
+		public Member memberNamed(String memberName) {
+			for (Member member : this.members) {
+				if (member.getName().equals(memberName)) {
+					return member;
+				}
+			}
+			throw new IllegalArgumentException(memberName);
+		}
+
+		@Override
+		public void toString(StringBuilder sb) {
+			sb.append(this.name);
+		}
+	}
+
+	/**
+	 * inner class
+	 */
+	public class Member extends AbstractModel {
+		private String name;
+			public static final String NAME_PROPERTY = "name";
+
+		public Member(String name) {
+			super();
+			this.name = name;
+		}
+
+		public String getName() {
+			return this.name;
+		}
+
+		public void setName(String name) {
+			Object old = this.name;
+			this.name = name;
+			this.firePropertyChanged(NAME_PROPERTY, old, name);
+		}
+
+		@Override
+		public void toString(StringBuilder sb) {
+			sb.append(this.name);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CompositeListValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CompositeListValueModelTests.java
new file mode 100644
index 0000000..05a5dab
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CompositeListValueModelTests.java
@@ -0,0 +1,1256 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CompositeListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleListValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class CompositeListValueModelTests extends TestCase {
+
+	private LocalListValueModel<String> lvm0;
+	private LocalListValueModel<String> lvm1;
+	private LocalListValueModel<String> lvm2;
+	private LocalListValueModel<String> lvm3;
+	private LocalListValueModel<LocalListValueModel<String>> uberLVM;
+	private CompositeListValueModel<LocalListValueModel<String>, String> compositeLVM;
+
+	public CompositeListValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+
+		this.lvm0 = new LocalListValueModel<String>();
+		this.lvm0.add("aaa");
+		this.lvm0.add("bbb");
+		this.lvm0.add("ccc");
+
+		this.lvm1 = new LocalListValueModel<String>();
+		this.lvm1.add("ddd");
+		this.lvm1.add("eee");
+
+		this.lvm2 = new LocalListValueModel<String>();
+		this.lvm2.add("fff");
+
+		this.lvm3 = new LocalListValueModel<String>();
+		this.lvm3.add("ggg");
+		this.lvm3.add("hhh");
+		this.lvm3.add("iii");
+		this.lvm3.add("jjj");
+		this.lvm3.add("kkk");
+
+		this.uberLVM = new LocalListValueModel<LocalListValueModel<String>>();
+		this.uberLVM.add(this.lvm0);
+		this.uberLVM.add(this.lvm1);
+		this.uberLVM.add(this.lvm2);
+		this.uberLVM.add(this.lvm3);
+
+		this.compositeLVM = CompositeListValueModel.forModels((ListValueModel<LocalListValueModel<String>>) this.uberLVM);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testGetInt() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+		assertEquals("aaa", this.compositeLVM.get(0));
+		assertEquals("aaa", coordList.get(0));
+		assertEquals("bbb", this.compositeLVM.get(1));
+		assertEquals("bbb", coordList.get(1));
+		assertEquals("ccc", this.compositeLVM.get(2));
+		assertEquals("ccc", coordList.get(2));
+
+		assertEquals("ddd", this.compositeLVM.get(3));
+		assertEquals("ddd", coordList.get(3));
+		assertEquals("eee", this.compositeLVM.get(4));
+		assertEquals("eee", coordList.get(4));
+
+		assertEquals("fff", this.compositeLVM.get(5));
+		assertEquals("fff", coordList.get(5));
+
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testIterator() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+		assertEquals("aaa", this.compositeLVM.iterator().next());
+		assertEquals("aaa", coordList.iterator().next());
+		Iterator<String> stream1 = coordList.iterator();
+		for (Iterator<String> stream2 = this.compositeLVM.iterator(); stream2.hasNext(); ) {
+			assertEquals(stream1.next(), stream2.next());
+		}
+		assertFalse(stream1.hasNext());
+	}
+
+	public void testSize() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+		assertEquals(11, this.compositeLVM.size());
+		assertEquals(11, coordList.size());
+	}
+
+	public void testToArray() {
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+	}
+
+	public void testHasListeners() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		assertTrue(this.compositeLVM.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertTrue(this.lvm0.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		this.compositeLVM.removeListChangeListener(ListValueModel.LIST_VALUES, coordList);
+		assertFalse(this.compositeLVM.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(this.lvm0.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, coordList);
+		assertTrue(this.compositeLVM.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertTrue(this.lvm0.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	public void testAddSource_Begin() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		LocalListValueModel<String> lvm = new LocalListValueModel<String>();
+		lvm.add("xxx");
+		lvm.add("yyy");
+		lvm.add("zzz");
+		this.uberLVM.add(0, lvm);
+
+		Object[] expected = new Object[] { "xxx", "yyy", "zzz", "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(9));
+		assertEquals("ggg", coordList.get(9));
+	}
+
+	public void testAddSource_Middle() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		LocalListValueModel<String> lvm = new LocalListValueModel<String>();
+		lvm.add("xxx");
+		lvm.add("yyy");
+		lvm.add("zzz");
+		this.uberLVM.add(2, lvm);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "xxx", "yyy", "zzz", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(9));
+		assertEquals("ggg", coordList.get(9));
+	}
+
+	public void testAddSource_End() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		LocalListValueModel<String> lvm = new LocalListValueModel<String>();
+		lvm.add("xxx");
+		lvm.add("yyy");
+		lvm.add("zzz");
+		this.uberLVM.add(lvm);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "xxx", "yyy", "zzz" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testAddSources() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		LocalListValueModel<String> lvmA = new LocalListValueModel<String>();
+		lvmA.add("xxx");
+		lvmA.add("yyy");
+		lvmA.add("zzz");
+		LocalListValueModel<String> lvmB = new LocalListValueModel<String>();
+		lvmB.add("ppp");
+		lvmB.add("qqq");
+		lvmB.add("rrr");
+		Collection<LocalListValueModel<String>> c = new ArrayList<LocalListValueModel<String>>();
+		c.add(lvmA);
+		c.add(lvmB);
+		this.uberLVM.addAll(2, c);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "xxx", "yyy", "zzz", "ppp", "qqq", "rrr", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(12));
+		assertEquals("ggg", coordList.get(12));
+	}
+
+	public void testRemoveSource_Begin() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.remove(0);
+
+		Object[] expected = new Object[] { "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(3));
+		assertEquals("ggg", coordList.get(3));
+	}
+
+	public void testRemoveSource_Middle() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.remove(2);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(5));
+		assertEquals("ggg", coordList.get(5));
+	}
+
+	public void testRemoveSource_End() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.remove(3);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("fff", this.compositeLVM.get(5));
+		assertEquals("fff", coordList.get(5));
+	}
+
+	public void testRemoveSources() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.remove(2, 2);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("eee", this.compositeLVM.get(4));
+		assertEquals("eee", coordList.get(4));
+	}
+
+	public void testReplaceSources() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		LocalListValueModel<String> lvmA = new LocalListValueModel<String>();
+		lvmA.add("xxx");
+		lvmA.add("yyy");
+		lvmA.add("zzz");
+		LocalListValueModel<String> lvmB = new LocalListValueModel<String>();
+		lvmB.add("ppp");
+		lvmB.add("qqq");
+		lvmB.add("rrr");
+		List<LocalListValueModel<String>> list = new ArrayList<LocalListValueModel<String>>();
+		list.add(lvmA);
+		list.add(lvmB);
+		this.uberLVM.set(2, list);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "xxx", "yyy", "zzz", "ppp", "qqq", "rrr" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("qqq", this.compositeLVM.get(9));
+		assertEquals("qqq", coordList.get(9));
+	}
+
+	public void testMoveSources_Begin() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.move(0, 2, 2);
+
+		Object[] expected = new Object[] { "fff", "ggg", "hhh", "iii", "jjj", "kkk", "aaa", "bbb", "ccc", "ddd", "eee" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(1));
+		assertEquals("ggg", coordList.get(1));
+	}
+
+	public void testMoveSources_Middle() {
+		LocalListValueModel<String> lvm4 = new LocalListValueModel<String>();
+		lvm4.add("lll");
+		lvm4.add("mmm");
+		this.uberLVM.add(lvm4);
+
+		LocalListValueModel<String> lvm5 = new LocalListValueModel<String>();
+		lvm5.add("nnn");
+		lvm5.add("ooo");
+		lvm5.add("ppp");
+		lvm5.add("qqq");
+		this.uberLVM.add(lvm5);
+
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.move(1, 3, 2);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "ddd", "eee", "fff", "nnn", "ooo", "ppp", "qqq" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(3));
+		assertEquals("ggg", coordList.get(3));
+	}
+
+	public void testMoveSources_End() {
+		LocalListValueModel<String> lvm4 = new LocalListValueModel<String>();
+		lvm4.add("lll");
+		lvm4.add("mmm");
+		this.uberLVM.add(lvm4);
+
+		LocalListValueModel<String> lvm5 = new LocalListValueModel<String>();
+		lvm5.add("nnn");
+		lvm5.add("ooo");
+		lvm5.add("ppp");
+		lvm5.add("qqq");
+		this.uberLVM.add(lvm5);
+
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.move(3, 0, 3);
+
+		Object[] expected = new Object[] { "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo", "ppp", "qqq", "aaa", "bbb", "ccc", "ddd", "eee", "fff" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(0));
+		assertEquals("ggg", coordList.get(0));
+	}
+
+	public void testMoveSource() {
+		LocalListValueModel<String> lvm4 = new LocalListValueModel<String>();
+		lvm4.add("lll");
+		lvm4.add("mmm");
+		this.uberLVM.add(lvm4);
+
+		LocalListValueModel<String> lvm5 = new LocalListValueModel<String>();
+		lvm5.add("nnn");
+		lvm5.add("ooo");
+		lvm5.add("ppp");
+		lvm5.add("qqq");
+		this.uberLVM.add(lvm5);
+
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.move(3, 1);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "ddd", "eee", "lll", "mmm", "nnn", "ooo", "ppp", "qqq" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ooo", this.compositeLVM.get(14));
+		assertEquals("ooo", coordList.get(14));
+	}
+
+	public void testClearSources() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.clear();
+
+		Object[] expected = new Object[0];
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+	}
+
+	public void testChangeSources1() {
+		List<LocalListValueModel<String>> newList = new ArrayList<LocalListValueModel<String>>();
+		LocalListValueModel<String> lvm4 = new LocalListValueModel<String>();
+		lvm4.add("lll");
+		lvm4.add("mmm");
+		newList.add(lvm4);
+
+		LocalListValueModel<String> lvm5 = new LocalListValueModel<String>();
+		lvm5.add("nnn");
+		lvm5.add("ooo");
+		lvm5.add("ppp");
+		lvm5.add("qqq");
+		newList.add(lvm5);
+
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.setListValues(newList);
+
+		Object[] expected = new Object[] { "lll", "mmm", "nnn", "ooo", "ppp", "qqq" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ooo", this.compositeLVM.get(3));
+		assertEquals("ooo", coordList.get(3));
+	}
+
+	public void testChangeSources2() {
+		List<LocalListValueModel<String>> newList = new ArrayList<LocalListValueModel<String>>();
+		LocalListValueModel<String> lvm4 = new LocalListValueModel<String>();
+		lvm4.add("lll");
+		lvm4.add("mmm");
+		newList.add(lvm4);
+
+		LocalListValueModel<String> lvm5 = new LocalListValueModel<String>();
+		lvm5.add("nnn");
+		lvm5.add("ooo");
+		lvm5.add("ppp");
+		lvm5.add("qqq");
+		newList.add(lvm5);
+
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.changeListValues(newList);
+
+		Object[] expected = new Object[] { "lll", "mmm", "nnn", "ooo", "ppp", "qqq" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ooo", this.compositeLVM.get(3));
+		assertEquals("ooo", coordList.get(3));
+	}
+
+	public void testChangeSources3() {
+		ListChangeListener listener = new ErrorListener();
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+
+		List<LocalListValueModel<String>> newList = new ArrayList<LocalListValueModel<String>>();
+		newList.add(this.lvm0);
+		newList.add(this.lvm1);
+		newList.add(this.lvm2);
+		newList.add(this.lvm3);
+
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.changeListValues(newList);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ddd", this.compositeLVM.get(3));
+		assertEquals("ddd", coordList.get(3));
+	}
+
+	public void testChangeSources4() {
+		ListChangeListener listener = new ErrorListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) { /* OK */ }
+		};
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+
+		List<LocalListValueModel<String>> newList = new ArrayList<LocalListValueModel<String>>();
+		newList.add(this.lvm0);
+		newList.add(this.lvm1);
+		newList.add(this.lvm2);
+		newList.add(this.lvm3);
+		LocalListValueModel<String> lvm4 = new LocalListValueModel<String>();
+		lvm4.add("lll");
+		lvm4.add("mmm");
+		newList.add(lvm4);
+
+
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.changeListValues(newList);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ddd", this.compositeLVM.get(3));
+		assertEquals("ddd", coordList.get(3));
+	}
+
+	public void testChangeSources5() {
+		ListChangeListener listener = new ErrorListener() {
+			@Override
+			public void itemsRemoved(ListRemoveEvent event) { /* OK */ }
+		};
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+
+		List<LocalListValueModel<String>> newList = new ArrayList<LocalListValueModel<String>>();
+		newList.add(this.lvm0);
+		newList.add(this.lvm1);
+		newList.add(this.lvm2);
+
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.changeListValues(newList);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ddd", this.compositeLVM.get(3));
+		assertEquals("ddd", coordList.get(3));
+	}
+
+	public void testChangeSources6() {
+		ListChangeListener listener = new ErrorListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) { /* OK */ }
+			@Override
+			public void itemsRemoved(ListRemoveEvent event) { /* OK */ }
+		};
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+
+		List<LocalListValueModel<String>> newList = new ArrayList<LocalListValueModel<String>>();
+		newList.add(this.lvm0);
+		newList.add(this.lvm1);
+
+		LocalListValueModel<String> lvm4 = new LocalListValueModel<String>();
+		lvm4.add("lll");
+		lvm4.add("mmm");
+		newList.add(lvm4);
+
+		newList.add(this.lvm3);
+
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.uberLVM.changeListValues(newList);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "lll", "mmm", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ddd", this.compositeLVM.get(3));
+		assertEquals("ddd", coordList.get(3));
+	}
+
+	public void testAddItem_Begin() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm0.add(0, "xxx");
+
+		Object[] expected = new Object[] { "xxx", "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(7));
+		assertEquals("ggg", coordList.get(7));
+	}
+
+	public void testAddItem_Middle() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm2.add(1, "xxx");
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "xxx", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(7));
+		assertEquals("ggg", coordList.get(7));
+	}
+
+	public void testAddItem_End() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.add(5, "xxx");
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "xxx" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testAddItems_Begin() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm0.addAll(0, Arrays.asList(new String[] { "xxx", "yyy", "zzz" }));
+
+		Object[] expected = new Object[] { "xxx", "yyy", "zzz", "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(9));
+		assertEquals("ggg", coordList.get(9));
+	}
+
+	public void testAddItems_Middle() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm2.addAll(1, Arrays.asList(new String[] { "xxx", "yyy", "zzz" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "xxx", "yyy", "zzz", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(9));
+		assertEquals("ggg", coordList.get(9));
+	}
+
+	public void testAddItems_End() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.addAll(5, Arrays.asList(new String[] { "xxx", "yyy", "zzz" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "xxx", "yyy", "zzz" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testRemoveItem_Begin() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm0.remove(0);
+
+		Object[] expected = new Object[] { "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(5));
+		assertEquals("ggg", coordList.get(5));
+	}
+
+	public void testRemoveItem_Middle() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm2.remove(0);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(5));
+		assertEquals("ggg", coordList.get(5));
+	}
+
+	public void testRemoveItem_End() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.remove(4);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testRemoveItems_Begin() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm0.remove(0, 3);
+
+		Object[] expected = new Object[] { "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(3));
+		assertEquals("ggg", coordList.get(3));
+	}
+
+	public void testRemoveItems_Middle() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.remove(1, 3);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("kkk", this.compositeLVM.get(7));
+		assertEquals("kkk", coordList.get(7));
+	}
+
+	public void testRemoveItems_End() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.remove(3, 2);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testReplaceItem_Begin() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm0.set(0, "xxx");
+
+		Object[] expected = new Object[] { "xxx", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testReplaceItem_Middle() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm2.set(0, "xxx");
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "xxx", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testReplaceItem_End() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.set(4, "xxx");
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "xxx" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testReplaceItems_Begin() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm0.set(0, Arrays.asList(new String[] { "xxx", "yyy", "zzz" }));
+
+		Object[] expected = new Object[] { "xxx", "yyy", "zzz", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testReplaceItems_Middle() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.set(1, Arrays.asList(new String[] { "xxx", "yyy", "zzz" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "xxx", "yyy", "zzz", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("kkk", this.compositeLVM.get(10));
+		assertEquals("kkk", coordList.get(10));
+	}
+
+	public void testReplaceItems_End() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.set(3, Arrays.asList(new String[] { "xxx", "yyy" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "xxx", "yyy" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testMoveItem_Begin() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm0.move(2, 0);
+
+		Object[] expected = new Object[] { "bbb", "ccc", "aaa", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testMoveItem_Middle() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm1.move(0, 1);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "eee", "ddd", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testMoveItem_End() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.move(0, 4);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "kkk", "ggg", "hhh", "iii", "jjj" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(7));
+		assertEquals("ggg", coordList.get(7));
+	}
+
+	public void testMoveItems_Begin() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm0.move(1, 0, 2);
+
+		Object[] expected = new Object[] { "ccc", "aaa", "bbb", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testMoveItems_Middle() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm1.add("eee.1");
+		this.lvm1.add("eee.2");
+		this.lvm1.add("eee.3");
+		this.lvm1.move(1, 2, 3);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee.1", "eee.2", "eee.3", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(9));
+		assertEquals("ggg", coordList.get(9));
+	}
+
+	public void testMoveItems_End() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.move(0, 2, 3);
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "iii", "jjj", "kkk", "ggg", "hhh" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(9));
+		assertEquals("ggg", coordList.get(9));
+	}
+
+	public void testClearItems_Begin() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm0.clear();
+
+		Object[] expected = new Object[] { "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(3));
+		assertEquals("ggg", coordList.get(3));
+	}
+
+	public void testClearItems_Middle() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm1.clear();
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(4));
+		assertEquals("ggg", coordList.get(4));
+	}
+
+	public void testClearItems_End() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.clear();
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("fff", this.compositeLVM.get(5));
+		assertEquals("fff", coordList.get(5));
+	}
+
+	public void testChangeItems_Begin1() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm0.setListValues(Arrays.asList(new String[] { "xxx", "yyy", "zzz" }));
+
+		Object[] expected = new Object[] { "xxx", "yyy", "zzz", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testChangeItems_Middle1() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm1.setListValues(Arrays.asList(new String[] { "xxx", "yyy", "zzz" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "xxx", "yyy", "zzz", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(7));
+		assertEquals("ggg", coordList.get(7));
+	}
+
+	public void testChangeItems_End1() {
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.setListValues(Arrays.asList(new String[] { "xxx", "yyy", "zzz" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "xxx", "yyy", "zzz" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("fff", this.compositeLVM.get(5));
+		assertEquals("fff", coordList.get(5));
+	}
+
+	public void testChangeItems_Begin2() {
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, new ErrorListener());
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm0.changeListValues(Arrays.asList(new String[] { "aaa", "bbb", "ccc" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testChangeItems_Middle2() {
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, new ErrorListener());
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm1.changeListValues(Arrays.asList(new String[] { "ddd", "eee" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("hhh", this.compositeLVM.get(7));
+		assertEquals("hhh", coordList.get(7));
+	}
+
+	public void testChangeItems_End2() {
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, new ErrorListener());
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.changeListValues(Arrays.asList(new String[] { "ggg", "hhh", "iii", "jjj", "kkk" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("fff", this.compositeLVM.get(5));
+		assertEquals("fff", coordList.get(5));
+	}
+
+	public void testChangeItems_Begin3() {
+		ListChangeListener listener = new ErrorListener() {
+			@Override
+			public void itemsReplaced(ListReplaceEvent event) { /* OK */ }
+		};
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm0.changeListValues(Arrays.asList(new String[] { "aaa", "bbb", "xxx" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "xxx", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(6));
+		assertEquals("ggg", coordList.get(6));
+	}
+
+	public void testChangeItems_Middle3() {
+		ListChangeListener listener = new ErrorListener() {
+			@Override
+			public void itemsReplaced(ListReplaceEvent event) { /* OK */ }
+		};
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm1.changeListValues(Arrays.asList(new String[] { "ddd", "xxx" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "xxx", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("hhh", this.compositeLVM.get(7));
+		assertEquals("hhh", coordList.get(7));
+	}
+
+	public void testChangeItems_End3() {
+		ListChangeListener listener = new ErrorListener() {
+			@Override
+			public void itemsReplaced(ListReplaceEvent event) { /* OK */ }
+		};
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.changeListValues(Arrays.asList(new String[] { "ggg", "hhh", "iii", "xxx", "kkk" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "xxx", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("fff", this.compositeLVM.get(5));
+		assertEquals("fff", coordList.get(5));
+	}
+
+	public void testChangeItems_Begin4() {
+		ListChangeListener listener = new ErrorListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) { /* OK */ }
+		};
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm0.changeListValues(Arrays.asList(new String[] { "aaa", "bbb", "ccc", "xxx" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "xxx", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("fff", this.compositeLVM.get(6));
+		assertEquals("fff", coordList.get(6));
+	}
+
+	public void testChangeItems_Middle4() {
+		ListChangeListener listener = new ErrorListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) { /* OK */ }
+		};
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm1.changeListValues(Arrays.asList(new String[] { "ddd", "eee", "xxx" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "xxx", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("ggg", this.compositeLVM.get(7));
+		assertEquals("ggg", coordList.get(7));
+	}
+
+	public void testChangeItems_End4() {
+		ListChangeListener listener = new ErrorListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) { /* OK */ }
+		};
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.changeListValues(Arrays.asList(new String[] { "ggg", "hhh", "iii", "jjj", "kkk", "xxx" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "xxx" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("fff", this.compositeLVM.get(5));
+		assertEquals("fff", coordList.get(5));
+	}
+
+	public void testChangeItems_Begin5() {
+		ListChangeListener listener = new ErrorListener() {
+			@Override
+			public void itemsRemoved(ListRemoveEvent event) { /* OK */ }
+		};
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm0.changeListValues(Arrays.asList(new String[] { "aaa" }));
+
+		Object[] expected = new Object[] { "aaa", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("iii", this.compositeLVM.get(6));
+		assertEquals("iii", coordList.get(6));
+	}
+
+	public void testChangeItems_Middle5() {
+		ListChangeListener listener = new ErrorListener() {
+			@Override
+			public void itemsRemoved(ListRemoveEvent event) { /* OK */ }
+		};
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm1.changeListValues(Arrays.asList(new String[] { "ddd" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "fff", "ggg", "hhh", "iii", "jjj", "kkk" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("iii", this.compositeLVM.get(7));
+		assertEquals("iii", coordList.get(7));
+	}
+
+	public void testChangeItems_End5() {
+		ListChangeListener listener = new ErrorListener() {
+			@Override
+			public void itemsRemoved(ListRemoveEvent event) { /* OK */ }
+		};
+		this.compositeLVM.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		CoordinatedList<String> coordList = new CoordinatedList<String>(this.compositeLVM);
+
+		this.lvm3.changeListValues(Arrays.asList(new String[] { "ggg", "hhh", "iii" }));
+
+		Object[] expected = new Object[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii" };
+		assertEquals(expected.length, this.compositeLVM.size());
+		assertEquals(expected.length, coordList.size());
+		assertTrue(Arrays.equals(expected, this.compositeLVM.toArray()));
+		assertTrue(Arrays.equals(expected, coordList.toArray()));
+		assertEquals("fff", this.compositeLVM.get(5));
+		assertEquals("fff", coordList.get(5));
+	}
+
+	class ErrorListener implements ListChangeListener {
+		@Override
+		public void itemsAdded(ListAddEvent event) {
+			fail();
+		}
+		@Override
+		public void itemsRemoved(ListRemoveEvent event) {
+			fail();
+		}
+		@Override
+		public void itemsMoved(ListMoveEvent event) {
+			fail();
+		}
+		@Override
+		public void itemsReplaced(ListReplaceEvent event) {
+			fail();
+		}
+		@Override
+		public void listCleared(ListClearEvent event) {
+			fail();
+		}
+		@Override
+		public void listChanged(ListChangeEvent event) {
+			fail();
+		}
+	}
+
+	class LocalListValueModel<E> extends SimpleListValueModel<E> {
+		LocalListValueModel() {
+			super();
+		}
+		void changeListValues(Iterable<E> listValues) {
+			if (listValues == null) {
+				throw new NullPointerException();
+			}
+			this.list.clear();
+			CollectionTools.addAll(this.list, listValues);
+			this.fireListChanged(LIST_VALUES, this.list);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CompositePropertyValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CompositePropertyValueModelTests.java
new file mode 100644
index 0000000..4f0ad7c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CompositePropertyValueModelTests.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.CompositePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+public class CompositePropertyValueModelTests extends TestCase {
+
+	private SimplePropertyValueModel<Integer> pvm1;
+	private ModifiablePropertyValueModel<Integer> pvm2;
+	private ModifiablePropertyValueModel<Integer> pvm3;
+	private ModifiablePropertyValueModel<Integer> pvm4;
+	private Collection<ModifiablePropertyValueModel<Integer>> collection;
+	private SimpleCollectionValueModel<ModifiablePropertyValueModel<Integer>> cvm;
+	private PropertyValueModel<Integer> compositePVM;
+	PropertyChangeEvent event;
+
+
+	public CompositePropertyValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.pvm1 = new SimplePropertyValueModel<Integer>(Integer.valueOf(1));
+		this.pvm2 = new SimplePropertyValueModel<Integer>(Integer.valueOf(2));
+		this.pvm3 = new SimplePropertyValueModel<Integer>(Integer.valueOf(3));
+		this.pvm4 = new SimplePropertyValueModel<Integer>(Integer.valueOf(4));
+		this.collection = new ArrayList<ModifiablePropertyValueModel<Integer>>();
+		this.collection.add(this.pvm1);
+		this.collection.add(this.pvm2);
+		this.collection.add(this.pvm3);
+		this.collection.add(this.pvm4);
+		this.cvm = new SimpleCollectionValueModel<ModifiablePropertyValueModel<Integer>>(this.collection);
+
+		this.compositePVM = this.buildCompositePVM(cvm);
+	}
+
+	private <T extends PropertyValueModel<Integer>> PropertyValueModel<Integer> buildCompositePVM(CollectionValueModel<T> pvms) {
+		return new CompositePropertyValueModel<Integer, Integer>(pvms) {
+			@Override
+			protected Integer buildValue() {
+				int sum = 0;
+				for (PropertyValueModel<? extends Integer> each : this.collectionModel) {
+					sum += each.getValue().intValue();
+				}
+				return Integer.valueOf(sum);
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testGetValue() {
+		assertNull(this.compositePVM.getValue());
+		ChangeListener listener = this.buildListener();
+		this.compositePVM.addChangeListener(listener);
+		assertEquals(10, this.compositePVM.getValue().intValue());
+	}
+
+	public void testValueAndListeners1() {
+		assertNull(this.compositePVM.getValue());
+		ChangeListener listener = this.buildListener();
+		this.compositePVM.addChangeListener(listener);
+		assertEquals(10, this.compositePVM.getValue().intValue());
+		this.compositePVM.removeChangeListener(listener);
+		assertNull(this.compositePVM.getValue());
+	}
+
+	public void testValueAndListeners2() {
+		assertNull(this.compositePVM.getValue());
+		ChangeListener listener = this.buildListener();
+		this.compositePVM.addPropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertEquals(10, this.compositePVM.getValue().intValue());
+		this.compositePVM.removePropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertNull(this.compositePVM.getValue());
+	}
+
+	public void testPropertyChange1() {
+		this.compositePVM.addChangeListener(this.buildListener());
+		this.verifyPropertyChange();
+	}
+
+	public void testPropertyChange2() {
+		this.compositePVM.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildListener());
+		this.verifyPropertyChange();
+	}
+
+	private void verifyPropertyChange() {
+		this.event = null;
+		this.pvm1.setValue(Integer.valueOf(5));
+		this.verifyEvent(10, 14);
+
+		this.event = null;
+		this.pvm4.setValue(Integer.valueOf(0));
+		this.verifyEvent(14, 10);
+	}
+
+	public void testCollectionChange1() {
+		this.compositePVM.addChangeListener(this.buildListener());
+		this.verifyCollectionChange();
+	}
+
+	public void testCollectionChange2() {
+		this.compositePVM.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildListener());
+		this.verifyCollectionChange();
+	}
+
+	private void verifyCollectionChange() {
+		this.event = null;
+		ModifiablePropertyValueModel<Integer> pvm = new SimplePropertyValueModel<Integer>(Integer.valueOf(77));
+		this.cvm.add(pvm);
+		this.verifyEvent(10, 87);
+
+		this.event = null;
+		this.cvm.remove(pvm);
+		this.verifyEvent(87, 10);
+
+		this.event = null;
+		this.cvm.clear();
+		this.verifyEvent(10, 0);
+
+		Collection<ModifiablePropertyValueModel<Integer>> c2 = new ArrayList<ModifiablePropertyValueModel<Integer>>();
+		c2.add(this.pvm1);
+		c2.add(this.pvm2);
+		this.event = null;
+		this.cvm.setValues(c2);
+		this.verifyEvent(0, 3);
+	}
+
+	public void testLazyListening1() {
+		assertFalse(this.pvm1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		ChangeListener listener = this.buildListener();
+
+		this.compositePVM.addChangeListener(listener);
+		assertTrue(this.pvm1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.compositePVM.removeChangeListener(listener);
+		assertFalse(this.pvm1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	public void testLazyListening2() {
+		assertFalse(this.pvm1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		ChangeListener listener = this.buildListener();
+
+		this.compositePVM.addPropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(this.pvm1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.compositePVM.removePropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertFalse(this.pvm1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	private ChangeListener buildListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				CompositePropertyValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	private void verifyEvent(int oldValue, int newValue) {
+		assertEquals(this.compositePVM, this.event.getSource());
+		assertEquals(PropertyValueModel.VALUE, this.event.getPropertyName());
+		assertEquals(Integer.valueOf(oldValue), this.event.getOldValue());
+		assertEquals(Integer.valueOf(newValue), this.event.getNewValue());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CoordinatedBag.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CoordinatedBag.java
new file mode 100644
index 0000000..9ef6565
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CoordinatedBag.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.Collection;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+
+/**
+ * Helper class that keeps an internal collection in synch with the
+ * collection held by a collection value model.
+ */
+class CoordinatedBag<E> implements Bag<E>, CollectionChangeListener {
+
+	private Bag<E> bag = new HashBag<E>();
+
+	CoordinatedBag(CollectionValueModel<E> cvm) {
+		cvm.addCollectionChangeListener(CollectionValueModel.VALUES, this);
+	}
+
+
+	// ********** Collection implementation **********
+
+	@Override
+	public boolean add(E o) {
+		return this.bag.add(o);
+	}
+
+	@Override
+	public boolean addAll(Collection<? extends E> c) {
+		return this.bag.addAll(c);
+	}
+
+	@Override
+	public void clear() {
+		this.bag.clear();
+	}
+
+	@Override
+	public boolean contains(Object o) {
+		return this.bag.contains(o);
+	}
+
+	@Override
+	public boolean containsAll(Collection<?> c) {
+		return this.bag.containsAll(c);
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return this.bag.isEmpty();
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return this.bag.iterator();
+	}
+
+	@Override
+	public boolean remove(Object o) {
+		return this.bag.remove(o);
+	}
+
+	@Override
+	public boolean removeAll(Collection<?> c) {
+		return this.bag.removeAll(c);
+	}
+
+	@Override
+	public boolean retainAll(Collection<?> c) {
+		return this.bag.retainAll(c);
+	}
+
+	@Override
+	public int size() {
+		return this.bag.size();
+	}
+
+	@Override
+	public Object[] toArray() {
+		return this.bag.toArray();
+	}
+
+	@Override
+	public <T> T[] toArray(T[] a) {
+		return this.bag.toArray(a);
+	}
+
+
+	// ********** Bag implementation **********
+
+	@Override
+	public int count(Object o) {
+		return this.bag.count(o);
+	}
+
+	@Override
+	public boolean add(E o, int count) {
+		return this.bag.add(o, count);
+	}
+
+	@Override
+	public boolean remove(Object o, int count) {
+		return this.bag.remove(o, count);
+	}
+
+	@Override
+	public Iterator<E> uniqueIterator() {
+		return this.bag.uniqueIterator();
+	}
+
+	@Override
+	public int uniqueCount() {
+		return this.bag.uniqueCount();
+	}
+
+	@Override
+	public Iterator<Bag.Entry<E>> entries() {
+		return this.bag.entries();
+	}
+
+	// ********** CollectionChangeListener implementation **********
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public void itemsAdded(CollectionAddEvent event) {
+		for (E item : (Iterable<E>) event.getItems()) {
+			this.bag.add(item);
+		}
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public void itemsRemoved(CollectionRemoveEvent event) {
+		for (E item : (Iterable<E>) event.getItems()) {
+			this.bag.remove(item);
+		}
+	}
+
+	@Override
+	public void collectionCleared(CollectionClearEvent event) {
+		this.bag.clear();
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public void collectionChanged(CollectionChangeEvent event) {
+		this.bag.clear();
+		CollectionTools.addAll(this.bag, ((CollectionValueModel<E>) event.getSource()).iterator());
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public boolean equals(Object o) {
+		return this.bag.equals(o);
+	}
+
+	@Override
+	public int hashCode() {
+		return this.bag.hashCode();
+	}
+
+	@Override
+	public String toString() {
+		return this.bag.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CoordinatedList.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CoordinatedList.java
new file mode 100644
index 0000000..85b5670
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/CoordinatedList.java
@@ -0,0 +1,298 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import javax.swing.ListModel;
+import javax.swing.event.ListDataEvent;
+import javax.swing.event.ListDataListener;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+
+/**
+ * Helper class that keeps an internal list in synch with the
+ * list held by a list value model.
+ */
+public class CoordinatedList<E> implements List<E>, ListChangeListener, ListDataListener {
+	private List<E> list = new ArrayList<E>();
+
+	public CoordinatedList(ListValueModel<E> listValueModel) {
+		listValueModel.addListChangeListener(ListValueModel.LIST_VALUES, this);
+		for (Iterator<E> stream = listValueModel.iterator(); stream.hasNext(); ) {
+			this.add(stream.next());
+		}
+	}
+
+	public CoordinatedList(ListModel listModel) {
+		listModel.addListDataListener(this);
+		for (int i = 0; i < listModel.getSize(); i++) {
+			this.add(i, this.getElementAt(listModel, i));
+		}
+	}
+
+
+	// ********** List implementation **********
+
+	@Override
+	public void add(int index, E element) {
+		this.list.add(index, element);
+	}
+
+	@Override
+	public boolean add(E o) {
+		return this.list.add(o);
+	}
+
+	@Override
+	public boolean addAll(Collection<? extends E> c) {
+		return this.list.addAll(c);
+	}
+
+	@Override
+	public boolean addAll(int index, Collection<? extends E> c) {
+		return this.list.addAll(index, c);
+	}
+
+	@Override
+	public void clear() {
+		this.list.clear();
+	}
+
+	@Override
+	public boolean contains(Object o) {
+		return this.list.contains(o);
+	}
+
+	@Override
+	public boolean containsAll(Collection<?> c) {
+		return this.list.containsAll(c);
+	}
+
+	@Override
+	public E get(int index) {
+		return this.list.get(index);
+	}
+
+	@Override
+	public int indexOf(Object o) {
+		return this.list.indexOf(o);
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return this.list.isEmpty();
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return this.list.iterator();
+	}
+
+	@Override
+	public int lastIndexOf(Object o) {
+		return this.list.lastIndexOf(o);
+	}
+
+	@Override
+	public ListIterator<E> listIterator() {
+		return this.list.listIterator();
+	}
+
+	@Override
+	public ListIterator<E> listIterator(int index) {
+		return this.list.listIterator(index);
+	}
+
+	@Override
+	public E remove(int index) {
+		return this.list.remove(index);
+	}
+
+	@Override
+	public boolean remove(Object o) {
+		return this.list.remove(o);
+	}
+
+	@Override
+	public boolean removeAll(Collection<?> c) {
+		return this.list.removeAll(c);
+	}
+
+	@Override
+	public boolean retainAll(Collection<?> c) {
+		return this.list.retainAll(c);
+	}
+
+	@Override
+	public E set(int index, E element) {
+		return this.list.set(index, element);
+	}
+
+	@Override
+	public int size() {
+		return this.list.size();
+	}
+
+	@Override
+	public List<E> subList(int fromIndex, int toIndex) {
+		return this.list.subList(fromIndex, toIndex);
+	}
+
+	@Override
+	public Object[] toArray() {
+		return this.list.toArray();
+	}
+
+	@Override
+	public <T> T[] toArray(T[] a) {
+		return this.list.toArray(a);
+	}
+
+
+	// ********** ListChangeListener implementation **********
+
+	@Override
+	public void itemsAdded(ListAddEvent e) {
+		int i = e.getIndex();
+		for (E item : this.getItems(e)) {
+			this.list.add(i++, item);
+		}
+	}
+
+	@Override
+	public void itemsRemoved(ListRemoveEvent e) {
+		int base = e.getIndex();
+		for (int i = e.getItemsSize(); i-- > 0; ) {
+			this.list.remove(base + i);  // remove from end
+		}
+	}
+
+	@Override
+	public void itemsReplaced(ListReplaceEvent e) {
+		int i = e.getIndex();
+		for (E item : this.getNewItems(e)) {
+			this.list.set(i++, item);
+		}
+	}
+
+	@Override
+	public void itemsMoved(ListMoveEvent e) {
+		ListTools.move(this.list, e.getTargetIndex(), e.getSourceIndex(), e.getLength());
+	}
+
+	@Override
+	public void listCleared(ListClearEvent e) {
+		this.list.clear();
+	}
+
+	@Override
+	public void listChanged(ListChangeEvent e) {
+		this.list.clear();
+		CollectionTools.addAll(this.list, this.getSource(e).iterator());
+	}
+
+
+	// ********** ListDataListener implementation **********
+
+	@Override
+	public void contentsChanged(ListDataEvent e) {
+		this.list.clear();
+		ListModel lm = (ListModel) e.getSource();
+		int size = lm.getSize();
+		for (int i = 0; i < size; i++) {
+			this.list.add(i, this.getElementAt(lm, i));
+		}
+	}
+
+	@Override
+	public void intervalAdded(ListDataEvent e) {
+		ListModel lm = (ListModel) e.getSource();
+		int start = Math.min(e.getIndex0(), e.getIndex1());
+		int end = Math.max(e.getIndex0(), e.getIndex1());
+		for (int i = start; i <= end; i++) {
+			this.list.add(i, this.getElementAt(lm, i));
+		}
+	}
+
+	@Override
+	public void intervalRemoved(ListDataEvent e) {
+		int start = Math.min(e.getIndex0(), e.getIndex1());
+		int end = Math.max(e.getIndex0(), e.getIndex1());
+		int length = end - start + 1;
+		for (int i = 1; i <= length; i++) {
+			this.list.remove(start);
+		}
+	}
+
+
+	// ********** standard methods **********
+
+    @Override
+	public boolean equals(Object o) {
+		return this.list.equals(o);
+	}
+
+    @Override
+	public int hashCode() {
+		return this.list.hashCode();
+	}
+
+    @Override
+	public String toString() {
+		return this.list.toString();
+	}
+
+
+	// ********** internal methods **********
+
+	/**
+	 * minimize the scope of the suppressed warnings.=
+	 */
+	@SuppressWarnings("unchecked")
+	private E getElementAt(ListModel listModel, int index) {
+		return (E) listModel.getElementAt(index);
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	private Iterable<E> getItems(ListAddEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	private Iterable<E> getNewItems(ListReplaceEvent event) {
+		return (Iterable<E>) event.getNewItems();
+	}
+
+	/**
+	 * minimize the scope of the suppressed warnings.=
+	 */
+	@SuppressWarnings("unchecked")
+	private ListValueModel<E> getSource(ListChangeEvent event) {
+		return (ListValueModel<E>) event.getSource();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/DoubleModifiablePropertyValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/DoubleModifiablePropertyValueModelTests.java
new file mode 100644
index 0000000..ab9c0c8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/DoubleModifiablePropertyValueModelTests.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import org.eclipse.persistence.tools.utility.model.value.DoubleModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+
+@SuppressWarnings("nls")
+public class DoubleModifiablePropertyValueModelTests
+	extends DoublePropertyValueModelTests
+{
+	public DoubleModifiablePropertyValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected PropertyValueModel<String> buildDoubleModel() {
+		return new DoubleModifiablePropertyValueModel<String>(this.stringModelModel);
+	}
+
+	protected ModifiablePropertyValueModel<String> getDoubleModel() {
+		return (ModifiablePropertyValueModel<String>) this.doubleModel;
+	}
+
+	public void testSetValue() {
+		assertEquals("foo", this.stringModel.getValue());
+		assertEquals(this.stringModel, this.stringModelModel.getValue());
+		assertNull(this.doubleModel.getValue());
+		this.doubleModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.doubleModelListener);
+		assertEquals("foo", this.doubleModel.getValue());
+
+		this.getDoubleModel().setValue("bar");
+		assertEquals("bar", this.stringModel.getValue());
+		assertEquals("bar", this.doubleModel.getValue());
+
+		this.stringModelModel.setValue(null);
+		assertNull(this.doubleModel.getValue());
+		this.getDoubleModel().setValue("TTT");  // NOP?
+		assertEquals("bar", this.stringModel.getValue());
+		assertNull(this.doubleModel.getValue());
+	}
+
+	public void testPropertyChange3() {
+		this.stringModel.addChangeListener(this.stringModelListener);
+		this.stringModelModel.addChangeListener(this.stringModelModelListener);
+		this.doubleModel.addChangeListener(this.doubleModelListener);
+		this.verifyPropertyChanges2();
+	}
+
+	public void testPropertyChange4() {
+		this.stringModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.stringModelListener);
+		this.stringModelModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.stringModelModelListener);
+		this.doubleModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.doubleModelListener);
+		this.verifyPropertyChanges2();
+	}
+
+	protected void verifyPropertyChanges2() {
+		this.stringModelEvent = null;
+		this.stringModelModelEvent = null;
+		this.doubleModelEvent = null;
+		this.getDoubleModel().setValue("bar");
+		this.verifyEvent(this.stringModelEvent, this.stringModel, "foo", "bar");
+		assertNull(this.stringModelModelEvent);
+		this.verifyEvent(this.doubleModelEvent, this.doubleModel, "foo", "bar");
+
+		this.stringModelEvent = null;
+		this.stringModelModelEvent = null;
+		this.doubleModelEvent = null;
+		this.getDoubleModel().setValue(null);
+		this.verifyEvent(this.stringModelEvent, this.stringModel, "bar", null);
+		assertNull(this.stringModelModelEvent);
+		this.verifyEvent(this.doubleModelEvent, this.doubleModel, "bar", null);
+
+		this.stringModelEvent = null;
+		this.stringModelModelEvent = null;
+		this.doubleModelEvent = null;
+		this.getDoubleModel().setValue("foo");
+		this.verifyEvent(this.stringModelEvent, this.stringModel, null, "foo");
+		assertNull(this.stringModelModelEvent);
+		this.verifyEvent(this.doubleModelEvent, this.doubleModel, null, "foo");
+
+		this.stringModelEvent = null;
+		this.stringModelModelEvent = null;
+		this.doubleModelEvent = null;
+		ModifiablePropertyValueModel<String> stringModel2 = new SimplePropertyValueModel<String>("TTT");
+		this.stringModelModel.setValue(stringModel2);
+		assertNull(this.stringModelEvent);
+		this.verifyEvent(this.stringModelModelEvent, this.stringModelModel, this.stringModel, stringModel2);
+		this.verifyEvent(this.doubleModelEvent, this.doubleModel, "foo", "TTT");
+
+		this.stringModelEvent = null;
+		this.stringModelModelEvent = null;
+		this.doubleModelEvent = null;
+		this.getDoubleModel().setValue("XXX");
+		assertNull(this.stringModelEvent);
+		assertNull(this.stringModelModelEvent);
+		this.verifyEvent(this.doubleModelEvent, this.doubleModel, "TTT", "XXX");
+		assertEquals("foo", this.stringModel.getValue());
+		assertEquals("XXX", stringModel2.getValue());
+
+		this.stringModelEvent = null;
+		this.stringModelModelEvent = null;
+		this.doubleModelEvent = null;
+		this.stringModelModel.setValue(this.stringModel);
+		assertNull(this.stringModelEvent);
+		this.verifyEvent(this.stringModelModelEvent, this.stringModelModel, stringModel2, this.stringModel);
+		this.verifyEvent(this.doubleModelEvent, this.doubleModel, "XXX", "foo");
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/DoublePropertyValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/DoublePropertyValueModelTests.java
new file mode 100644
index 0000000..43f7752
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/DoublePropertyValueModelTests.java
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.DoublePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class DoublePropertyValueModelTests
+	extends TestCase
+{
+	protected ModifiablePropertyValueModel<String> stringModel;
+	protected ChangeListener stringModelListener;
+	protected PropertyChangeEvent stringModelEvent;
+
+	protected ModifiablePropertyValueModel<ModifiablePropertyValueModel<String>> stringModelModel;
+	protected ChangeListener stringModelModelListener;
+	protected PropertyChangeEvent stringModelModelEvent;
+
+	protected PropertyValueModel<String> doubleModel;
+	protected ChangeListener doubleModelListener;
+	protected PropertyChangeEvent doubleModelEvent;
+
+	public DoublePropertyValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.stringModel = new SimplePropertyValueModel<String>("foo");
+		this.stringModelListener = new StringModelListener();
+
+		this.stringModelModel = new SimplePropertyValueModel<ModifiablePropertyValueModel<String>>(stringModel);
+		this.stringModelModelListener = new StringModelModelListener();
+
+		this.doubleModel = this.buildDoubleModel();
+		this.doubleModelListener = new DoubleModelListener();
+	}
+
+	protected PropertyValueModel<String> buildDoubleModel() {
+		return new DoublePropertyValueModel<String>(this.stringModelModel);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testGetValue1() {
+		assertEquals("foo", this.stringModel.getValue());
+		assertEquals(this.stringModel, this.stringModelModel.getValue());
+		assertNull(this.doubleModel.getValue());
+		this.doubleModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.doubleModelListener);
+		assertEquals("foo", this.doubleModel.getValue());
+
+		this.stringModel.setValue("bar");
+		assertEquals("bar", this.stringModel.getValue());
+		assertEquals("bar", this.doubleModel.getValue());
+
+		this.stringModel.setValue("baz");
+		assertEquals("baz", this.stringModel.getValue());
+		assertEquals("baz", this.doubleModel.getValue());
+
+		this.stringModel.setValue(null);
+		assertNull(this.stringModel.getValue());
+		assertNull(this.doubleModel.getValue());
+
+		this.stringModel.setValue("foo");
+		assertEquals("foo", this.stringModel.getValue());
+		assertEquals("foo", this.doubleModel.getValue());
+	}
+
+	public void testGetValue2() {
+		assertNull(this.doubleModel.getValue());
+		this.doubleModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.doubleModelListener);
+		assertEquals("foo", this.doubleModel.getValue());
+
+		this.stringModelModel.setValue(null);
+		assertNull(this.doubleModel.getValue());
+
+		ModifiablePropertyValueModel<String> stringModel2 = new SimplePropertyValueModel<String>("TTT");
+		this.stringModelModel.setValue(stringModel2);
+		assertEquals("TTT", this.doubleModel.getValue());
+
+		this.stringModelModel.setValue(this.stringModel);
+		assertEquals("foo", this.doubleModel.getValue());
+	}
+
+	public void testLazyListening() {
+		assertTrue(((AbstractModel) this.stringModel).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.stringModelModel).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.doubleModel.addChangeListener(this.doubleModelListener);
+		assertTrue(((AbstractModel) this.stringModel).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.stringModelModel).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.doubleModel.removeChangeListener(this.doubleModelListener);
+		assertTrue(((AbstractModel) this.stringModel).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) this.stringModelModel).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.doubleModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.doubleModelListener);
+		assertTrue(((AbstractModel) this.stringModel).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.doubleModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.doubleModelListener);
+		assertTrue(((AbstractModel) this.stringModel).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.doubleModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.doubleModelListener);
+		ModifiablePropertyValueModel<String> stringModel2 = new SimplePropertyValueModel<String>("TTT");
+		assertTrue(((AbstractModel) this.stringModel).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) stringModel2).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.stringModelModel.setValue(stringModel2);
+		assertTrue(((AbstractModel) this.stringModel).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) stringModel2).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.stringModelModel.setValue(this.stringModel);
+		assertTrue(((AbstractModel) this.stringModel).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(((AbstractModel) stringModel2).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	public void testPropertyChange1() {
+		this.stringModel.addChangeListener(this.stringModelListener);
+		this.stringModelModel.addChangeListener(this.stringModelModelListener);
+		this.doubleModel.addChangeListener(this.doubleModelListener);
+		this.verifyPropertyChanges1();
+	}
+
+	public void testPropertyChange2() {
+		this.stringModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.stringModelListener);
+		this.stringModelModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.stringModelModelListener);
+		this.doubleModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.doubleModelListener);
+		this.verifyPropertyChanges1();
+	}
+
+	protected void verifyPropertyChanges1() {
+		this.stringModelEvent = null;
+		this.stringModelModelEvent = null;
+		this.doubleModelEvent = null;
+		this.stringModel.setValue("bar");
+		this.verifyEvent(this.stringModelEvent, this.stringModel, "foo", "bar");
+		assertNull(this.stringModelModelEvent);
+		this.verifyEvent(this.doubleModelEvent, this.doubleModel, "foo", "bar");
+
+		this.stringModelEvent = null;
+		this.stringModelModelEvent = null;
+		this.doubleModelEvent = null;
+		this.stringModel.setValue(null);
+		this.verifyEvent(this.stringModelEvent, this.stringModel, "bar", null);
+		assertNull(this.stringModelModelEvent);
+		this.verifyEvent(this.doubleModelEvent, this.doubleModel, "bar", null);
+
+		this.stringModelEvent = null;
+		this.stringModelModelEvent = null;
+		this.doubleModelEvent = null;
+		this.stringModel.setValue("foo");
+		this.verifyEvent(this.stringModelEvent, this.stringModel, null, "foo");
+		assertNull(this.stringModelModelEvent);
+		this.verifyEvent(this.doubleModelEvent, this.doubleModel, null, "foo");
+
+		this.stringModelEvent = null;
+		this.stringModelModelEvent = null;
+		this.doubleModelEvent = null;
+		ModifiablePropertyValueModel<String> stringModel2 = new SimplePropertyValueModel<String>("TTT");
+		this.stringModelModel.setValue(stringModel2);
+		assertNull(this.stringModelEvent);
+		this.verifyEvent(this.stringModelModelEvent, this.stringModelModel, this.stringModel, stringModel2);
+		this.verifyEvent(this.doubleModelEvent, this.doubleModel, "foo", "TTT");
+
+		this.stringModelEvent = null;
+		this.stringModelModelEvent = null;
+		this.doubleModelEvent = null;
+		this.stringModelModel.setValue(this.stringModel);
+		assertNull(this.stringModelEvent);
+		this.verifyEvent(this.stringModelModelEvent, this.stringModelModel, stringModel2, this.stringModel);
+		this.verifyEvent(this.doubleModelEvent, this.doubleModel, "TTT", "foo");
+	}
+
+	protected void verifyEvent(PropertyChangeEvent event, Object source, Object oldValue, Object newValue) {
+		assertEquals(source, event.getSource());
+		assertEquals(PropertyValueModel.VALUE, event.getPropertyName());
+		assertEquals(oldValue, event.getOldValue());
+		assertEquals(newValue, event.getNewValue());
+	}
+
+	protected class StringModelListener
+		extends ChangeAdapter
+	{
+		@Override
+		public void propertyChanged(PropertyChangeEvent event) {
+			DoublePropertyValueModelTests.this.stringModelEvent = event;
+		}
+	}
+
+	protected class StringModelModelListener
+		extends ChangeAdapter
+	{
+		@Override
+		public void propertyChanged(PropertyChangeEvent event) {
+			DoublePropertyValueModelTests.this.stringModelModelEvent = event;
+		}
+	}
+
+	protected class DoubleModelListener
+		extends ChangeAdapter
+	{
+		@Override
+		public void propertyChanged(PropertyChangeEvent event) {
+			DoublePropertyValueModelTests.this.doubleModelEvent = event;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ExtendedListValueModelWrapperTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ExtendedListValueModelWrapperTests.java
new file mode 100644
index 0000000..3182d13
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ExtendedListValueModelWrapperTests.java
@@ -0,0 +1,317 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ExtendedListValueModelWrapper;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleListValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class ExtendedListValueModelWrapperTests extends TestCase {
+
+	private SimpleListValueModel<String> listHolder;
+	private ListValueModel<String> extendedListHolder;
+	ListEvent event;
+	String eventType;
+
+	private static final String ADD = "add";
+	private static final String REMOVE = "remove";
+	private static final String REPLACE = "replace";
+	private static final String MOVE = "move";
+	private static final String CLEAR = "clear";
+	private static final String CHANGE = "change";
+
+	public ExtendedListValueModelWrapperTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.listHolder = new SimpleListValueModel<String>(this.buildList());
+		this.extendedListHolder = this.buildExtendedListHolder(this.listHolder);
+	}
+
+	private List<String> buildList() {
+		List<String> result = new ArrayList<String>();
+		result.add("A");
+		result.add("B");
+		result.add("C");
+		result.add("D");
+		return result;
+	}
+
+	private List<String> buildExtendedList() {
+		List<String> extendedList = new ArrayList<String>();
+		extendedList.addAll(this.buildPrefix());
+		extendedList.addAll(this.buildList());
+		extendedList.addAll(this.buildSuffix());
+		return extendedList;
+	}
+
+	private List<String> buildPrefix() {
+		List<String> prefix = new ArrayList<String>();
+		prefix.add("x");
+		prefix.add("y");
+		prefix.add("z");
+		return prefix;
+	}
+
+	private List<String> buildSuffix() {
+		List<String> suffix = new ArrayList<String>();
+		suffix.add("i");
+		suffix.add("j");
+		return suffix;
+	}
+
+	private ListValueModel<String> buildExtendedListHolder(ListValueModel<String> lvm) {
+		return new ExtendedListValueModelWrapper<String>(this.buildPrefix(), lvm, this.buildSuffix());
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testIterator() {
+		this.extendedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
+		assertEquals(this.buildExtendedList(), ListTools.list(this.extendedListHolder.iterator()));
+	}
+
+	public void testSize() {
+		this.extendedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
+		assertEquals(this.buildExtendedList().size(), IteratorTools.size(this.extendedListHolder.iterator()));
+		assertEquals(this.buildExtendedList().size(), this.extendedListHolder.size());
+	}
+
+	private boolean extendedListContains(Object item) {
+		return IteratorTools.contains(this.extendedListHolder.iterator(), item);
+	}
+
+	private boolean extendedListContainsAll(Collection<String> items) {
+		return IteratorTools.containsAll(this.extendedListHolder.iterator(), items);
+	}
+
+	private boolean extendedListContainsAny(Collection<String> items) {
+		List<String> extendedList = ListTools.list(this.extendedListHolder.iterator());
+		for (Iterator<String> stream = items.iterator(); stream.hasNext(); ) {
+			if (extendedList.contains(stream.next())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private boolean listContains(Object item) {
+		return IteratorTools.contains(this.listHolder.iterator(), item);
+	}
+
+	private boolean listContainsAll(Collection<String> items) {
+		return IteratorTools.containsAll(this.listHolder.iterator(), items);
+	}
+
+//	private boolean listContainsAny(Collection<String> items) {
+//		List<String> extendedList = CollectionTools.list(this.listHolder.iterator());
+//		for (Iterator<String> stream = items.iterator(); stream.hasNext(); ) {
+//			if (extendedList.contains(stream.next())) {
+//				return true;
+//			}
+//		}
+//		return false;
+//	}
+//
+	public void testAdd1() {
+		this.extendedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
+
+		assertFalse(this.extendedListContains("E"));
+		this.listHolder.add(4, "E");
+		assertTrue(this.extendedListContains("E"));
+		assertTrue(this.listContains("E"));
+	}
+
+	public void testAdd2() {
+		this.extendedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
+
+		assertFalse(this.extendedListContains(null));
+		this.listHolder.add(4, null);
+		assertTrue(this.extendedListContains(null));
+		assertTrue(this.listContains(null));
+	}
+
+	private List<String> buildAddList() {
+		List<String> addList = new ArrayList<String>();
+		addList.add("E");
+		addList.add("F");
+		return addList;
+	}
+
+	public void testAddAll1() {
+		this.extendedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
+
+		assertFalse(this.extendedListContainsAny(this.buildAddList()));
+		this.listHolder.addAll(4, this.buildAddList());
+		assertTrue(this.extendedListContainsAll(this.buildAddList()));
+		assertTrue(this.listContainsAll(this.buildAddList()));
+	}
+
+	public void testRemove1() {
+		this.extendedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
+
+		assertTrue(this.extendedListContains("B"));
+		this.listHolder.remove(this.buildList().indexOf("B"));
+		assertFalse(this.extendedListContains("B"));
+		assertFalse(this.listContains("B"));
+	}
+
+	public void testListChangeGeneric() {
+		this.extendedListHolder.addChangeListener(this.buildListener());
+		this.verifyListChange();
+	}
+
+	public void testListChangeNamed() {
+		this.extendedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
+		this.verifyListChange();
+	}
+
+	private void verifyListChange() {
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.add(4, "E");
+		this.verifyEvent(ADD, 7, "E");
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.add(5, null);
+		this.verifyEvent(ADD, 8, null);
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.remove(5);
+		this.verifyEvent(REMOVE, 8, null);
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.remove(4);
+		this.verifyEvent(REMOVE, 7, "E");
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.addAll(0, this.buildList());
+		this.verifyEvent(ADD);
+		assertEquals(this.buildList(), ListTools.list(((ListAddEvent) this.event).getItems()));
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.set(0, "AA");
+		this.verifyEvent(REPLACE);
+		assertFalse(IterableTools.contains(((ListReplaceEvent) this.event).getNewItems(), "A"));
+		assertTrue(IterableTools.contains(((ListReplaceEvent) this.event).getNewItems(), "AA"));
+	}
+
+	private ChangeListener buildListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {
+				ExtendedListValueModelWrapperTests.this.eventType = ADD;
+				ExtendedListValueModelWrapperTests.this.event = e;
+			}
+			@Override
+			public void itemsRemoved(ListRemoveEvent e) {
+				ExtendedListValueModelWrapperTests.this.eventType = REMOVE;
+				ExtendedListValueModelWrapperTests.this.event = e;
+			}
+			@Override
+			public void itemsReplaced(ListReplaceEvent e) {
+				ExtendedListValueModelWrapperTests.this.eventType = REPLACE;
+				ExtendedListValueModelWrapperTests.this.event = e;
+			}
+			@Override
+			public void itemsMoved(ListMoveEvent e) {
+				ExtendedListValueModelWrapperTests.this.eventType = MOVE;
+				ExtendedListValueModelWrapperTests.this.event = e;
+			}
+			@Override
+			public void listCleared(ListClearEvent e) {
+				ExtendedListValueModelWrapperTests.this.eventType = CLEAR;
+				ExtendedListValueModelWrapperTests.this.event = e;
+			}
+			@Override
+			public void listChanged(ListChangeEvent e) {
+				ExtendedListValueModelWrapperTests.this.eventType = CHANGE;
+				ExtendedListValueModelWrapperTests.this.event = e;
+			}
+		};
+	}
+
+	private void verifyEvent(String type) {
+		assertEquals(type, this.eventType);
+		assertEquals(this.extendedListHolder, this.event.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event.getListName());
+	}
+
+	private void verifyEvent(String type, int index, Object item) {
+		this.verifyEvent(type);
+		if (type == ADD) {
+			assertEquals(index, ((ListAddEvent) this.event).getIndex());
+			assertEquals(item, ((ListAddEvent) this.event).getItems().iterator().next());
+		} else if (type == REMOVE) {
+			assertEquals(index, ((ListRemoveEvent) this.event).getIndex());
+			assertEquals(item, ((ListRemoveEvent) this.event).getItems().iterator().next());
+		}
+	}
+
+	public void testHasListeners() {
+		/*
+		 * adding listeners to the extended list will cause listeners
+		 * to be added to the wrapped list;
+		 * likewise, removing listeners from the extended list will
+		 * cause listeners to be removed from the wrapped list
+		 */
+		assertFalse(((AbstractModel) this.listHolder).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		ChangeListener listener = this.buildListener();
+
+		this.extendedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		assertTrue(((AbstractModel) this.listHolder).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		this.extendedListHolder.removeListChangeListener(ListValueModel.LIST_VALUES, listener);
+		assertFalse(((AbstractModel) this.listHolder).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		this.extendedListHolder.addChangeListener(listener);
+		assertTrue(((AbstractModel) this.listHolder).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		this.extendedListHolder.removeChangeListener(listener);
+		assertFalse(((AbstractModel) this.listHolder).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/FilteringCollectionValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/FilteringCollectionValueModelTests.java
new file mode 100644
index 0000000..e9f7c62
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/FilteringCollectionValueModelTests.java
@@ -0,0 +1,360 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Vector;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.FilteringCollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class FilteringCollectionValueModelTests extends TestCase {
+
+	private SimpleCollectionValueModel<String> collectionHolder;
+	CollectionAddEvent addEvent;
+	CollectionRemoveEvent removeEvent;
+	CollectionClearEvent collectionClearedEvent;
+	CollectionChangeEvent collectionChangedEvent;
+
+	private CollectionValueModel<String> filteredCollectionHolder;
+	CollectionAddEvent filteredAddEvent;
+	CollectionRemoveEvent filteredRemoveEvent;
+	CollectionClearEvent filteredCollectionClearedEvent;
+	CollectionChangeEvent filteredCollectionChangedEvent;
+
+	public FilteringCollectionValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.collectionHolder = new SimpleCollectionValueModel<String>(buildCollection());
+		this.filteredCollectionHolder = new FilteringCollectionValueModel<String>(this.collectionHolder, this.buildFilter());
+	}
+
+	private Collection<String> buildCollection() {
+		Collection<String> collection = new Vector<String>();
+		collection.add("foo");
+		return collection;
+	}
+
+	private Filter<String> buildFilter() {
+		return new Filter<String>() {
+			@Override
+			public boolean accept(String s) {
+				return s.startsWith("b");
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testIterator() {
+		// add a listener to "activate" the wrapper
+		this.filteredCollectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.buildFilteredListener());
+
+		assertEquals("foo", this.collectionHolder.iterator().next());
+		assertFalse(this.filteredCollectionHolder.iterator().hasNext());
+
+		this.collectionHolder.add("bar");
+		Iterator<String> collectionHolderValue = this.collectionHolder.iterator();
+		assertEquals("foo", collectionHolderValue.next());
+		assertEquals("bar", collectionHolderValue.next());
+		assertTrue(this.filteredCollectionHolder.iterator().hasNext());
+		assertEquals("bar", this.filteredCollectionHolder.iterator().next());
+
+		this.collectionHolder.remove("bar");
+		assertEquals("foo", this.collectionHolder.iterator().next());
+		assertFalse(this.filteredCollectionHolder.iterator().hasNext());
+
+		this.collectionHolder.remove("foo");
+		assertFalse(this.collectionHolder.iterator().hasNext());
+		assertFalse(this.filteredCollectionHolder.iterator().hasNext());
+
+		this.collectionHolder.add("foo");
+		assertEquals("foo", this.collectionHolder.iterator().next());
+		assertFalse(this.filteredCollectionHolder.iterator().hasNext());
+	}
+
+	public void testSetValue() {
+		// add a listener to "activate" the wrapper
+		this.filteredCollectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.buildFilteredListener());
+
+		Collection<String> newCollection = new Vector<String>();
+		newCollection.add("fox");
+		newCollection.add("baz");
+
+		this.collectionHolder.setValues(newCollection);
+
+		Iterator<String> collectionValues = this.collectionHolder.iterator();
+		assertEquals("fox", collectionValues.next());
+		assertEquals("baz", collectionValues.next());
+		Iterator<String> filteredCollectionValues = this.filteredCollectionHolder.iterator();
+		assertEquals("baz", filteredCollectionValues.next());
+		assertFalse(filteredCollectionValues.hasNext());
+	}
+
+	public void testLazyListening() {
+		assertTrue(((AbstractModel) this.collectionHolder).hasNoCollectionChangeListeners(CollectionValueModel.VALUES));
+		ChangeListener listener = this.buildFilteredChangeListener();
+		this.filteredCollectionHolder.addChangeListener(listener);
+		assertTrue(((AbstractModel) this.collectionHolder).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		this.filteredCollectionHolder.removeChangeListener(listener);
+		assertTrue(((AbstractModel) this.collectionHolder).hasNoCollectionChangeListeners(CollectionValueModel.VALUES));
+
+		this.filteredCollectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, listener);
+		assertTrue(((AbstractModel) this.collectionHolder).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		this.filteredCollectionHolder.removeCollectionChangeListener(CollectionValueModel.VALUES, listener);
+		assertTrue(((AbstractModel) this.collectionHolder).hasNoCollectionChangeListeners(CollectionValueModel.VALUES));
+	}
+
+	public void testCollectionChange1() {
+		this.collectionHolder.addChangeListener(this.buildChangeListener());
+		this.filteredCollectionHolder.addChangeListener(this.buildFilteredChangeListener());
+		this.verifyCollectionChanges();
+	}
+
+	public void testCollectionChange2() {
+		this.collectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.buildListener());
+		this.filteredCollectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.buildFilteredListener());
+		this.verifyCollectionChanges();
+	}
+
+	private void clearEvents() {
+		this.addEvent = null;
+		this.removeEvent = null;
+		this.collectionClearedEvent = null;
+		this.collectionChangedEvent = null;
+		this.filteredAddEvent = null;
+		this.filteredRemoveEvent = null;
+		this.filteredCollectionClearedEvent = null;
+		this.filteredCollectionChangedEvent = null;
+	}
+
+	private void verifyCollectionChanges() {
+		clearEvents();
+		this.collectionHolder.add("bar");
+		Collection<String> tempCollection = new Vector<String>();
+		tempCollection.add("bar");
+		this.verifyEvent(this.addEvent, this.collectionHolder, tempCollection);
+		this.verifyEvent(this.filteredAddEvent, this.filteredCollectionHolder, tempCollection);
+
+		clearEvents();
+		this.collectionHolder.remove("foo");
+		tempCollection.remove("bar");
+		tempCollection.add("foo");
+		this.verifyEvent(this.removeEvent, this.collectionHolder, tempCollection);
+		assertNull(this.filteredRemoveEvent);
+
+
+		clearEvents();
+		this.collectionHolder.remove("bar");
+		tempCollection.add("bar");
+		tempCollection.remove("foo");
+		this.verifyEvent(this.removeEvent, this.collectionHolder, tempCollection);
+		this.verifyEvent(this.filteredRemoveEvent, this.filteredCollectionHolder, tempCollection);
+
+
+		clearEvents();
+		this.collectionHolder.add("foo");
+		tempCollection.remove("bar");
+		tempCollection.add("foo");
+		this.verifyEvent(this.addEvent, this.collectionHolder, tempCollection);
+		assertNull(this.filteredAddEvent);
+
+
+		clearEvents();
+		Collection<String> newCollection = new Vector<String>();
+		newCollection.add("fox");
+		newCollection.add("baz");
+
+		this.collectionHolder.setValues(newCollection);
+
+		this.verifyEvent(this.collectionChangedEvent, this.collectionHolder);
+
+		tempCollection.remove("foo");
+		tempCollection.add("baz");
+		this.verifyEvent(this.filteredCollectionChangedEvent, this.filteredCollectionHolder);
+
+	}
+
+	private CollectionChangeListener buildListener() {
+		return new CollectionChangeListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {
+				FilteringCollectionValueModelTests.this.addEvent = e;
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {
+				FilteringCollectionValueModelTests.this.removeEvent = e;
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent e) {
+				FilteringCollectionValueModelTests.this.collectionClearedEvent = e;
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent e) {
+				FilteringCollectionValueModelTests.this.collectionChangedEvent = e;
+			}
+		};
+	}
+
+	private ChangeListener buildChangeListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {
+				FilteringCollectionValueModelTests.this.addEvent = e;
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {
+				FilteringCollectionValueModelTests.this.removeEvent = e;
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent e) {
+				FilteringCollectionValueModelTests.this.collectionClearedEvent = e;
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent e) {
+				FilteringCollectionValueModelTests.this.collectionChangedEvent = e;
+			}
+		};
+	}
+
+	private CollectionChangeListener buildFilteredListener() {
+		return new CollectionChangeListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {
+				FilteringCollectionValueModelTests.this.filteredAddEvent = e;
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {
+				FilteringCollectionValueModelTests.this.filteredRemoveEvent = e;
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent e) {
+				FilteringCollectionValueModelTests.this.filteredCollectionClearedEvent = e;
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent e) {
+				FilteringCollectionValueModelTests.this.filteredCollectionChangedEvent = e;
+			}
+		};
+	}
+
+	private ChangeListener buildFilteredChangeListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {
+				FilteringCollectionValueModelTests.this.filteredAddEvent = e;
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {
+				FilteringCollectionValueModelTests.this.filteredRemoveEvent = e;
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent e) {
+				FilteringCollectionValueModelTests.this.filteredCollectionClearedEvent = e;
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent e) {
+				FilteringCollectionValueModelTests.this.filteredCollectionChangedEvent = e;
+			}
+		};
+	}
+
+	private void verifyEvent(CollectionChangeEvent event, Object source) {
+		assertEquals(source, event.getSource());
+		assertEquals(CollectionValueModel.VALUES, event.getCollectionName());
+	}
+
+	private void verifyEvent(CollectionAddEvent event, Object source, Object items) {
+		assertEquals(source, event.getSource());
+		assertEquals(CollectionValueModel.VALUES, event.getCollectionName());
+		assertEquals(items, CollectionTools.vector(event.getItems()));
+	}
+
+	private void verifyEvent(CollectionRemoveEvent event, Object source, Object items) {
+		assertEquals(source, event.getSource());
+		assertEquals(CollectionValueModel.VALUES, event.getCollectionName());
+		assertEquals(items, CollectionTools.vector(event.getItems()));
+	}
+
+	public void testRemoveFilteredItem() {
+		// build collection with TestItems
+		SimpleCollectionValueModel<TestItem> tiHolder = new SimpleCollectionValueModel<TestItem>(this.buildCollection2());
+		CollectionValueModel<TestItem> filteredTIHolder = new FilteringCollectionValueModel<TestItem>(tiHolder, this.buildFilter2());
+		// add a listener to "activate" the wrapper
+		filteredTIHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.buildFilteredListener());
+
+		assertEquals(0, filteredTIHolder.size());
+
+		tiHolder.add(new TestItem("bar"));
+		assertEquals(1, filteredTIHolder.size());
+
+		TestItem baz = new TestItem("baz");
+		tiHolder.add(baz);
+		assertEquals(2, filteredTIHolder.size());
+		// before removing it, change the item so that it is filtered
+		baz.name = "jaz";
+		tiHolder.remove(baz);
+		// this would fail because the item was not removed from
+		// the filtered collection cache... but we've fixed it now
+		assertEquals(1, filteredTIHolder.size());
+	}
+
+	private Collection<TestItem> buildCollection2() {
+		Collection<TestItem> collection = new Vector<TestItem>();
+		collection.add(new TestItem("foo"));
+		return collection;
+	}
+
+	private Filter<TestItem> buildFilter2() {
+		return new Filter<TestItem>() {
+			@Override
+			public boolean accept(TestItem ti) {
+				return ti.name.startsWith("b");
+			}
+		};
+	}
+
+
+	// ********** TestItem inner class **********
+
+	private class TestItem {
+		String name;
+		TestItem(String name) {
+			super();
+			this.name = name;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/FilteringPropertyValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/FilteringPropertyValueModelTests.java
new file mode 100644
index 0000000..695fec9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/FilteringPropertyValueModelTests.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.FilteringModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class FilteringPropertyValueModelTests extends TestCase {
+
+	private ModifiablePropertyValueModel<String> objectHolder;
+	PropertyChangeEvent event;
+
+	private ModifiablePropertyValueModel<String> filteredObjectHolder;
+	PropertyChangeEvent filteredEvent;
+
+	public FilteringPropertyValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.objectHolder = new SimplePropertyValueModel<String>("foo");
+		this.filteredObjectHolder = new FilteringModifiablePropertyValueModel<String>(this.objectHolder, this.buildFilter(), this.buildSetFilter());
+	}
+
+	private Filter<String> buildFilter() {
+		return new Filter<String>() {
+			@Override
+			public boolean accept(String s) {
+				return (s != null) && s.startsWith("b");
+			}
+		};
+	}
+
+	private Filter<String> buildSetFilter() {
+		return new Filter<String>() {
+			@Override
+			public boolean accept(String s) {
+				return (s != null) && s.startsWith("b");
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testValue() {
+		assertEquals("foo", this.objectHolder.getValue());
+		assertNull(this.filteredObjectHolder.getValue());
+
+		this.objectHolder.setValue("bar");
+		assertEquals("bar", this.objectHolder.getValue());
+		assertNotNull(this.filteredObjectHolder.getValue());
+		assertEquals("bar", this.filteredObjectHolder.getValue());
+
+		this.objectHolder.setValue("baz");
+		assertEquals("baz", this.objectHolder.getValue());
+		assertNotNull(this.filteredObjectHolder.getValue());
+		assertEquals("baz", this.filteredObjectHolder.getValue());
+
+		this.objectHolder.setValue(null);
+		assertNull(this.objectHolder.getValue());
+		assertNull(this.filteredObjectHolder.getValue());
+
+		this.objectHolder.setValue("foo");
+		assertEquals("foo", this.objectHolder.getValue());
+		assertNull(this.filteredObjectHolder.getValue());
+	}
+
+	public void testSetValue() {
+		this.filteredObjectHolder.setValue("bar");
+		assertEquals("bar", this.objectHolder.getValue());
+		assertEquals("bar", this.filteredObjectHolder.getValue());
+
+		this.filteredObjectHolder.setValue("foo");
+		assertEquals("bar", this.objectHolder.getValue());
+		assertEquals("bar", this.filteredObjectHolder.getValue());
+
+		this.filteredObjectHolder.setValue(null);
+		assertEquals("bar", this.objectHolder.getValue());
+		assertEquals("bar", this.filteredObjectHolder.getValue());
+
+		this.filteredObjectHolder.setValue("baz");
+		assertEquals("baz", this.objectHolder.getValue());
+		assertEquals("baz", this.filteredObjectHolder.getValue());
+	}
+
+	public void testLazyListening() {
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		ChangeListener listener = this.buildFilteredListener();
+		this.filteredObjectHolder.addChangeListener(listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.filteredObjectHolder.removeChangeListener(listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.filteredObjectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.filteredObjectHolder.removePropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	public void testPropertyChange1() {
+		this.objectHolder.addChangeListener(this.buildListener());
+		this.filteredObjectHolder.addChangeListener(this.buildFilteredListener());
+		this.verifyPropertyChanges();
+	}
+
+	public void testPropertyChange2() {
+		this.objectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildListener());
+		this.filteredObjectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildFilteredListener());
+		this.verifyPropertyChanges();
+	}
+
+	private void verifyPropertyChanges() {
+		this.event = null;
+		this.filteredEvent = null;
+		this.objectHolder.setValue("bar");
+		this.verifyEvent(this.event, this.objectHolder, "foo", "bar");
+		this.verifyEvent(this.filteredEvent, this.filteredObjectHolder, null, "bar");
+
+		this.event = null;
+		this.filteredEvent = null;
+		this.objectHolder.setValue("baz");
+		this.verifyEvent(this.event, this.objectHolder, "bar", "baz");
+		this.verifyEvent(this.filteredEvent, this.filteredObjectHolder, "bar", "baz");
+
+		this.event = null;
+		this.filteredEvent = null;
+		this.objectHolder.setValue("foo");
+		this.verifyEvent(this.event, this.objectHolder, "baz", "foo");
+		this.verifyEvent(this.filteredEvent, this.filteredObjectHolder, "baz", null);
+
+		this.event = null;
+		this.filteredEvent = null;
+		this.objectHolder.setValue("fop");
+		this.verifyEvent(this.event, this.objectHolder, "foo", "fop");
+		assertNull(this.filteredEvent);
+
+		this.event = null;
+		this.filteredEvent = null;
+		this.objectHolder.setValue(null);
+		this.verifyEvent(this.event, this.objectHolder, "fop", null);
+		assertNull(this.filteredEvent);
+
+		this.event = null;
+		this.filteredEvent = null;
+		this.objectHolder.setValue("bar");
+		this.verifyEvent(this.event, this.objectHolder, null, "bar");
+		this.verifyEvent(this.filteredEvent, this.filteredObjectHolder, null, "bar");
+	}
+
+	private ChangeListener buildListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				FilteringPropertyValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	private ChangeListener buildFilteredListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				FilteringPropertyValueModelTests.this.filteredEvent = e;
+			}
+		};
+	}
+
+	private void verifyEvent(PropertyChangeEvent e, Object source, Object oldValue, Object newValue) {
+		assertEquals(source, e.getSource());
+		assertEquals(PropertyValueModel.VALUE, e.getPropertyName());
+		assertEquals(oldValue, e.getOldValue());
+		assertEquals(newValue, e.getNewValue());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ItemCollectionListValueModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ItemCollectionListValueModelAdapterTests.java
new file mode 100644
index 0000000..85fa4cd
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ItemCollectionListValueModelAdapterTests.java
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.swing.Icon;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.value.ItemCollectionListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SortedListValueModelWrapper;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+import org.eclipse.persistence.tools.utility.tests.model.Displayable;
+
+@SuppressWarnings("nls")
+public class ItemCollectionListValueModelAdapterTests extends TestCase {
+
+	private Junk foo;
+	private Junk bar;
+	private Junk baz;
+	private Junk joo;
+	private Junk jar;
+	private Junk jaz;
+
+	private Junk tom;
+	private Junk dick;
+	private Junk harry;
+
+	public ItemCollectionListValueModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.foo = new Junk("foo");
+		this.bar = new Junk("bar");
+		this.baz = new Junk("baz");
+		this.joo = new Junk("joo");
+		this.jar = new Junk("jar");
+		this.jaz = new Junk("jaz");
+
+		this.tom = new Junk("tom");
+		this.dick = new Junk("dick");
+		this.harry = new Junk("harry");
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testCollectionSynchronization() {
+		SimpleCollectionValueModel<Junk> collectionHolder = this.buildCollectionHolder();
+		ListValueModel<Junk> listValueModel = new ItemCollectionListValueModelAdapter<Junk>(collectionHolder, Junk.STUFF_COLLECTION);
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		collectionHolder.add(this.tom);
+		collectionHolder.add(this.dick);
+		collectionHolder.add(this.harry);
+		assertEquals(9, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		collectionHolder.remove(this.foo);
+		collectionHolder.remove(this.jar);
+		collectionHolder.remove(this.harry);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+	}
+
+	public void testListSynchronization() {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		ListValueModel<Junk> listValueModel = new ItemCollectionListValueModelAdapter<Junk>(listHolder, Junk.STUFF_COLLECTION);
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		listHolder.add(6, this.tom);
+		listHolder.add(7, this.dick);
+		listHolder.add(8, this.harry);
+		assertEquals(9, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		listHolder.remove(8);
+		listHolder.remove(0);
+		listHolder.remove(4);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+	}
+
+	private void compare(ListValueModel<Junk> listValueModel, List<Junk> list) {
+		assertEquals(listValueModel.size(), list.size());
+		for (int i = 0; i < listValueModel.size(); i++) {
+			assertEquals(listValueModel.get(i), list.get(i));
+		}
+	}
+
+
+	public void testHasListeners() throws Exception {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(this.foo.hasAnyListChangeListeners(Junk.STUFF_COLLECTION));
+		assertFalse(this.jaz.hasAnyListChangeListeners(Junk.STUFF_COLLECTION));
+
+		ListValueModel<Junk> listValueModel = new ItemCollectionListValueModelAdapter<Junk>(listHolder, Junk.STUFF_COLLECTION);
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(this.foo.hasAnyCollectionChangeListeners(Junk.STUFF_COLLECTION));
+		assertFalse(this.jaz.hasAnyCollectionChangeListeners(Junk.STUFF_COLLECTION));
+		this.verifyHasNoListeners(listValueModel);
+
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertTrue(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertTrue(this.foo.hasAnyCollectionChangeListeners(Junk.STUFF_COLLECTION));
+		assertTrue(this.jaz.hasAnyCollectionChangeListeners(Junk.STUFF_COLLECTION));
+		this.verifyHasListeners(listValueModel);
+
+		listValueModel.removeListChangeListener(ListValueModel.LIST_VALUES, synchList);
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(this.foo.hasAnyCollectionChangeListeners(Junk.STUFF_COLLECTION));
+		assertFalse(this.jaz.hasAnyCollectionChangeListeners(Junk.STUFF_COLLECTION));
+		this.verifyHasNoListeners(listValueModel);
+	}
+
+	public void testGetSize() throws Exception {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		ListValueModel<Junk> listValueModel = new ItemCollectionListValueModelAdapter<Junk>(listHolder, Junk.STUFF_COLLECTION);
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		this.verifyHasListeners(listValueModel);
+		assertEquals(6, listValueModel.size());
+		assertEquals(6, synchList.size());
+	}
+
+	public void testGet() throws Exception {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		ListValueModel<Junk> listValueModel = new SortedListValueModelWrapper<Junk>(new ItemCollectionListValueModelAdapter<Junk>(listHolder, Junk.STUFF_COLLECTION));
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		this.verifyHasListeners(listValueModel);
+		assertEquals(this.bar, listValueModel.get(0));
+		assertEquals(this.bar, synchList.get(0));
+		this.bar.removeStuff("bar");
+		this.bar.addStuff("zzz");
+		this.bar.addStuff("bar");
+		assertEquals(this.bar, listValueModel.get(5));
+		assertEquals(this.bar, synchList.get(5));
+		this.bar.removeStuff("zzz");
+	}
+
+	private void verifyHasNoListeners(ListValueModel<Junk> listValueModel) throws Exception {
+		assertTrue(((AbstractModel) listValueModel).hasNoListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	private void verifyHasListeners(ListValueModel<Junk> listValueModel) throws Exception {
+		assertTrue(((AbstractModel) listValueModel).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	private SimpleCollectionValueModel<Junk> buildCollectionHolder() {
+		return new SimpleCollectionValueModel<Junk>(this.buildCollection());
+	}
+
+	private Collection<Junk> buildCollection() {
+		Bag<Junk> bag = new HashBag<Junk>();
+		this.populateCollection(bag);
+		return bag;
+	}
+
+	private SimpleListValueModel<Junk> buildListHolder() {
+		return new SimpleListValueModel<Junk>(this.buildList());
+	}
+
+	private List<Junk> buildList() {
+		List<Junk> list = new ArrayList<Junk>();
+		this.populateCollection(list);
+		return list;
+	}
+
+	private void populateCollection(Collection<Junk> c) {
+		c.add(this.foo);
+		c.add(this.bar);
+		c.add(this.baz);
+		c.add(this.joo);
+		c.add(this.jar);
+		c.add(this.jaz);
+	}
+
+
+	// ********** Junk class **********
+
+	private class Junk extends AbstractModel implements Displayable, Comparable<Junk> {
+		private Collection<String> stuff;
+			public static final String STUFF_COLLECTION = "stuff";
+
+
+		public Junk(String stuffItem) {
+			this.stuff = new ArrayList<String>();
+			this.stuff.add(stuffItem);
+		}
+
+		public void addStuff(String stuffItem) {
+			this.addItemToCollection(stuffItem, this.stuff, STUFF_COLLECTION);
+		}
+
+		public void removeStuff(String stuffItem) {
+			this.removeItemFromCollection(stuffItem, this.stuff, STUFF_COLLECTION);
+		}
+
+		@Override
+		public String displayString() {
+			return toString();
+		}
+
+		@Override
+		public Icon icon() {
+			return null;
+		}
+
+		@Override
+		public int compareTo(Junk o) {
+			return this.displayString().compareTo(o.displayString());
+		}
+
+		@Override
+		public String toString() {
+			return "Junk(" + this.stuff + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ItemListListValueModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ItemListListValueModelAdapterTests.java
new file mode 100644
index 0000000..8006fe0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ItemListListValueModelAdapterTests.java
@@ -0,0 +1,248 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.swing.Icon;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.value.ItemListListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SortedListValueModelWrapper;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+import org.eclipse.persistence.tools.utility.tests.model.Displayable;
+
+@SuppressWarnings("nls")
+public class ItemListListValueModelAdapterTests extends TestCase {
+
+	private Junk foo;
+	private Junk bar;
+	private Junk baz;
+	private Junk joo;
+	private Junk jar;
+	private Junk jaz;
+
+	private Junk tom;
+	private Junk dick;
+	private Junk harry;
+
+	public ItemListListValueModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.foo = new Junk("foo");
+		this.bar = new Junk("bar");
+		this.baz = new Junk("baz");
+		this.joo = new Junk("joo");
+		this.jar = new Junk("jar");
+		this.jaz = new Junk("jaz");
+
+		this.tom = new Junk("tom");
+		this.dick = new Junk("dick");
+		this.harry = new Junk("harry");
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testCollectionSynchronization() {
+		SimpleCollectionValueModel<Junk> collectionHolder = this.buildCollectionHolder();
+		ListValueModel<Junk> listValueModel = new ItemListListValueModelAdapter<Junk>(collectionHolder, Junk.STUFF_LIST);
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		collectionHolder.add(this.tom);
+		collectionHolder.add(this.dick);
+		collectionHolder.add(this.harry);
+		assertEquals(9, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		collectionHolder.remove(this.foo);
+		collectionHolder.remove(this.jar);
+		collectionHolder.remove(this.harry);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+	}
+
+	public void testListSynchronization() {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		ListValueModel<Junk> listValueModel = new ItemListListValueModelAdapter<Junk>(listHolder, Junk.STUFF_LIST);
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		listHolder.add(6, this.tom);
+		listHolder.add(7, this.dick);
+		listHolder.add(8, this.harry);
+		assertEquals(9, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		listHolder.remove(8);
+		listHolder.remove(0);
+		listHolder.remove(4);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+	}
+
+	private void compare(ListValueModel<Junk> listValueModel, List<Junk> list) {
+		assertEquals(listValueModel.size(), list.size());
+		for (int i = 0; i < listValueModel.size(); i++) {
+			assertEquals(listValueModel.get(i), list.get(i));
+		}
+	}
+
+
+	public void testHasListeners() throws Exception {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(this.foo.hasAnyListChangeListeners(Junk.STUFF_LIST));
+		assertFalse(this.jaz.hasAnyListChangeListeners(Junk.STUFF_LIST));
+
+		ListValueModel<Junk> listValueModel = new ItemListListValueModelAdapter<Junk>(listHolder, Junk.STUFF_LIST);
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(this.foo.hasAnyListChangeListeners(Junk.STUFF_LIST));
+		assertFalse(this.jaz.hasAnyListChangeListeners(Junk.STUFF_LIST));
+		this.verifyHasNoListeners(listValueModel);
+
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertTrue(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertTrue(this.foo.hasAnyListChangeListeners(Junk.STUFF_LIST));
+		assertTrue(this.jaz.hasAnyListChangeListeners(Junk.STUFF_LIST));
+		this.verifyHasListeners(listValueModel);
+
+		listValueModel.removeListChangeListener(ListValueModel.LIST_VALUES, synchList);
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(this.foo.hasAnyListChangeListeners(Junk.STUFF_LIST));
+		assertFalse(this.jaz.hasAnyListChangeListeners(Junk.STUFF_LIST));
+		this.verifyHasNoListeners(listValueModel);
+	}
+
+	public void testGetSize() throws Exception {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		ListValueModel<Junk> listValueModel = new ItemListListValueModelAdapter<Junk>(listHolder, Junk.STUFF_LIST);
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		this.verifyHasListeners(listValueModel);
+		assertEquals(6, listValueModel.size());
+		assertEquals(6, synchList.size());
+	}
+
+	public void testGet() throws Exception {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		ListValueModel<Junk> listValueModel = new SortedListValueModelWrapper<Junk>(new ItemListListValueModelAdapter<Junk>(listHolder, Junk.STUFF_LIST));
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		this.verifyHasListeners(listValueModel);
+		assertEquals(this.bar, listValueModel.get(0));
+		assertEquals(this.bar, synchList.get(0));
+		this.bar.removeStuff("bar");
+		this.bar.addStuff("zzz");
+		this.bar.addStuff("bar");
+		assertEquals(this.bar, listValueModel.get(5));
+		assertEquals(this.bar, synchList.get(5));
+		this.bar.removeStuff("zzz");
+	}
+
+	private void verifyHasNoListeners(ListValueModel<Junk> listValueModel) throws Exception {
+		assertTrue(((AbstractModel) listValueModel).hasNoListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	private void verifyHasListeners(ListValueModel<Junk> listValueModel) throws Exception {
+		assertTrue(((AbstractModel) listValueModel).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	private SimpleCollectionValueModel<Junk> buildCollectionHolder() {
+		return new SimpleCollectionValueModel<Junk>(this.buildCollection());
+	}
+
+	private Collection<Junk> buildCollection() {
+		Bag<Junk> bag = new HashBag<Junk>();
+		this.populateCollection(bag);
+		return bag;
+	}
+
+	private SimpleListValueModel<Junk> buildListHolder() {
+		return new SimpleListValueModel<Junk>(this.buildList());
+	}
+
+	private List<Junk> buildList() {
+		List<Junk> list = new ArrayList<Junk>();
+		this.populateCollection(list);
+		return list;
+	}
+
+	private void populateCollection(Collection<Junk> c) {
+		c.add(this.foo);
+		c.add(this.bar);
+		c.add(this.baz);
+		c.add(this.joo);
+		c.add(this.jar);
+		c.add(this.jaz);
+	}
+
+
+	// ********** Junk class **********
+
+	private class Junk extends AbstractModel implements Displayable, Comparable<Junk> {
+		private List<String> stuff;
+			public static final String STUFF_LIST = "stuff";
+
+
+		public Junk(String stuffItem) {
+			this.stuff = new ArrayList<String>();
+			this.stuff.add(stuffItem);
+		}
+		public void addStuff(String stuffItem) {
+			this.stuff.add(stuffItem);
+			fireItemAdded(STUFF_LIST, this.stuff.indexOf(stuffItem), stuffItem);
+		}
+
+		public void removeStuff(String stuffItem) {
+			int index = this.stuff.indexOf(stuffItem);
+			this.stuff.remove(stuffItem);
+			fireItemRemoved(STUFF_LIST, index, stuffItem);
+		}
+
+		@Override
+		public String displayString() {
+			return toString();
+		}
+
+		@Override
+		public Icon icon() {
+			return null;
+		}
+
+		@Override
+		public int compareTo(Junk o) {
+			return this.displayString().compareTo(o.displayString());
+		}
+
+		@Override
+		public String toString() {
+			return "Junk(" + this.stuff + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ItemPropertyListValueModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ItemPropertyListValueModelAdapterTests.java
new file mode 100644
index 0000000..ed61223
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ItemPropertyListValueModelAdapterTests.java
@@ -0,0 +1,340 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import javax.swing.Icon;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SortedListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.SortedListValueModelWrapper;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+import org.eclipse.persistence.tools.utility.tests.model.Displayable;
+
+@SuppressWarnings("nls")
+public class ItemPropertyListValueModelAdapterTests extends TestCase {
+
+	private Junk foo;
+	private Junk bar;
+	private Junk baz;
+	private Junk joo;
+	private Junk jar;
+	private Junk jaz;
+
+	private Junk tom;
+	private Junk dick;
+	private Junk harry;
+
+	public ItemPropertyListValueModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.foo = new Junk("this.foo");
+		this.bar = new Junk("this.bar");
+		this.baz = new Junk("this.baz");
+		this.joo = new Junk("this.joo");
+		this.jar = new Junk("this.jar");
+		this.jaz = new Junk("this.jaz");
+
+		this.tom = new Junk("this.tom");
+		this.dick = new Junk("this.dick");
+		this.harry = new Junk("this.harry");
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testCollectionSynchronization() {
+		SimpleCollectionValueModel<Junk> collectionHolder = this.buildCollectionHolder();
+		ListValueModel<Junk> listValueModel = new ItemPropertyListValueModelAdapter<Junk>(collectionHolder, Displayable.DISPLAY_STRING_PROPERTY, Displayable.ICON_PROPERTY);
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		collectionHolder.add(this.tom);
+		collectionHolder.add(this.dick);
+		collectionHolder.add(this.harry);
+		assertEquals(9, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		collectionHolder.remove(this.foo);
+		collectionHolder.remove(this.jar);
+		collectionHolder.remove(this.harry);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		collectionHolder.setValues(this.buildCollection());
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+	}
+
+	public void testListSynchronization() {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		ListValueModel<Junk> listValueModel = new ItemPropertyListValueModelAdapter<Junk>(listHolder, Displayable.DISPLAY_STRING_PROPERTY, Displayable.ICON_PROPERTY);
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		listHolder.add(6, this.tom);
+		listHolder.add(7, this.dick);
+		listHolder.add(8, this.harry);
+		assertEquals(9, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		listHolder.remove(8);
+		listHolder.remove(0);
+		listHolder.remove(4);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		// test concurrent modification exception
+		listHolder.setListValues(this.buildList());
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+	}
+
+	private void compare(ListValueModel<Junk> listValueModel, List<Junk> list) {
+		assertEquals(listValueModel.size(), list.size());
+		for (int i = 0; i < listValueModel.size(); i++) {
+			assertEquals(listValueModel.get(i), list.get(i));
+		}
+	}
+
+	public void testCollectionSort() {
+		this.verifyCollectionSort(null);
+	}
+
+	public void testListSort() {
+		this.verifyListSort(null);
+	}
+
+	public void testCustomCollectionSort() {
+		this.verifyCollectionSort(this.buildCustomComparator());
+	}
+
+	public void testCustomListSort() {
+		this.verifyListSort(this.buildCustomComparator());
+	}
+
+	private Comparator<Junk> buildCustomComparator() {
+		// sort with reverse order
+		return new Comparator<Junk>() {
+			@Override
+			public int compare(Junk o1, Junk o2) {
+				return o2.displayString().compareTo(o1.displayString());
+			}
+		};
+	}
+
+	private void verifyCollectionSort(Comparator<Junk> comparator) {
+		SimpleCollectionValueModel<Junk> collectionHolder = this.buildCollectionHolder();
+		ListValueModel<Junk> listValueModel = new ItemPropertyListValueModelAdapter<Junk>(new SortedListValueModelAdapter<Junk>(collectionHolder, comparator), Displayable.DISPLAY_STRING_PROPERTY, Displayable.ICON_PROPERTY);
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertEquals(6, synchList.size());
+		this.compareSort(listValueModel, synchList, comparator);
+
+		collectionHolder.add(this.tom);
+		collectionHolder.add(this.dick);
+		collectionHolder.add(this.harry);
+		assertEquals(9, synchList.size());
+		this.compareSort(listValueModel, synchList, comparator);
+
+		collectionHolder.remove(this.foo);
+		collectionHolder.remove(this.jar);
+		collectionHolder.remove(this.harry);
+		assertEquals(6, synchList.size());
+		this.compareSort(listValueModel, synchList, comparator);
+
+		collectionHolder.setValues(this.buildCollection());
+		assertEquals(6, synchList.size());
+		this.compareSort(listValueModel, synchList, comparator);
+	}
+
+	private void verifyListSort(Comparator<Junk> comparator) {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		ListValueModel<Junk> listValueModel = new ItemPropertyListValueModelAdapter<Junk>(new SortedListValueModelWrapper<Junk>(listHolder, comparator), Displayable.DISPLAY_STRING_PROPERTY, Displayable.ICON_PROPERTY);
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertEquals(6, synchList.size());
+		this.compareSort(listValueModel, synchList, comparator);
+
+		listHolder.add(0, this.tom);
+		listHolder.add(0, this.dick);
+		listHolder.add(0, this.harry);
+		assertEquals(9, synchList.size());
+		this.compareSort(listValueModel, synchList, comparator);
+
+		listHolder.remove(8);
+		listHolder.remove(4);
+		listHolder.remove(0);
+		listHolder.remove(5);
+		assertEquals(5, synchList.size());
+		this.compareSort(listValueModel, synchList, comparator);
+
+		listHolder.setListValues(this.buildList());
+		assertEquals(6, synchList.size());
+		this.compareSort(listValueModel, synchList, comparator);
+	}
+
+	private void compareSort(ListValueModel<Junk> listValueModel, List<Junk> list, Comparator<Junk> comparator) {
+		SortedSet<Junk> ss = new TreeSet<Junk>(comparator);
+		for (int i = 0; i < listValueModel.size(); i++) {
+			ss.add(listValueModel.get(i));
+		}
+		assertEquals(ss.size(), list.size());
+		for (Iterator<Junk> stream1 = ss.iterator(), stream2 = list.iterator(); stream1.hasNext(); ) {
+			assertEquals(stream1.next(), stream2.next());
+		}
+	}
+
+	public void testHasListeners() throws Exception {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(this.foo.hasAnyPropertyChangeListeners(Displayable.DISPLAY_STRING_PROPERTY));
+		assertFalse(this.foo.hasAnyPropertyChangeListeners(Displayable.ICON_PROPERTY));
+		assertFalse(this.jaz.hasAnyPropertyChangeListeners(Displayable.DISPLAY_STRING_PROPERTY));
+		assertFalse(this.jaz.hasAnyPropertyChangeListeners(Displayable.ICON_PROPERTY));
+
+		ListValueModel<Junk> listValueModel = new ItemPropertyListValueModelAdapter<Junk>(new SortedListValueModelWrapper<Junk>(listHolder), Displayable.DISPLAY_STRING_PROPERTY, Displayable.ICON_PROPERTY);
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(this.foo.hasAnyPropertyChangeListeners(Displayable.DISPLAY_STRING_PROPERTY));
+		assertFalse(this.foo.hasAnyPropertyChangeListeners(Displayable.ICON_PROPERTY));
+		assertFalse(this.jaz.hasAnyPropertyChangeListeners(Displayable.DISPLAY_STRING_PROPERTY));
+		assertFalse(this.jaz.hasAnyPropertyChangeListeners(Displayable.ICON_PROPERTY));
+		this.verifyHasNoListeners(listValueModel);
+
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertTrue(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertTrue(this.foo.hasAnyPropertyChangeListeners(Displayable.DISPLAY_STRING_PROPERTY));
+		assertTrue(this.foo.hasAnyPropertyChangeListeners(Displayable.ICON_PROPERTY));
+		assertTrue(this.jaz.hasAnyPropertyChangeListeners(Displayable.DISPLAY_STRING_PROPERTY));
+		assertTrue(this.jaz.hasAnyPropertyChangeListeners(Displayable.ICON_PROPERTY));
+		this.verifyHasListeners(listValueModel);
+
+		listValueModel.removeListChangeListener(ListValueModel.LIST_VALUES, synchList);
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(this.foo.hasAnyPropertyChangeListeners(Displayable.DISPLAY_STRING_PROPERTY));
+		assertFalse(this.foo.hasAnyPropertyChangeListeners(Displayable.ICON_PROPERTY));
+		assertFalse(this.jaz.hasAnyPropertyChangeListeners(Displayable.DISPLAY_STRING_PROPERTY));
+		assertFalse(this.jaz.hasAnyPropertyChangeListeners(Displayable.ICON_PROPERTY));
+		this.verifyHasNoListeners(listValueModel);
+	}
+
+	public void testGetSize() throws Exception {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		ListValueModel<Junk> listValueModel = new ItemPropertyListValueModelAdapter<Junk>(new SortedListValueModelWrapper<Junk>(listHolder), Displayable.DISPLAY_STRING_PROPERTY, Displayable.ICON_PROPERTY);
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		this.verifyHasListeners(listValueModel);
+		assertEquals(6, listValueModel.size());
+		assertEquals(6, synchList.size());
+	}
+
+	public void testGet() throws Exception {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		ListValueModel<Junk> listValueModel = new SortedListValueModelWrapper<Junk>(new ItemPropertyListValueModelAdapter<Junk>(listHolder, Displayable.DISPLAY_STRING_PROPERTY, Displayable.ICON_PROPERTY));
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		this.verifyHasListeners(listValueModel);
+		assertEquals(this.bar, listValueModel.get(0));
+		assertEquals(this.bar, synchList.get(0));
+		this.bar.setName("zzz");
+		assertEquals(this.bar, listValueModel.get(5));
+		assertEquals(this.bar, synchList.get(5));
+		this.bar.setName("this.bar");
+	}
+
+	private void verifyHasNoListeners(ListValueModel<Junk> listValueModel) throws Exception {
+		assertTrue(((AbstractModel) listValueModel).hasNoListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	private void verifyHasListeners(ListValueModel<Junk> listValueModel) throws Exception {
+		assertTrue(((AbstractModel) listValueModel).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	private SimpleCollectionValueModel<Junk> buildCollectionHolder() {
+		return new SimpleCollectionValueModel<Junk>(this.buildCollection());
+	}
+
+	private Collection<Junk> buildCollection() {
+		Bag<Junk> bag = new HashBag<Junk>();
+		this.populateCollection(bag);
+		return bag;
+	}
+
+	private SimpleListValueModel<Junk> buildListHolder() {
+		return new SimpleListValueModel<Junk>(this.buildList());
+	}
+
+	private List<Junk> buildList() {
+		List<Junk> list = new ArrayList<Junk>();
+		this.populateCollection(list);
+		return list;
+	}
+
+	private void populateCollection(Collection<Junk> c) {
+		c.add(this.foo);
+		c.add(this.bar);
+		c.add(this.baz);
+		c.add(this.joo);
+		c.add(this.jar);
+		c.add(this.jaz);
+	}
+
+
+	// ********** Junk class **********
+
+	private class Junk extends AbstractModel implements Displayable, Comparable<Junk> {
+		private String name;
+		public Junk(String name) {
+			this.name = name;
+		}
+		@Override
+		public String displayString() {
+			return this.name;
+		}
+		@Override
+		public Icon icon() {
+			return null;
+		}
+		public void setName(String name) {
+			Object old = this.name;
+			this.name = name;
+			this.firePropertyChanged(DISPLAY_STRING_PROPERTY, old, name);
+		}
+		@Override
+		public int compareTo(Junk o) {
+			return this.displayString().compareTo(o.displayString());
+		}
+		@Override
+		public String toString() {
+			return "Junk(" + this.name + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ItemStateListValueModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ItemStateListValueModelAdapterTests.java
new file mode 100644
index 0000000..6d65012
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ItemStateListValueModelAdapterTests.java
@@ -0,0 +1,310 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.value.ItemStateListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SortedListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.SortedListValueModelWrapper;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class ItemStateListValueModelAdapterTests extends TestCase {
+
+	private Junk foo;
+	private Junk bar;
+	private Junk baz;
+	private Junk joo;
+	private Junk jar;
+	private Junk jaz;
+
+	private Junk tom;
+	private Junk dick;
+	private Junk harry;
+
+	public ItemStateListValueModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.foo = new Junk("this.foo");
+		this.bar = new Junk("this.bar");
+		this.baz = new Junk("this.baz");
+		this.joo = new Junk("this.joo");
+		this.jar = new Junk("this.jar");
+		this.jaz = new Junk("this.jaz");
+
+		this.tom = new Junk("this.tom");
+		this.dick = new Junk("this.dick");
+		this.harry = new Junk("this.harry");
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testCollectionSynchronization() {
+		SimpleCollectionValueModel<Junk> collectionHolder = this.buildCollectionHolder();
+		ListValueModel<Junk> listValueModel = new ItemStateListValueModelAdapter<Junk>(collectionHolder);
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		collectionHolder.add(this.tom);
+		collectionHolder.add(this.dick);
+		collectionHolder.add(this.harry);
+		assertEquals(9, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		collectionHolder.remove(this.foo);
+		collectionHolder.remove(this.jar);
+		collectionHolder.remove(this.harry);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+	}
+
+	public void testListSynchronization() {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		ListValueModel<Junk> listValueModel = new ItemStateListValueModelAdapter<Junk>(listHolder);
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		listHolder.add(6, this.tom);
+		listHolder.add(7, this.dick);
+		listHolder.add(8, this.harry);
+		assertEquals(9, synchList.size());
+		this.compare(listValueModel, synchList);
+
+		listHolder.remove(8);
+		listHolder.remove(0);
+		listHolder.remove(4);
+		assertEquals(6, synchList.size());
+		this.compare(listValueModel, synchList);
+	}
+
+	private void compare(ListValueModel<Junk> listValueModel, List<Junk> list) {
+		assertEquals(listValueModel.size(), list.size());
+		for (int i = 0; i < listValueModel.size(); i++) {
+			assertEquals(listValueModel.get(i), list.get(i));
+		}
+	}
+
+	public void testCollectionSort() {
+		this.verifyCollectionSort(null);
+	}
+
+	public void testListSort() {
+		this.verifyListSort(null);
+	}
+
+	public void testCustomCollectionSort() {
+		this.verifyCollectionSort(this.buildCustomComparator());
+	}
+
+	public void testCustomListSort() {
+		this.verifyListSort(this.buildCustomComparator());
+	}
+
+	private Comparator<Junk> buildCustomComparator() {
+		// sort with reverse order
+		return new Comparator<Junk>() {
+			@Override
+			public int compare(Junk o1, Junk o2) {
+				return o2.compareTo(o1);
+			}
+		};
+	}
+
+	private void verifyCollectionSort(Comparator<Junk> comparator) {
+		SimpleCollectionValueModel<Junk> collectionHolder = this.buildCollectionHolder();
+		ListValueModel<Junk> listValueModel = new ItemStateListValueModelAdapter<Junk>(new SortedListValueModelAdapter<Junk>(collectionHolder, comparator));
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertEquals(6, synchList.size());
+		this.compareSort(listValueModel, synchList, comparator);
+
+		collectionHolder.add(this.tom);
+		collectionHolder.add(this.dick);
+		collectionHolder.add(this.harry);
+		assertEquals(9, synchList.size());
+		this.compareSort(listValueModel, synchList, comparator);
+
+		collectionHolder.remove(this.foo);
+		collectionHolder.remove(this.jar);
+		collectionHolder.remove(this.harry);
+		assertEquals(6, synchList.size());
+		this.compareSort(listValueModel, synchList, comparator);
+	}
+
+	private void verifyListSort(Comparator<Junk> comparator) {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		ListValueModel<Junk> listValueModel = new ItemStateListValueModelAdapter<Junk>(new SortedListValueModelWrapper<Junk>(listHolder, comparator));
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertEquals(6, synchList.size());
+		this.compareSort(listValueModel, synchList, comparator);
+
+		listHolder.add(0, this.tom);
+		listHolder.add(0, this.dick);
+		listHolder.add(0, this.harry);
+		assertEquals(9, synchList.size());
+		this.compareSort(listValueModel, synchList, comparator);
+
+		listHolder.remove(8);
+		listHolder.remove(4);
+		listHolder.remove(0);
+		listHolder.remove(5);
+		assertEquals(5, synchList.size());
+		this.compareSort(listValueModel, synchList, comparator);
+	}
+
+	private void compareSort(ListValueModel<Junk> listValueModel, List<Junk> list, Comparator<Junk> comparator) {
+		SortedSet<Junk> ss = new TreeSet<Junk>(comparator);
+		for (int i = 0; i < listValueModel.size(); i++) {
+			ss.add(listValueModel.get(i));
+		}
+		assertEquals(ss.size(), list.size());
+		for (Iterator<Junk> stream1 = ss.iterator(), stream2 = list.iterator(); stream1.hasNext(); ) {
+			assertEquals(stream1.next(), stream2.next());
+		}
+	}
+
+	public void testHasListeners() throws Exception {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(this.foo.hasAnyStateChangeListeners());
+		assertFalse(this.foo.hasAnyStateChangeListeners());
+		assertFalse(this.jaz.hasAnyStateChangeListeners());
+		assertFalse(this.jaz.hasAnyStateChangeListeners());
+
+		ListValueModel<Junk> listValueModel = new ItemStateListValueModelAdapter<Junk>(new SortedListValueModelWrapper<Junk>(listHolder));
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(this.foo.hasAnyStateChangeListeners());
+		assertFalse(this.foo.hasAnyStateChangeListeners());
+		assertFalse(this.jaz.hasAnyStateChangeListeners());
+		assertFalse(this.jaz.hasAnyStateChangeListeners());
+		this.verifyHasNoListeners(listValueModel);
+
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		assertTrue(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertTrue(this.foo.hasAnyStateChangeListeners());
+		assertTrue(this.foo.hasAnyStateChangeListeners());
+		assertTrue(this.jaz.hasAnyStateChangeListeners());
+		assertTrue(this.jaz.hasAnyStateChangeListeners());
+		this.verifyHasListeners(listValueModel);
+
+		listValueModel.removeListChangeListener(ListValueModel.LIST_VALUES, synchList);
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(this.foo.hasAnyStateChangeListeners());
+		assertFalse(this.foo.hasAnyStateChangeListeners());
+		assertFalse(this.jaz.hasAnyStateChangeListeners());
+		assertFalse(this.jaz.hasAnyStateChangeListeners());
+		this.verifyHasNoListeners(listValueModel);
+	}
+
+	public void testGetSize() throws Exception {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		ListValueModel<Junk> listValueModel = new ItemStateListValueModelAdapter<Junk>(new SortedListValueModelWrapper<Junk>(listHolder));
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		this.verifyHasListeners(listValueModel);
+		assertEquals(6, listValueModel.size());
+		assertEquals(6, synchList.size());
+	}
+
+	public void testGet() throws Exception {
+		SimpleListValueModel<Junk> listHolder = this.buildListHolder();
+		ListValueModel<Junk> listValueModel = new SortedListValueModelWrapper<Junk>(new ItemStateListValueModelAdapter<Junk>(listHolder));
+		CoordinatedList<Junk> synchList = new CoordinatedList<Junk>(listValueModel);
+		this.verifyHasListeners(listValueModel);
+		assertEquals(this.bar, listValueModel.get(0));
+		assertEquals(this.bar, synchList.get(0));
+		this.bar.setName("zzz");
+		assertEquals(this.bar, listValueModel.get(5));
+		assertEquals(this.bar, synchList.get(5));
+		this.bar.setName("this.bar");
+	}
+
+	private void verifyHasNoListeners(ListValueModel<Junk> listValueModel) throws Exception {
+		assertTrue(((AbstractModel) listValueModel).hasNoListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	private void verifyHasListeners(ListValueModel<Junk> listValueModel) throws Exception {
+		assertTrue(((AbstractModel) listValueModel).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	private SimpleCollectionValueModel<Junk> buildCollectionHolder() {
+		return new SimpleCollectionValueModel<Junk>(this.buildCollection());
+	}
+
+	private Collection<Junk> buildCollection() {
+		Bag<Junk> bag = new HashBag<Junk>();
+		this.populateCollection(bag);
+		return bag;
+	}
+
+	private SimpleListValueModel<Junk> buildListHolder() {
+		return new SimpleListValueModel<Junk>(this.buildList());
+	}
+
+	private List<Junk> buildList() {
+		List<Junk> list = new ArrayList<Junk>();
+		this.populateCollection(list);
+		return list;
+	}
+
+	private void populateCollection(Collection<Junk> c) {
+		c.add(this.foo);
+		c.add(this.bar);
+		c.add(this.baz);
+		c.add(this.joo);
+		c.add(this.jar);
+		c.add(this.jaz);
+	}
+
+	// ********** Junk class **********
+	private class Junk extends AbstractModel implements Comparable<Junk> {
+		private String name;
+		public Junk(String name) {
+			this.name = name;
+		}
+		public void setName(String name) {
+			this.name = name;
+			this.fireStateChanged();
+		}
+		@Override
+		public int compareTo(Junk j) {
+			return this.name.compareTo(j.name);
+		}
+		@Override
+		public String toString() {
+			return "Junk(" + this.name + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ListAspectAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ListAspectAdapterTests.java
new file mode 100644
index 0000000..b46e1b2
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ListAspectAdapterTests.java
@@ -0,0 +1,485 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyListIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ListAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class ListAspectAdapterTests extends TestCase {
+
+	private TestSubject subject1;
+	private ModifiablePropertyValueModel<TestSubject> subjectHolder1;
+	private LocalListAspectAdapter aa1;
+	private ListEvent event1;
+	private ListChangeListener listener1;
+
+	private TestSubject subject2;
+
+	public ListAspectAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.subject1 = new TestSubject();
+		this.subject1.addNames(this.subject1Names());
+		this.subject1.addDescriptions(this.subject1Descriptions());
+		this.subjectHolder1 = new SimplePropertyValueModel<TestSubject>(this.subject1);
+		this.aa1 = this.buildAspectAdapter(this.subjectHolder1);
+		this.listener1 = this.buildValueChangeListener1();
+		this.aa1.addListChangeListener(ListValueModel.LIST_VALUES, this.listener1);
+		this.event1 = null;
+
+		this.subject2 = new TestSubject();
+		this.subject2.addNames(this.subject2Names());
+		this.subject2.addDescriptions(this.subject2Descriptions());
+	}
+
+	private List<String> subject1Names() {
+		List<String> result = new ArrayList<String>();
+		result.add("foo");
+		result.add("bar");
+		result.add("baz");
+		result.add("bam");
+		return result;
+	}
+
+	private List<String> subject1Descriptions() {
+		List<String> result = new ArrayList<String>();
+		result.add("this.subject1 description1");
+		result.add("this.subject1 description2");
+		return result;
+	}
+
+	private List<String> subject2Names() {
+		List<String> result = new ArrayList<String>();
+		result.add("joo");
+		result.add("jar");
+		result.add("jaz");
+		result.add("jam");
+		return result;
+	}
+
+	private List<String> subject2Descriptions() {
+		List<String> result = new ArrayList<String>();
+		result.add("this.subject2 description1");
+		result.add("this.subject2 description2");
+		return result;
+	}
+
+	private LocalListAspectAdapter buildAspectAdapter(PropertyValueModel<TestSubject> subjectHolder) {
+		return new LocalListAspectAdapter(subjectHolder);
+	}
+
+	private ListChangeListener buildValueChangeListener1() {
+		return new ListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {
+				ListAspectAdapterTests.this.value1Changed(e);
+			}
+			@Override
+			public void itemsRemoved(ListRemoveEvent e) {
+				ListAspectAdapterTests.this.value1Changed(e);
+			}
+			@Override
+			public void itemsReplaced(ListReplaceEvent e) {
+				ListAspectAdapterTests.this.value1Changed(e);
+			}
+			@Override
+			public void itemsMoved(ListMoveEvent e) {
+				ListAspectAdapterTests.this.value1Changed(e);
+			}
+			@Override
+			public void listCleared(ListClearEvent e) {
+				ListAspectAdapterTests.this.value1Changed(e);
+			}
+			@Override
+			public void listChanged(ListChangeEvent e) {
+				ListAspectAdapterTests.this.value1Changed(e);
+			}
+		};
+	}
+
+	void value1Changed(ListEvent e) {
+		this.event1 = e;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testSubjectHolder() {
+		assertEquals(this.subject1Names(), ListTools.list(this.aa1.listIterator()));
+		assertNull(this.event1);
+
+		this.subjectHolder1.setValue(this.subject2);
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(this.subject2Names(), ListTools.list(this.aa1.listIterator()));
+
+		this.event1 = null;
+		this.subjectHolder1.setValue(null);
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertFalse(this.aa1.iterator().hasNext());
+
+		this.event1 = null;
+		this.subjectHolder1.setValue(this.subject1);
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(this.subject1Names(), ListTools.list(this.aa1.listIterator()));
+	}
+
+	public void testAdd() {
+		assertEquals(this.subject1Names(), ListTools.list(this.aa1.listIterator()));
+		assertNull(this.event1);
+
+		this.subject1.addName("jam");
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(this.subject1Names().size(), ((ListAddEvent) this.event1).getIndex());
+		assertEquals("jam", ((ListAddEvent) this.event1).getItems().iterator().next());
+		List<String> namesPlus = this.subject1Names();
+		namesPlus.add("jam");
+		assertEquals(namesPlus, ListTools.list(this.aa1.listIterator()));
+
+		this.event1 = null;
+		this.aa1.add(2, "jaz");
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(2, ((ListAddEvent) this.event1).getIndex());
+		assertEquals("jaz", ((ListAddEvent) this.event1).getItems().iterator().next());
+		namesPlus.add(2, "jaz");
+		assertEquals(namesPlus, ListTools.list(this.aa1.listIterator()));
+	}
+
+	public void testDefaultAdd() {
+		assertEquals(this.subject1Names(), ListTools.list(this.aa1.listIterator()));
+		assertNull(this.event1);
+
+		List<String> items = new ArrayList<String>();
+		items.add("joo");
+		items.add("jar");
+		items.add("jaz");
+		items.add("jam");
+
+		this.event1 = null;
+		this.aa1.addAll(2, items);
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(5, ((ListAddEvent) this.event1).getIndex());		// only the last "add" event will still be there
+		assertEquals("jam", ((ListAddEvent) this.event1).getItems().iterator().next());
+		List<String> namesPlus = this.subject1Names();
+		namesPlus.addAll(2, items);
+		assertEquals(namesPlus, ListTools.list(this.aa1.listIterator()));
+	}
+
+	public void testRemove() {
+		assertEquals(this.subject1Names(), ListTools.list(this.aa1.listIterator()));
+		assertNull(this.event1);
+
+		String removedName = this.subject1.removeName(0);	// should be "foo"
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(0, ((ListRemoveEvent) this.event1).getIndex());
+		assertEquals(removedName, ((ListRemoveEvent) this.event1).getItems().iterator().next());
+		List<String> namesMinus = this.subject1Names();
+		namesMinus.remove(0);
+		assertEquals(namesMinus, ListTools.list(this.aa1.listIterator()));
+
+		this.event1 = null;
+		Object removedItem = this.aa1.remove(0);
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(0, ((ListRemoveEvent) this.event1).getIndex());
+		assertEquals(removedItem, ((ListRemoveEvent) this.event1).getItems().iterator().next());
+		namesMinus.remove(0);
+		assertEquals(namesMinus, ListTools.list(this.aa1.listIterator()));
+	}
+
+	public void testDefaultLength() {
+		assertEquals(this.subject1Names(), ListTools.list(this.aa1.listIterator()));
+		assertNull(this.event1);
+
+		List<String> items = new ArrayList<String>();
+		items.add("bar");
+		items.add("baz");
+
+		this.event1 = null;
+		this.aa1.remove(1, 2);
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(1, ((ListRemoveEvent) this.event1).getIndex());		// only the last "remove" event will still be there
+		assertEquals("baz", ((ListRemoveEvent) this.event1).getItems().iterator().next());
+		List<String> namesPlus = this.subject1Names();
+		namesPlus.remove(1);
+		namesPlus.remove(1);
+		assertEquals(namesPlus, ListTools.list(this.aa1.listIterator()));
+	}
+
+	public void testReplace() {
+		assertEquals(this.subject1Names(), ListTools.list(this.aa1.listIterator()));
+		assertNull(this.event1);
+
+		String replacedName = this.subject1.setName(0, "jelly");	// should be "foo"
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(0, ((ListReplaceEvent) this.event1).getIndex());
+		assertEquals("jelly", ((ListReplaceEvent) this.event1).getNewItems().iterator().next());
+		assertEquals(replacedName, ((ListReplaceEvent) this.event1).getOldItems().iterator().next());
+		List<String> namesChanged = this.subject1Names();
+		namesChanged.set(0, "jelly");
+		assertEquals(namesChanged, ListTools.list(this.aa1.listIterator()));
+
+		this.event1 = null;
+		replacedName = this.subject1.setName(1, "roll");	// should be "bar"
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(1, ((ListReplaceEvent) this.event1).getIndex());
+		assertEquals("roll", ((ListReplaceEvent) this.event1).getNewItems().iterator().next());
+		assertEquals(replacedName, ((ListReplaceEvent) this.event1).getOldItems().iterator().next());
+		namesChanged = this.subject1Names();
+		namesChanged.set(0, "jelly");
+		namesChanged.set(1, "roll");
+		assertEquals(namesChanged, ListTools.list(this.aa1.listIterator()));
+	}
+
+	public void testListChange() {
+		assertEquals(this.subject1Names(), ListTools.list(this.aa1.listIterator()));
+		assertNull(this.event1);
+
+		this.subject1.addTwoNames("jam", "jaz");
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		List<String> namesPlus2 = this.subject1Names();
+		namesPlus2.add(0, "jaz");
+		namesPlus2.add(0, "jam");
+		assertEquals(namesPlus2, ListTools.list(this.aa1.listIterator()));
+	}
+
+	public void testIterator() {
+		assertEquals(this.subject1Names(), ListTools.list(this.subject1.names()));
+		assertEquals(this.subject1Names(), ListTools.list(this.aa1.listIterator()));
+	}
+
+	public void testGet() {
+		assertEquals(this.subject1Names().get(0), this.subject1.getName(0));
+		assertEquals(this.subject1Names().get(0), this.aa1.get(0));
+	}
+
+	public void testSize() {
+		assertEquals(this.subject1Names().size(), IteratorTools.size(this.subject1.names()));
+		assertEquals(this.subject1Names().size(), IteratorTools.size(this.aa1.listIterator()));
+	}
+
+	public void testHasListeners() {
+		assertTrue(this.aa1.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertTrue(this.subject1.hasAnyListChangeListeners(TestSubject.NAMES_LIST));
+		this.aa1.removeListChangeListener(ListValueModel.LIST_VALUES, this.listener1);
+		assertFalse(this.subject1.hasAnyListChangeListeners(TestSubject.NAMES_LIST));
+		assertFalse(this.aa1.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		ChangeListener listener2 = new ChangeAdapter();
+		this.aa1.addChangeListener(listener2);
+		assertTrue(this.aa1.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertTrue(this.subject1.hasAnyListChangeListeners(TestSubject.NAMES_LIST));
+		this.aa1.removeChangeListener(listener2);
+		assertFalse(this.subject1.hasAnyListChangeListeners(TestSubject.NAMES_LIST));
+		assertFalse(this.aa1.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+
+	// ********** inner class **********
+
+	class TestSubject extends AbstractModel {
+		private List<String> names;
+		public static final String NAMES_LIST = "names";
+		private List<String> descriptions;
+		public static final String DESCRIPTIONS_LIST = "descriptions";
+
+		public TestSubject() {
+			this.names = new ArrayList<String>();
+			this.descriptions = new ArrayList<String>();
+		}
+		public ListIterator<String> names() {
+			return new ReadOnlyListIterator<String>(this.names);
+		}
+		public String getName(int index) {
+			return this.names.get(index);
+		}
+		public void addName(int index, String name) {
+			this.names.add(index, name);
+			this.fireItemAdded(NAMES_LIST, index, name);
+		}
+		public void addName(String name) {
+			this.addName(this.names.size(), name);
+		}
+		public void addNames(ListIterator<String> newNames) {
+			while (newNames.hasNext()) {
+				this.addName(newNames.next());
+			}
+		}
+		public void addNames(List<String> newNames) {
+			this.addNames(newNames.listIterator());
+		}
+		public void addTwoNames(String name1, String name2) {
+			this.names.add(0, name2);
+			this.names.add(0, name1);
+			this.fireListChanged(NAMES_LIST, this.names);
+		}
+		public String removeName(int index) {
+			String removedName = this.names.remove(index);
+			this.fireItemRemoved(NAMES_LIST, index, removedName);
+			return removedName;
+		}
+		public String setName(int index, String name) {
+			String replacedName = this.names.set(index, name);
+			this.fireItemReplaced(NAMES_LIST, index, name, replacedName);
+			return replacedName;
+		}
+		public ListIterator<String> descriptions() {
+			return new ReadOnlyListIterator<String>(this.descriptions);
+		}
+		public String getDescription(int index) {
+			return this.descriptions.get(index);
+		}
+		public void addDescription(int index, String description) {
+			this.descriptions.add(index, description);
+			this.fireItemAdded(DESCRIPTIONS_LIST, index, description);
+		}
+		public void addDescription(String description) {
+			this.addDescription(this.descriptions.size(), description);
+		}
+		public void addDescriptions(ListIterator<String> newDescriptions) {
+			while (newDescriptions.hasNext()) {
+				this.addDescription(newDescriptions.next());
+			}
+		}
+		public void addDescriptions(List<String> newDescriptions) {
+			this.addDescriptions(newDescriptions.listIterator());
+		}
+		public String removeDescription(int index) {
+			String removedDescription = this.descriptions.remove(index);
+			this.fireItemRemoved(DESCRIPTIONS_LIST, index, removedDescription);
+			return removedDescription;
+		}
+		public String setDescription(int index, String description) {
+			String replacedDescription = this.descriptions.set(index, description);
+			this.fireItemReplaced(DESCRIPTIONS_LIST, index, description, replacedDescription);
+			return replacedDescription;
+		}
+	}
+
+
+	// this is not a typical aspect adapter - the value is determined by the aspect name
+	class LocalListAspectAdapter extends ListAspectAdapter<TestSubject, String> {
+
+		LocalListAspectAdapter(PropertyValueModel<TestSubject> subjectHolder) {
+			super(subjectHolder, TestSubject.NAMES_LIST);
+		}
+
+		@Override
+		protected ListIterator<String> listIterator_() {
+			if (this.aspectNames[0] == TestSubject.NAMES_LIST) {
+				return this.subject.names();
+			} else if (this.aspectNames[0] == TestSubject.DESCRIPTIONS_LIST) {
+				return this.subject.descriptions();
+			} else {
+				throw new IllegalStateException("invalid aspect name: " + this.aspectNames[0]);
+			}
+		}
+
+		public void add(int index, Object item) {
+			if (this.aspectNames[0] == TestSubject.NAMES_LIST) {
+				this.subject.addName(index, (String) item);
+			} else if (this.aspectNames[0] == TestSubject.DESCRIPTIONS_LIST) {
+				this.subject.addDescription(index, (String) item);
+			} else {
+				throw new IllegalStateException("invalid aspect name: " + this.aspectNames[0]);
+			}
+		}
+
+		public void addAll(int index, List<String> items) {
+			for (int i = 0; i < items.size(); i++) {
+				this.add(index + i, items.get(i));
+			}
+		}
+
+		public String remove(int index) {
+			if (this.aspectNames[0] == TestSubject.NAMES_LIST) {
+				return this.subject.removeName(index);
+			} else if (this.aspectNames[0] == TestSubject.DESCRIPTIONS_LIST) {
+				return this.subject.removeDescription(index);
+			} else {
+				throw new IllegalStateException("invalid aspect name: " + this.aspectNames[0]);
+			}
+		}
+
+		public List<String> remove(int index, int length) {
+			List<String> removedItems = new ArrayList<String>(length);
+			for (int i = 0; i < length; i++) {
+				removedItems.add(this.remove(index));
+			}
+			return removedItems;
+		}
+
+		public Object replace(int index, Object item) {
+			if (this.aspectNames[0] == TestSubject.NAMES_LIST) {
+				return this.subject.setName(index, (String) item);
+			} else if (this.aspectNames[0] == TestSubject.DESCRIPTIONS_LIST) {
+				return this.subject.setDescription(index, (String) item);
+			} else {
+				throw new IllegalStateException("invalid aspect name: " + this.aspectNames[0]);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ListCollectionValueModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ListCollectionValueModelAdapterTests.java
new file mode 100644
index 0000000..0542321
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ListCollectionValueModelAdapterTests.java
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.swing.JList;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ListCollectionValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.SimpleListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.ListModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class ListCollectionValueModelAdapterTests extends TestCase {
+
+	CollectionValueModel<String> adapter;
+	private SimpleListValueModel<String> wrappedListHolder;
+	private List<String> wrappedList;
+
+	public ListCollectionValueModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.wrappedList = new ArrayList<String>();
+		this.wrappedListHolder = new SimpleListValueModel<String>(this.wrappedList);
+		this.adapter = new ListCollectionValueModelAdapter<String>(this.wrappedListHolder);
+	}
+
+	private Collection<String> wrappedCollection() {
+		return CollectionTools.collection(this.wrappedList.iterator());
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testIterator() {
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, new TestListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {
+				// override failure
+			}
+		});
+		this.wrappedListHolder.add(0, "foo");
+		this.wrappedListHolder.add(1, "bar");
+		this.wrappedListHolder.add(2, "baz");
+		Collection<String> adapterCollection = CollectionTools.collection(this.adapter.iterator());
+		assertEquals(3, adapterCollection.size());
+		assertEquals(this.wrappedCollection(), adapterCollection);
+	}
+
+	public void testStaleValues() {
+		CollectionChangeListener listener = new TestListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {/* OK */}
+		};
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, listener);
+		this.wrappedListHolder.add(0, "foo");
+		this.wrappedListHolder.add(1, "bar");
+		this.wrappedListHolder.add(2, "baz");
+		Collection<String> adapterCollection = CollectionTools.collection(this.adapter.iterator());
+		assertEquals(3, adapterCollection.size());
+		assertEquals(this.wrappedCollection(), adapterCollection);
+
+		this.adapter.removeCollectionChangeListener(CollectionValueModel.VALUES, listener);
+		adapterCollection = CollectionTools.collection(this.adapter.iterator());
+		assertEquals(0, adapterCollection.size());
+		assertEquals(new HashBag<String>(), adapterCollection);
+
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, listener);
+		adapterCollection = CollectionTools.collection(this.adapter.iterator());
+		assertEquals(3, adapterCollection.size());
+		assertEquals(this.wrappedCollection(), adapterCollection);
+	}
+
+	public void testAdd() {
+		Bag<String> synchCollection = new CoordinatedBag<String>(this.adapter);
+		List<String> synchList = new CoordinatedList<String>(this.wrappedListHolder);
+		this.wrappedListHolder.add(0, "foo");
+		assertTrue(this.wrappedList.contains("foo"));
+		this.wrappedListHolder.add(1, "bar");
+		this.wrappedListHolder.add(2, "baz");
+		this.wrappedListHolder.add(3, "joo");
+		this.wrappedListHolder.add(4, "jar");
+		this.wrappedListHolder.add(5, "jaz");
+		assertEquals(6, this.wrappedList.size());
+
+		Collection<String> adapterCollection = CollectionTools.collection(this.adapter.iterator());
+		assertEquals(this.wrappedCollection(), adapterCollection);
+		assertEquals(this.wrappedCollection(), CollectionTools.collection(synchList.iterator()));
+		assertEquals(this.wrappedCollection(), synchCollection);
+	}
+
+	public void testRemove() {
+		Bag<String> synchCollection = new CoordinatedBag<String>(this.adapter);
+		List<String> synchList = new CoordinatedList<String>(this.wrappedListHolder);
+		this.wrappedListHolder.add(0, "foo");
+		this.wrappedListHolder.add(1, "bar");
+		this.wrappedListHolder.add(2, "baz");
+		this.wrappedListHolder.add(3, "joo");
+		this.wrappedListHolder.add(4, "jar");
+		this.wrappedListHolder.add(5, "jaz");
+		assertEquals("jaz", this.wrappedListHolder.remove(5));
+		assertFalse(this.wrappedList.contains("jaz"));
+		assertEquals("foo", this.wrappedListHolder.remove(0));
+		assertFalse(this.wrappedList.contains("foo"));
+		assertEquals(4, this.wrappedList.size());
+
+		Collection<String> adapterCollection = CollectionTools.collection(this.adapter.iterator());
+		assertEquals(this.wrappedCollection(), adapterCollection);
+		assertEquals(this.wrappedCollection(), CollectionTools.collection(synchList.iterator()));
+		assertEquals(this.wrappedCollection(), synchCollection);
+	}
+
+	public void testListSynch() {
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, new TestListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {
+				// override failure
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {
+				// override failure
+			}
+		});
+		this.wrappedListHolder.add(0, "foo");
+		this.wrappedListHolder.add(1, "bar");
+		this.wrappedListHolder.add(2, "baz");
+		this.wrappedListHolder.add(3, "joo");
+		this.wrappedListHolder.add(4, "jar");
+		this.wrappedListHolder.add(5, "jaz");
+		this.wrappedListHolder.remove(5);
+		assertFalse(this.wrappedList.contains("jaz"));
+		this.wrappedListHolder.remove(0);
+		assertFalse(this.wrappedList.contains("foo"));
+		assertEquals(4, this.wrappedList.size());
+
+		Collection<String> adapterCollection = CollectionTools.collection(this.adapter.iterator());
+		assertEquals(this.wrappedCollection(), adapterCollection);
+	}
+
+	public void testReplace() {
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, new TestListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {
+				// override failure
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {
+				// override failure
+			}
+		});
+		this.wrappedListHolder.add(0, "foo");
+		this.wrappedListHolder.add(1, "bar");
+		this.wrappedListHolder.add(2, "baz");
+		Collection<String> adapterCollection = CollectionTools.collection(this.adapter.iterator());
+		assertEquals(3, adapterCollection.size());
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, new TestListener() {
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {
+				assertEquals("foo", e.getItems().iterator().next());
+				assertFalse(IteratorTools.contains(ListCollectionValueModelAdapterTests.this.adapter.iterator(), "joo"));
+				assertEquals(2, ListCollectionValueModelAdapterTests.this.adapter.size());
+			}
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {
+				assertEquals("joo", e.getItems().iterator().next());
+				assertEquals(3, ListCollectionValueModelAdapterTests.this.adapter.size());
+			}
+		});
+		this.wrappedListHolder.set(0, "joo");
+		adapterCollection = CollectionTools.collection(this.adapter.iterator());
+		assertEquals(3, adapterCollection.size());
+		assertEquals(this.wrappedCollection(), adapterCollection);
+	}
+
+	public void testHasListeners() {
+		assertFalse(((AbstractModel) this.adapter).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		CoordinatedBag<String> synchCollection = new CoordinatedBag<String>(this.adapter);
+		assertTrue(((AbstractModel) this.adapter).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		this.adapter.removeCollectionChangeListener(CollectionValueModel.VALUES, synchCollection);
+		assertFalse(((AbstractModel) this.adapter).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+
+		ChangeListener cl = new ChangeAdapter();
+		this.adapter.addChangeListener(cl);
+		assertTrue(((AbstractModel) this.adapter).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		this.adapter.removeChangeListener(cl);
+		assertFalse(((AbstractModel) this.adapter).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+	}
+
+	public void testListChangedToEmpty() {
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, new TestListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {/* OK */}
+			@Override
+			public void collectionCleared(CollectionClearEvent e) {/* OK */}
+		});
+		this.wrappedListHolder.add(0, "foo");
+		this.wrappedListHolder.add(1, "bar");
+		this.wrappedListHolder.add(2, "baz");
+		JList jList = new JList(new ListModelAdapter(this.adapter));
+		this.wrappedListHolder.setListValues(new ArrayList<String>());
+		assertEquals(0, jList.getModel().getSize());
+	}
+
+	public void testCollectionChangedFromEmpty() {
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, new TestListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {/* OK */}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {/* OK */}
+		});
+		JList jList = new JList(new ListModelAdapter(this.adapter));
+
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("foo");
+		list.add("bar");
+		this.wrappedListHolder.setListValues(list);
+		assertEquals(2, jList.getModel().getSize());
+	}
+
+	public void testCollectionChangedFromEmptyToEmpty() {
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, new TestListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {/* OK */}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {/* OK */}
+		});
+		JList jList = new JList(new ListModelAdapter(this.adapter));
+
+		ArrayList<String> list = new ArrayList<String>();
+		this.wrappedListHolder.setListValues(list);
+		assertEquals(0, jList.getModel().getSize());
+	}
+
+
+	// ********** inner class **********
+
+	class TestListener implements CollectionChangeListener {
+		@Override
+		public void itemsAdded(CollectionAddEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsRemoved(CollectionRemoveEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void collectionCleared(CollectionClearEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void collectionChanged(CollectionChangeEvent e) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ListCuratorTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ListCuratorTests.java
new file mode 100644
index 0000000..7f140d4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ListCuratorTests.java
@@ -0,0 +1,357 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyListIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ListCurator;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public final class ListCuratorTests
+	extends TestCase
+{
+	private TestSubject subject1;
+	private ModifiablePropertyValueModel<TestSubject> subjectHolder1;
+
+	private ListCurator<TestSubject, String> curator;
+	private ListChangeListener listener1;
+	private ListEvent event1;
+
+	private TestSubject subject2;
+
+	public ListCuratorTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.subject1 = new TestSubject(this.subject1Names());
+		this.subjectHolder1 = new SimplePropertyValueModel<TestSubject>(this.subject1);
+		this.curator = this.buildListCurator(this.subjectHolder1);
+		this.listener1 = this.buildListChangeListener1();
+		this.curator.addListChangeListener(ListValueModel.LIST_VALUES, this.listener1);
+		this.event1 = null;
+
+		this.subject2 = new TestSubject(this.subject2Names());
+	}
+
+	private List<String> subject1Names() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("alpha");
+		list.add("bravo");
+		list.add("charlie");
+		list.add("delta");
+		return list;
+	}
+
+	private List<String> subject2Names() {
+		ArrayList<String> list = new ArrayList<String>();
+		list.add("echo");
+		list.add("foxtrot");
+		list.add("glove");
+		list.add("hotel");
+		return list;
+	}
+
+	private ListCurator<TestSubject, String> buildListCurator(PropertyValueModel<TestSubject> subjectHolder) {
+		return new ListCurator<TestSubject, String>(subjectHolder) {
+			@Override
+			public Iterator<String> iteratorForRecord() {
+				return this.subject.strings();
+			}
+		};
+	}
+
+	private ListChangeListener buildListChangeListener1() {
+		return new ListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {
+				ListCuratorTests.this.value1Changed(e);
+			}
+			@Override
+			public void itemsRemoved(ListRemoveEvent e) {
+				ListCuratorTests.this.value1Changed(e);
+			}
+			@Override
+			public void itemsReplaced(ListReplaceEvent e) {
+				ListCuratorTests.this.value1Changed(e);
+			}
+			@Override
+			public void itemsMoved(ListMoveEvent e) {
+				ListCuratorTests.this.value1Changed(e);
+			}
+			@Override
+			public void listCleared(ListClearEvent e) {
+				ListCuratorTests.this.value1Changed(e);
+			}
+			@Override
+			public void listChanged(ListChangeEvent e) {
+				ListCuratorTests.this.value1Changed(e);
+			}
+		};
+	}
+
+	void value1Changed(ListEvent e) {
+		this.event1 = e;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testSubjectHolder() {
+		assertEquals(this.subject1Names(), ListTools.list(this.curator.listIterator()));
+		assertNull(this.event1);
+
+		this.subjectHolder1.setValue(this.subject2);
+		assertNotNull(this.event1);
+		assertEquals(this.curator, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(this.subject2Names(), ListTools.list(this.curator.listIterator()));
+
+		this.event1 = null;
+		this.subjectHolder1.setValue(null);
+		assertNotNull(this.event1);
+		assertEquals(this.curator, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertFalse(this.curator.iterator().hasNext());
+
+		this.event1 = null;
+		this.subjectHolder1.setValue(this.subject1);
+		assertNotNull(this.event1);
+		assertEquals(this.curator, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(this.subject1Names(), ListTools.list(this.curator.listIterator()));
+	}
+
+	public void testAdd() {
+		assertEquals(this.subject1Names(), ListTools.list(this.curator.listIterator()));
+		assertNull(this.event1);
+
+		this.subject1.addString("echo");
+		assertNotNull(this.event1);
+		assertEquals(this.curator, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(this.subject1Names().size(), ((ListAddEvent) this.event1).getIndex());
+		assertEquals("echo", ((ListAddEvent) this.event1).getItems().iterator().next());
+		List<String> stringsPlus = this.subject1Names();
+		stringsPlus.add("echo");
+		assertEquals(stringsPlus, ListTools.list(this.curator.listIterator()));
+
+		this.event1 = null;
+		this.subject1.addString(0, "zulu");
+		assertNotNull(this.event1);
+		assertEquals(this.curator, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(0, ((ListAddEvent) this.event1).getIndex());
+		assertEquals("zulu", ((ListAddEvent) this.event1).getItems().iterator().next());
+		stringsPlus.add(0, "zulu");
+		assertEquals(stringsPlus, ListTools.list(this.curator.listIterator()));
+	}
+
+	public void testRemove() {
+		assertEquals(this.subject1Names(), ListTools.list(this.curator.listIterator()));
+		assertNull(this.event1);
+
+		String removedString = this.subject1.removeString(0);	// should be "alpha"
+		assertNotNull(this.event1);
+		assertEquals(this.curator, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(0, ((ListRemoveEvent) this.event1).getIndex());
+		assertEquals(removedString, ((ListRemoveEvent) this.event1).getItems().iterator().next());
+		List<String> stringsMinus = this.subject1Names();
+		stringsMinus.remove(0);
+		assertEquals(stringsMinus, ListTools.list(this.curator.listIterator()));
+
+		removedString = this.subject1.removeString(2);	// should be "delta"
+		assertNotNull(this.event1);
+		assertEquals(this.curator, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(2, ((ListRemoveEvent) this.event1).getIndex());
+		assertEquals(removedString, ((ListRemoveEvent) this.event1).getItems().iterator().next());
+		stringsMinus.remove(2);
+		assertEquals(stringsMinus, ListTools.list(this.curator.listIterator()));
+	}
+
+	public void testCompleteListChange() {
+		assertEquals(this.subject1Names(), ListTools.list(this.curator.listIterator()));
+		assertNull(this.event1);
+
+		this.subject1.setStrings(this.subject2Names());
+		assertNotNull(this.event1);
+		assertEquals(this.curator, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		List<String> newStrings = this.subject2Names();
+		assertEquals(newStrings, ListTools.list(this.curator.listIterator()));
+	}
+
+	public void testPartialListChange() {
+		List<String> startingList = ListTools.list(this.curator.listIterator());
+		assertEquals(this.subject1Names(), startingList);
+		assertNull(this.event1);
+
+		String identicalString = startingList.get(1);  // should be "bravo"
+		String nonidenticalString = startingList.get(0); // should be "alpha"
+		List<String> newStrings = ListTools.list(new String[] {new String("bravo"), new String("alpha"), "echo", "delta", "foxtrot"});
+		this.subject1.setStrings(newStrings);
+
+		List<String> finalList = ListTools.list(this.curator.listIterator());
+		assertNotNull(this.event1);
+		assertEquals(this.curator, this.event1.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event1.getListName());
+		assertEquals(newStrings, finalList);
+		assertTrue(identicalString == finalList.get(0));
+		assertTrue(nonidenticalString != finalList.get(1));
+	}
+
+	public void testIterator() {
+		assertEquals(this.subject1Names(), ListTools.list(this.subject1.strings()));
+		assertEquals(this.subject1Names(), ListTools.list(this.curator.listIterator()));
+	}
+
+	public void testGet() {
+		assertEquals(this.subject1Names().get(0), this.subject1.getString(0));
+		assertEquals(this.subject1Names().get(0), this.curator.get(0));
+	}
+
+	public void testSize() {
+		assertEquals(this.subject1Names().size(), IteratorTools.size(this.subject1.strings()));
+		assertEquals(this.subject1Names().size(), IteratorTools.size(this.curator.listIterator()));
+		assertEquals(this.subject1Names().size(), this.curator.size());
+	}
+
+	public void testHasListeners() {
+		assertTrue(this.curator.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertTrue(this.subject1.hasAnyStateChangeListeners());
+		this.curator.removeListChangeListener(ListValueModel.LIST_VALUES, this.listener1);
+		assertFalse(this.subject1.hasAnyStateChangeListeners());
+		assertFalse(this.curator.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		ChangeListener listener2 = this.buildChangeListener();
+		this.curator.addChangeListener(listener2);
+		assertTrue(this.curator.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertTrue(this.subject1.hasAnyStateChangeListeners());
+		this.curator.removeChangeListener(listener2);
+		assertFalse(this.subject1.hasAnyStateChangeListeners());
+		assertFalse(this.curator.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	private ChangeListener buildChangeListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {
+				ListCuratorTests.this.value1Changed(e);
+			}
+			@Override
+			public void itemsRemoved(ListRemoveEvent e) {
+				ListCuratorTests.this.value1Changed(e);
+			}
+			@Override
+			public void itemsReplaced(ListReplaceEvent e) {
+				ListCuratorTests.this.value1Changed(e);
+			}
+			@Override
+			public void itemsMoved(ListMoveEvent e) {
+				ListCuratorTests.this.value1Changed(e);
+			}
+			@Override
+			public void listCleared(ListClearEvent e) {
+				ListCuratorTests.this.value1Changed(e);
+			}
+			@Override
+			public void listChanged(ListChangeEvent e) {
+				ListCuratorTests.this.value1Changed(e);
+			}
+		};
+	}
+
+
+	// **************** Inner Class *******************************************
+
+	class TestSubject extends AbstractModel {
+		private List<String> strings;
+
+		public TestSubject() {
+			this.strings = new ArrayList<String>();
+		}
+
+		public TestSubject(List<String> strings) {
+			this();
+			this.setStrings(strings);
+		}
+
+		public String getString(int index) {
+			return this.strings.get(index);
+		}
+
+		public ListIterator<String> strings() {
+			return new ReadOnlyListIterator<String>(this.strings);
+		}
+
+		public void addString(int index, String string) {
+			this.strings.add(index, string);
+			this.fireStateChanged();
+		}
+
+		public void addString(String string) {
+			this.addString(this.strings.size(), string);
+		}
+
+		public String removeString(int index) {
+			String string = this.strings.get(index);
+			this.removeString(string);
+			return string;
+		}
+
+		public void removeString(String string) {
+			this.strings.remove(string);
+			this.fireStateChanged();
+		}
+
+		public void setStrings(List<String> strings) {
+			this.strings = new ArrayList<String>(strings);
+			this.fireStateChanged();
+		}
+
+		public void setStrings(String[] strings) {
+			this.strings = ListTools.list(strings);
+			this.fireStateChanged();
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/NullCollectionValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/NullCollectionValueModelTests.java
new file mode 100644
index 0000000..49cfa98
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/NullCollectionValueModelTests.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.NullCollectionValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+public class NullCollectionValueModelTests extends TestCase {
+	private CollectionValueModel<Object> collectionHolder;
+
+	public NullCollectionValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.collectionHolder = new NullCollectionValueModel<Object>();
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testSize() {
+		assertEquals(0, this.collectionHolder.size());
+	}
+
+	public void testIterator() {
+		assertFalse(this.collectionHolder.iterator().hasNext());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/NullListValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/NullListValueModelTests.java
new file mode 100644
index 0000000..f191a7d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/NullListValueModelTests.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.NullListValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+public class NullListValueModelTests extends TestCase {
+
+	private ListValueModel<Object> listHolder;
+
+	public NullListValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.listHolder = new NullListValueModel<Object>();
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testGet() {
+		boolean exCaught = false;
+		try {
+			this.listHolder.get(0);
+		} catch (IndexOutOfBoundsException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testSize() {
+		assertEquals(0, this.listHolder.size());
+	}
+
+	public void testIterator() {
+		assertFalse(this.listHolder.iterator().hasNext());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/NullPropertyValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/NullPropertyValueModelTests.java
new file mode 100644
index 0000000..dce470b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/NullPropertyValueModelTests.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.value.NullPropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+public class NullPropertyValueModelTests extends TestCase {
+
+	private PropertyValueModel<Object> valueHolder;
+
+	public NullPropertyValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.valueHolder = new NullPropertyValueModel<Object>();
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testValue() {
+		assertNull(this.valueHolder.getValue());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/PropertyAspectAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/PropertyAspectAdapterTests.java
new file mode 100644
index 0000000..eaefe84
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/PropertyAspectAdapterTests.java
@@ -0,0 +1,349 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class PropertyAspectAdapterTests extends TestCase {
+
+	private TestSubject subject1;
+	private ModifiablePropertyValueModel<TestSubject> subjectHolder1;
+	private PropertyAspectAdapter<TestSubject, String> aa1;
+	private PropertyChangeEvent event1;
+	private PropertyChangeListener listener1;
+
+	private TestSubject subject2;
+
+	private PropertyChangeEvent multipleValueEvent;
+
+	private PropertyChangeEvent customValueEvent;
+
+
+	public PropertyAspectAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.subject1 = new TestSubject("foo", "test subject 1");
+		this.subjectHolder1 = new SimplePropertyValueModel<TestSubject> (this.subject1);
+		this.aa1 = this.buildAspectAdapter(this.subjectHolder1);
+		this.listener1 = this.buildValueChangeListener1();
+		this.aa1.addPropertyChangeListener(PropertyValueModel.VALUE, this.listener1);
+		this.event1 = null;
+
+		this.subject2 = new TestSubject("bar", "test subject 2");
+	}
+
+	private PropertyAspectAdapter<TestSubject, String> buildAspectAdapter(PropertyValueModel<TestSubject> subjectHolder) {
+		return new PropertyAspectAdapter<TestSubject, String>(subjectHolder, TestSubject.NAME_PROPERTY) {
+			// this is not a aspect adapter - the value is determined by the aspect name
+			@Override
+			protected String buildValue_() {
+				if (this.aspectNames[0] == TestSubject.NAME_PROPERTY) {
+					return this.subject.getName();
+				} else if (this.aspectNames[0] == TestSubject.DESCRIPTION_PROPERTY) {
+					return this.subject.getDescription();
+				} else {
+					throw new IllegalStateException("invalid aspect name: " + this.aspectNames[0]);
+				}
+			}
+			@Override
+			protected void setValue_(String value) {
+				if (this.aspectNames[0] == TestSubject.NAME_PROPERTY) {
+					this.subject.setName(value);
+				} else if (this.aspectNames[0] == TestSubject.DESCRIPTION_PROPERTY) {
+					this.subject.setDescription(value);
+				} else {
+					throw new IllegalStateException("invalid aspect name: " + this.aspectNames[0]);
+				}
+			}
+		};
+	}
+
+	private ChangeListener buildValueChangeListener1() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				PropertyAspectAdapterTests.this.value1Changed(e);
+			}
+		};
+	}
+
+	void value1Changed(PropertyChangeEvent e) {
+		this.event1 = e;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testSubjectHolder() {
+		assertEquals("foo", this.aa1.getValue());
+		assertNull(this.event1);
+
+		this.subjectHolder1.setValue(this.subject2);
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(PropertyValueModel.VALUE, this.event1.getPropertyName());
+		assertEquals("foo", this.event1.getOldValue());
+		assertEquals("bar", this.event1.getNewValue());
+		assertEquals("bar", this.aa1.getValue());
+
+		this.event1 = null;
+		this.subjectHolder1.setValue(null);
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(PropertyValueModel.VALUE, this.event1.getPropertyName());
+		assertEquals("bar", this.event1.getOldValue());
+		assertNull(this.event1.getNewValue());
+		assertNull(this.aa1.getValue());
+
+		this.event1 = null;
+		this.subjectHolder1.setValue(this.subject1);
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(PropertyValueModel.VALUE, this.event1.getPropertyName());
+		assertEquals(null, this.event1.getOldValue());
+		assertEquals("foo", this.event1.getNewValue());
+		assertEquals("foo", this.aa1.getValue());
+	}
+
+	public void testPropertyChange() {
+		assertEquals("foo", this.aa1.getValue());
+		assertNull(this.event1);
+
+		this.subject1.setName("baz");
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(PropertyValueModel.VALUE, this.event1.getPropertyName());
+		assertEquals("foo", this.event1.getOldValue());
+		assertEquals("baz", this.event1.getNewValue());
+		assertEquals("baz", this.aa1.getValue());
+
+		this.event1 = null;
+		this.subject1.setName(null);
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(PropertyValueModel.VALUE, this.event1.getPropertyName());
+		assertEquals("baz", this.event1.getOldValue());
+		assertEquals(null, this.event1.getNewValue());
+		assertEquals(null, this.aa1.getValue());
+
+		this.event1 = null;
+		this.subject1.setName("foo");
+		assertNotNull(this.event1);
+		assertEquals(this.aa1, this.event1.getSource());
+		assertEquals(PropertyValueModel.VALUE, this.event1.getPropertyName());
+		assertEquals(null, this.event1.getOldValue());
+		assertEquals("foo", this.event1.getNewValue());
+		assertEquals("foo", this.aa1.getValue());
+	}
+
+	public void testValue() {
+		assertEquals("foo", this.subject1.getName());
+		assertEquals("foo", this.aa1.getValue());
+	}
+
+	public void testStaleValue() {
+		assertEquals("foo", this.subject1.getName());
+		assertEquals("foo", this.aa1.getValue());
+
+		this.aa1.removePropertyChangeListener(PropertyValueModel.VALUE, this.listener1);
+		assertEquals(null, this.aa1.getValue());
+
+		this.aa1.addPropertyChangeListener(PropertyValueModel.VALUE, this.listener1);
+		assertEquals("foo", this.aa1.getValue());
+
+		this.aa1.removePropertyChangeListener(PropertyValueModel.VALUE, this.listener1);
+		this.subjectHolder1.setValue(this.subject2);
+		assertEquals(null, this.aa1.getValue());
+
+		this.aa1.addPropertyChangeListener(PropertyValueModel.VALUE, this.listener1);
+		assertEquals("bar", this.aa1.getValue());
+	}
+
+	public void testSetValue() {
+		this.aa1.setValue("baz");
+		assertEquals("baz", this.aa1.getValue());
+		assertEquals("baz", this.subject1.getName());
+	}
+
+	public void testHasListeners() {
+		assertTrue(this.aa1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(this.subject1.hasAnyPropertyChangeListeners(TestSubject.NAME_PROPERTY));
+		this.aa1.removePropertyChangeListener(PropertyValueModel.VALUE, this.listener1);
+		assertFalse(this.subject1.hasAnyPropertyChangeListeners(TestSubject.NAME_PROPERTY));
+		assertFalse(this.aa1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		ChangeListener listener2 = this.buildValueChangeListener1();
+		this.aa1.addChangeListener(listener2);
+		assertTrue(this.aa1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(this.subject1.hasAnyPropertyChangeListeners(TestSubject.NAME_PROPERTY));
+		this.aa1.removeChangeListener(listener2);
+		assertFalse(this.subject1.hasAnyPropertyChangeListeners(TestSubject.NAME_PROPERTY));
+		assertFalse(this.aa1.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	public void testMultipleAspectAdapter() {
+		TestSubject testSubject = new TestSubject("fred", "husband");
+		ModifiablePropertyValueModel<TestSubject> testSubjectHolder = new SimplePropertyValueModel<TestSubject>(testSubject);
+		ModifiablePropertyValueModel<String> testAA = this.buildMultipleAspectAdapter(testSubjectHolder);
+		PropertyChangeListener testListener = this.buildMultipleValueChangeListener();
+		testAA.addPropertyChangeListener(PropertyValueModel.VALUE, testListener);
+		assertEquals("fred:husband", testAA.getValue());
+
+		this.multipleValueEvent = null;
+		testSubject.setName("wilma");
+		assertEquals("wilma:husband", testAA.getValue());
+		assertEquals("fred:husband", this.multipleValueEvent.getOldValue());
+		assertEquals("wilma:husband", this.multipleValueEvent.getNewValue());
+
+		this.multipleValueEvent = null;
+		testSubject.setDescription("wife");
+		assertEquals("wilma:wife", testAA.getValue());
+		assertEquals("wilma:husband", this.multipleValueEvent.getOldValue());
+		assertEquals("wilma:wife", this.multipleValueEvent.getNewValue());
+	}
+
+	private ModifiablePropertyValueModel<String> buildMultipleAspectAdapter(PropertyValueModel<TestSubject> subjectHolder) {
+		return new PropertyAspectAdapter<TestSubject, String>(subjectHolder, TestSubject.NAME_PROPERTY, TestSubject.DESCRIPTION_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getName() + ":" + this.subject.getDescription();
+			}
+		};
+	}
+
+	private PropertyChangeListener buildMultipleValueChangeListener() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				PropertyAspectAdapterTests.this.multipleValueChanged(e);
+			}
+		};
+	}
+
+	void multipleValueChanged(PropertyChangeEvent e) {
+		this.multipleValueEvent = e;
+	}
+
+	/**
+	 * test a bug where we would call #buildValue() in
+	 * #engageNonNullSubject(), when we needed to call
+	 * it in #engageSubject(), so the cached value would
+	 * be rebuilt when the this.subject was set to null
+	 */
+	public void testCustomBuildValueWithNullSubject() {
+		TestSubject customSubject = new TestSubject("fred", "laborer");
+		ModifiablePropertyValueModel<TestSubject> customSubjectHolder = new SimplePropertyValueModel<TestSubject>(customSubject);
+		ModifiablePropertyValueModel<String> customAA = this.buildCustomAspectAdapter(customSubjectHolder);
+		PropertyChangeListener customListener = this.buildCustomValueChangeListener();
+		customAA.addPropertyChangeListener(PropertyValueModel.VALUE, customListener);
+		assertEquals("fred", customAA.getValue());
+
+		this.customValueEvent = null;
+		customSubject.setName("wilma");
+		assertEquals("wilma", customAA.getValue());
+		assertEquals("fred", this.customValueEvent.getOldValue());
+		assertEquals("wilma", this.customValueEvent.getNewValue());
+
+		this.customValueEvent = null;
+		customSubjectHolder.setValue(null);
+		// this would fail - the value would be null...
+		assertEquals("<unnamed>", customAA.getValue());
+		assertEquals("wilma", this.customValueEvent.getOldValue());
+		assertEquals("<unnamed>", this.customValueEvent.getNewValue());
+	}
+
+	/**
+	 * Test a bug:
+	 * If two listeners were added to an aspect adapter, one with an
+	 * aspect name and one without, the aspect adapter would add its
+	 * 'subjectChangeListener' to its 'subjectHolder' twice. As a result,
+	 * the following code will trigger an IllegalArgumentException
+	 * if the bug is present; otherwise, it completes silently.
+	 */
+	public void testDuplicateListener() {
+		ChangeListener listener2 = new ChangeAdapter();
+		this.aa1.addChangeListener(listener2);
+	}
+
+	private ModifiablePropertyValueModel<String> buildCustomAspectAdapter(PropertyValueModel<TestSubject> subjectHolder) {
+		return new PropertyAspectAdapter<TestSubject, String>(subjectHolder, TestSubject.NAME_PROPERTY) {
+			@Override
+			protected String buildValue() {
+				return (this.subject == null) ? "<unnamed>" : this.subject.getName();
+			}
+		};
+	}
+
+	private PropertyChangeListener buildCustomValueChangeListener() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				PropertyAspectAdapterTests.this.customValueChanged(e);
+			}
+		};
+	}
+
+	void customValueChanged(PropertyChangeEvent e) {
+		this.customValueEvent = e;
+	}
+
+
+	// ********** test model **********
+
+	private static class TestSubject extends AbstractModel {
+		private String name;
+		public static final String NAME_PROPERTY = "name";
+		private String description;
+		public static final String DESCRIPTION_PROPERTY = "description";
+
+		public TestSubject(String name, String description) {
+			this.name = name;
+			this.description = description;
+		}
+		public String getName() {
+			return this.name;
+		}
+		public void setName(String name) {
+			Object old = this.name;
+			this.name = name;
+			this.firePropertyChanged(NAME_PROPERTY, old, name);
+		}
+		public String getDescription() {
+			return this.description;
+		}
+		public void setDescription(String description) {
+			Object old = this.description;
+			this.description = description;
+			this.firePropertyChanged(DESCRIPTION_PROPERTY, old, description);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/PropertyCollectionValueModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/PropertyCollectionValueModelAdapterTests.java
new file mode 100644
index 0000000..ec77da5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/PropertyCollectionValueModelAdapterTests.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.Collection;
+import javax.swing.JList;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.iterator.SingleElementIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyCollectionValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.ListModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class PropertyCollectionValueModelAdapterTests extends TestCase {
+	private CollectionValueModel<String> adapter;
+	private ModifiablePropertyValueModel<String> wrappedValueHolder;
+
+	public PropertyCollectionValueModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.wrappedValueHolder = new SimplePropertyValueModel<String>();
+		this.adapter = new PropertyCollectionValueModelAdapter<String>(this.wrappedValueHolder);
+	}
+
+	private Collection<String> wrappedCollection() {
+		return CollectionTools.collection(new SingleElementIterator<String>(this.wrappedValueHolder.getValue()));
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testIterator() {
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, new TestListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {/* OK */}
+		});
+		this.wrappedValueHolder.setValue("foo");
+		Collection<String> adapterCollection = CollectionTools.collection(this.adapter.iterator());
+		assertEquals(1, adapterCollection.size());
+		assertEquals(this.wrappedCollection(), adapterCollection);
+		assertEquals("foo", adapterCollection.iterator().next());
+	}
+
+	public void testStaleValue() {
+		CollectionChangeListener listener = new TestListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {/* OK */}
+		};
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, listener);
+		this.wrappedValueHolder.setValue("foo");
+		Collection<String> adapterCollection = CollectionTools.collection(this.adapter.iterator());
+		assertEquals(1, adapterCollection.size());
+		assertEquals(this.wrappedCollection(), adapterCollection);
+		assertEquals("foo", adapterCollection.iterator().next());
+
+		this.adapter.removeCollectionChangeListener(CollectionValueModel.VALUES, listener);
+		adapterCollection = CollectionTools.collection(this.adapter.iterator());
+		assertEquals(0, adapterCollection.size());
+		assertEquals(new HashBag<String>(), adapterCollection);
+
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, listener);
+		adapterCollection = CollectionTools.collection(this.adapter.iterator());
+		assertEquals(1, adapterCollection.size());
+		assertEquals(this.wrappedCollection(), adapterCollection);
+		assertEquals("foo", adapterCollection.iterator().next());
+	}
+
+	public void testHasListeners() {
+		assertFalse(((AbstractModel) this.adapter).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		CoordinatedBag<String> synchCollection = new CoordinatedBag<String>(this.adapter);
+		assertTrue(((AbstractModel) this.adapter).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		this.adapter.removeCollectionChangeListener(CollectionValueModel.VALUES, synchCollection);
+		assertFalse(((AbstractModel) this.adapter).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+
+		ChangeListener cl = new ChangeAdapter();
+		this.adapter.addChangeListener(cl);
+		assertTrue(((AbstractModel) this.adapter).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		this.adapter.removeChangeListener(cl);
+		assertFalse(((AbstractModel) this.adapter).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+	}
+
+	public void testListChangedToEmpty() {
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, new TestListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {/* OK */}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {/* OK */}
+		});
+		this.wrappedValueHolder.setValue("foo");
+		JList jList = new JList(new ListModelAdapter(this.adapter));
+		this.wrappedValueHolder.setValue(null);
+		assertEquals(0, jList.getModel().getSize());
+	}
+
+	public void testCollectionChangedFromEmpty() {
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, new TestListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {/* OK */}
+		});
+		JList jList = new JList(new ListModelAdapter(this.adapter));
+
+		this.wrappedValueHolder.setValue("foo");
+		assertEquals(1, jList.getModel().getSize());
+	}
+
+	public void testCollectionChangedFromEmptyToEmpty() {
+		this.adapter.addCollectionChangeListener(CollectionValueModel.VALUES, new TestListener());
+		JList jList = new JList(new ListModelAdapter(this.adapter));
+
+		this.wrappedValueHolder.setValue(null);
+		assertEquals(0, jList.getModel().getSize());
+	}
+
+
+	// ********** member class **********
+
+	static class TestListener implements CollectionChangeListener {
+		@Override
+		public void collectionChanged(CollectionChangeEvent event) {
+			fail("unexpected event");
+		}
+		@Override
+		public void collectionCleared(CollectionClearEvent event) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsAdded(CollectionAddEvent event) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsRemoved(CollectionRemoveEvent event) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/PropertyListValueModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/PropertyListValueModelAdapterTests.java
new file mode 100644
index 0000000..a572c93
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/PropertyListValueModelAdapterTests.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.swing.JList;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.SingleElementIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.ListModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class PropertyListValueModelAdapterTests extends TestCase {
+
+	private ListValueModel<String> adapter;
+	private ModifiablePropertyValueModel<String> wrappedValueHolder;
+
+	public PropertyListValueModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.wrappedValueHolder = new SimplePropertyValueModel<String>();
+		this.adapter = new PropertyListValueModelAdapter<String>(this.wrappedValueHolder);
+	}
+
+	private Collection<String> wrappedList() {
+		return ListTools.list(new SingleElementIterator<String>(this.wrappedValueHolder.getValue()));
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testIterator() {
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) {/* OK */}
+		});
+		assertFalse(this.adapter.iterator().hasNext());
+		this.wrappedValueHolder.setValue("foo");
+		List<String> adapterList = ListTools.list(this.adapter.iterator());
+		assertEquals(1, adapterList.size());
+		assertEquals(this.wrappedList(), adapterList);
+		assertEquals("foo", adapterList.iterator().next());
+	}
+
+	public void testGetInt() {
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) {/* OK */}
+		});
+		this.wrappedValueHolder.setValue("foo");
+		assertEquals("foo", this.adapter.get(0));
+	}
+
+	public void testToArray1() {
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) {/* OK */}
+		});
+		this.wrappedValueHolder.setValue("foo");
+		Object[] array = this.adapter.toArray();
+		assertEquals("foo", array[0]);
+		assertEquals(1, array.length);
+	}
+
+	public void testToArray2() {
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListener());
+		Object[] array = this.adapter.toArray();
+		assertEquals(0, array.length);
+	}
+
+	public void testStaleValue() {
+		ListChangeListener listener = new TestListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) {/* OK */}
+		};
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		this.wrappedValueHolder.setValue("foo");
+		List<String> adapterList = ListTools.list(this.adapter.iterator());
+		assertEquals(1, adapterList.size());
+		assertEquals(this.wrappedList(), adapterList);
+		assertEquals("foo", adapterList.iterator().next());
+
+		this.adapter.removeListChangeListener(ListValueModel.LIST_VALUES, listener);
+		adapterList = ListTools.list(this.adapter.iterator());
+		assertEquals(0, adapterList.size());
+		assertEquals(new ArrayList<String>(), adapterList);
+
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		adapterList = ListTools.list(this.adapter.iterator());
+		assertEquals(1, adapterList.size());
+		assertEquals(this.wrappedList(), adapterList);
+		assertEquals("foo", adapterList.iterator().next());
+	}
+
+	public void testHasListeners() {
+		assertFalse(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		CoordinatedList<String> synchList = new CoordinatedList<String>(this.adapter);
+		assertTrue(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		this.adapter.removeListChangeListener(ListValueModel.LIST_VALUES, synchList);
+		assertFalse(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		ChangeListener cl = new ChangeAdapter();
+		this.adapter.addChangeListener(cl);
+		assertTrue(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		this.adapter.removeChangeListener(cl);
+		assertFalse(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	public void testListChangedToEmpty() {
+		this.wrappedValueHolder.setValue("foo");
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListener() {
+			@Override
+			public void itemsRemoved(ListRemoveEvent event) {/* OK */}
+		});
+		JList jList = new JList(new ListModelAdapter(this.adapter));
+		this.wrappedValueHolder.setValue(null);
+		assertEquals(0, jList.getModel().getSize());
+	}
+
+	public void testListChangedFromEmpty() {
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) {/* OK */}
+		});
+		JList jList = new JList(new ListModelAdapter(this.adapter));
+
+		this.wrappedValueHolder.setValue("foo");
+		assertEquals(1, jList.getModel().getSize());
+	}
+
+	public void testListItemChanged() {
+		this.wrappedValueHolder.setValue("foo");
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListener() {
+			@Override
+			public void itemsReplaced(ListReplaceEvent event) {/* OK */}
+		});
+		JList jList = new JList(new ListModelAdapter(this.adapter));
+		assertEquals(1, jList.getModel().getSize());
+		assertEquals("foo", jList.getModel().getElementAt(0));
+
+		this.wrappedValueHolder.setValue("bar");
+		assertEquals(1, jList.getModel().getSize());
+		assertEquals("bar", jList.getModel().getElementAt(0));
+	}
+
+	public void testListChangedFromEmptyToEmpty() {
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListener());
+		JList jList = new JList(new ListModelAdapter(this.adapter));
+
+		this.wrappedValueHolder.setValue(null);
+		assertEquals(0, jList.getModel().getSize());
+	}
+
+
+	// ********** member class **********
+
+	static class TestListener implements ListChangeListener {
+		@Override
+		public void listChanged(ListChangeEvent event) {
+			fail("unexpected event");
+		}
+		@Override
+		public void listCleared(ListClearEvent event) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsAdded(ListAddEvent event) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsRemoved(ListRemoveEvent event) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsMoved(ListMoveEvent event) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsReplaced(ListReplaceEvent event) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ReadOnlyModifiablePropertyValueModelWrapperTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ReadOnlyModifiablePropertyValueModelWrapperTests.java
new file mode 100644
index 0000000..deeaf95
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ReadOnlyModifiablePropertyValueModelWrapperTests.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ReadOnlyModifiablePropertyValueModelWrapper;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class ReadOnlyModifiablePropertyValueModelWrapperTests
+	extends TestCase
+{
+	private ModifiablePropertyValueModel<String> objectHolder;
+
+	PropertyChangeEvent event;
+
+	private ModifiablePropertyValueModel<String> wrapperObjectHolder;
+
+	PropertyChangeEvent wrapperEvent;
+
+
+	public ReadOnlyModifiablePropertyValueModelWrapperTests(String name) {
+		super(name);
+	}
+
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.objectHolder = new SimplePropertyValueModel<String>("foo");
+		this.wrapperObjectHolder = new ReadOnlyModifiablePropertyValueModelWrapper<String>(this.objectHolder);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+
+	public void testValue() {
+		assertEquals("foo", this.objectHolder.getValue());
+		assertEquals("foo", this.wrapperObjectHolder.getValue());
+
+		this.objectHolder.setValue("bar");
+		assertEquals("bar", this.objectHolder.getValue());
+		assertEquals("bar", this.wrapperObjectHolder.getValue());
+
+		this.objectHolder.setValue(null);
+		assertNull(this.objectHolder.getValue());
+		assertNull(this.wrapperObjectHolder.getValue());
+
+		this.objectHolder.setValue("foo");
+		assertEquals("foo", this.objectHolder.getValue());
+		assertEquals("foo", this.wrapperObjectHolder.getValue());
+	}
+
+	public void testSetValue() {
+		boolean exceptionOccurred = false;
+		try {
+			this.wrapperObjectHolder.setValue("bar");
+		}
+		catch (UnsupportedOperationException uoe) {
+			exceptionOccurred = true;
+		}
+
+		assertTrue(exceptionOccurred);
+		assertEquals("foo", this.objectHolder.getValue());
+		assertEquals("foo", this.wrapperObjectHolder.getValue());
+	}
+
+	public void testLazyListening() {
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		ChangeListener listener = buildWrapperListener();
+		this.wrapperObjectHolder.addChangeListener(listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.wrapperObjectHolder.removeChangeListener(listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.wrapperObjectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.wrapperObjectHolder.removePropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	public void testPropertyChange1() {
+		this.objectHolder.addChangeListener(this.buildListener());
+		this.wrapperObjectHolder.addChangeListener(this.buildWrapperListener());
+		this.verifyPropertyChanges();
+	}
+
+	public void testPropertyChange2() {
+		this.objectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildListener());
+		this.wrapperObjectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildWrapperListener());
+		this.verifyPropertyChanges();
+	}
+
+	private void verifyPropertyChanges() {
+		this.event = null;
+		this.wrapperEvent = null;
+		this.objectHolder.setValue("bar");
+		verifyEvent(this.event, this.objectHolder, "foo", "bar");
+		verifyEvent(this.wrapperEvent, this.wrapperObjectHolder, "foo", "bar");
+
+		this.event = null;
+		this.wrapperEvent = null;
+		this.objectHolder.setValue(null);
+		verifyEvent(this.event, this.objectHolder, "bar", null);
+		verifyEvent(this.wrapperEvent, this.wrapperObjectHolder, "bar", null);
+
+		this.event = null;
+		this.wrapperEvent = null;
+		this.objectHolder.setValue("foo");
+		verifyEvent(this.event, this.objectHolder, null, "foo");
+		verifyEvent(this.wrapperEvent, this.wrapperObjectHolder, null, "foo");
+	}
+
+	private ChangeListener buildListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				ReadOnlyModifiablePropertyValueModelWrapperTests.this.event = e;
+			}
+		};
+	}
+
+	private ChangeListener buildWrapperListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				ReadOnlyModifiablePropertyValueModelWrapperTests.this.wrapperEvent = e;
+			}
+		};
+	}
+
+	private void verifyEvent(PropertyChangeEvent e, Object source, Object oldValue, Object newValue) {
+		assertEquals(source, e.getSource());
+		assertEquals(PropertyValueModel.VALUE, e.getPropertyName());
+		assertEquals(oldValue, e.getOldValue());
+		assertEquals(newValue, e.getNewValue());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SetCollectionValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SetCollectionValueModelTests.java
new file mode 100644
index 0000000..75d2181
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SetCollectionValueModelTests.java
@@ -0,0 +1,338 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SetCollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class SetCollectionValueModelTests extends TestCase {
+
+	private SimpleCollectionValueModel<String> collectionHolder;
+	CollectionAddEvent addEvent;
+	CollectionRemoveEvent removeEvent;
+	CollectionClearEvent collectionClearedEvent;
+	CollectionChangeEvent collectionChangedEvent;
+
+	private CollectionValueModel<String> setHolder;
+	CollectionAddEvent setAddEvent;
+	CollectionRemoveEvent setRemoveEvent;
+	CollectionClearEvent setClearedEvent;
+	CollectionChangeEvent setChangedEvent;
+
+	public SetCollectionValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.collectionHolder = new SimpleCollectionValueModel<String>(this.buildCollection());
+		this.setHolder = new SetCollectionValueModel<String>(this.collectionHolder);
+	}
+
+	private Collection<String> buildCollection() {
+		Collection<String> collection = new ArrayList<String>();
+		collection.add("foo");
+		collection.add("foo");
+		return collection;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testIterator() {
+		// add a listener to "activate" the wrapper
+		this.setHolder.addChangeListener(this.buildSetChangeListener());
+
+		this.verify(this.collectionHolder, "foo", "foo");
+		this.verify(this.setHolder, "foo");
+
+		this.collectionHolder.add("bar");
+		this.collectionHolder.add("bar");
+		this.verify(this.collectionHolder, "foo", "foo", "bar", "bar");
+		this.verify(this.setHolder, "foo", "bar");
+
+		this.collectionHolder.remove("bar");
+		this.verify(this.collectionHolder, "foo", "foo", "bar");
+		this.verify(this.setHolder, "foo", "bar");
+
+		this.collectionHolder.remove("bar");
+		this.verify(this.collectionHolder, "foo", "foo");
+		this.verify(this.setHolder, "foo");
+
+		this.collectionHolder.remove("foo");
+		this.verify(this.collectionHolder, "foo");
+		this.verify(this.setHolder, "foo");
+
+		this.collectionHolder.remove("foo");
+		assertFalse(this.collectionHolder.iterator().hasNext());
+		assertFalse(this.setHolder.iterator().hasNext());
+	}
+
+	public void testSize() {
+		// add a listener to "activate" the wrapper
+		this.setHolder.addChangeListener(this.buildSetChangeListener());
+
+		assertEquals(2, this.collectionHolder.size());
+		assertEquals(1, this.setHolder.size());
+
+		this.collectionHolder.add("bar");
+		this.collectionHolder.add("bar");
+		assertEquals(4, this.collectionHolder.size());
+		assertEquals(2, this.setHolder.size());
+
+		this.collectionHolder.remove("bar");
+		assertEquals(3, this.collectionHolder.size());
+		assertEquals(2, this.setHolder.size());
+
+		this.collectionHolder.remove("bar");
+		assertEquals(2, this.collectionHolder.size());
+		assertEquals(1, this.setHolder.size());
+
+		this.collectionHolder.remove("foo");
+		assertEquals(1, this.collectionHolder.size());
+		assertEquals(1, this.setHolder.size());
+
+		this.collectionHolder.remove("foo");
+		assertEquals(0, this.collectionHolder.size());
+		assertEquals(0, this.setHolder.size());
+	}
+
+	public void testBulkChange() {
+		// add a listener to "activate" the wrapper
+		this.setHolder.addChangeListener(this.buildSetChangeListener());
+
+		Collection<String> newCollection = new ArrayList<String>();
+		newCollection.add("fox");
+		newCollection.add("fox");
+		newCollection.add("bat");
+
+		this.collectionHolder.setValues(newCollection);
+		this.verify(this.collectionHolder, "fox", "fox", "bat");
+		this.verify(this.setHolder, "fox", "bat");
+	}
+
+	public void testLazyListening() {
+		assertTrue(((AbstractModel) this.collectionHolder).hasNoCollectionChangeListeners(CollectionValueModel.VALUES));
+		ChangeListener listener = this.buildSetChangeListener();
+		this.setHolder.addChangeListener(listener);
+		assertTrue(((AbstractModel) this.collectionHolder).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		this.setHolder.removeChangeListener(listener);
+		assertTrue(((AbstractModel) this.collectionHolder).hasNoCollectionChangeListeners(CollectionValueModel.VALUES));
+
+		this.setHolder.addCollectionChangeListener(CollectionValueModel.VALUES, listener);
+		assertTrue(((AbstractModel) this.collectionHolder).hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		this.setHolder.removeCollectionChangeListener(CollectionValueModel.VALUES, listener);
+		assertTrue(((AbstractModel) this.collectionHolder).hasNoCollectionChangeListeners(CollectionValueModel.VALUES));
+	}
+
+	public void testEvents1() {
+		this.collectionHolder.addChangeListener(this.buildChangeListener());
+		this.setHolder.addChangeListener(this.buildSetChangeListener());
+		this.verifyEvents();
+	}
+
+	public void testEvents2() {
+		this.collectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.buildCollectionChangeListener());
+		this.setHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.buildSetCollectionChangeListener());
+		this.verifyEvents();
+	}
+
+	private void clearEvents() {
+		this.addEvent = null;
+		this.removeEvent = null;
+		this.collectionClearedEvent = null;
+		this.collectionChangedEvent = null;
+		this.setAddEvent = null;
+		this.setRemoveEvent = null;
+		this.setClearedEvent = null;
+		this.setChangedEvent = null;
+	}
+
+	private void verifyEvents() {
+		this.clearEvents();
+		this.collectionHolder.add("bar");
+		this.verifyEvent(this.addEvent, this.collectionHolder, "bar");
+		this.verifyEvent(this.setAddEvent, this.setHolder, "bar");
+
+		this.clearEvents();
+		this.collectionHolder.remove("foo");
+		this.verifyEvent(this.removeEvent, this.collectionHolder, "foo");
+		assertNull(this.setRemoveEvent);
+
+		this.clearEvents();
+		this.collectionHolder.add("bar");
+		this.verifyEvent(this.addEvent, this.collectionHolder, "bar");
+		assertNull(this.setAddEvent);
+
+		this.clearEvents();
+		this.collectionHolder.remove("foo");
+		this.verifyEvent(this.removeEvent, this.collectionHolder, "foo");
+		this.verifyEvent(this.setRemoveEvent, this.setHolder, "foo");
+
+		this.clearEvents();
+		this.collectionHolder.add("foo");
+		this.verifyEvent(this.addEvent, this.collectionHolder, "foo");
+		this.verifyEvent(this.setAddEvent, this.setHolder, "foo");
+
+		this.clearEvents();
+		this.collectionHolder.clear();
+		this.verifyEvent(this.collectionClearedEvent, this.collectionHolder);
+		this.verifyEvent(this.setClearedEvent, this.setHolder);
+
+		this.clearEvents();
+		Collection<String> newCollection = new ArrayList<String>();
+		newCollection.add("fox");
+		newCollection.add("fox");
+		newCollection.add("bat");
+		newCollection.add("bat");
+		newCollection.add("bat");
+		this.collectionHolder.setValues(newCollection);
+		this.verifyEvent(this.collectionChangedEvent, this.collectionHolder, "fox", "fox", "bat", "bat", "bat");
+		this.verifyEvent(this.setChangedEvent, this.setHolder, "fox", "bat");
+
+	}
+
+	private CollectionChangeListener buildCollectionChangeListener() {
+		return new CollectionChangeListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent event) {
+				SetCollectionValueModelTests.this.addEvent = event;
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent event) {
+				SetCollectionValueModelTests.this.removeEvent = event;
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent event) {
+				SetCollectionValueModelTests.this.collectionClearedEvent = event;
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent event) {
+				SetCollectionValueModelTests.this.collectionChangedEvent = event;
+			}
+		};
+	}
+
+	private ChangeListener buildChangeListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void itemsAdded(CollectionAddEvent event) {
+				SetCollectionValueModelTests.this.addEvent = event;
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent event) {
+				SetCollectionValueModelTests.this.removeEvent = event;
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent event) {
+				SetCollectionValueModelTests.this.collectionClearedEvent = event;
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent event) {
+				SetCollectionValueModelTests.this.collectionChangedEvent = event;
+			}
+		};
+	}
+
+	private CollectionChangeListener buildSetCollectionChangeListener() {
+		return new CollectionChangeListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent event) {
+				SetCollectionValueModelTests.this.setAddEvent = event;
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent event) {
+				SetCollectionValueModelTests.this.setRemoveEvent = event;
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent event) {
+				SetCollectionValueModelTests.this.setClearedEvent = event;
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent event) {
+				SetCollectionValueModelTests.this.setChangedEvent = event;
+			}
+		};
+	}
+
+	private ChangeListener buildSetChangeListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void itemsAdded(CollectionAddEvent event) {
+				SetCollectionValueModelTests.this.setAddEvent = event;
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent event) {
+				SetCollectionValueModelTests.this.setRemoveEvent = event;
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent event) {
+				SetCollectionValueModelTests.this.setClearedEvent = event;
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent event) {
+				SetCollectionValueModelTests.this.setChangedEvent = event;
+			}
+		};
+	}
+
+	private void verify(CollectionValueModel<String> cvm, String... expectedItems) {
+		Bag<String> actual = CollectionTools.bag(cvm);
+		Bag<String> expected = CollectionTools.bag(expectedItems);
+		assertEquals(expected, actual);
+	}
+
+	private void verifyEvent(CollectionAddEvent event, Object source, Object... expectedItems) {
+		assertEquals(source, event.getSource());
+		assertEquals(CollectionValueModel.VALUES, event.getCollectionName());
+		assertEquals(CollectionTools.bag(expectedItems), CollectionTools.bag(event.getItems()));
+	}
+
+	private void verifyEvent(CollectionRemoveEvent event, Object source, Object... expectedItems) {
+		assertEquals(source, event.getSource());
+		assertEquals(CollectionValueModel.VALUES, event.getCollectionName());
+		assertEquals(CollectionTools.bag(expectedItems), CollectionTools.bag(event.getItems()));
+	}
+
+	private void verifyEvent(CollectionClearEvent event, Object source) {
+		assertEquals(source, event.getSource());
+		assertEquals(CollectionValueModel.VALUES, event.getCollectionName());
+	}
+
+	private void verifyEvent(CollectionChangeEvent event, Object source, Object... expectedItems) {
+		assertEquals(source, event.getSource());
+		assertEquals(CollectionValueModel.VALUES, event.getCollectionName());
+		assertEquals(CollectionTools.bag(expectedItems), CollectionTools.bag(event.getCollection()));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SimpleCollectionValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SimpleCollectionValueModelTests.java
new file mode 100644
index 0000000..4408cc0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SimpleCollectionValueModelTests.java
@@ -0,0 +1,446 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class SimpleCollectionValueModelTests extends TestCase {
+
+	private SimpleCollectionValueModel<String> bagHolder;
+	CollectionEvent bagEvent;
+	String bagEventType;
+
+	private SimpleCollectionValueModel<String> setHolder;
+	CollectionEvent setEvent;
+	String setEventType;
+
+	private static final String ADD = "add";
+	private static final String REMOVE = "remove";
+	private static final String CHANGE = "change";
+	private static final String CLEAR = "clear";
+
+
+	public SimpleCollectionValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.bagHolder = new SimpleCollectionValueModel<String>(this.buildBag());
+		this.setHolder = new SimpleCollectionValueModel<String>(this.buildSet());
+	}
+
+	private Bag<String> buildBag() {
+		Bag<String> result = new HashBag<String>();
+		this.addItemsTo(result);
+		return result;
+	}
+
+	private Set<String> buildSet() {
+		Set<String> result = new HashSet<String>();
+		this.addItemsTo(result);
+		return result;
+	}
+
+	private void addItemsTo(Collection<String> c) {
+		c.add("foo");
+		c.add("bar");
+		c.add("baz");
+	}
+
+	private Bag<String> buildAddItems() {
+		Bag<String> result = new HashBag<String>();
+		result.add("joo");
+		result.add("jar");
+		result.add("jaz");
+		return result;
+	}
+
+	private Bag<String> buildRemoveItems() {
+		Bag<String> result = new HashBag<String>();
+		result.add("foo");
+		result.add("baz");
+		return result;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testIterator() {
+		assertEquals(this.buildBag(), CollectionTools.bag(this.bagHolder.iterator()));
+		assertEquals(this.buildSet(), CollectionTools.set(this.setHolder.iterator()));
+	}
+
+	public void testSize() {
+		assertEquals(this.buildBag().size(), IteratorTools.size(this.bagHolder.iterator()));
+		assertEquals(this.buildSet().size(), IteratorTools.size(this.setHolder.iterator()));
+	}
+
+	private boolean bagHolderContains(Object item) {
+		return IteratorTools.contains(this.bagHolder.iterator(), item);
+	}
+
+	private boolean setHolderContains(Object item) {
+		return IteratorTools.contains(this.setHolder.iterator(), item);
+	}
+
+	private boolean bagHolderContainsAll(Collection<String> items) {
+		return IteratorTools.containsAll(this.bagHolder.iterator(), items);
+	}
+
+	private boolean setHolderContainsAll(Collection<String> items) {
+		return IteratorTools.containsAll(this.setHolder.iterator(), items);
+	}
+
+	private boolean bagHolderContainsAny(Collection<String> items) {
+		Bag<String> bag = CollectionTools.bag(this.bagHolder.iterator());
+		for (String string : items) {
+			if (bag.contains(string)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private boolean setHolderContainsAny(Collection<String> items) {
+		Set<String> set = CollectionTools.set(this.setHolder.iterator());
+		for (String string : items) {
+			if (set.contains(string)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public void testAdd() {
+		assertFalse(this.bagHolderContains("joo"));
+		this.bagHolder.add("joo");
+		assertTrue(this.bagHolderContains("joo"));
+
+		assertFalse(this.bagHolderContains(null));
+		this.bagHolder.add(null);
+		assertTrue(this.bagHolderContains(null));
+
+		assertFalse(this.setHolderContains("joo"));
+		this.setHolder.add("joo");
+		assertTrue(this.setHolderContains("joo"));
+
+		assertFalse(this.setHolderContains(null));
+		this.setHolder.add(null);
+		assertTrue(this.setHolderContains(null));
+	}
+
+	public void testAddAll() {
+		assertFalse(this.bagHolderContainsAny(this.buildAddItems()));
+		this.bagHolder.addAll(this.buildAddItems());
+		assertTrue(this.bagHolderContainsAll(this.buildAddItems()));
+
+		assertFalse(this.setHolderContainsAny(this.buildAddItems()));
+		this.setHolder.addAll(this.buildAddItems());
+		assertTrue(this.setHolderContainsAll(this.buildAddItems()));
+	}
+
+	public void testRemove() {
+		assertTrue(this.bagHolderContains("bar"));
+		this.bagHolder.remove("bar");
+		assertFalse(this.bagHolderContains("bar"));
+
+		this.bagHolder.add(null);
+		assertTrue(this.bagHolderContains(null));
+		this.bagHolder.remove(null);
+		assertFalse(this.bagHolderContains(null));
+
+		assertTrue(this.setHolderContains("bar"));
+		this.setHolder.remove("bar");
+		assertFalse(this.setHolderContains("bar"));
+
+		this.setHolder.add(null);
+		assertTrue(this.setHolderContains(null));
+		this.setHolder.remove(null);
+		assertFalse(this.setHolderContains(null));
+	}
+
+	public void testRemoveAll() {
+		assertTrue(this.bagHolderContainsAll(this.buildRemoveItems()));
+		this.bagHolder.removeAll(this.buildRemoveItems());
+		assertFalse(this.bagHolderContainsAny(this.buildRemoveItems()));
+
+		assertTrue(this.setHolderContainsAll(this.buildRemoveItems()));
+		this.setHolder.removeAll(this.buildRemoveItems());
+		assertFalse(this.setHolderContainsAny(this.buildRemoveItems()));
+	}
+
+	public void testSetValues() {
+		assertTrue(this.bagHolderContains("bar"));
+		assertFalse(this.bagHolderContains("jar"));
+		this.bagHolder.setValues(this.buildAddItems());
+		assertFalse(this.bagHolderContains("bar"));
+		assertTrue(this.bagHolderContains("jar"));
+
+		this.bagHolder.add(null);
+		assertTrue(this.bagHolderContains(null));
+		this.bagHolder.remove(null);
+		assertFalse(this.bagHolderContains(null));
+
+		this.bagHolder.setValues(new HashBag<String>());
+		assertFalse(this.bagHolderContains("jar"));
+
+		assertTrue(this.setHolderContains("bar"));
+		assertFalse(this.setHolderContains("jar"));
+		this.setHolder.setValues(this.buildAddItems());
+		assertFalse(this.setHolderContains("bar"));
+		assertTrue(this.setHolderContains("jar"));
+
+		this.setHolder.add(null);
+		assertTrue(this.setHolderContains(null));
+		this.setHolder.remove(null);
+		assertFalse(this.setHolderContains(null));
+
+		this.setHolder.setValues(new HashBag<String>());
+		assertFalse(this.setHolderContains("jar"));
+	}
+
+	public void testCollectionChange1() {
+		this.bagHolder.addChangeListener(this.buildBagListener());
+		this.verifyBagChange();
+
+		this.setHolder.addChangeListener(this.buildSetListener());
+		this.verifySetChange();
+	}
+
+	public void testCollectionChange2() {
+		this.bagHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.buildBagListener());
+		this.verifyBagChange();
+
+		this.setHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.buildSetListener());
+		this.verifySetChange();
+	}
+
+	private void verifyBagChange() {
+		this.bagEvent = null;
+		this.bagEventType = null;
+		this.bagHolder.add("foo");
+		this.verifyBagEvent(ADD, "foo");
+
+		this.bagEvent = null;
+		this.bagEventType = null;
+		this.bagHolder.add("foo");
+		this.verifyBagEvent(ADD, "foo");
+
+		this.bagEvent = null;
+		this.bagEventType = null;
+		this.bagHolder.add("joo");
+		this.verifyBagEvent(ADD, "joo");
+
+		this.bagEvent = null;
+		this.bagEventType = null;
+		this.bagHolder.add(null);
+		this.verifyBagEvent(ADD, null);
+
+		this.bagEvent = null;
+		this.bagEventType = null;
+		this.bagHolder.add(null);
+		this.verifyBagEvent(ADD, null);
+
+		this.bagEvent = null;
+		this.bagEventType = null;
+		this.bagHolder.remove("joo");
+		this.verifyBagEvent(REMOVE, "joo");
+
+		this.bagEvent = null;
+		this.bagEventType = null;
+		this.bagHolder.remove(null);
+		this.verifyBagEvent(REMOVE, null);
+
+		this.bagEvent = null;
+		this.bagEventType = null;
+		this.bagHolder.setValues(this.buildBag());
+		this.verifyBagEvent(CHANGE);
+
+		this.bagEvent = null;
+		this.bagEventType = null;
+		this.bagHolder.addAll(this.buildBag());
+		this.verifyBagEvent(ADD);
+		assertEquals(this.buildBag(), CollectionTools.bag(((CollectionAddEvent) this.bagEvent).getItems()));
+	}
+
+	private void verifySetChange() {
+		this.setEvent = null;
+		this.setEventType = null;
+		this.setHolder.add("foo");
+		assertNull(this.setEvent);
+		assertNull(this.setEventType);
+
+		this.setEvent = null;
+		this.setEventType = null;
+		this.setHolder.add("joo");
+		this.verifySetEvent(ADD, "joo");
+
+		this.setEvent = null;
+		this.setEventType = null;
+		this.setHolder.add("joo");
+		assertNull(this.setEvent);
+		assertNull(this.setEventType);
+
+		this.setEvent = null;
+		this.setEventType = null;
+		this.setHolder.add(null);
+		this.verifySetEvent(ADD, null);
+
+		this.setEvent = null;
+		this.setEventType = null;
+		this.setHolder.add(null);
+		assertNull(this.setEvent);
+		assertNull(this.setEventType);
+
+		this.setEvent = null;
+		this.setEventType = null;
+		this.setHolder.remove("joo");
+		this.verifySetEvent(REMOVE, "joo");
+
+		this.setEvent = null;
+		this.setEventType = null;
+		this.setHolder.remove("joo");
+		assertNull(this.setEvent);
+		assertNull(this.setEventType);
+
+		this.setEvent = null;
+		this.setEventType = null;
+		this.setHolder.remove(null);
+		this.verifySetEvent(REMOVE, null);
+
+		this.setEvent = null;
+		this.setEventType = null;
+		this.setHolder.setValues(this.buildSet());
+		this.verifySetEvent(CHANGE);
+
+		this.setEvent = null;
+		this.setEventType = null;
+		this.setHolder.addAll(this.buildSet());
+		assertNull(this.setEvent);
+		assertNull(this.setEventType);
+	}
+
+	private ChangeListener buildBagListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {
+				SimpleCollectionValueModelTests.this.bagEventType = ADD;
+				SimpleCollectionValueModelTests.this.bagEvent = e;
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {
+				SimpleCollectionValueModelTests.this.bagEventType = REMOVE;
+				SimpleCollectionValueModelTests.this.bagEvent = e;
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent e) {
+				SimpleCollectionValueModelTests.this.bagEventType = CLEAR;
+				SimpleCollectionValueModelTests.this.bagEvent = e;
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent e) {
+				SimpleCollectionValueModelTests.this.bagEventType = CHANGE;
+				SimpleCollectionValueModelTests.this.bagEvent = e;
+			}
+		};
+	}
+
+	private ChangeListener buildSetListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {
+				SimpleCollectionValueModelTests.this.setEventType = ADD;
+				SimpleCollectionValueModelTests.this.setEvent = e;
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {
+				SimpleCollectionValueModelTests.this.setEventType = REMOVE;
+				SimpleCollectionValueModelTests.this.setEvent = e;
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent e) {
+				SimpleCollectionValueModelTests.this.setEventType = CLEAR;
+				SimpleCollectionValueModelTests.this.setEvent = e;
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent e) {
+				SimpleCollectionValueModelTests.this.setEventType = CHANGE;
+				SimpleCollectionValueModelTests.this.setEvent = e;
+			}
+		};
+	}
+
+	private void verifyBagEvent(String eventType) {
+		assertEquals(eventType, this.bagEventType);
+		assertEquals(this.bagHolder, this.bagEvent.getSource());
+		assertEquals(CollectionValueModel.VALUES, this.bagEvent.getCollectionName());
+	}
+
+	private void verifyBagEvent(String eventType, Object item) {
+		this.verifyBagEvent(eventType);
+		assertEquals(item, this.getBagEventItems().iterator().next());
+	}
+
+	private Iterable<?> getBagEventItems() {
+		if (this.bagEvent instanceof CollectionAddEvent) {
+			return ((CollectionAddEvent) this.bagEvent).getItems();
+		} else if (this.bagEvent instanceof CollectionRemoveEvent) {
+			return ((CollectionRemoveEvent) this.bagEvent).getItems();
+		}
+		throw new IllegalStateException();
+	}
+
+	private void verifySetEvent(String eventType) {
+		assertEquals(eventType, this.setEventType);
+		assertEquals(this.setHolder, this.setEvent.getSource());
+		assertEquals(CollectionValueModel.VALUES, this.setEvent.getCollectionName());
+	}
+
+	private void verifySetEvent(String eventType, Object item) {
+		this.verifySetEvent(eventType);
+		assertEquals(item, this.getSetEventItems().iterator().next());
+	}
+
+	private Iterable<?> getSetEventItems() {
+		if (this.setEvent instanceof CollectionAddEvent) {
+			return ((CollectionAddEvent) this.setEvent).getItems();
+		} else if (this.setEvent instanceof CollectionRemoveEvent) {
+			return ((CollectionRemoveEvent) this.setEvent).getItems();
+		}
+		throw new IllegalStateException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SimpleListValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SimpleListValueModelTests.java
new file mode 100644
index 0000000..1fab96d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SimpleListValueModelTests.java
@@ -0,0 +1,389 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleListValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class SimpleListValueModelTests extends TestCase {
+
+	private SimpleListValueModel<String> listHolder;
+	ListEvent event;
+	String eventType;
+
+	private static final String ADD = "add";
+	private static final String REMOVE = "remove";
+	private static final String REPLACE = "replace";
+	private static final String MOVE = "move";
+	private static final String CLEAR = "clear";
+	private static final String CHANGE = "change";
+
+
+	public SimpleListValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.listHolder = new SimpleListValueModel<String>(this.buildList());
+	}
+
+	private List<String> buildList() {
+		List<String> result = new ArrayList<String>();
+		result.add("foo");
+		result.add("bar");
+		result.add("baz");
+		return result;
+	}
+
+	private List<String> buildAddList() {
+		List<String> result = new ArrayList<String>();
+		result.add("joo");
+		result.add("jar");
+		result.add("jaz");
+		return result;
+	}
+
+//	private List<String> buildRemoveList() {
+//		List<String> result = new ArrayList<String>();
+//		result.add("foo");
+//		result.add("bar");
+//		return result;
+//	}
+//
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testIterator() {
+		assertEquals(this.buildList(), ListTools.list(this.listHolder.iterator()));
+	}
+
+	public void testListIterator() {
+		assertEquals(this.buildList(), ListTools.list(this.listHolder.listIterator()));
+	}
+
+	public void testListIteratorInt() {
+		assertEquals(ListTools.list(this.buildList().listIterator(1)), ListTools.list(this.listHolder.listIterator(1)));
+	}
+
+	public void testSize() {
+		assertEquals(this.buildList().size(), this.listHolder.size());
+	}
+
+	private boolean listContains(Object item) {
+		return IteratorTools.contains(this.listHolder.listIterator(), item);
+	}
+
+	private boolean listContainsAll(Collection<String> items) {
+		return IteratorTools.containsAll(this.listHolder.listIterator(), items);
+	}
+
+	private boolean listContainsAny(Collection<String> items) {
+		Set<String> set = CollectionTools.set(this.listHolder.iterator());
+		for (Iterator<String> stream = items.iterator(); stream.hasNext(); ) {
+			if (set.contains(stream.next())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public void testAddObject() {
+		assertFalse(this.listContains("joo"));
+		this.listHolder.add("joo");
+		assertTrue(this.listContains("joo"));
+
+		assertFalse(this.listContains(null));
+		this.listHolder.add(null);
+		assertTrue(this.listContains(null));
+	}
+
+	public void testAddIntObject() {
+		assertFalse(this.listContains("joo"));
+		this.listHolder.add(2, "joo");
+		assertTrue(this.listContains("joo"));
+
+		assertFalse(this.listContains(null));
+		this.listHolder.add(0, null);
+		assertTrue(this.listContains(null));
+	}
+
+	public void testAddAllCollection() {
+		assertFalse(this.listContainsAny(this.buildAddList()));
+		this.listHolder.addAll(this.buildAddList());
+		assertTrue(this.listContainsAll(this.buildAddList()));
+	}
+
+	public void testAddAllIntCollection() {
+		assertFalse(this.listContainsAny(this.buildAddList()));
+		this.listHolder.addAll(2, this.buildAddList());
+		assertTrue(this.listContainsAll(this.buildAddList()));
+	}
+
+	public void testClear() {
+		assertFalse(this.listHolder.isEmpty());
+		this.listHolder.clear();
+		assertTrue(this.listHolder.isEmpty());
+	}
+
+	public void testContainsObject() {
+		assertTrue(this.listHolder.contains("foo"));
+		assertFalse(this.listHolder.contains("joo"));
+	}
+
+	public void testContainsAllCollection() {
+		Collection<String> c = new ArrayList<String>();
+		c.add("foo");
+		c.add("bar");
+		assertTrue(this.listHolder.containsAll(c));
+
+		c.add("joo");
+		assertFalse(this.listHolder.containsAll(c));
+	}
+
+	public void testEquals() {
+		assertEquals(new SimpleListValueModel<String>(this.buildList()), this.listHolder);
+		assertFalse(this.listHolder.equals(new SimpleListValueModel<String>(this.buildAddList())));
+		assertFalse(this.listHolder.equals(this.buildList()));
+		assertFalse(this.listHolder.equals(new SimpleListValueModel<String>()));
+	}
+
+	public void testGetInt() {
+		assertEquals("foo", this.listHolder.get(0));
+		assertEquals("bar", this.listHolder.get(1));
+		assertEquals("baz", this.listHolder.get(2));
+	}
+
+	public void testHashCode() {
+		assertEquals(new SimpleListValueModel<String>(this.buildList()).hashCode(), this.listHolder.hashCode());
+	}
+
+	public void testIndexOfObject() {
+		assertEquals(0, this.listHolder.indexOf("foo"));
+		assertEquals(1, this.listHolder.indexOf("bar"));
+		assertEquals(2, this.listHolder.indexOf("baz"));
+		assertEquals(-1, this.listHolder.indexOf("joo"));
+	}
+
+	public void testLastIndexOfObject() {
+		assertEquals(0, this.listHolder.lastIndexOf("foo"));
+		assertEquals(1, this.listHolder.lastIndexOf("bar"));
+		assertEquals(2, this.listHolder.lastIndexOf("baz"));
+		assertEquals(-1, this.listHolder.lastIndexOf("joo"));
+
+		this.listHolder.add("foo");
+		assertEquals(3, this.listHolder.lastIndexOf("foo"));
+	}
+
+	public void testIsEmpty() {
+		assertFalse(this.listHolder.isEmpty());
+		this.listHolder.clear();
+		assertTrue(this.listHolder.isEmpty());
+	}
+
+	public void testRemove() {
+		assertTrue(this.listContains("bar"));
+		this.listHolder.remove(this.buildList().indexOf("bar"));
+		assertFalse(this.listContains("bar"));
+
+		this.listHolder.add(1, null);
+		assertTrue(this.listContains(null));
+		this.listHolder.remove(1);
+		assertFalse(this.listContains(null));
+	}
+
+	public void testSetValues() {
+		List<String> newList = new ArrayList<String>();
+		newList.add("joo");
+		newList.add("jar");
+		newList.add("jaz");
+
+		assertTrue(this.listContains("bar"));
+		assertFalse(this.listContains("jar"));
+		this.listHolder.setListValues(newList);
+		assertFalse(this.listContains("bar"));
+		assertTrue(this.listContains("jar"));
+
+		this.listHolder.add(1, null);
+		assertTrue(this.listContains(null));
+		this.listHolder.remove(1);
+		assertFalse(this.listContains(null));
+
+		this.listHolder.setListValues(new ArrayList<String>());
+		assertFalse(this.listContains("jar"));
+	}
+
+	public void testListChange1() {
+		this.listHolder.addChangeListener(this.buildChangeListener());
+		this.verifyListChange();
+	}
+
+	public void testListChange2() {
+		this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
+		this.verifyListChange();
+	}
+
+	private void verifyListChange() {
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.add(1, "joo");
+		this.verifyEvent(ADD, 1, "joo");
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.add(1, null);
+		this.verifyEvent(ADD, 1, null);
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.remove(1);
+		this.verifyEvent(REMOVE, 1, null);
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.remove(1);
+		this.verifyEvent(REMOVE, 1, "joo");
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.setListValues(this.buildList());
+		this.verifyEvent(CHANGE);
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.addAll(0, this.buildList());
+		this.verifyEvent(ADD);
+		assertEquals(this.buildList(), ListTools.list(((ListAddEvent) this.event).getItems()));
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.set(0, "joo");
+		this.verifyEvent(REPLACE);
+		assertFalse(IterableTools.contains(((ListReplaceEvent) this.event).getNewItems(), "foo"));
+		assertTrue(IterableTools.contains(((ListReplaceEvent) this.event).getNewItems(), "joo"));
+	}
+
+	private ListChangeListener buildListener() {
+		return new ListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {
+				SimpleListValueModelTests.this.eventType = ADD;
+				SimpleListValueModelTests.this.event = e;
+			}
+			@Override
+			public void itemsRemoved(ListRemoveEvent e) {
+				SimpleListValueModelTests.this.eventType = REMOVE;
+				SimpleListValueModelTests.this.event = e;
+			}
+			@Override
+			public void itemsReplaced(ListReplaceEvent e) {
+				SimpleListValueModelTests.this.eventType = REPLACE;
+				SimpleListValueModelTests.this.event = e;
+			}
+			@Override
+			public void itemsMoved(ListMoveEvent e) {
+				SimpleListValueModelTests.this.eventType = MOVE;
+				SimpleListValueModelTests.this.event = e;
+			}
+			@Override
+			public void listCleared(ListClearEvent e) {
+				SimpleListValueModelTests.this.eventType = CLEAR;
+				SimpleListValueModelTests.this.event = e;
+			}
+			@Override
+			public void listChanged(ListChangeEvent e) {
+				SimpleListValueModelTests.this.eventType = CHANGE;
+				SimpleListValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	private ChangeListener buildChangeListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {
+				SimpleListValueModelTests.this.eventType = ADD;
+				SimpleListValueModelTests.this.event = e;
+			}
+			@Override
+			public void itemsRemoved(ListRemoveEvent e) {
+				SimpleListValueModelTests.this.eventType = REMOVE;
+				SimpleListValueModelTests.this.event = e;
+			}
+			@Override
+			public void itemsReplaced(ListReplaceEvent e) {
+				SimpleListValueModelTests.this.eventType = REPLACE;
+				SimpleListValueModelTests.this.event = e;
+			}
+			@Override
+			public void itemsMoved(ListMoveEvent e) {
+				SimpleListValueModelTests.this.eventType = MOVE;
+				SimpleListValueModelTests.this.event = e;
+			}
+			@Override
+			public void listCleared(ListClearEvent e) {
+				SimpleListValueModelTests.this.eventType = CLEAR;
+				SimpleListValueModelTests.this.event = e;
+			}
+			@Override
+			public void listChanged(ListChangeEvent e) {
+				SimpleListValueModelTests.this.eventType = CHANGE;
+				SimpleListValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	private void verifyEvent(String e) {
+		assertEquals(e, this.eventType);
+		assertEquals(this.listHolder, this.event.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event.getListName());
+	}
+
+	private void verifyEvent(String e, int index, Object item) {
+		this.verifyEvent(e);
+		if (e == ADD) {
+			assertEquals(index, ((ListAddEvent) this.event).getIndex());
+			assertEquals(item, ((ListAddEvent) this.event).getItems().iterator().next());
+		} else if (e == REMOVE) {
+			assertEquals(index, ((ListRemoveEvent) this.event).getIndex());
+			assertEquals(item, ((ListRemoveEvent) this.event).getItems().iterator().next());
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SimplePropertyValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SimplePropertyValueModelTests.java
new file mode 100644
index 0000000..c454740
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SimplePropertyValueModelTests.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class SimplePropertyValueModelTests extends TestCase {
+
+	private ModifiablePropertyValueModel<String> objectHolder;
+	PropertyChangeEvent event;
+
+	public SimplePropertyValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.objectHolder = new SimplePropertyValueModel<String>("foo");
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testValue() {
+		assertEquals("foo", this.objectHolder.getValue());
+	}
+
+	public void testSetValue() {
+		this.objectHolder.setValue("bar");
+		assertEquals("bar", this.objectHolder.getValue());
+		this.objectHolder.setValue(null);
+		assertEquals(null, this.objectHolder.getValue());
+		this.objectHolder.setValue("baz");
+		assertEquals("baz", this.objectHolder.getValue());
+	}
+
+	public void testPropertyChange1() {
+		this.objectHolder.addChangeListener(this.buildListener());
+		this.verifyPropertyChange();
+	}
+
+	public void testPropertyChange2() {
+		this.objectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildListener());
+		this.verifyPropertyChange();
+	}
+
+	private void verifyPropertyChange() {
+		this.event = null;
+		this.objectHolder.setValue("bar");
+		this.verifyEvent("foo", "bar");
+
+		this.event = null;
+		this.objectHolder.setValue(null);
+		this.verifyEvent("bar", null);
+
+		this.event = null;
+		this.objectHolder.setValue("baz");
+		this.verifyEvent(null, "baz");
+	}
+
+	private ChangeListener buildListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				SimplePropertyValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	private void verifyEvent(Object oldValue, Object newValue) {
+		assertEquals(this.objectHolder, this.event.getSource());
+		assertEquals(PropertyValueModel.VALUE, this.event.getPropertyName());
+		assertEquals(oldValue, this.event.getOldValue());
+		assertEquals(newValue, this.event.getNewValue());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SortedListValueModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SortedListValueModelAdapterTests.java
new file mode 100644
index 0000000..c7a042c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SortedListValueModelAdapterTests.java
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.TreeSet;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ReverseComparator;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SortedListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class SortedListValueModelAdapterTests extends TestCase {
+	private SortedListValueModelAdapter<String> adapter;
+	private SimpleCollectionValueModel<String> wrappedCollectionHolder;
+	private Collection<String> wrappedCollection;
+
+
+	public SortedListValueModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.wrappedCollection = new HashBag<String>();
+		this.wrappedCollectionHolder = new SimpleCollectionValueModel<String>(this.wrappedCollection);
+		this.adapter = new SortedListValueModelAdapter<String>(this.wrappedCollectionHolder);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	private void verifyList(Collection<String> expected, ListValueModel<String> actual) {
+		this.verifyList(expected, actual, null);
+	}
+
+	private void verifyList(Collection<String> expected, ListValueModel<String> actual, Comparator<String> comparator) {
+		Collection<String> sortedSet = new TreeSet<String>(comparator);
+		sortedSet.addAll(expected);
+		List<String> expectedList = new ArrayList<String>(sortedSet);
+		List<String> actualList = ListTools.list(actual.iterator());
+		assertEquals(expectedList, actualList);
+	}
+
+	public void testAdd() {
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {/* OK */}
+			@Override
+			public void itemsReplaced(ListReplaceEvent e) {/* OK */}
+		});
+		this.wrappedCollectionHolder.add("foo");
+		this.wrappedCollectionHolder.add("bar");
+		this.wrappedCollectionHolder.add("baz");
+		assertEquals(3, this.adapter.size());
+		this.verifyList(this.wrappedCollection, this.adapter);
+	}
+
+	public void testAddItem() {
+		List<String> synchList = new CoordinatedList<String>(this.adapter);
+		Bag<String> synchCollection = new CoordinatedBag<String>(this.wrappedCollectionHolder);
+		this.wrappedCollectionHolder.add("foo");
+		assertTrue(this.wrappedCollection.contains("foo"));
+		this.wrappedCollectionHolder.add("bar");
+		this.wrappedCollectionHolder.add("baz");
+		this.wrappedCollectionHolder.add("joo");
+		this.wrappedCollectionHolder.add("jar");
+		this.wrappedCollectionHolder.add("jaz");
+		assertEquals(6, this.wrappedCollection.size());
+
+		this.verifyList(this.wrappedCollection, this.adapter);
+		assertEquals(this.wrappedCollection, CollectionTools.collection(synchList.iterator()));
+		assertEquals(this.wrappedCollection, synchCollection);
+	}
+
+	public void testRemoveItem() {
+		List<String> synchList = new CoordinatedList<String>(this.adapter);
+		Bag<String> synchCollection = new CoordinatedBag<String>(this.wrappedCollectionHolder);
+		this.wrappedCollectionHolder.add("foo");
+		this.wrappedCollectionHolder.add("bar");
+		this.wrappedCollectionHolder.add("baz");
+		this.wrappedCollectionHolder.add("joo");
+		this.wrappedCollectionHolder.add("jar");
+		this.wrappedCollectionHolder.add("jaz");
+		this.wrappedCollectionHolder.remove("jaz");
+		assertFalse(this.wrappedCollection.contains("jaz"));
+		this.wrappedCollectionHolder.remove("foo");
+		assertFalse(this.wrappedCollection.contains("foo"));
+		assertEquals(4, this.wrappedCollection.size());
+
+		this.verifyList(this.wrappedCollection, this.adapter);
+		assertEquals(this.wrappedCollection, CollectionTools.collection(synchList.iterator()));
+		assertEquals(this.wrappedCollection, synchCollection);
+	}
+
+	public void testListSynch() {
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {/* OK */}
+			@Override
+			public void itemsRemoved(ListRemoveEvent e) {/* OK */}
+			@Override
+			public void itemsReplaced(ListReplaceEvent e) {/* OK */}
+		});
+		this.wrappedCollectionHolder.add("foo");
+		this.wrappedCollectionHolder.add("bar");
+		this.wrappedCollectionHolder.add("baz");
+		this.wrappedCollectionHolder.add("joo");
+		this.wrappedCollectionHolder.add("jar");
+		this.wrappedCollectionHolder.add("jaz");
+		this.wrappedCollectionHolder.remove("jaz");
+		assertFalse(this.wrappedCollection.contains("jaz"));
+		this.wrappedCollectionHolder.remove("foo");
+		assertFalse(this.wrappedCollection.contains("foo"));
+		assertEquals(4, this.wrappedCollection.size());
+
+		this.verifyList(this.wrappedCollection, this.adapter);
+	}
+
+	public void testSetComparator() {
+		List<String> synchList = new CoordinatedList<String>(this.adapter);
+		Bag<String> synchCollection = new CoordinatedBag<String>(this.wrappedCollectionHolder);
+		this.wrappedCollectionHolder.add("foo");
+		assertTrue(this.wrappedCollection.contains("foo"));
+		this.wrappedCollectionHolder.add("bar");
+		this.wrappedCollectionHolder.add("baz");
+		this.wrappedCollectionHolder.add("joo");
+		this.wrappedCollectionHolder.add("jar");
+		this.wrappedCollectionHolder.add("jaz");
+		assertEquals(6, this.wrappedCollection.size());
+
+		this.verifyList(this.wrappedCollection, this.adapter);
+		assertEquals(this.wrappedCollection, CollectionTools.collection(synchList.iterator()));
+		assertEquals(this.wrappedCollection, synchCollection);
+
+		this.adapter.setComparator(new ReverseComparator<String>());
+		this.verifyList(this.wrappedCollection, this.adapter, new ReverseComparator<String>());
+		assertEquals(this.wrappedCollection, CollectionTools.collection(synchList.iterator()));
+		assertEquals(this.wrappedCollection, synchCollection);
+	}
+
+	public void testHasListeners() {
+		assertFalse(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		CoordinatedList<String> synchList = new CoordinatedList<String>(this.adapter);
+		assertTrue(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		this.adapter.removeListChangeListener(ListValueModel.LIST_VALUES, synchList);
+		assertFalse(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		ChangeListener cl = new ChangeAdapter();
+		this.adapter.addChangeListener(cl);
+		assertTrue(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		this.adapter.removeChangeListener(cl);
+		assertFalse(((AbstractModel) this.adapter).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	public void testCollectionChange() {
+		this.wrappedCollectionHolder.add("fred");
+		this.adapter.addListChangeListener(ListValueModel.LIST_VALUES, new TestListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {/* OK */}
+			@Override
+			public void itemsReplaced(ListReplaceEvent e) {/* OK */}
+		});
+		this.wrappedCollectionHolder.setValues(Arrays.asList(new String[] {"foo", "bar", "baz"}));
+		assertEquals(3, this.adapter.size());
+		this.verifyList(this.wrappedCollection, this.adapter);
+	}
+
+	class TestListChangeListener implements ListChangeListener {
+		@Override
+		public void itemsAdded(ListAddEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsRemoved(ListRemoveEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsReplaced(ListReplaceEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsMoved(ListMoveEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void listCleared(ListClearEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void listChanged(ListChangeEvent e) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SortedListValueModelWrapperTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SortedListValueModelWrapperTests.java
new file mode 100644
index 0000000..8a8ebb4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/SortedListValueModelWrapperTests.java
@@ -0,0 +1,244 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.TreeSet;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ReverseComparator;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SortedListValueModelWrapper;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class SortedListValueModelWrapperTests extends TestCase {
+	private List<String> list;
+	private SimpleListValueModel<String> listModel;
+	private SortedListValueModelWrapper<String> sortedListModel;
+
+
+	public SortedListValueModelWrapperTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.list = new ArrayList<String>();
+		this.listModel = new SimpleListValueModel<String>(this.list);
+		this.sortedListModel = new SortedListValueModelWrapper<String>(this.listModel);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	private void verifyList(Collection<String> expected, ListValueModel<String> actual) {
+		this.verifyList(expected, actual, null);
+	}
+
+	private void verifyList(Collection<String> expected, ListValueModel<String> actual, Comparator<String> comparator) {
+		Collection<String> sortedSet = new TreeSet<String>(comparator);
+		sortedSet.addAll(expected);
+		List<String> expectedList = new ArrayList<String>(sortedSet);
+		List<String> actualList = ListTools.list(actual);
+		assertEquals(expectedList, actualList);
+	}
+
+	public void testAdd() {
+		this.sortedListModel.addListChangeListener(ListValueModel.LIST_VALUES, new TestListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {/* OK */}
+			@Override
+			public void itemsReplaced(ListReplaceEvent e) {/* OK */}
+		});
+		this.listModel.add("foo");
+		this.listModel.add("bar");
+		this.listModel.add("baz");
+		assertEquals(3, this.sortedListModel.size());
+		this.verifyList(this.list, this.sortedListModel);
+	}
+
+	public void testAddItem() {
+		List<String> sortedSynchList = new CoordinatedList<String>(this.sortedListModel);
+		List<String> synchList = new CoordinatedList<String>(this.listModel);
+		this.listModel.add("foo");
+		assertTrue(this.list.contains("foo"));
+		this.listModel.add("bar");
+		this.listModel.add("baz");
+		this.listModel.add("joo");
+		this.listModel.add("jar");
+		this.listModel.add("jaz");
+		assertEquals(6, this.list.size());
+
+		this.verifyList(this.list, this.sortedListModel);
+		assertEquals(this.list, synchList);
+		assertEquals(ListTools.list(this.sortedListModel), sortedSynchList);
+	}
+
+	public void testRemoveItem() {
+		List<String> sortedSynchList = new CoordinatedList<String>(this.sortedListModel);
+		List<String> synchList = new CoordinatedList<String>(this.listModel);
+		this.listModel.add("foo");
+		this.listModel.add("bar");
+		this.listModel.add("baz");
+		this.listModel.add("joo");
+		this.listModel.add("jar");
+		this.listModel.add("jaz");
+		this.listModel.remove("jaz");
+		assertFalse(this.list.contains("jaz"));
+		this.listModel.remove("foo");
+		assertFalse(this.list.contains("foo"));
+		assertEquals(4, this.list.size());
+
+		this.verifyList(this.list, this.sortedListModel);
+		assertEquals(this.list, synchList);
+		assertEquals(ListTools.list(this.sortedListModel), sortedSynchList);
+	}
+
+	public void testReplaceItem() {
+		List<String> sortedSynchList = new CoordinatedList<String>(this.sortedListModel);
+		List<String> synchList = new CoordinatedList<String>(this.listModel);
+		this.listModel.add("foo");
+		assertTrue(this.list.contains("foo"));
+		this.listModel.add("bar");
+		this.listModel.add("baz");
+		this.listModel.add("joo");
+		this.listModel.add("jar");
+		this.listModel.add("jaz");
+		assertEquals(6, this.list.size());
+		this.listModel.set(3, "ttt");
+		this.listModel.set(4, "xxx");
+		assertTrue(this.list.contains("xxx"));
+
+		this.verifyList(this.list, this.sortedListModel);
+		assertEquals(this.list, synchList);
+		assertEquals(ListTools.list(this.sortedListModel), sortedSynchList);
+	}
+
+	public void testListSynch() {
+		this.sortedListModel.addListChangeListener(ListValueModel.LIST_VALUES, new TestListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {/* OK */}
+			@Override
+			public void itemsRemoved(ListRemoveEvent e) {/* OK */}
+			@Override
+			public void itemsReplaced(ListReplaceEvent e) {/* OK */}
+		});
+		this.listModel.add("foo");
+		this.listModel.add("bar");
+		this.listModel.add("baz");
+		this.listModel.add("joo");
+		this.listModel.add("jar");
+		this.listModel.add("jaz");
+		this.listModel.remove("jaz");
+		assertFalse(this.list.contains("jaz"));
+		this.listModel.remove("foo");
+		assertFalse(this.list.contains("foo"));
+		assertEquals(4, this.list.size());
+
+		this.verifyList(this.list, this.sortedListModel);
+	}
+
+	public void testSetComparator() {
+		List<String> sortedSynchList = new CoordinatedList<String>(this.sortedListModel);
+		List<String> synchList = new CoordinatedList<String>(this.listModel);
+		this.listModel.add("foo");
+		assertTrue(this.list.contains("foo"));
+		this.listModel.add("bar");
+		this.listModel.add("baz");
+		this.listModel.add("joo");
+		this.listModel.add("jar");
+		this.listModel.add("jaz");
+		assertEquals(6, this.list.size());
+
+		this.verifyList(this.list, this.sortedListModel);
+		assertEquals(this.list, synchList);
+		assertEquals(ListTools.list(this.sortedListModel), sortedSynchList);
+
+		this.sortedListModel.setComparator(new ReverseComparator<String>());
+		this.verifyList(this.list, this.sortedListModel, new ReverseComparator<String>());
+		assertEquals(this.list, synchList);
+	}
+
+	public void testHasListeners() {
+		assertFalse(((AbstractModel) this.sortedListModel).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		CoordinatedList<String> sortedSynchList = new CoordinatedList<String>(this.sortedListModel);
+		assertTrue(((AbstractModel) this.sortedListModel).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		this.sortedListModel.removeListChangeListener(ListValueModel.LIST_VALUES, sortedSynchList);
+		assertFalse(((AbstractModel) this.sortedListModel).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		ChangeListener cl = new ChangeAdapter();
+		this.sortedListModel.addChangeListener(cl);
+		assertTrue(((AbstractModel) this.sortedListModel).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		this.sortedListModel.removeChangeListener(cl);
+		assertFalse(((AbstractModel) this.sortedListModel).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	public void testListChange() {
+		this.listModel.add("fred");
+		this.sortedListModel.addListChangeListener(ListValueModel.LIST_VALUES, new TestListChangeListener() {
+			@Override
+			public void listChanged(ListChangeEvent e) {/* OK */}
+		});
+		this.listModel.setListValues(Arrays.asList(new String[] {"foo", "bar", "baz"}));
+		assertEquals(3, this.sortedListModel.size());
+		this.verifyList(this.list, this.sortedListModel);
+	}
+
+	class TestListChangeListener implements ListChangeListener {
+		@Override
+		public void itemsAdded(ListAddEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsRemoved(ListRemoveEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsReplaced(ListReplaceEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void itemsMoved(ListMoveEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void listCleared(ListClearEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void listChanged(ListChangeEvent e) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/StaticCollectionValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/StaticCollectionValueModelTests.java
new file mode 100644
index 0000000..6c3c539
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/StaticCollectionValueModelTests.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.Collection;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.StaticCollectionValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class StaticCollectionValueModelTests extends TestCase {
+
+	private static final Collection<String> COLLECTION = buildCollection();
+	private static Collection<String> buildCollection() {
+		Collection<String> result = new HashBag<String>();
+		result.add("foo");
+		result.add("bar");
+		return result;
+	}
+
+	private CollectionValueModel<String> collectionHolder;
+
+
+	public StaticCollectionValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.collectionHolder = this.buildCollectionHolder();
+	}
+
+	private CollectionValueModel<String> buildCollectionHolder() {
+		return new StaticCollectionValueModel<String>(COLLECTION);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testIterator() {
+		assertEquals(buildCollection(), CollectionTools.bag(this.collectionHolder.iterator()));
+	}
+
+	public void testSize() {
+		assertEquals(buildCollection().size(), this.collectionHolder.size());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/StaticListValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/StaticListValueModelTests.java
new file mode 100644
index 0000000..3604e0e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/StaticListValueModelTests.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.List;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.StaticListValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class StaticListValueModelTests extends TestCase {
+
+	private static final List<String> LIST = buildList();
+	private static List<String> buildList() {
+		List<String> result = new ArrayList<String>();
+		result.add("foo");
+		result.add("bar");
+		return result;
+	}
+
+	private ListValueModel<String> listHolder;
+
+
+	public StaticListValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.listHolder = new StaticListValueModel<String>(LIST);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testGet() {
+		List<String> expected = buildList();
+		for (int i = 0; i < this.listHolder.size(); i++) {
+			assertEquals(expected.get(i), this.listHolder.get(i));
+		}
+	}
+
+	public void testIterator() {
+		assertEquals(buildList(), ListTools.list(this.listHolder.listIterator()));
+	}
+
+	public void testSize() {
+		assertEquals(buildList().size(), this.listHolder.size());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/StaticValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/StaticValueModelTests.java
new file mode 100644
index 0000000..47cbf72
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/StaticValueModelTests.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.StaticPropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class StaticValueModelTests extends TestCase {
+	private PropertyValueModel<String> objectHolder;
+	private static final PropertyValueModel<String> OBJECT_HOLDER = new StaticPropertyValueModel<String>("foo");
+
+
+	public StaticValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.objectHolder = OBJECT_HOLDER;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testValue() {
+		assertEquals("foo", this.objectHolder.getValue());
+	}
+
+	public void testToString() {
+		assertTrue(this.objectHolder.toString().indexOf("foo") >= 0);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/TransformationListValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/TransformationListValueModelTests.java
new file mode 100644
index 0000000..68501b7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/TransformationListValueModelTests.java
@@ -0,0 +1,345 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.TransformationListValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+@SuppressWarnings("nls")
+public class TransformationListValueModelTests extends TestCase {
+
+	private SimpleListValueModel<String> listHolder;
+	private ListValueModel<String> transformedListHolder;
+	ListEvent event;
+	String eventType;
+
+	private static final String ADD = "add";
+	private static final String REMOVE = "remove";
+	private static final String REPLACE = "replace";
+	private static final String MOVE = "move";
+	private static final String CLEAR = "clear";
+	private static final String CHANGE = "change";
+
+
+	public TransformationListValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.listHolder = new SimpleListValueModel<String>(this.buildList());
+		this.transformedListHolder = this.buildTransformedListHolder(this.listHolder);
+	}
+
+	private List<String> buildList() {
+		List<String> result = new ArrayList<String>();
+		result.add("foo");
+		result.add("bar");
+		result.add("baz");
+		return result;
+	}
+
+	private List<String> buildTransformedList() {
+		return this.transform(this.buildList());
+	}
+
+	private List<String> transform(List<String> list) {
+		List<String> result = new ArrayList<String>(list.size());
+		for (String string : list) {
+			if (string == null) {
+				result.add(null);
+			} else {
+				result.add(string.toUpperCase());
+			}
+		}
+		return result;
+	}
+
+	private List<String> buildAddList() {
+		List<String> result = new ArrayList<String>();
+		result.add("joo");
+		result.add("jar");
+		result.add("jaz");
+		return result;
+	}
+
+	private List<String> buildTransformedAddList() {
+		return this.transform(this.buildAddList());
+	}
+
+//	private List<String> buildRemoveList() {
+//		List<String> result = new ArrayList<String>();
+//		result.add("foo");
+//		result.add("bar");
+//		return result;
+//	}
+//
+//	private List<String> buildTransformedRemoveList() {
+//		return this.transform(this.buildRemoveList());
+//	}
+//
+	ListValueModel<String> buildTransformedListHolder(ListValueModel<String> lvm) {
+		return new TransformationListValueModel<String, String>(lvm) {
+			@Override
+			protected String transformItem_(String s) {
+				return s.toUpperCase();
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testIterator() {
+		this.transformedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
+		assertEquals(this.buildTransformedList(), ListTools.list(this.transformedListHolder.iterator()));
+	}
+
+	public void testStaleValues() {
+		ListChangeListener listener = this.buildListener();
+		this.transformedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		assertEquals(this.buildTransformedList(), ListTools.list(this.transformedListHolder.iterator()));
+
+		this.transformedListHolder.removeListChangeListener(ListValueModel.LIST_VALUES, listener);
+		assertEquals(Collections.EMPTY_LIST, ListTools.list(this.transformedListHolder.iterator()));
+	}
+
+	public void testSize() {
+		this.transformedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
+		assertEquals(this.buildTransformedList().size(), IteratorTools.size(this.transformedListHolder.iterator()));
+	}
+
+	private boolean transformedListContains(Object item) {
+		return IteratorTools.contains(this.transformedListHolder.iterator(), item);
+	}
+
+	private boolean transformedListContainsAll(Collection<String> items) {
+		return IteratorTools.containsAll(this.transformedListHolder.iterator(), items);
+	}
+
+	private boolean transformedListContainsAny(Collection<String> items) {
+		List<String> transformedList = ListTools.list(this.transformedListHolder.iterator());
+		for (Iterator<String> stream = items.iterator(); stream.hasNext(); ) {
+			if (transformedList.contains(stream.next())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public void testAdd() {
+		this.transformedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
+
+		assertFalse(this.transformedListContains("JOO"));
+		this.listHolder.add(2, "joo");
+		assertTrue(this.transformedListContains("JOO"));
+
+		assertFalse(this.transformedListContains(null));
+		this.listHolder.add(0, null);
+		assertTrue(this.transformedListContains(null));
+	}
+
+	public void testAddAll() {
+		this.transformedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
+
+		assertFalse(this.transformedListContainsAny(this.buildTransformedAddList()));
+		this.listHolder.addAll(2, this.buildAddList());
+		assertTrue(this.transformedListContainsAll(this.buildTransformedAddList()));
+	}
+
+	public void testRemove() {
+		this.transformedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
+
+		assertTrue(this.transformedListContains("BAR"));
+		this.listHolder.remove(this.buildList().indexOf("bar"));
+		assertFalse(this.transformedListContains("BAR"));
+
+		this.listHolder.add(1, null);
+		assertTrue(this.transformedListContains(null));
+		this.listHolder.remove(1);
+		assertFalse(this.transformedListContains(null));
+	}
+
+	public void testListChangeGeneric() {
+		this.transformedListHolder.addChangeListener(this.buildListener());
+		this.verifyListChange();
+	}
+
+	public void testListChangeNamed() {
+		this.transformedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.buildListener());
+		this.verifyListChange();
+	}
+
+	private void verifyListChange() {
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.add(1, "joo");
+		this.verifyEvent(ADD, 1, "JOO");
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.add(1, null);
+		this.verifyEvent(ADD, 1, null);
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.remove(1);
+		this.verifyEvent(REMOVE, 1, null);
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.remove(1);
+		this.verifyEvent(REMOVE, 1, "JOO");
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.addAll(0, this.buildList());
+		this.verifyEvent(ADD);
+		assertEquals(this.buildTransformedList(), ListTools.list(((ListAddEvent) this.event).getItems()));
+
+		this.event = null;
+		this.eventType = null;
+		this.listHolder.set(0, "joo");
+		this.verifyEvent(REPLACE);
+		assertFalse(IterableTools.contains(((ListReplaceEvent) this.event).getNewItems(), "FOO"));
+		assertTrue(IterableTools.contains(((ListReplaceEvent) this.event).getNewItems(), "JOO"));
+	}
+
+	private ChangeListener buildListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void itemsAdded(ListAddEvent e) {
+				TransformationListValueModelTests.this.eventType = ADD;
+				TransformationListValueModelTests.this.event = e;
+			}
+			@Override
+			public void itemsRemoved(ListRemoveEvent e) {
+				TransformationListValueModelTests.this.eventType = REMOVE;
+				TransformationListValueModelTests.this.event = e;
+			}
+			@Override
+			public void itemsReplaced(ListReplaceEvent e) {
+				TransformationListValueModelTests.this.eventType = REPLACE;
+				TransformationListValueModelTests.this.event = e;
+			}
+			@Override
+			public void itemsMoved(ListMoveEvent e) {
+				TransformationListValueModelTests.this.eventType = MOVE;
+				TransformationListValueModelTests.this.event = e;
+			}
+			@Override
+			public void listCleared(ListClearEvent e) {
+				TransformationListValueModelTests.this.eventType = CLEAR;
+				TransformationListValueModelTests.this.event = e;
+			}
+			@Override
+			public void listChanged(ListChangeEvent e) {
+				TransformationListValueModelTests.this.eventType = CHANGE;
+				TransformationListValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	private void verifyEvent(String type) {
+		assertEquals(type, this.eventType);
+		assertEquals(this.transformedListHolder, this.event.getSource());
+		assertEquals(ListValueModel.LIST_VALUES, this.event.getListName());
+	}
+
+	private void verifyEvent(String type, int index, Object item) {
+		this.verifyEvent(type);
+		if (type == ADD) {
+			assertEquals(index, ((ListAddEvent) this.event).getIndex());
+			assertEquals(item, ((ListAddEvent) this.event).getItems().iterator().next());
+		} else if (type == REMOVE) {
+			assertEquals(index, ((ListRemoveEvent) this.event).getIndex());
+			assertEquals(item, ((ListRemoveEvent) this.event).getItems().iterator().next());
+		}
+	}
+
+	public void testHasListeners() {
+		/*
+		 * adding listeners to the transformed list will cause listeners
+		 * to be added to the wrapped list;
+		 * likewise, removing listeners from the transformed list will
+		 * cause listeners to be removed from the wrapped list
+		 */
+		assertFalse(((AbstractModel) this.listHolder).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		ChangeListener listener = this.buildListener();
+
+		this.transformedListHolder.addListChangeListener(ListValueModel.LIST_VALUES, listener);
+		assertTrue(((AbstractModel) this.listHolder).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		this.transformedListHolder.removeListChangeListener(ListValueModel.LIST_VALUES, listener);
+		assertFalse(((AbstractModel) this.listHolder).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		this.transformedListHolder.addChangeListener(listener);
+		assertTrue(((AbstractModel) this.listHolder).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		this.transformedListHolder.removeChangeListener(listener);
+		assertFalse(((AbstractModel) this.listHolder).hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+
+	/**
+	 * execute the same set of tests again, but by passing a Transformer to the adapter
+	 * (as opposed to overriding #transformItem(Object))
+	 */
+	public static class TransformerTests extends TransformationListValueModelTests {
+		public TransformerTests(String name) {
+			super(name);
+		}
+		@Override
+		ListValueModel<String> buildTransformedListHolder(ListValueModel<String> lvm) {
+			return new TransformationListValueModel<String, String>(lvm, this.buildTransformer());
+		}
+		private Transformer<String, String> buildTransformer() {
+			return new Transformer<String, String>() {
+				@Override
+				public String transform(String s) {
+					return (s == null) ? null : s.toUpperCase();
+				}
+			};
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/TransformationModifiablePropertyValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/TransformationModifiablePropertyValueModelTests.java
new file mode 100644
index 0000000..835fe0f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/TransformationModifiablePropertyValueModelTests.java
@@ -0,0 +1,265 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.TransformationModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+@SuppressWarnings("nls")
+public class TransformationModifiablePropertyValueModelTests
+	extends TestCase
+{
+	private ModifiablePropertyValueModel<Person> objectHolder;
+	PropertyChangeEvent event;
+
+	private ModifiablePropertyValueModel<Person> transformationObjectHolder;
+	PropertyChangeEvent transformationEvent;
+
+	public TransformationModifiablePropertyValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.objectHolder = new SimplePropertyValueModel<Person>(new Person("Karen", "Peggy", null));
+		this.transformationObjectHolder = new TransformationModifiablePropertyValueModel<Person, Person>(this.objectHolder, this.buildTransformer(), this.buildReverseTransformer());
+	}
+
+	private Transformer<Person, Person> buildTransformer() {
+		return new Transformer<Person, Person>() {
+			@Override
+			public Person transform(Person p) {
+				return (p == null) ? null : p.getParent();
+			}
+		};
+	}
+
+	private Transformer<Person, Person> buildReverseTransformer() {
+		return new Transformer<Person, Person>() {
+			@Override
+			public Person transform(Person p) {
+				return (p == null) ? null : p.getChild();
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testValue() {
+		ChangeListener listener = this.buildTransformationListener();
+		this.transformationObjectHolder.addChangeListener(listener);
+
+
+		Person person = this.objectHolder.getValue();
+		assertEquals("Karen", person.getName());
+		Person parent = this.transformationObjectHolder.getValue();
+		assertEquals(person.getParent().getName(), parent.getName());
+		assertNotSame(person.getParent(), this.transformationObjectHolder.getValue());
+		assertEquals(parent, this.transformationObjectHolder.getValue());
+
+		Person person1 = new Person("Matt", "Mitch", null);
+		this.objectHolder.setValue(person1);
+		Person parent2 = this.transformationObjectHolder.getValue();
+		assertEquals(person1.getParent().getName(), parent2.getName());
+		assertNotSame(person1.getParent(), this.transformationObjectHolder.getValue());
+		assertEquals(parent2, this.transformationObjectHolder.getValue());
+
+
+		this.objectHolder.setValue(null);
+		assertNull(this.objectHolder.getValue());
+		assertNull(this.transformationObjectHolder.getValue());
+
+		Person person3 = new Person("Karen", "Peggy", null);
+		this.objectHolder.setValue(person3);
+		assertEquals("Karen", person3.getName());
+		Person parent3 = this.transformationObjectHolder.getValue();
+		assertEquals(person3.getParent().getName(), parent3.getName());
+		assertNotSame(person3.getParent(), this.transformationObjectHolder.getValue());
+		assertEquals(parent3, this.transformationObjectHolder.getValue());
+	}
+
+	public void testSetValue() {
+		ChangeListener listener = this.buildTransformationListener();
+		this.transformationObjectHolder.addChangeListener(listener);
+
+		Person person = new Person("Chris", "Noel", null);
+		this.transformationObjectHolder.setValue(person.getParent());
+		assertEquals(person, this.objectHolder.getValue());
+		assertEquals(person.getParent().getName(), this.transformationObjectHolder.getValue().getName());
+		assertNotSame(person.getParent(), this.transformationObjectHolder.getValue());
+
+		Person person2 = new Person("Jon", "Elizabeth", null);
+		this.transformationObjectHolder.setValue(person2.getParent());
+		assertEquals(person2, this.objectHolder.getValue());
+		assertEquals(person2.getParent().getName(), this.transformationObjectHolder.getValue().getName());
+		assertNotSame(person2.getParent(), this.transformationObjectHolder.getValue());
+
+		this.transformationObjectHolder.setValue(null);
+		assertNull(this.objectHolder.getValue());
+		assertNull(this.transformationObjectHolder.getValue());
+
+		this.transformationObjectHolder.setValue(person.getParent());
+		assertEquals(person, this.objectHolder.getValue());
+		assertEquals(person.getParent().getName(), this.transformationObjectHolder.getValue().getName());
+		assertNotSame(person.getParent(), this.transformationObjectHolder.getValue());
+	}
+
+	public void testLazyListening() {
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		ChangeListener listener = this.buildTransformationListener();
+		this.transformationObjectHolder.addChangeListener(listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.transformationObjectHolder.removeChangeListener(listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.transformationObjectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.transformationObjectHolder.removePropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	public void testPropertyChange1() {
+		this.objectHolder.addChangeListener(this.buildListener());
+		this.transformationObjectHolder.addChangeListener(this.buildTransformationListener());
+		this.verifyPropertyChanges();
+	}
+
+	public void testPropertyChange2() {
+		this.objectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildListener());
+		this.transformationObjectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildTransformationListener());
+		this.verifyPropertyChanges();
+	}
+
+	private void verifyPropertyChanges() {
+		this.event = null;
+		this.transformationEvent = null;
+		Person oldPerson = this.objectHolder.getValue();
+		Person oldParent = this.transformationObjectHolder.getValue();
+		Person newPerson = new Person("Karen" , "Peggy", null);
+		this.objectHolder.setValue(newPerson);
+		Person newParent = this.transformationObjectHolder.getValue();
+		this.verifyEvent(this.event, this.objectHolder, oldPerson, newPerson);
+		this.verifyEvent(this.transformationEvent, this.transformationObjectHolder, oldParent, newParent);
+
+//
+//		this.event = null;
+//		this.transformationEvent = null;
+//		this.objectHolder.setValue("Foo");
+//		this.verifyEvent(this.event, this.objectHolder, "baz", "Foo");
+//		this.verifyEvent(this.transformationEvent, this.transformationObjectHolder, "BAZ", "FOO");
+//
+//		this.event = null;
+//		this.transformationEvent = null;
+//		this.objectHolder.setValue("FOO");
+//		this.verifyEvent(this.event, this.objectHolder, "Foo", "FOO");
+//		assertNull(this.transformationEvent);
+//
+//		this.event = null;
+//		this.transformationEvent = null;
+//		this.objectHolder.setValue(null);
+//		this.verifyEvent(this.event, this.objectHolder, "FOO", null);
+//		this.verifyEvent(this.transformationEvent, this.transformationObjectHolder, "FOO", null);
+//
+//		this.event = null;
+//		this.transformationEvent = null;
+//		this.objectHolder.setValue("bar");
+//		this.verifyEvent(this.event, this.objectHolder, null, "bar");
+//		this.verifyEvent(this.transformationEvent, this.transformationObjectHolder, null, "BAR");
+	}
+
+	private ChangeListener buildListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				TransformationModifiablePropertyValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	private ChangeListener buildTransformationListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				TransformationModifiablePropertyValueModelTests.this.transformationEvent = e;
+			}
+		};
+	}
+
+	private void verifyEvent(PropertyChangeEvent e, Object source, Object oldValue, Object newValue) {
+		assertEquals(source, e.getSource());
+		assertEquals(PropertyValueModel.VALUE, e.getPropertyName());
+		assertEquals(oldValue, e.getOldValue());
+		assertEquals(newValue, e.getNewValue());
+	}
+
+
+	class Person extends AbstractModel {
+
+		private String name;
+			public static final String NAME_PROPERTY = "name";
+
+		private String parentName;
+			public static final String PARENT_NAME_PROPERTY = "parentName";
+
+		private Person child;
+
+		public Person(String name, String parentName, Person child) {
+			this.name = name;
+			this.parentName = parentName;
+			this.child = child;
+		}
+
+		public String getName() {
+			return this.name;
+		}
+
+		public void setName(String newName) {
+			String oldName = this.name;
+			this.name = newName;
+			firePropertyChanged(NAME_PROPERTY, oldName, newName);
+		}
+
+		public Person getParent() {
+			return new Person(this.parentName, null, this);
+		}
+
+		public String getParentName() {
+			return this.parentName;
+		}
+
+		public void setParentName(String newParentName) {
+			String oldParentName = this.parentName;
+			this.parentName = newParentName;
+			firePropertyChanged(PARENT_NAME_PROPERTY, oldParentName, newParentName);
+		}
+
+		public Person getChild() {
+			return this.child;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/TransformationPropertyValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/TransformationPropertyValueModelTests.java
new file mode 100644
index 0000000..f1bcbb8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/TransformationPropertyValueModelTests.java
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.TransformationModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+@SuppressWarnings("nls")
+public class TransformationPropertyValueModelTests
+	extends TestCase
+{
+	private ModifiablePropertyValueModel<String> objectHolder;
+	PropertyChangeEvent event;
+
+	private ModifiablePropertyValueModel<String> transformationObjectHolder;
+	PropertyChangeEvent transformationEvent;
+
+	public TransformationPropertyValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.objectHolder = new SimplePropertyValueModel<String>("foo");
+		this.transformationObjectHolder = new TransformationModifiablePropertyValueModel<String, String>(this.objectHolder, this.buildTransformer(), this.buildReverseTransformer());
+	}
+
+	private Transformer<String, String> buildTransformer() {
+		return new Transformer<String, String>() {
+			@Override
+			public String transform(String s) {
+				return (s == null) ? null : s.toUpperCase();
+			}
+		};
+	}
+
+	private Transformer<String, String> buildReverseTransformer() {
+		return new Transformer<String, String>() {
+			@Override
+			public String transform(String s) {
+				return (s == null) ? null : s.toLowerCase();
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testValue() {
+		assertEquals("foo", this.objectHolder.getValue());
+		assertNull(this.transformationObjectHolder.getValue());
+		ChangeListener listener = this.buildTransformationListener();
+		this.transformationObjectHolder.addChangeListener(listener);
+		assertEquals("FOO", this.transformationObjectHolder.getValue());
+
+		this.objectHolder.setValue("bar");
+		assertEquals("bar", this.objectHolder.getValue());
+		assertEquals("BAR", this.transformationObjectHolder.getValue());
+
+		this.objectHolder.setValue("baz");
+		assertEquals("baz", this.objectHolder.getValue());
+		assertEquals("BAZ", this.transformationObjectHolder.getValue());
+
+		this.objectHolder.setValue(null);
+		assertNull(this.objectHolder.getValue());
+		assertNull(this.transformationObjectHolder.getValue());
+
+		this.objectHolder.setValue("foo");
+		assertEquals("foo", this.objectHolder.getValue());
+		assertEquals("FOO", this.transformationObjectHolder.getValue());
+	}
+
+	public void testSetValue() {
+		this.transformationObjectHolder.setValue("BAR");
+		assertEquals("bar", this.objectHolder.getValue());
+		assertEquals("BAR", this.transformationObjectHolder.getValue());
+
+		// NB: odd behavior(!)
+		this.transformationObjectHolder.setValue("Foo");
+		assertEquals("foo", this.objectHolder.getValue());
+		assertEquals("Foo", this.transformationObjectHolder.getValue());
+		ChangeListener listener = this.buildTransformationListener();
+		this.transformationObjectHolder.addChangeListener(listener);
+		assertEquals("FOO", this.transformationObjectHolder.getValue());
+		this.transformationObjectHolder.removeChangeListener(listener);
+
+		this.transformationObjectHolder.setValue(null);
+		assertNull(this.objectHolder.getValue());
+		assertNull(this.transformationObjectHolder.getValue());
+
+		// NB: odd behavior(!)
+		this.transformationObjectHolder.setValue("baz");
+		assertEquals("baz", this.objectHolder.getValue());
+		assertEquals("baz", this.transformationObjectHolder.getValue());
+		this.transformationObjectHolder.addChangeListener(listener);
+		assertEquals("BAZ", this.transformationObjectHolder.getValue());
+		this.transformationObjectHolder.removeChangeListener(listener);
+	}
+
+	public void testLazyListening() {
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+		ChangeListener listener = this.buildTransformationListener();
+		this.transformationObjectHolder.addChangeListener(listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.transformationObjectHolder.removeChangeListener(listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.transformationObjectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.transformationObjectHolder.removePropertyChangeListener(PropertyValueModel.VALUE, listener);
+		assertTrue(((AbstractModel) this.objectHolder).hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	public void testPropertyChange1() {
+		this.objectHolder.addChangeListener(this.buildListener());
+		this.transformationObjectHolder.addChangeListener(this.buildTransformationListener());
+		this.verifyPropertyChanges();
+	}
+
+	public void testPropertyChange2() {
+		this.objectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildListener());
+		this.transformationObjectHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.buildTransformationListener());
+		this.verifyPropertyChanges();
+	}
+
+	private void verifyPropertyChanges() {
+		this.event = null;
+		this.transformationEvent = null;
+		this.objectHolder.setValue("bar");
+		this.verifyEvent(this.event, this.objectHolder, "foo", "bar");
+		this.verifyEvent(this.transformationEvent, this.transformationObjectHolder, "FOO", "BAR");
+
+		this.event = null;
+		this.transformationEvent = null;
+		this.objectHolder.setValue("baz");
+		this.verifyEvent(this.event, this.objectHolder, "bar", "baz");
+		this.verifyEvent(this.transformationEvent, this.transformationObjectHolder, "BAR", "BAZ");
+
+		this.event = null;
+		this.transformationEvent = null;
+		this.objectHolder.setValue("Foo");
+		this.verifyEvent(this.event, this.objectHolder, "baz", "Foo");
+		this.verifyEvent(this.transformationEvent, this.transformationObjectHolder, "BAZ", "FOO");
+
+		this.event = null;
+		this.transformationEvent = null;
+		this.objectHolder.setValue("FOO");
+		this.verifyEvent(this.event, this.objectHolder, "Foo", "FOO");
+		assertNull(this.transformationEvent);
+
+		this.event = null;
+		this.transformationEvent = null;
+		this.objectHolder.setValue(null);
+		this.verifyEvent(this.event, this.objectHolder, "FOO", null);
+		this.verifyEvent(this.transformationEvent, this.transformationObjectHolder, "FOO", null);
+
+		this.event = null;
+		this.transformationEvent = null;
+		this.objectHolder.setValue("bar");
+		this.verifyEvent(this.event, this.objectHolder, null, "bar");
+		this.verifyEvent(this.transformationEvent, this.transformationObjectHolder, null, "BAR");
+	}
+
+	private ChangeListener buildListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				TransformationPropertyValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	private ChangeListener buildTransformationListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				TransformationPropertyValueModelTests.this.transformationEvent = e;
+			}
+		};
+	}
+
+	private void verifyEvent(PropertyChangeEvent e, Object source, Object oldValue, Object newValue) {
+		assertEquals(source, e.getSource());
+		assertEquals(PropertyValueModel.VALUE, e.getPropertyName());
+		assertEquals(oldValue, e.getOldValue());
+		assertEquals(newValue, e.getNewValue());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/UtilityModelValueTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/UtilityModelValueTests.java
new file mode 100644
index 0000000..3597486
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/UtilityModelValueTests.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.eclipse.persistence.tools.utility.tests.model.value.prefs.UtilityModelValuePrefsTests;
+import org.eclipse.persistence.tools.utility.tests.model.value.swing.UtilityModelValueSwingTests;
+
+public class UtilityModelValueTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(UtilityModelValueTests.class.getPackage().getName());
+
+		suite.addTest(UtilityModelValuePrefsTests.suite());
+		suite.addTest(UtilityModelValueSwingTests.suite());
+
+		suite.addTestSuite(BufferedModifiablePropertyValueModelTests.class);
+		suite.addTestSuite(CachingTransformationPropertyValueModelTests.class);
+		suite.addTestSuite(CollectionAspectAdapterTests.class);
+		suite.addTestSuite(CollectionListValueModelAdapterTests.class);
+		suite.addTestSuite(CollectionPropertyValueModelAdapterTests.class);
+		suite.addTestSuite(CompositeBooleanPropertyValueModelTests.class);
+		suite.addTestSuite(CompositeCollectionValueModelTests.class);
+		suite.addTestSuite(CompositeListValueModelTests.class);
+		suite.addTestSuite(CompositePropertyValueModelTests.class);
+		suite.addTestSuite(DoubleModifiablePropertyValueModelTests.class);
+		suite.addTestSuite(DoublePropertyValueModelTests.class);
+		suite.addTestSuite(ExtendedListValueModelWrapperTests.class);
+		suite.addTestSuite(FilteringCollectionValueModelTests.class);
+		suite.addTestSuite(FilteringPropertyValueModelTests.class);
+		suite.addTestSuite(ItemCollectionListValueModelAdapterTests.class);
+		suite.addTestSuite(ItemListListValueModelAdapterTests.class);
+		suite.addTestSuite(ItemPropertyListValueModelAdapterTests.class);
+		suite.addTestSuite(ItemStateListValueModelAdapterTests.class);
+		suite.addTestSuite(ListAspectAdapterTests.class);
+		suite.addTestSuite(ListCollectionValueModelAdapterTests.class);
+		suite.addTestSuite(ListCuratorTests.class);
+		suite.addTestSuite(NullCollectionValueModelTests.class);
+		suite.addTestSuite(NullListValueModelTests.class);
+		suite.addTestSuite(NullPropertyValueModelTests.class);
+		suite.addTestSuite(PropertyAspectAdapterTests.class);
+		suite.addTestSuite(PropertyCollectionValueModelAdapterTests.class);
+		suite.addTestSuite(PropertyListValueModelAdapterTests.class);
+		suite.addTestSuite(ReadOnlyModifiablePropertyValueModelWrapperTests.class);
+		suite.addTestSuite(SetCollectionValueModelTests.class);
+		suite.addTestSuite(SimpleCollectionValueModelTests.class);
+		suite.addTestSuite(SimpleListValueModelTests.class);
+		suite.addTestSuite(SimplePropertyValueModelTests.class);
+		suite.addTestSuite(SortedListValueModelAdapterTests.class);
+		suite.addTestSuite(SortedListValueModelWrapperTests.class);
+		suite.addTestSuite(StaticCollectionValueModelTests.class);
+		suite.addTestSuite(StaticListValueModelTests.class);
+		suite.addTestSuite(StaticValueModelTests.class);
+		suite.addTestSuite(TransformationListValueModelTests.class);
+		suite.addTestSuite(TransformationListValueModelTests.TransformerTests.class);
+		suite.addTestSuite(TransformationModifiablePropertyValueModelTests.class);
+		suite.addTestSuite(TransformationPropertyValueModelTests.class);
+		suite.addTestSuite(ValueCollectionAdapterTests.class);
+		suite.addTestSuite(ValueListAdapterTests.class);
+		suite.addTestSuite(ValuePropertyAdapterTests.class);
+		suite.addTestSuite(ValueStateAdapterTests.class);
+
+		return suite;
+	}
+
+	private UtilityModelValueTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ValueCollectionAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ValueCollectionAdapterTests.java
new file mode 100644
index 0000000..36552b1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ValueCollectionAdapterTests.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ValueCollectionAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class ValueCollectionAdapterTests extends TestCase {
+	private Junk junk;
+	private SimplePropertyValueModel<Junk> junkHolder;
+	private ValueCollectionAdapter<Junk> junkHolder2;
+
+
+	public ValueCollectionAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.junk = new Junk("foo");
+		this.junkHolder = new SimplePropertyValueModel<Junk>(this.junk);
+		this.junkHolder2 = new ValueCollectionAdapter<Junk>(this.junkHolder, Junk.STUFF_COLLECTION);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testWrappedPVM() {
+		Junk junk2 = new Junk("bar");
+		LocalListener l = new LocalListener(this.junkHolder2, this.junk, junk2);
+		this.junkHolder2.addChangeListener(l);
+		this.junkHolder.setValue(junk2);
+		assertTrue(l.eventReceived());
+	}
+
+	public void testHasPropertyChangeListeners() throws Exception {
+		assertFalse(this.junkHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertFalse(this.junkHolder2.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		LocalListener l = new LocalListener(this.junkHolder2, null, this.junk);
+		this.junkHolder2.addChangeListener(l);
+		assertTrue(this.junkHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(this.junkHolder2.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.junkHolder2.removeChangeListener(l);
+		assertFalse(this.junkHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertFalse(this.junkHolder2.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	public void testHasStateChangeListeners() throws Exception {
+		assertFalse(this.junk.hasAnyCollectionChangeListeners(Junk.STUFF_COLLECTION));
+		assertFalse(this.junkHolder2.hasAnyStateChangeListeners());
+
+		LocalListener l = new LocalListener(this.junkHolder2, null, this.junk);
+		this.junkHolder2.addStateChangeListener(l);
+		assertTrue(this.junk.hasAnyCollectionChangeListeners(Junk.STUFF_COLLECTION));
+		assertTrue(this.junkHolder2.hasAnyStateChangeListeners());
+
+		this.junkHolder2.removeStateChangeListener(l);
+		assertFalse(this.junk.hasAnyCollectionChangeListeners(Junk.STUFF_COLLECTION));
+		assertFalse(this.junkHolder2.hasAnyStateChangeListeners());
+	}
+
+	public void testCollectionAdd() {
+		LocalListener l = new LocalListener(this.junkHolder2);
+		this.junkHolder2.addStateChangeListener(l);
+		this.junk.addStuff("bar");
+		assertTrue(l.eventReceived());
+	}
+
+	public void testCollectionRemove() {
+		LocalListener l = new LocalListener(this.junkHolder2);
+		this.junkHolder2.addStateChangeListener(l);
+		this.junk.removeStuff("foo");
+		assertTrue(l.eventReceived());
+	}
+
+
+	class LocalListener extends ChangeAdapter {
+		private boolean eventReceived = false;
+		private final Object source;
+		private final Object oldValue;
+		private final Object newValue;
+		LocalListener(Object source) {
+			this(source, null, null);
+		}
+		LocalListener(Object source, Object oldValue, Object newValue) {
+			super();
+			this.source = source;
+			this.oldValue = oldValue;
+			this.newValue = newValue;
+		}
+		@Override
+		public void propertyChanged(PropertyChangeEvent e) {
+			this.eventReceived = true;
+			assertEquals(this.source, e.getSource());
+			assertEquals(this.oldValue, e.getOldValue());
+			assertEquals(this.newValue, e.getNewValue());
+			assertEquals(PropertyValueModel.VALUE, e.getPropertyName());
+		}
+		@Override
+		public void stateChanged(StateChangeEvent e) {
+			this.eventReceived = true;
+			assertEquals(this.source, e.getSource());
+		}
+		boolean eventReceived() {
+			return this.eventReceived;
+		}
+	}
+
+
+	private class Junk extends AbstractModel {
+		private Collection<String> stuff;
+			public static final String STUFF_COLLECTION = "stuff";
+
+		public Junk(String stuffItem) {
+			this.stuff = new ArrayList<String>();
+			this.stuff.add(stuffItem);
+		}
+
+		public void addStuff(String stuffItem) {
+			this.addItemToCollection(stuffItem, this.stuff, STUFF_COLLECTION);
+		}
+
+		public void removeStuff(String stuffItem) {
+			this.removeItemFromCollection(stuffItem, this.stuff, STUFF_COLLECTION);
+		}
+
+		@Override
+		public String toString() {
+			return "Junk(" + this.stuff + ")";
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ValueListAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ValueListAdapterTests.java
new file mode 100644
index 0000000..3fc09d8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ValueListAdapterTests.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import java.util.ArrayList;
+import java.util.List;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ValueListAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class ValueListAdapterTests extends TestCase {
+	private Junk junk;
+	private SimplePropertyValueModel<Junk> junkHolder;
+	private ValueListAdapter<Junk> junkHolder2;
+
+
+	public ValueListAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.junk = new Junk("foo");
+		this.junkHolder = new SimplePropertyValueModel<Junk>(this.junk);
+		this.junkHolder2 = new ValueListAdapter<Junk>(this.junkHolder, Junk.STUFF_LIST);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testWrappedPVM() {
+		Junk junk2 = new Junk("bar");
+		LocalListener l = new LocalListener(this.junkHolder2, this.junk, junk2);
+		this.junkHolder2.addChangeListener(l);
+		this.junkHolder.setValue(junk2);
+		assertTrue(l.eventReceived());
+	}
+
+	public void testHasPropertyChangeListeners() throws Exception {
+		assertFalse(this.junkHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertFalse(this.junkHolder2.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		LocalListener l = new LocalListener(this.junkHolder2, null, this.junk);
+		this.junkHolder2.addChangeListener(l);
+		assertTrue(this.junkHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(this.junkHolder2.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.junkHolder2.removeChangeListener(l);
+		assertFalse(this.junkHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertFalse(this.junkHolder2.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	public void testHasStateChangeListeners() throws Exception {
+		assertFalse(this.junk.hasAnyListChangeListeners(Junk.STUFF_LIST));
+		assertFalse(this.junkHolder2.hasAnyStateChangeListeners());
+
+		LocalListener l = new LocalListener(this.junkHolder2, null, this.junk);
+		this.junkHolder2.addStateChangeListener(l);
+		assertTrue(this.junk.hasAnyListChangeListeners(Junk.STUFF_LIST));
+		assertTrue(this.junkHolder2.hasAnyStateChangeListeners());
+
+		this.junkHolder2.removeStateChangeListener(l);
+		assertFalse(this.junk.hasAnyListChangeListeners(Junk.STUFF_LIST));
+		assertFalse(this.junkHolder2.hasAnyStateChangeListeners());
+	}
+
+	public void testListAdd() {
+		LocalListener l = new LocalListener(this.junkHolder2, null, this.junk);
+		this.junkHolder2.addStateChangeListener(l);
+		this.junk.addStuff("bar");
+		assertTrue(l.eventReceived());
+	}
+
+	public void testListRemove() {
+		LocalListener l = new LocalListener(this.junkHolder2, null, this.junk);
+		this.junkHolder2.addStateChangeListener(l);
+		this.junk.removeStuff("foo");
+		assertTrue(l.eventReceived());
+	}
+
+	public void testListReplace() {
+		LocalListener l = new LocalListener(this.junkHolder2, null, this.junk);
+		this.junkHolder2.addStateChangeListener(l);
+		this.junk.replaceStuff("foo", "bar");
+		assertTrue(l.eventReceived());
+	}
+
+
+	class LocalListener extends ChangeAdapter {
+		private boolean eventReceived = false;
+		private final Object source;
+		private final Object oldValue;
+		private final Object newValue;
+		LocalListener(Object source) {
+			this(source, null, null);
+		}
+		LocalListener(Object source, Object oldValue, Object newValue) {
+			super();
+			this.source = source;
+			this.oldValue = oldValue;
+			this.newValue = newValue;
+		}
+		@Override
+		public void propertyChanged(PropertyChangeEvent e) {
+			this.eventReceived = true;
+			assertEquals(this.source, e.getSource());
+			assertEquals(this.oldValue, e.getOldValue());
+			assertEquals(this.newValue, e.getNewValue());
+			assertEquals(PropertyValueModel.VALUE, e.getPropertyName());
+		}
+		@Override
+		public void stateChanged(StateChangeEvent e) {
+			this.eventReceived = true;
+			assertEquals(this.source, e.getSource());
+		}
+		boolean eventReceived() {
+			return this.eventReceived;
+		}
+	}
+
+	private class Junk extends AbstractModel {
+		private List<String> stuff;
+			public static final String STUFF_LIST = "stuff";
+
+		public Junk(String stuffItem) {
+			this.stuff = new ArrayList<String>();
+			this.stuff.add(stuffItem);
+		}
+
+		public void addStuff(String stuffItem) {
+			this.addItemToList(stuffItem, this.stuff, STUFF_LIST);
+		}
+
+		public void removeStuff(String stuffItem) {
+			this.removeItemFromList(stuffItem, this.stuff, STUFF_LIST);
+		}
+
+		public void replaceStuff(String oldStuffItem, String newStuffItem) {
+			this.replaceItemInList(oldStuffItem, newStuffItem, this.stuff, STUFF_LIST);
+		}
+
+		@Override
+		public String toString() {
+			return "Junk(" + this.stuff + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ValuePropertyAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ValuePropertyAdapterTests.java
new file mode 100644
index 0000000..3a70578
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ValuePropertyAdapterTests.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ValuePropertyAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class ValuePropertyAdapterTests extends TestCase {
+
+	private Junk junk;
+	private SimplePropertyValueModel<Junk> junkHolder;
+	private ValuePropertyAdapter<Junk> junkHolder2;
+
+	public ValuePropertyAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.junk = new Junk("foo");
+		this.junkHolder = new SimplePropertyValueModel<Junk>(this.junk);
+		this.junkHolder2 = new ValuePropertyAdapter<Junk>(this.junkHolder, Junk.NAME_PROPERTY);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testWrappedPVM() {
+		Junk junk2 = new Junk("bar");
+		LocalListener l = new LocalListener(this.junkHolder2, this.junk, junk2);
+		this.junkHolder2.addChangeListener(l);
+		this.junkHolder.setValue(junk2);
+		assertTrue(l.eventReceived());
+	}
+
+	public void testHasPropertyChangeListeners() throws Exception {
+		assertFalse(this.junkHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertFalse(this.junkHolder2.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		LocalListener l = new LocalListener(this.junkHolder2, null, this.junk);
+		this.junkHolder2.addChangeListener(l);
+		assertTrue(this.junkHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(this.junkHolder2.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.junkHolder2.removeChangeListener(l);
+		assertFalse(this.junkHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertFalse(this.junkHolder2.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	public void testHasStateChangeListeners() throws Exception {
+		assertFalse(this.junk.hasAnyPropertyChangeListeners(Junk.NAME_PROPERTY));
+		assertFalse(this.junkHolder2.hasAnyStateChangeListeners());
+
+		LocalListener l = new LocalListener(this.junkHolder2, null, this.junk);
+		this.junkHolder2.addStateChangeListener(l);
+		assertTrue(this.junk.hasAnyPropertyChangeListeners(Junk.NAME_PROPERTY));
+		assertTrue(this.junkHolder2.hasAnyStateChangeListeners());
+
+		this.junkHolder2.removeStateChangeListener(l);
+		assertFalse(this.junk.hasAnyPropertyChangeListeners(Junk.NAME_PROPERTY));
+		assertFalse(this.junkHolder2.hasAnyStateChangeListeners());
+	}
+
+	public void testChangeProperty() {
+		LocalListener l = new LocalListener(this.junkHolder2, null, this.junk);
+		this.junkHolder2.addStateChangeListener(l);
+		this.junk.setName("bar");
+		assertTrue(l.eventReceived());
+	}
+
+
+	class LocalListener extends ChangeAdapter {
+		private boolean eventReceived = false;
+		private final Object source;
+		private final Object oldValue;
+		private final Object newValue;
+		LocalListener(Object source) {
+			this(source, null, null);
+		}
+		LocalListener(Object source, Object oldValue, Object newValue) {
+			super();
+			this.source = source;
+			this.oldValue = oldValue;
+			this.newValue = newValue;
+		}
+		@Override
+		public void propertyChanged(PropertyChangeEvent e) {
+			this.eventReceived = true;
+			assertEquals(this.source, e.getSource());
+			assertEquals(this.oldValue, e.getOldValue());
+			assertEquals(this.newValue, e.getNewValue());
+			assertEquals(PropertyValueModel.VALUE, e.getPropertyName());
+		}
+		@Override
+		public void stateChanged(StateChangeEvent e) {
+			this.eventReceived = true;
+			assertEquals(this.source, e.getSource());
+		}
+		boolean eventReceived() {
+			return this.eventReceived;
+		}
+	}
+
+	class Junk extends AbstractModel {
+		private String name;
+			public static final String NAME_PROPERTY = "name";
+
+		public Junk(String name) {
+			this.name = name;
+		}
+
+		public void setName(String name) {
+			String old = this.name;
+			this.name = name;
+			this.firePropertyChanged(NAME_PROPERTY, old, name);
+		}
+
+		@Override
+		public String toString() {
+			return "Junk(" + this.name + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ValueStateAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ValueStateAdapterTests.java
new file mode 100644
index 0000000..8f81396
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/ValueStateAdapterTests.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ValueStateAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class ValueStateAdapterTests extends TestCase {
+
+	private Junk junk;
+	private SimplePropertyValueModel<Junk> junkHolder;
+	private ValueStateAdapter<Junk> junkHolder2;
+
+	public ValueStateAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.junk = new Junk("foo");
+		this.junkHolder = new SimplePropertyValueModel<Junk>(this.junk);
+		this.junkHolder2 = new ValueStateAdapter<Junk>(this.junkHolder);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testWrappedPVM() {
+		Junk junk2 = new Junk("bar");
+		LocalListener l = new LocalListener(this.junkHolder2, this.junk, junk2);
+		this.junkHolder2.addChangeListener(l);
+		this.junkHolder.setValue(junk2);
+		assertTrue(l.eventReceived());
+	}
+
+	public void testHasPropertyChangeListeners() throws Exception {
+		assertFalse(this.junkHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertFalse(this.junkHolder2.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		LocalListener l = new LocalListener(this.junkHolder2, null, this.junk);
+		this.junkHolder2.addChangeListener(l);
+		assertTrue(this.junkHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(this.junkHolder2.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		this.junkHolder2.removeChangeListener(l);
+		assertFalse(this.junkHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertFalse(this.junkHolder2.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	public void testHasStateChangeListeners() throws Exception {
+		assertFalse(this.junk.hasAnyStateChangeListeners());
+		assertFalse(this.junkHolder2.hasAnyStateChangeListeners());
+
+		LocalListener l = new LocalListener(this.junkHolder2, null, this.junk);
+		this.junkHolder2.addStateChangeListener(l);
+		assertTrue(this.junk.hasAnyStateChangeListeners());
+		assertTrue(this.junkHolder2.hasAnyStateChangeListeners());
+
+		this.junkHolder2.removeStateChangeListener(l);
+		assertFalse(this.junk.hasAnyStateChangeListeners());
+		assertFalse(this.junkHolder2.hasAnyStateChangeListeners());
+	}
+
+	public void testChangeState() {
+		LocalListener l = new LocalListener(this.junkHolder2, null, this.junk);
+		this.junkHolder2.addChangeListener(l);
+		this.junkHolder2.addStateChangeListener(l);
+		this.junk.setName("bar");
+		assertTrue(l.eventReceived());
+	}
+
+
+	class LocalListener extends ChangeAdapter {
+		private boolean eventReceived = false;
+		private final Object source;
+		private final Object oldValue;
+		private final Object newValue;
+		LocalListener(Object source) {
+			this(source, null, null);
+		}
+		LocalListener(Object source, Object oldValue, Object newValue) {
+			super();
+			this.source = source;
+			this.oldValue = oldValue;
+			this.newValue = newValue;
+		}
+		@Override
+		public void propertyChanged(PropertyChangeEvent e) {
+			this.eventReceived = true;
+			assertEquals(this.source, e.getSource());
+			assertEquals(this.oldValue, e.getOldValue());
+			assertEquals(this.newValue, e.getNewValue());
+			assertEquals(PropertyValueModel.VALUE, e.getPropertyName());
+		}
+		@Override
+		public void stateChanged(StateChangeEvent e) {
+			this.eventReceived = true;
+			assertEquals(this.source, e.getSource());
+		}
+		boolean eventReceived() {
+			return this.eventReceived;
+		}
+	}
+
+	class Junk extends AbstractModel {
+		private String name;
+			public static final String NAME_PROPERTY = "name";
+
+		public Junk(String name) {
+			this.name = name;
+		}
+
+		public void setName(String name) {
+			this.name = name;
+			this.fireStateChanged();
+		}
+
+		@Override
+		public String toString() {
+			return "Junk(" + this.name + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/prefs/PreferencePropertyValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/prefs/PreferencePropertyValueModelTests.java
new file mode 100644
index 0000000..636187e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/prefs/PreferencePropertyValueModelTests.java
@@ -0,0 +1,418 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.prefs;
+
+import java.util.prefs.NodeChangeEvent;
+import java.util.prefs.NodeChangeListener;
+import java.util.prefs.PreferenceChangeEvent;
+import java.util.prefs.PreferenceChangeListener;
+import java.util.prefs.Preferences;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.prefs.PreferencePropertyValueModel;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+@SuppressWarnings("nls")
+public class PreferencePropertyValueModelTests extends PreferencesTestCase {
+	private ModifiablePropertyValueModel<Preferences> nodeHolder;
+	PreferencePropertyValueModel<String> preferenceAdapter;
+	PropertyChangeEvent event;
+	PropertyChangeListener listener;
+	boolean listenerRemoved = false;
+	PreferenceChangeEvent preferenceEvent;
+	private static final String KEY_NAME = "foo";
+	private static final String STRING_VALUE = "original string value";
+
+	public PreferencePropertyValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.testNode.put(KEY_NAME, STRING_VALUE);
+
+		this.nodeHolder = new SimplePropertyValueModel<Preferences>(this.testNode);
+		this.preferenceAdapter = PreferencePropertyValueModel.forString(this.nodeHolder, KEY_NAME, null);
+		this.listener = this.buildValueChangeListener();
+		this.preferenceAdapter.addPropertyChangeListener(PropertyValueModel.VALUE, this.listener);
+		this.event = null;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		super.tearDown();
+	}
+
+	private PropertyChangeListener buildValueChangeListener() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				if (PreferencePropertyValueModelTests.this.event != null) {
+					throw new IllegalStateException("unexpected this.event: " + e);
+				}
+				PreferencePropertyValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	public void testSubjectHolder() throws Exception {
+		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
+		assertNull(this.event);
+
+		String ANOTHER_STRING_VALUE = "some other value";
+		Preferences anotherNode = this.classNode.node("another test node");
+		anotherNode.put(KEY_NAME, ANOTHER_STRING_VALUE);
+
+		this.nodeHolder.setValue(anotherNode);
+		this.verifyEvent(STRING_VALUE, ANOTHER_STRING_VALUE);
+		assertEquals(ANOTHER_STRING_VALUE, this.preferenceAdapter.getValue());
+
+		this.event = null;
+		this.nodeHolder.setValue(null);
+		this.verifyEvent(ANOTHER_STRING_VALUE, null);
+		assertNull(this.preferenceAdapter.getValue());
+
+		this.event = null;
+		this.nodeHolder.setValue(this.testNode);
+		this.verifyEvent(null, STRING_VALUE);
+		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
+	}
+
+	public void testPreferenceChange() throws Exception {
+		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
+		assertNull(this.event);
+
+		this.testNode.put(KEY_NAME, STRING_VALUE + STRING_VALUE);
+		this.waitForEventQueueToClear();
+		this.verifyEvent(STRING_VALUE, STRING_VALUE + STRING_VALUE);
+		assertEquals(STRING_VALUE + STRING_VALUE, this.preferenceAdapter.getValue());
+
+		this.event = null;
+		this.testNode.remove(KEY_NAME);
+		this.waitForEventQueueToClear();
+		this.verifyEvent(STRING_VALUE + STRING_VALUE, null);
+		assertNull(this.preferenceAdapter.getValue());
+
+		this.event = null;
+		this.testNode.put(KEY_NAME, STRING_VALUE);
+		this.waitForEventQueueToClear();
+		this.verifyEvent(null, STRING_VALUE);
+		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
+	}
+
+	public void testValue() throws Exception {
+		assertEquals(STRING_VALUE, this.testNode.get(KEY_NAME, "<missing preference>"));
+		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
+	}
+
+	public void testSetValue() throws Exception {
+		String ANOTHER_STRING_VALUE = "some other value";
+		this.preferenceAdapter.setValue(ANOTHER_STRING_VALUE);
+		assertEquals(ANOTHER_STRING_VALUE, this.preferenceAdapter.getValue());
+		assertEquals(ANOTHER_STRING_VALUE, this.testNode.get(KEY_NAME, "<missing preference>"));
+	}
+
+	public void testHasListeners() throws Exception {
+		assertTrue(this.preferenceAdapter.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(this.nodeHasAnyPrefListeners(this.testNode));
+		this.preferenceAdapter.removePropertyChangeListener(PropertyValueModel.VALUE, this.listener);
+		assertFalse(this.nodeHasAnyPrefListeners(this.testNode));
+		assertFalse(this.preferenceAdapter.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		ChangeListener listener2 = this.buildChangeListener();
+		this.preferenceAdapter.addChangeListener(listener2);
+		assertTrue(this.preferenceAdapter.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		assertTrue(this.nodeHasAnyPrefListeners(this.testNode));
+		this.preferenceAdapter.removeChangeListener(listener2);
+		assertFalse(this.nodeHasAnyPrefListeners(this.testNode));
+		assertFalse(this.preferenceAdapter.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	private ChangeListener buildChangeListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				if (PreferencePropertyValueModelTests.this.event != null) {
+					throw new IllegalStateException("unexpected this.event: " + e);
+				}
+				PreferencePropertyValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	public void testRemoveAndReAddPreference() throws Exception {
+		assertEquals(STRING_VALUE, this.testNode.get(KEY_NAME, null));
+		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
+		assertNull(this.event);
+
+		// remove the preference entirely...
+		this.testNode.remove(KEY_NAME);
+		this.waitForEventQueueToClear();
+		assertNull(this.testNode.get(KEY_NAME, null));
+		this.verifyEvent(STRING_VALUE, null);
+		assertNull(this.preferenceAdapter.getValue());
+
+		// ...then re-add it with the same key
+		this.event = null;
+		this.testNode.put(KEY_NAME, STRING_VALUE);
+		this.waitForEventQueueToClear();
+		assertEquals(STRING_VALUE, this.testNode.get(KEY_NAME, null));
+		this.verifyEvent(null, STRING_VALUE);
+		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
+	}
+
+	public void testDefaultValue() throws Exception {
+		// rebuild the adapter with a default value
+		String DEFAULT_VALUE = "default value";
+		this.preferenceAdapter.removePropertyChangeListener(PropertyValueModel.VALUE, this.listener);
+		this.preferenceAdapter = PreferencePropertyValueModel.forString(this.nodeHolder, KEY_NAME, DEFAULT_VALUE);
+		this.preferenceAdapter.addPropertyChangeListener(PropertyValueModel.VALUE, this.listener);
+
+		assertEquals(STRING_VALUE, this.testNode.get(KEY_NAME, null));
+		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
+		assertNull(this.event);
+
+		// remove the preference entirely...
+		this.testNode.remove(KEY_NAME);
+		this.waitForEventQueueToClear();
+		assertNull(this.testNode.get(KEY_NAME, null));
+		this.verifyEvent(STRING_VALUE, DEFAULT_VALUE);
+		assertEquals(DEFAULT_VALUE, this.preferenceAdapter.getValue());
+
+		// ...then re-add it with the same key
+		this.event = null;
+		this.testNode.put(KEY_NAME, STRING_VALUE);
+		this.waitForEventQueueToClear();
+		assertEquals(STRING_VALUE, this.testNode.get(KEY_NAME, null));
+		this.verifyEvent(DEFAULT_VALUE, STRING_VALUE);
+		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
+	}
+
+	public void testUnsynchronizedValue() throws Exception {
+		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
+		assertNull(this.event);
+
+		// remove the this.listener so the adapter no longer listens to the preference
+		this.preferenceAdapter.removePropertyChangeListener(PropertyValueModel.VALUE, this.listener);
+
+		this.testNode.put(KEY_NAME, STRING_VALUE + STRING_VALUE);
+		this.waitForEventQueueToClear();
+		// no this.event should have been fired...
+		assertNull(this.event);
+		// ...and the adapter's value should be null
+		assertNull(this.preferenceAdapter.getValue());
+
+		this.testNode.remove(KEY_NAME);
+		this.waitForEventQueueToClear();
+		assertNull(this.event);
+		assertNull(this.preferenceAdapter.getValue());
+
+		this.testNode.put(KEY_NAME, STRING_VALUE);
+		this.waitForEventQueueToClear();
+		assertNull(this.event);
+		assertNull(this.preferenceAdapter.getValue());
+
+		// add the this.listener so the adapter synchs
+		this.preferenceAdapter.addPropertyChangeListener(PropertyValueModel.VALUE, this.listener);
+		assertEquals(STRING_VALUE, this.preferenceAdapter.getValue());
+	}
+
+	public void testIntegerPreference() throws Exception {
+		// stop listening to the node and convert it to an integer
+		this.preferenceAdapter.removePropertyChangeListener(PropertyValueModel.VALUE, this.listener);
+
+		PreferencePropertyValueModel<Integer> integerPreferenceAdapter = PreferencePropertyValueModel.forInteger(this.nodeHolder, KEY_NAME, 0);
+		this.testNode.putInt(KEY_NAME, 123);
+		integerPreferenceAdapter = PreferencePropertyValueModel.forInteger(this.testNode, KEY_NAME, 0);
+		integerPreferenceAdapter.addPropertyChangeListener(PropertyValueModel.VALUE, this.listener);
+		assertEquals(new Integer(123), integerPreferenceAdapter.getValue());
+		assertNull(this.event);
+
+		this.testNode.putInt(KEY_NAME, 246);
+		this.waitForEventQueueToClear();
+		this.verifyEvent(integerPreferenceAdapter, new Integer(123), new Integer(246));
+		assertEquals(new Integer(246), integerPreferenceAdapter.getValue());
+
+		this.event = null;
+		this.testNode.remove(KEY_NAME);
+		this.waitForEventQueueToClear();
+		this.verifyEvent(integerPreferenceAdapter, new Integer(246), new Integer(0));
+		assertEquals(new Integer(0), integerPreferenceAdapter.getValue());
+
+		this.event = null;
+		this.testNode.putInt(KEY_NAME, 123);
+		this.waitForEventQueueToClear();
+		this.verifyEvent(integerPreferenceAdapter, new Integer(0), new Integer(123));
+		assertEquals(new Integer(123), integerPreferenceAdapter.getValue());
+	}
+
+	/**
+	 * test a situation where
+	 * - we are listening to the node when it gets removed from the preferences "repository"
+	 * - we get notification that it has been removed
+	 * - we try to remove our this.listener
+	 * - the node will throw an IllegalStateException - the adapter should handle it OK...
+	 */
+	public void testRemoveNode() throws Exception {
+		assertTrue(this.preferenceAdapter.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		Preferences parent = this.testNode.parent();
+		parent.addNodeChangeListener(this.buildParentNodeChangeListener());
+		this.testNode.removeNode();
+		this.testNode.flush();		// this seems to be required for the this.event to trigger...
+		this.waitForEventQueueToClear();
+
+		assertTrue(this.listenerRemoved);
+		assertTrue(this.preferenceAdapter.hasNoPropertyChangeListeners(PropertyValueModel.VALUE));
+	}
+
+	private NodeChangeListener buildParentNodeChangeListener() {
+		return new NodeChangeListener() {
+			@Override
+			public void childAdded(NodeChangeEvent e) {
+				throw new IllegalStateException("unexpected this.event: " + e);
+			}
+			@Override
+			public void childRemoved(NodeChangeEvent e) {
+				if (e.getChild() == PreferencePropertyValueModelTests.this.testNode) {
+					PreferencePropertyValueModelTests.this.preferenceAdapter.removePropertyChangeListener(PropertyValueModel.VALUE, PreferencePropertyValueModelTests.this.listener);
+					// this line of code will not execute if the line above triggers an exception
+					PreferencePropertyValueModelTests.this.listenerRemoved = true;
+				}
+			}
+		};
+	}
+
+	public void testSetSameValue() {
+		assertNull(this.event);
+		assertNull(this.preferenceEvent);
+		this.testNode.addPreferenceChangeListener(this.buildPreferenceChangeListener());
+
+		String ANOTHER_STRING_VALUE = "some other value";
+		this.preferenceAdapter.setValue(ANOTHER_STRING_VALUE);
+
+		this.verifyEvent(STRING_VALUE, ANOTHER_STRING_VALUE);
+		this.waitForEventQueueToClear();
+		this.verifyPreferenceEvent(ANOTHER_STRING_VALUE);
+
+		// now set to *same* value - nothing should happen...
+		this.event = null;
+		this.preferenceEvent = null;
+		this.preferenceAdapter.setValue(ANOTHER_STRING_VALUE);
+
+		assertNull(this.event);
+		assertNull(this.preferenceEvent);
+	}
+
+	public void testSetSameValueForcePassThrough() throws Exception {
+		assertNull(this.event);
+		assertNull(this.preferenceEvent);
+
+		this.preferenceAdapter.removePropertyChangeListener(PropertyValueModel.VALUE, this.listener);
+		this.preferenceAdapter = AlwaysUpdatePreferencePropertyValueModel.forString(this.nodeHolder, KEY_NAME, null);
+		this.preferenceAdapter.addPropertyChangeListener(PropertyValueModel.VALUE, this.listener);
+
+		this.testNode.addPreferenceChangeListener(this.buildPreferenceChangeListener());
+
+		String ANOTHER_STRING_VALUE = "some other value";
+		this.preferenceAdapter.setValue(ANOTHER_STRING_VALUE);
+
+		this.verifyEvent(STRING_VALUE, ANOTHER_STRING_VALUE);
+		this.waitForEventQueueToClear();
+		this.verifyPreferenceEvent(ANOTHER_STRING_VALUE);
+
+		// now set to *same* value - only one this.event should fire
+		this.event = null;
+		this.preferenceEvent = null;
+		this.preferenceAdapter.setValue(ANOTHER_STRING_VALUE);
+
+		assertNull(this.event);
+		this.waitForEventQueueToClear();
+		this.verifyPreferenceEvent(ANOTHER_STRING_VALUE);
+		assertNull(this.event);
+	}
+
+	private PreferenceChangeListener buildPreferenceChangeListener() {
+		return new PreferenceChangeListener() {
+			@Override
+			public void preferenceChange(PreferenceChangeEvent evt) {
+				PreferencePropertyValueModelTests.this.preferenceEvent = evt;
+			}
+		};
+	}
+
+	private void verifyEvent(Model source, Object oldValue, Object newValue) {
+		assertNotNull(this.event);
+		assertEquals(source, this.event.getSource());
+		assertEquals(PropertyValueModel.VALUE, this.event.getPropertyName());
+		assertEquals(oldValue, this.event.getOldValue());
+		assertEquals(newValue, this.event.getNewValue());
+	}
+
+	private void verifyEvent(Object oldValue, Object newValue) {
+		this.verifyEvent(this.preferenceAdapter, oldValue, newValue);
+	}
+
+	private void verifyPreferenceEvent(Object newValue) {
+		assertNotNull(this.preferenceEvent);
+		assertEquals(this.testNode, this.preferenceEvent.getSource());
+		assertEquals(KEY_NAME, this.preferenceEvent.getKey());
+		assertEquals(newValue, this.preferenceEvent.getNewValue());
+		assertEquals(newValue, this.testNode.get(KEY_NAME, "<missing preference>"));
+	}
+
+	private boolean nodeHasAnyPrefListeners(Preferences node) throws Exception {
+		PreferenceChangeListener[] prefListeners = (PreferenceChangeListener[]) ObjectTools.get(node, "prefListeners");
+		return prefListeners.length > 0;
+	}
+
+
+	/**
+	 * Use this adapter to test out always passing through the new value
+	 * to the preference.
+	 */
+	/* CU private */ static class AlwaysUpdatePreferencePropertyValueModel<P>
+		extends PreferencePropertyValueModel<P>
+	{
+		public static PreferencePropertyValueModel<String> forString(PropertyValueModel<? extends Preferences> preferencesModel, String key, String defaultValue) {
+			return new AlwaysUpdatePreferencePropertyValueModel<String>(
+					preferencesModel,
+					key,
+					defaultValue,
+					Transformer.Non.<String>instance()
+				);
+		}
+
+		AlwaysUpdatePreferencePropertyValueModel(
+				PropertyValueModel<? extends Preferences> preferencesModel,
+				String key,
+				P defaultValue,
+				Transformer<String, P> stringTransformer) {
+			super(preferencesModel, key, defaultValue, stringTransformer);
+		}
+
+		@Override
+		protected boolean preferenceIsToBeSet(Object oldValue, Object newValue) {
+			return true;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/prefs/PreferencesCollectionValueModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/prefs/PreferencesCollectionValueModelTests.java
new file mode 100644
index 0000000..1f9f4d0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/prefs/PreferencesCollectionValueModelTests.java
@@ -0,0 +1,334 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.prefs;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.prefs.NodeChangeEvent;
+import java.util.prefs.NodeChangeListener;
+import java.util.prefs.PreferenceChangeListener;
+import java.util.prefs.Preferences;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.prefs.PreferencePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.prefs.PreferencesCollectionValueModel;
+
+@SuppressWarnings("nls")
+public class PreferencesCollectionValueModelTests extends PreferencesTestCase {
+	private Map<String, String> expectedValues;
+	private ModifiablePropertyValueModel<Preferences> nodeHolder;
+	PreferencesCollectionValueModel<String> preferencesAdapter;
+	CollectionEvent event;
+	CollectionChangeListener listener;
+	private PropertyChangeListener itemListener;
+	boolean listenerRemoved = false;
+	private static final String KEY_NAME_1 = "foo 1";
+	private static final String KEY_NAME_2 = "foo 2";
+	private static final String KEY_NAME_3 = "foo 3";
+	private static final String STRING_VALUE_1 = "original string value 1";
+	private static final String STRING_VALUE_2 = "original string value 2";
+	private static final String STRING_VALUE_3 = "original string value 3";
+
+	public PreferencesCollectionValueModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.expectedValues = new HashMap<String, String>();
+		this.testNode.put(KEY_NAME_1, STRING_VALUE_1);	this.expectedValues.put(KEY_NAME_1, STRING_VALUE_1);
+		this.testNode.put(KEY_NAME_2, STRING_VALUE_2);	this.expectedValues.put(KEY_NAME_2, STRING_VALUE_2);
+		this.testNode.put(KEY_NAME_3, STRING_VALUE_3);	this.expectedValues.put(KEY_NAME_3, STRING_VALUE_3);
+
+		this.nodeHolder = new SimplePropertyValueModel<Preferences>(this.testNode);
+		this.preferencesAdapter = new PreferencesCollectionValueModel<String>(this.nodeHolder, new XXX());
+		this.listener = this.buildCollectionChangeListener();
+		this.itemListener = this.buildItemListener();
+		this.preferencesAdapter.addCollectionChangeListener(CollectionValueModel.VALUES, this.listener);
+		this.event = null;
+	}
+
+	protected static class XXX
+		implements PreferencesCollectionValueModel.Adapter<String>
+	{
+		@Override
+		public PreferencePropertyValueModel<String> buildPreferenceModel(PropertyValueModel<? extends Preferences> preferencesModel, String key) {
+			return PreferencePropertyValueModel.forString(preferencesModel, key, null);
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.toString(this);
+		}
+	}
+
+	private CollectionChangeListener buildCollectionChangeListener() {
+		return new CollectionChangeListener() {
+			@Override
+			public void collectionChanged(CollectionChangeEvent e) {
+				this.logEvent(e);
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent e) {
+				this.logEvent(e);
+			}
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {
+				this.logEvent(e);
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {
+				this.logEvent(e);
+			}
+			private void logEvent(CollectionEvent e) {
+				if (PreferencesCollectionValueModelTests.this.event != null) {
+					throw new IllegalStateException("unexpected this.event: " + e);
+				}
+				PreferencesCollectionValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	private PropertyChangeListener buildItemListener() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent e) {
+				throw new IllegalStateException("unexpected this.event: " + e);
+			}
+		};
+	}
+
+	public void testSubjectHolder() throws Exception {
+		this.verifyAdapter(this.preferencesAdapter);
+		assertNull(this.event);
+
+		String ANOTHER_KEY_NAME_1 = "another key 1";
+		String ANOTHER_KEY_NAME_2 = "another key 2";
+		String ANOTHER_KEY_NAME_3 = "another key 3";
+		String ANOTHER_STRING_VALUE_1 = "another string value 1";
+		String ANOTHER_STRING_VALUE_2 = "another string value 2";
+		String ANOTHER_STRING_VALUE_3 = "another string value 3";
+		Preferences anotherNode = this.classNode.node("another test node");
+		this.expectedValues.clear();
+		anotherNode.put(ANOTHER_KEY_NAME_1, ANOTHER_STRING_VALUE_1);	this.expectedValues.put(ANOTHER_KEY_NAME_1, ANOTHER_STRING_VALUE_1);
+		anotherNode.put(ANOTHER_KEY_NAME_2, ANOTHER_STRING_VALUE_2);	this.expectedValues.put(ANOTHER_KEY_NAME_2, ANOTHER_STRING_VALUE_2);
+		anotherNode.put(ANOTHER_KEY_NAME_3, ANOTHER_STRING_VALUE_3);	this.expectedValues.put(ANOTHER_KEY_NAME_3, ANOTHER_STRING_VALUE_3);
+
+		this.nodeHolder.setValue(anotherNode);
+		// collectionChanged does not pass any items in the this.event
+		this.verifyEvent();
+		this.verifyAdapter(this.preferencesAdapter);
+
+		this.event = null;
+		this.expectedValues.clear();
+		this.nodeHolder.setValue(null);
+		this.verifyEvent();
+		assertFalse(this.preferencesAdapter.iterator().hasNext());
+
+		this.event = null;
+		this.nodeHolder.setValue(this.testNode);
+		this.verifyEvent();
+		this.expectedValues.clear();
+		this.expectedValues.put(KEY_NAME_1, STRING_VALUE_1);
+		this.expectedValues.put(KEY_NAME_2, STRING_VALUE_2);
+		this.expectedValues.put(KEY_NAME_3, STRING_VALUE_3);
+		this.verifyAdapter(this.preferencesAdapter);
+	}
+
+	public void testAddPreference() throws Exception {
+		this.verifyAdapter(this.preferencesAdapter);
+		assertNull(this.event);
+
+		String ANOTHER_KEY_NAME = "another key";
+		String ANOTHER_STRING_VALUE = "another string value";
+		this.testNode.put(ANOTHER_KEY_NAME, ANOTHER_STRING_VALUE);
+		this.waitForEventQueueToClear();
+		Map<String, String> expectedItems = new HashMap<String, String>();
+		expectedItems.put(ANOTHER_KEY_NAME, ANOTHER_STRING_VALUE);
+		this.verifyEvent(expectedItems);
+		this.expectedValues.put(ANOTHER_KEY_NAME, ANOTHER_STRING_VALUE);
+		this.verifyAdapter(this.preferencesAdapter);
+	}
+
+	public void testRemovePreference() throws Exception {
+		this.verifyAdapter(this.preferencesAdapter);
+		assertNull(this.event);
+
+		this.testNode.remove(KEY_NAME_2);
+		this.waitForEventQueueToClear();
+
+		assertNotNull(this.event);
+		assertEquals(this.preferencesAdapter, this.event.getSource());
+		assertEquals(CollectionValueModel.VALUES, this.event.getCollectionName());
+		assertEquals(1, ((CollectionRemoveEvent) this.event).getItemsSize());
+		@SuppressWarnings("unchecked")
+		String key = ((PreferencePropertyValueModel<String>) ((CollectionRemoveEvent) this.event).getItems().iterator().next()).getKey();
+		assertEquals(KEY_NAME_2, key);
+
+		this.expectedValues.remove(KEY_NAME_2);
+		this.verifyAdapter(this.preferencesAdapter);
+	}
+
+	public void testChangePreference() throws Exception {
+		this.verifyAdapter(this.preferencesAdapter);
+		assertNull(this.event);
+
+		String DIFFERENT = "something completely different";
+		this.testNode.put(KEY_NAME_2, DIFFERENT);
+		this.waitForEventQueueToClear();
+
+		assertNull(this.event);
+
+		this.expectedValues.put(KEY_NAME_2, DIFFERENT);
+		this.verifyAdapter(this.preferencesAdapter);
+	}
+
+	public void testValues() throws Exception {
+		this.verifyNode(this.testNode);
+		this.verifyAdapter(this.preferencesAdapter);
+	}
+
+	/**
+	 * test a situation where
+	 * - we are listening to the node when it gets removed from the preferences "repository"
+	 * - we get notification that it has been removed
+	 * - we try to remove our this.listener
+	 * - the node will throw an IllegalStateException - the adapter should handle it OK...
+	 */
+	public void testRemoveNode() throws Exception {
+		assertTrue(this.preferencesAdapter.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+
+		Preferences parent = this.testNode.parent();
+		parent.addNodeChangeListener(this.buildParentNodeChangeListener());
+		this.testNode.removeNode();
+		this.testNode.flush();		// this seems to be required for the this.event to trigger...
+		this.waitForEventQueueToClear();
+
+		assertTrue(this.listenerRemoved);
+		assertFalse(this.preferencesAdapter.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+	}
+
+	private NodeChangeListener buildParentNodeChangeListener() {
+		return new NodeChangeListener() {
+			@Override
+			public void childAdded(NodeChangeEvent e) {
+				throw new IllegalStateException("unexpected this.event: " + e);
+			}
+			@Override
+			public void childRemoved(NodeChangeEvent e) {
+				if (e.getChild() == PreferencesCollectionValueModelTests.this.testNode) {
+					PreferencesCollectionValueModelTests.this.preferencesAdapter.removeCollectionChangeListener(CollectionValueModel.VALUES, PreferencesCollectionValueModelTests.this.listener);
+					// this line of code will not execute if the line above triggers an exception
+					PreferencesCollectionValueModelTests.this.listenerRemoved = true;
+				}
+			}
+		};
+	}
+
+	public void testHasListeners() throws Exception {
+		assertTrue(this.preferencesAdapter.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		assertTrue(this.nodeHasAnyPrefListeners(this.testNode));
+		this.preferencesAdapter.removeCollectionChangeListener(CollectionValueModel.VALUES, this.listener);
+		assertFalse(this.nodeHasAnyPrefListeners(this.testNode));
+		assertFalse(this.preferencesAdapter.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+
+		ChangeListener listener2 = this.buildChangeListener();
+		this.preferencesAdapter.addChangeListener(listener2);
+		assertTrue(this.preferencesAdapter.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+		assertTrue(this.nodeHasAnyPrefListeners(this.testNode));
+		this.preferencesAdapter.removeChangeListener(listener2);
+		assertFalse(this.nodeHasAnyPrefListeners(this.testNode));
+		assertFalse(this.preferencesAdapter.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES));
+	}
+
+	private ChangeListener buildChangeListener() {
+		return new ChangeAdapter() {
+			@Override
+			public void collectionChanged(CollectionChangeEvent e) {
+				this.logEvent(e);
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent e) {
+				this.logEvent(e);
+			}
+			@Override
+			public void itemsAdded(CollectionAddEvent e) {
+				this.logEvent(e);
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent e) {
+				this.logEvent(e);
+			}
+			private void logEvent(CollectionEvent e) {
+				if (PreferencesCollectionValueModelTests.this.event != null) {
+					throw new IllegalStateException("unexpected this.event: " + e);
+				}
+				PreferencesCollectionValueModelTests.this.event = e;
+			}
+		};
+	}
+
+	private void verifyEvent(Map<String, String> items) {
+		this.verifyEvent();
+		assertEquals(items.size(), ((CollectionAddEvent) this.event).getItemsSize());
+		@SuppressWarnings("unchecked")
+		Iterable<PreferencePropertyValueModel<String>> eventItems = (Iterable<PreferencePropertyValueModel<String>>) ((CollectionAddEvent) this.event).getItems();
+		this.verifyItems(items, eventItems);
+	}
+
+	private void verifyEvent() {
+		assertNotNull(this.event);
+		assertEquals(this.preferencesAdapter, this.event.getSource());
+		assertEquals(CollectionValueModel.VALUES, this.event.getCollectionName());
+	}
+
+	private void verifyNode(Preferences node) throws Exception {
+		String[] keys = node.keys();
+		assertEquals(this.expectedValues.size(), keys.length);
+		for (int i = 0; i < keys.length; i++) {
+			assertEquals(this.expectedValues.get(keys[i]), node.get(keys[i], "<missing preference>"));
+		}
+	}
+
+	private void verifyAdapter(PreferencesCollectionValueModel<String> cvm) {
+		assertEquals(this.expectedValues.size(), cvm.size());
+		this.verifyItems(this.expectedValues, cvm);
+	}
+
+	private void verifyItems(Map<String, String> expected, Iterable<PreferencePropertyValueModel<String>> actual) {
+		for (PreferencePropertyValueModel<String> model : actual) {
+			model.addPropertyChangeListener(PropertyValueModel.VALUE, this.itemListener);
+			assertEquals(expected.get(model.getKey()), model.getValue());
+			model.removePropertyChangeListener(PropertyValueModel.VALUE, this.itemListener);
+		}
+	}
+
+	private boolean nodeHasAnyPrefListeners(Preferences node) throws Exception {
+		PreferenceChangeListener[] prefListeners = (PreferenceChangeListener[]) ObjectTools.get(node, "prefListeners");
+		return prefListeners.length > 0;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/prefs/PreferencesTestCase.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/prefs/PreferencesTestCase.java
new file mode 100644
index 0000000..51e70e8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/prefs/PreferencesTestCase.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.prefs;
+
+import java.util.EventObject;
+import java.util.List;
+import java.util.prefs.AbstractPreferences;
+import java.util.prefs.Preferences;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ClassTools;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+/**
+ * set up and tear down a test node for any subclass that
+ * needs to test preferences-related stuff
+ */
+@SuppressWarnings("nls")
+public abstract class PreferencesTestCase extends TestCase {
+	protected Preferences classNode;
+	public Preferences testNode;
+	protected static final String TEST_NODE_NAME = "test node";
+
+	public PreferencesTestCase(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		Preferences packageNode = Preferences.userNodeForPackage(this.getClass());
+		this.classNode = packageNode.node(this.getClass().getSimpleName());
+		// clean out any leftover crap...
+		if ((this.classNode.keys().length > 0) || (this.classNode.childrenNames().length > 0)) {
+			this.classNode.removeNode();
+			// ...and re-create the node
+			this.classNode = packageNode.node(this.getClass().getSimpleName());
+		}
+		this.testNode = this.classNode.node(TEST_NODE_NAME);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		// wait for all the events to be delivered before tearing down
+		this.waitForEventQueueToClear();
+		Preferences node = this.classNode.parent();
+		this.classNode.removeNode();
+		while (this.nodeIsVestigial(node)) {
+			Preferences parent = node.parent();
+			node.removeNode();
+			node = parent;
+		}
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	private boolean nodeIsVestigial(Preferences node) throws Exception {
+		return (node != null)
+			&& (node.keys().length == 0)
+			&& (node.childrenNames().length == 0)
+			&& (node != Preferences.userRoot());
+	}
+
+	protected void waitForEventQueueToClear() {
+		while ( ! this.preferencesEventQueue().isEmpty()) {
+			TestTools.sleep(100);
+		}
+		TestTools.sleep(100);
+	}
+
+	@SuppressWarnings("unchecked")
+	private List<EventObject> preferencesEventQueue() {
+		return (List<EventObject>) ClassTools.get(AbstractPreferences.class, "eventQueue");
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/prefs/UtilityModelValuePrefsTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/prefs/UtilityModelValuePrefsTests.java
new file mode 100644
index 0000000..4de4e4e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/prefs/UtilityModelValuePrefsTests.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.prefs;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class UtilityModelValuePrefsTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(UtilityModelValuePrefsTests.class.getPackage().getName());
+
+		suite.addTestSuite(PreferencesCollectionValueModelTests.class);
+		suite.addTestSuite(PreferencePropertyValueModelTests.class);
+
+		return suite;
+	}
+
+	private UtilityModelValuePrefsTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/CheckBoxModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/CheckBoxModelAdapterTests.java
new file mode 100644
index 0000000..fc99c76
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/CheckBoxModelAdapterTests.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import javax.swing.ButtonModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.CheckBoxModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class CheckBoxModelAdapterTests extends TestCase {
+	private ModifiablePropertyValueModel<Boolean> booleanHolder;
+	private ButtonModel buttonModelAdapter;
+	boolean eventFired;
+
+	public CheckBoxModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.booleanHolder = new SimplePropertyValueModel<Boolean>(Boolean.TRUE);
+		this.buttonModelAdapter = new CheckBoxModelAdapter(this.booleanHolder) {
+			@Override
+			protected PropertyChangeListener buildBooleanChangeListener() {
+				return this.buildBooleanChangeListener_();
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testSetSelected() throws Exception {
+		this.eventFired = false;
+		this.buttonModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				CheckBoxModelAdapterTests.this.eventFired = true;
+			}
+		});
+		this.buttonModelAdapter.setSelected(false);
+		assertTrue(this.eventFired);
+		assertEquals(Boolean.FALSE, this.booleanHolder.getValue());
+	}
+
+	public void testSetValue() throws Exception {
+		this.eventFired = false;
+		this.buttonModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				CheckBoxModelAdapterTests.this.eventFired = true;
+			}
+		});
+		assertTrue(this.buttonModelAdapter.isSelected());
+		this.booleanHolder.setValue(Boolean.FALSE);
+		assertTrue(this.eventFired);
+		assertFalse(this.buttonModelAdapter.isSelected());
+	}
+
+	public void testDefaultValue() throws Exception {
+		this.eventFired = false;
+		this.buttonModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				CheckBoxModelAdapterTests.this.eventFired = true;
+			}
+		});
+		assertTrue(this.buttonModelAdapter.isSelected());
+		this.booleanHolder.setValue(null);
+		assertTrue(this.eventFired);
+		assertFalse(this.buttonModelAdapter.isSelected());
+
+		this.eventFired = false;
+		this.booleanHolder.setValue(Boolean.FALSE);
+		assertFalse(this.eventFired);
+		assertFalse(this.buttonModelAdapter.isSelected());
+	}
+
+	public void testHasListeners() throws Exception {
+		SimplePropertyValueModel<Boolean> localBooleanHolder = (SimplePropertyValueModel<Boolean>) this.booleanHolder;
+		assertFalse(localBooleanHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(this.buttonModelAdapter);
+
+		ChangeListener listener = new TestChangeListener();
+		this.buttonModelAdapter.addChangeListener(listener);
+		assertTrue(localBooleanHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasListeners(this.buttonModelAdapter);
+
+		this.buttonModelAdapter.removeChangeListener(listener);
+		assertFalse(localBooleanHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(this.buttonModelAdapter);
+	}
+
+	private void verifyHasNoListeners(Object model) throws Exception {
+		EventListenerList listenerList = (EventListenerList) ObjectTools.get(model, "listenerList");
+		assertEquals(0, listenerList.getListenerList().length);
+	}
+
+	private void verifyHasListeners(Object model) throws Exception {
+		EventListenerList listenerList = (EventListenerList) ObjectTools.get(model, "listenerList");
+		assertFalse(listenerList.getListenerList().length == 0);
+	}
+
+
+	// ********** member class **********
+	private class TestChangeListener implements ChangeListener {
+		TestChangeListener() {
+			super();
+		}
+		@Override
+		public void stateChanged(ChangeEvent e) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/CheckBoxModelAdapterUITest.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/CheckBoxModelAdapterUITest.java
new file mode 100644
index 0000000..18210e8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/CheckBoxModelAdapterUITest.java
@@ -0,0 +1,322 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ButtonModel;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.WindowConstants;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.CheckBoxModelAdapter;
+
+/**
+ * Play around with a set of check boxes.
+ */
+@SuppressWarnings("nls")
+public class CheckBoxModelAdapterUITest {
+
+	private TestModel testModel;
+	private ModifiablePropertyValueModel<TestModel> testModelHolder;
+	private ModifiablePropertyValueModel<Boolean> flag1Holder;
+	private ModifiablePropertyValueModel<Boolean> flag2Holder;
+	private ModifiablePropertyValueModel<Boolean> notFlag2Holder;
+	private ButtonModel flag1ButtonModel;
+	private ButtonModel flag2ButtonModel;
+	private ButtonModel notFlag2ButtonModel;
+
+	public static void main(String[] args) throws Exception {
+		new CheckBoxModelAdapterUITest().exec();
+	}
+
+	private CheckBoxModelAdapterUITest() {
+		super();
+	}
+
+	private void exec() throws Exception {
+		this.testModel = new TestModel(true, true);
+		this.testModelHolder = new SimplePropertyValueModel<TestModel>(this.testModel);
+		this.flag1Holder = this.buildFlag1Holder(this.testModelHolder);
+		this.flag1ButtonModel = this.buildCheckBoxModelAdapter(this.flag1Holder);
+		this.flag2Holder = this.buildFlag2Holder(this.testModelHolder);
+		this.flag2ButtonModel = this.buildCheckBoxModelAdapter(this.flag2Holder);
+		this.notFlag2Holder = this.buildNotFlag2Holder(this.testModelHolder);
+		this.notFlag2ButtonModel = this.buildCheckBoxModelAdapter(this.notFlag2Holder);
+		this.openWindow();
+	}
+
+	private ModifiablePropertyValueModel<Boolean> buildFlag1Holder(PropertyValueModel<TestModel> vm) {
+		return new PropertyAspectAdapter<TestModel, Boolean>(vm, TestModel.FLAG1_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.isFlag1());
+			}
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setFlag1(value.booleanValue());
+			}
+		};
+	}
+
+	private ModifiablePropertyValueModel<Boolean> buildFlag2Holder(PropertyValueModel<TestModel> vm) {
+		return new PropertyAspectAdapter<TestModel, Boolean>(vm, TestModel.FLAG2_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.isFlag2());
+			}
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setFlag2(value.booleanValue());
+			}
+		};
+	}
+
+	private ModifiablePropertyValueModel<Boolean> buildNotFlag2Holder(PropertyValueModel<TestModel> vm) {
+		return new PropertyAspectAdapter<TestModel, Boolean>(vm, TestModel.NOT_FLAG2_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.isNotFlag2());
+			}
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setNotFlag2(value.booleanValue());
+			}
+		};
+	}
+
+	private ButtonModel buildCheckBoxModelAdapter(ModifiablePropertyValueModel<Boolean> booleanHolder) {
+		return new CheckBoxModelAdapter(booleanHolder);
+	}
+
+	private void openWindow() {
+		JFrame window = new JFrame(this.getClass().getName());
+		window.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+		window.addWindowListener(this.buildWindowListener());
+		window.getContentPane().add(this.buildMainPanel(), "Center");
+		window.setSize(400, 100);
+		window.setVisible(true);
+	}
+
+	private WindowListener buildWindowListener() {
+		return new WindowAdapter() {
+			@Override
+			public void windowClosing(WindowEvent e) {
+				e.getWindow().setVisible(false);
+				System.exit(0);
+			}
+		};
+	}
+
+	private Component buildMainPanel() {
+		JPanel mainPanel = new JPanel(new BorderLayout());
+		mainPanel.add(this.buildCheckBoxPanel(), BorderLayout.NORTH);
+		mainPanel.add(this.buildControlPanel(), BorderLayout.SOUTH);
+		return mainPanel;
+	}
+
+	private Component buildCheckBoxPanel() {
+		JPanel taskListPanel = new JPanel(new GridLayout(1, 0));
+		taskListPanel.add(this.buildFlag1CheckBox());
+		taskListPanel.add(this.buildFlag2CheckBox());
+		taskListPanel.add(this.buildNotFlag2CheckBox());
+		taskListPanel.add(this.buildUnattachedCheckBox());
+		return taskListPanel;
+	}
+
+	private JCheckBox buildFlag1CheckBox() {
+		JCheckBox checkBox = new JCheckBox();
+		checkBox.setText("flag 1");
+		checkBox.setModel(this.flag1ButtonModel);
+		return checkBox;
+	}
+
+	private JCheckBox buildFlag2CheckBox() {
+		JCheckBox checkBox = new JCheckBox();
+		checkBox.setText("flag 2");
+		checkBox.setModel(this.flag2ButtonModel);
+		return checkBox;
+	}
+
+	private JCheckBox buildNotFlag2CheckBox() {
+		JCheckBox checkBox = new JCheckBox();
+		checkBox.setText("not flag 2");
+		checkBox.setModel(this.notFlag2ButtonModel);
+		return checkBox;
+	}
+
+	private JCheckBox buildUnattachedCheckBox() {
+		JCheckBox checkBox = new JCheckBox("unattached");
+		checkBox.getModel().addItemListener(this.buildUnattachedItemListener());
+		return checkBox;
+	}
+
+	private ItemListener buildUnattachedItemListener() {
+		return new ItemListener() {
+			@Override
+			public void itemStateChanged(ItemEvent e) {
+				System.out.println("unattached state changed: " + e);
+			}
+		};
+	}
+
+	private Component buildControlPanel() {
+		JPanel controlPanel = new JPanel(new GridLayout(1, 0));
+		controlPanel.add(this.buildFlipFlag1Button());
+		controlPanel.add(this.buildClearModelButton());
+		controlPanel.add(this.buildRestoreModelButton());
+		controlPanel.add(this.buildPrintModelButton());
+		return controlPanel;
+	}
+
+	private JButton buildFlipFlag1Button() {
+		return new JButton(this.buildFlipFlag1Action());
+	}
+
+	private Action buildFlipFlag1Action() {
+		Action action = new AbstractAction("flip flag 1") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				CheckBoxModelAdapterUITest.this.flipFlag1();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void flipFlag1() {
+		this.testModel.setFlag1( ! this.testModel.isFlag1());
+	}
+
+	private JButton buildClearModelButton() {
+		return new JButton(this.buildClearModelAction());
+	}
+
+	private Action buildClearModelAction() {
+		Action action = new AbstractAction("clear model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				CheckBoxModelAdapterUITest.this.clearModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void clearModel() {
+		this.testModelHolder.setValue(null);
+	}
+
+	private JButton buildRestoreModelButton() {
+		return new JButton(this.buildRestoreModelAction());
+	}
+
+	private Action buildRestoreModelAction() {
+		Action action = new AbstractAction("restore model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				CheckBoxModelAdapterUITest.this.restoreModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void restoreModel() {
+		this.testModelHolder.setValue(this.testModel);
+	}
+
+	private JButton buildPrintModelButton() {
+		return new JButton(this.buildPrintModelAction());
+	}
+
+	private Action buildPrintModelAction() {
+		Action action = new AbstractAction("print model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				CheckBoxModelAdapterUITest.this.printModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void printModel() {
+		System.out.println("flag 1: " + this.testModel.isFlag1());
+		System.out.println("flag 2: " + this.testModel.isFlag2());
+		System.out.println("not flag 2: " + this.testModel.isNotFlag2());
+		System.out.println("***");
+	}
+
+
+	private class TestModel extends AbstractModel {
+		private boolean flag1;
+			public static final String FLAG1_PROPERTY = "flag1";
+		private boolean flag2;
+			public static final String FLAG2_PROPERTY = "flag2";
+		private boolean notFlag2;
+			public static final String NOT_FLAG2_PROPERTY = "notFlag2";
+
+		public TestModel(boolean flag1, boolean flag2) {
+			this.flag1 = flag1;
+			this.flag2 = flag2;
+			this.notFlag2 = ! flag2;
+		}
+		public boolean isFlag1() {
+			return this.flag1;
+		}
+		public void setFlag1(boolean flag1) {
+			boolean old = this.flag1;
+			this.flag1 = flag1;
+			this.firePropertyChanged(FLAG1_PROPERTY, old, flag1);
+		}
+		public boolean isFlag2() {
+			return this.flag2;
+		}
+		public void setFlag2(boolean flag2) {
+			boolean old = this.flag2;
+			this.flag2 = flag2;
+			this.firePropertyChanged(FLAG2_PROPERTY, old, flag2);
+
+			old = this.notFlag2;
+			this.notFlag2 = ! flag2;
+			this.firePropertyChanged(NOT_FLAG2_PROPERTY, old, this.notFlag2);
+		}
+		public boolean isNotFlag2() {
+			return this.notFlag2;
+		}
+		public void setNotFlag2(boolean notFlag2) {
+			this.setFlag2( ! notFlag2);
+		}
+		@Override
+		public String toString() {
+			return "TestModel(" + this.isFlag1() + " - " + this.isFlag2() + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ComboBoxModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ComboBoxModelAdapterTests.java
new file mode 100644
index 0000000..65e3bf1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ComboBoxModelAdapterTests.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.swing.ComboBoxModel;
+import javax.swing.ListModel;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.ComboBoxModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.model.Displayable;
+import org.eclipse.persistence.tools.utility.tests.model.SimpleDisplayable;
+import org.eclipse.persistence.tools.utility.tests.model.value.CoordinatedList;
+
+@SuppressWarnings("nls")
+public class ComboBoxModelAdapterTests extends TestCase {
+
+	public ComboBoxModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		// nothing yet...
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		// nothing yet...
+		super.tearDown();
+	}
+
+	public void testHasListeners() throws Exception {
+		SimpleListValueModel<Displayable> listHolder = this.buildListHolder();
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		SimplePropertyValueModel<Object> selectionHolder = new SimplePropertyValueModel<Object>(listHolder.iterator().next());
+		assertFalse(selectionHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+
+		ComboBoxModel comboBoxModel = new ComboBoxModelAdapter(listHolder, selectionHolder);
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(selectionHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(comboBoxModel);
+
+		CoordinatedList<Displayable> synchList = new CoordinatedList<Displayable>(comboBoxModel);
+		PropertyChangeListener selectionListener = this.buildSelectionListener();
+		selectionHolder.addPropertyChangeListener(PropertyValueModel.VALUE, selectionListener);
+		assertTrue(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertTrue(selectionHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasListeners(comboBoxModel);
+
+		comboBoxModel.removeListDataListener(synchList);
+		selectionHolder.removePropertyChangeListener(PropertyValueModel.VALUE, selectionListener);
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertFalse(selectionHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(comboBoxModel);
+	}
+
+	private PropertyChangeListener buildSelectionListener() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent evt) {
+				// do nothing...
+			}
+		};
+	}
+
+	private void verifyHasNoListeners(ListModel listModel) throws Exception {
+		boolean hasNoListeners = ((Boolean) ObjectTools.execute(listModel, "hasNoListDataListeners")).booleanValue();
+		assertTrue(hasNoListeners);
+	}
+
+	private void verifyHasListeners(ListModel listModel) throws Exception {
+		boolean hasListeners = ((Boolean) ObjectTools.execute(listModel, "hasListDataListeners")).booleanValue();
+		assertTrue(hasListeners);
+	}
+
+	private SimpleListValueModel<Displayable> buildListHolder() {
+		return new SimpleListValueModel<Displayable>(this.buildList());
+	}
+
+	private List<Displayable> buildList() {
+		List<Displayable> list = new ArrayList<Displayable>();
+		this.populateCollection(list);
+		return list;
+	}
+
+	private void populateCollection(Collection<Displayable> c) {
+		c.add(new SimpleDisplayable("foo"));
+		c.add(new SimpleDisplayable("bar"));
+		c.add(new SimpleDisplayable("baz"));
+		c.add(new SimpleDisplayable("joo"));
+		c.add(new SimpleDisplayable("jar"));
+		c.add(new SimpleDisplayable("jaz"));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ComboBoxModelAdapterUITest.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ComboBoxModelAdapterUITest.java
new file mode 100644
index 0000000..a601008
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ComboBoxModelAdapterUITest.java
@@ -0,0 +1,400 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ComboBoxModel;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.ListCellRenderer;
+import javax.swing.UIManager;
+import javax.swing.WindowConstants;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.ComboBoxModelAdapter;
+import org.eclipse.persistence.tools.utility.swing.FilteringListBrowser;
+import org.eclipse.persistence.tools.utility.swing.ListChooser;
+import org.eclipse.persistence.tools.utility.swing.SimpleListCellRenderer;
+
+
+/**
+ * Play around with a set of combo-boxes.
+ *
+ * DefaultLongListBrowserDialogUITest subclasses this class; so be
+ * careful when making changes.
+ */
+@SuppressWarnings("nls")
+public class ComboBoxModelAdapterUITest {
+
+	protected JFrame window;
+	private TestModel testModel;
+	private ModifiablePropertyValueModel<TestModel> testModelHolder;
+	private ModifiablePropertyValueModel<Object> colorHolder;
+	private SimpleListValueModel<String> colorListHolder;
+	protected ComboBoxModel colorComboBoxModel;
+	private int nextColorNumber = 0;
+
+	public static void main(String[] args) throws Exception {
+		new ComboBoxModelAdapterUITest().exec();
+	}
+
+	protected ComboBoxModelAdapterUITest() {
+		super();
+	}
+
+	protected void exec() throws Exception {
+		UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+//		UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());	// Metal LAF
+//		UIManager.setLookAndFeel(com.sun.java.swing.plaf.windows.WindowsLookAndFeel.class.getName());
+//		UIManager.setLookAndFeel(com.sun.java.swing.plaf.motif.MotifLookAndFeel.class.getName());
+//		UIManager.setLookAndFeel(oracle.bali.ewt.olaf.OracleLookAndFeel.class.getName());
+		this.testModel = this.buildTestModel();
+		this.testModelHolder = new SimplePropertyValueModel<TestModel>(this.testModel);
+		this.colorHolder = this.buildColorHolder(this.testModelHolder);
+		this.colorListHolder = this.buildColorListHolder();
+		this.colorComboBoxModel = this.buildComboBoxModelAdapter(this.colorListHolder, this.colorHolder);
+		this.openWindow();
+	}
+
+	private ModifiablePropertyValueModel<Object> buildColorHolder(PropertyValueModel<TestModel> vm) {
+		return new PropertyAspectAdapter<TestModel, Object>(vm, TestModel.COLOR_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getColor();
+			}
+			@Override
+			protected void setValue_(Object value) {
+				this.subject.setColor((String) value);
+			}
+		};
+	}
+
+	protected TestModel buildTestModel() {
+		return new TestModel();
+	}
+
+	private SimpleListValueModel<String> buildColorListHolder() {
+		return new SimpleListValueModel<String>(TestModel.validColors());
+//		return new AbstractReadOnlyListValueModel() {
+//			public Object value() {
+//				return new ArrayListIterator(TestModel.VALID_COLORS);
+//			}
+//			public int size() {
+//				return TestModel.VALID_COLORS.length;
+//			}
+//		};
+	}
+
+	protected ListValueModel<String> uiColorListHolder() {
+		return this.colorListHolder;
+	}
+
+	private ComboBoxModel buildComboBoxModelAdapter(ListValueModel<String> listHolder, ModifiablePropertyValueModel<Object> selectionHolder) {
+		return new ComboBoxModelAdapter(listHolder, selectionHolder);
+	}
+
+	private void openWindow() {
+		this.window = new JFrame(this.getClass().getSimpleName());
+		this.window.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+		this.window.addWindowListener(this.buildWindowListener());
+		this.window.getContentPane().add(this.buildMainPanel(), "Center");
+		this.window.setLocation(300, 300);
+		this.window.setSize(400, 150);
+		this.window.setVisible(true);
+	}
+
+	private WindowListener buildWindowListener() {
+		return new WindowAdapter() {
+			@Override
+			public void windowClosing(WindowEvent e) {
+				e.getWindow().setVisible(false);
+				System.exit(0);
+			}
+		};
+	}
+
+	private Component buildMainPanel() {
+		JPanel mainPanel = new JPanel(new BorderLayout());
+		mainPanel.add(this.buildComboBoxPanel(), BorderLayout.NORTH);
+		mainPanel.add(this.buildControlPanel(), BorderLayout.SOUTH);
+		return mainPanel;
+	}
+
+	protected JPanel buildComboBoxPanel() {
+		JPanel panel = new JPanel(new GridLayout(1, 0));
+		panel.add(this.buildComboBox());
+		panel.add(this.buildComboBox());
+		panel.add(this.buildListChooser1());
+		panel.add(this.buildListChooser2());
+		return panel;
+	}
+
+	private JComboBox buildComboBox() {
+		JComboBox comboBox = new JComboBox(this.colorComboBoxModel);
+		comboBox.setRenderer(this.buildComboBoxRenderer());
+		return comboBox;
+	}
+
+	protected ListCellRenderer buildComboBoxRenderer() {
+		return new SimpleListCellRenderer() {
+			@Override
+			protected String buildText(Object value) {
+				return super.buildText(value);
+			}
+		};
+	}
+
+	private ListChooser buildListChooser1() {
+		return new LocalListChooser1(this.colorComboBoxModel);
+	}
+
+	private ListChooser buildListChooser2() {
+		return new LocalListChooser2(this.colorComboBoxModel);
+	}
+
+	private Component buildControlPanel() {
+		JPanel controlPanel = new JPanel(new GridLayout(2, 0));
+		controlPanel.add(this.buildResetColorButton());
+		controlPanel.add(this.buildClearModelButton());
+		controlPanel.add(this.buildRestoreModelButton());
+		controlPanel.add(this.buildPrintModelButton());
+		controlPanel.add(this.buildAddTenButton());
+		controlPanel.add(this.buildRemoveTenButton());
+		return controlPanel;
+	}
+
+	// ********** reset color button **********
+	private JButton buildResetColorButton() {
+		return new JButton(this.buildResetColorAction());
+	}
+
+	private Action buildResetColorAction() {
+		Action action = new AbstractAction("reset color") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				ComboBoxModelAdapterUITest.this.resetColor();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void resetColor() {
+		this.testModel.setColor(TestModel.DEFAULT_COLOR);
+	}
+
+	// ********** clear model button **********
+	private JButton buildClearModelButton() {
+		return new JButton(this.buildClearModelAction());
+	}
+
+	private Action buildClearModelAction() {
+		Action action = new AbstractAction("clear model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				ComboBoxModelAdapterUITest.this.clearModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void clearModel() {
+		this.testModelHolder.setValue(null);
+	}
+
+	// ********** restore model button **********
+	private JButton buildRestoreModelButton() {
+		return new JButton(this.buildRestoreModelAction());
+	}
+
+	private Action buildRestoreModelAction() {
+		Action action = new AbstractAction("restore model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				ComboBoxModelAdapterUITest.this.restoreModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void restoreModel() {
+		this.testModelHolder.setValue(this.testModel);
+	}
+
+	// ********** print model button **********
+	private JButton buildPrintModelButton() {
+		return new JButton(this.buildPrintModelAction());
+	}
+
+	private Action buildPrintModelAction() {
+		Action action = new AbstractAction("print model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				ComboBoxModelAdapterUITest.this.printModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void printModel() {
+		System.out.println(this.testModel);
+	}
+
+	// ********** add 20 button **********
+	private JButton buildAddTenButton() {
+		return new JButton(this.buildAddTenAction());
+	}
+
+	private Action buildAddTenAction() {
+		Action action = new AbstractAction("add 20") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				ComboBoxModelAdapterUITest.this.addTen();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void addTen() {
+		for (int i = this.nextColorNumber; i < this.nextColorNumber + 20; i++) {
+			this.colorListHolder.add(this.colorListHolder.size(), "color" + i);
+		}
+		this.nextColorNumber += 20;
+	}
+
+	// ********** remove 20 button **********
+	private JButton buildRemoveTenButton() {
+		return new JButton(this.buildRemoveTenAction());
+	}
+
+	private Action buildRemoveTenAction() {
+		Action action = new AbstractAction("remove 20") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				ComboBoxModelAdapterUITest.this.removeTen();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void removeTen() {
+		for (int i = 0; i < 20; i++) {
+			if (this.colorListHolder.size() > 0) {
+				this.colorListHolder.remove(this.colorListHolder.size() - 1);
+			}
+		}
+	}
+
+
+	protected static class TestModel extends AbstractModel {
+		private String color;
+			public static final String COLOR_PROPERTY = "color";
+			public static final String RED = "red";
+			public static final String ORANGE = "orange";
+			public static final String YELLOW = "yellow";
+			public static final String GREEN = "green";
+			public static final String BLUE = "blue";
+			public static final String INDIGO = "indigo";
+			public static final String VIOLET = "violet";
+			public static final String DEFAULT_COLOR = RED;
+			public static List<String> validColors;
+			public static final String[] DEFAULT_VALID_COLORS = {
+				RED,
+				ORANGE,
+				YELLOW,
+				GREEN,
+				BLUE,
+				INDIGO,
+				VIOLET
+			};
+
+		public static List<String> validColors() {
+			if (validColors == null) {
+				validColors = buildDefaultValidColors();
+			}
+			return validColors;
+		}
+		public static List<String> buildDefaultValidColors() {
+			List<String> result = new ArrayList<String>();
+			CollectionTools.addAll(result, DEFAULT_VALID_COLORS);
+			return result;
+		}
+
+		public TestModel() {
+			this(DEFAULT_COLOR);
+		}
+		public TestModel(String color) {
+			this.color = color;
+		}
+		public String getColor() {
+			return this.color;
+		}
+		public void setColor(String color) {
+			this.checkColor(color);
+			Object old = this.color;
+			this.color = color;
+			this.firePropertyChanged(COLOR_PROPERTY, old, color);
+		}
+		public void checkColor(String c) {
+			if ( ! validColors().contains(c)) {
+				throw new IllegalArgumentException(c);
+			}
+		}
+		@Override
+		public String toString() {
+			return "TestModel(" + this.color + ")";
+		}
+	}
+
+
+	private class LocalListChooser1 extends ListChooser {
+		public LocalListChooser1(ComboBoxModel model) {
+			super(model);
+		}
+	}
+
+
+	private class LocalListChooser2 extends ListChooser {
+		public LocalListChooser2(ComboBoxModel model) {
+			super(model);
+		}
+		@Override
+		protected ListBrowser buildBrowser() {
+			return new FilteringListBrowser<String>();
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ComboBoxModelAdapterUITest2.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ComboBoxModelAdapterUITest2.java
new file mode 100644
index 0000000..89b29fb
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ComboBoxModelAdapterUITest2.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import javax.swing.ListCellRenderer;
+import org.eclipse.persistence.tools.utility.model.value.ExtendedListValueModelWrapper;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.swing.SimpleListCellRenderer;
+
+@SuppressWarnings("nls")
+public class ComboBoxModelAdapterUITest2 extends ComboBoxModelAdapterUITest {
+
+	public static void main(String[] args) throws Exception {
+		new ComboBoxModelAdapterUITest2().exec();
+	}
+
+	public ComboBoxModelAdapterUITest2() {
+		super();
+	}
+
+	/**
+	 * use a different model that allows the color to be set to null
+	 */
+	@Override
+	protected TestModel buildTestModel() {
+		return new TestModel2();
+	}
+
+	/**
+	 * add a null to the front of the list
+	 */
+	@Override
+	protected ListValueModel<String> uiColorListHolder() {
+		// the default is to prepend the wrapped list with a null item
+		return new ExtendedListValueModelWrapper<String>(super.uiColorListHolder());
+	}
+
+	/**
+	 * convert null to some text
+	 */
+	@Override
+	protected ListCellRenderer buildComboBoxRenderer() {
+		return new SimpleListCellRenderer() {
+			@Override
+			protected String buildText(Object value) {
+				return (value == null) ? "<none selected>" : super.buildText(value);
+			}
+		};
+	}
+
+
+	protected static class TestModel2 extends TestModel {
+		/**
+		 * null is OK here
+		 */
+		@Override
+		public void checkColor(String color) {
+			if (color == null) {
+				return;
+			}
+			super.checkColor(color);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/DateSpinnerModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/DateSpinnerModelAdapterTests.java
new file mode 100644
index 0000000..3c5f408
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/DateSpinnerModelAdapterTests.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import java.util.Date;
+import javax.swing.SpinnerModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.DateSpinnerModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class DateSpinnerModelAdapterTests extends TestCase {
+	private ModifiablePropertyValueModel<Object> valueHolder;
+	private SpinnerModel spinnerModelAdapter;
+	boolean eventFired;
+
+	public DateSpinnerModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.valueHolder = new SimplePropertyValueModel<Object>(new Date());
+		this.spinnerModelAdapter = new DateSpinnerModelAdapter(this.valueHolder) {
+			@Override
+			protected PropertyChangeListener buildDateChangeListener() {
+				return this.buildDateChangeListener_();
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testSetValueSpinnerModel() throws Exception {
+		this.eventFired = false;
+		this.spinnerModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				DateSpinnerModelAdapterTests.this.eventFired = true;
+			}
+		});
+		Date newDate = new Date();
+		newDate.setTime(777777);
+		this.spinnerModelAdapter.setValue(newDate);
+		assertTrue(this.eventFired);
+		assertEquals(777777, ((Date) this.valueHolder.getValue()).getTime());
+	}
+
+	public void testSetValueValueHolder() throws Exception {
+		this.eventFired = false;
+		this.spinnerModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				DateSpinnerModelAdapterTests.this.eventFired = true;
+			}
+		});
+		Date newDate = new Date();
+		newDate.setTime(777777);
+		this.valueHolder.setValue(newDate);
+		assertTrue(this.eventFired);
+		assertEquals(777777, ((Date) this.spinnerModelAdapter.getValue()).getTime());
+	}
+
+	public void testDefaultValue() throws Exception {
+		Date newDate = new Date();
+		newDate.setTime(777777);
+		this.valueHolder.setValue(newDate);
+		this.eventFired = false;
+		this.spinnerModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				DateSpinnerModelAdapterTests.this.eventFired = true;
+			}
+		});
+		assertEquals(777777, ((Date) this.spinnerModelAdapter.getValue()).getTime());
+		this.valueHolder.setValue(null);
+		assertTrue(this.eventFired);
+		assertFalse(((Date) this.spinnerModelAdapter.getValue()).getTime() == 777777);
+	}
+
+	public void testHasListeners() throws Exception {
+		SimplePropertyValueModel<Object> localValueHolder = (SimplePropertyValueModel<Object>) this.valueHolder;
+		assertFalse(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(this.spinnerModelAdapter);
+
+		ChangeListener listener = new TestChangeListener();
+		this.spinnerModelAdapter.addChangeListener(listener);
+		assertTrue(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasListeners(this.spinnerModelAdapter);
+
+		this.spinnerModelAdapter.removeChangeListener(listener);
+		assertFalse(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(this.spinnerModelAdapter);
+	}
+
+	private void verifyHasNoListeners(SpinnerModel adapter) throws Exception {
+		assertEquals(0, ((DateSpinnerModelAdapter) adapter).getChangeListeners().length);
+	}
+
+	private void verifyHasListeners(Object adapter) throws Exception {
+		assertFalse(((DateSpinnerModelAdapter) adapter).getChangeListeners().length == 0);
+	}
+
+	public void testNullInitialValue() {
+		Date today = new Date();
+		this.valueHolder = new SimplePropertyValueModel<Object>();
+		this.spinnerModelAdapter = new DateSpinnerModelAdapter(this.valueHolder, today) {
+			@Override
+			protected PropertyChangeListener buildDateChangeListener() {
+				return this.buildDateChangeListener_();
+			}
+		};
+
+		this.eventFired = false;
+		this.spinnerModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				DateSpinnerModelAdapterTests.this.eventFired = true;
+			}
+		});
+		assertEquals(today, this.spinnerModelAdapter.getValue());
+
+		Date newDate = new Date();
+		newDate.setTime(777777);
+		this.valueHolder.setValue(newDate);
+
+		assertTrue(this.eventFired);
+		assertEquals(777777, ((Date) this.spinnerModelAdapter.getValue()).getTime());
+	}
+
+
+	// ********** inner class **********
+	private class TestChangeListener implements ChangeListener {
+		TestChangeListener() {
+			super();
+		}
+		@Override
+		public void stateChanged(ChangeEvent e) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/DocumentAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/DocumentAdapterTests.java
new file mode 100644
index 0000000..8b51181
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/DocumentAdapterTests.java
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentEvent.EventType;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.Document;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.DocumentAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class DocumentAdapterTests extends TestCase {
+	private ModifiablePropertyValueModel<String> stringHolder;
+	Document documentAdapter;
+	boolean eventFired;
+
+	public DocumentAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.stringHolder = new SimplePropertyValueModel<String>("0123456789");
+		this.documentAdapter = new DocumentAdapter(this.stringHolder) {
+			@Override
+			protected PropertyChangeListener buildStringListener() {
+				return this.buildStringListener_();
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testRemove() throws Exception {
+		this.eventFired = false;
+		this.documentAdapter.addDocumentListener(new TestDocumentListener() {
+			@Override
+			public void removeUpdate(DocumentEvent e) {
+				DocumentAdapterTests.this.eventFired = true;
+				assertEquals(EventType.REMOVE, e.getType());
+				assertEquals(DocumentAdapterTests.this.documentAdapter, e.getDocument());
+				// this will be the removal of "23456"
+				assertEquals(2, e.getOffset());
+				assertEquals(5, e.getLength());
+			}
+		});
+		this.documentAdapter.remove(2, 5);
+		assertTrue(this.eventFired);
+		assertEquals("01789", this.stringHolder.getValue());
+	}
+
+	public void testInsert() throws Exception {
+		this.eventFired = false;
+		this.documentAdapter.addDocumentListener(new TestDocumentListener() {
+			@Override
+			public void insertUpdate(DocumentEvent e) {
+				DocumentAdapterTests.this.eventFired = true;
+				assertEquals(EventType.INSERT, e.getType());
+				assertEquals(DocumentAdapterTests.this.documentAdapter, e.getDocument());
+				// this will be the insert of "xxxxxx"
+				assertEquals(2, e.getOffset());
+				assertEquals(5, e.getLength());
+			}
+		});
+		this.documentAdapter.insertString(2, "xxxxx", null);
+		assertTrue(this.eventFired);
+		assertEquals("01xxxxx23456789", this.stringHolder.getValue());
+	}
+
+	public void testSetValue() throws Exception {
+		this.eventFired = false;
+		this.documentAdapter.addDocumentListener(new TestDocumentListener() {
+			@Override
+			public void insertUpdate(DocumentEvent e) {
+				DocumentAdapterTests.this.eventFired = true;
+				assertEquals(EventType.INSERT, e.getType());
+				assertEquals(DocumentAdapterTests.this.documentAdapter, e.getDocument());
+				// this will be the insert of "foo"
+				assertEquals(0, e.getOffset());
+				assertEquals(3, e.getLength());
+			}
+			@Override
+			public void removeUpdate(DocumentEvent e) {
+				assertEquals(EventType.REMOVE, e.getType());
+				assertEquals(DocumentAdapterTests.this.documentAdapter, e.getDocument());
+				// this will be the removal of "0123456789"
+				assertEquals(0, e.getOffset());
+				assertEquals(10, e.getLength());
+			}
+		});
+		assertEquals("0123456789", this.documentAdapter.getText(0, this.documentAdapter.getLength()));
+		this.stringHolder.setValue("foo");
+		assertTrue(this.eventFired);
+		assertEquals("foo", this.documentAdapter.getText(0, this.documentAdapter.getLength()));
+	}
+
+	public void testHasListeners() throws Exception {
+		SimplePropertyValueModel<String> localStringHolder = (SimplePropertyValueModel<String>) this.stringHolder;
+		assertFalse(localStringHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(this.documentAdapter);
+
+		DocumentListener listener = new TestDocumentListener();
+		this.documentAdapter.addDocumentListener(listener);
+		assertTrue(localStringHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasListeners(this.documentAdapter);
+
+		this.documentAdapter.removeDocumentListener(listener);
+		assertFalse(localStringHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(this.documentAdapter);
+	}
+
+	private void verifyHasNoListeners(Object document) throws Exception {
+		Object delegate = ObjectTools.get(document, "delegate");
+		Object[] listeners = (Object[]) ObjectTools.execute(delegate, "getDocumentListeners");
+		assertEquals(0, listeners.length);
+	}
+
+	private void verifyHasListeners(Object document) throws Exception {
+		Object delegate = ObjectTools.get(document, "delegate");
+		Object[] listeners = (Object[]) ObjectTools.execute(delegate, "getDocumentListeners");
+		assertFalse(listeners.length == 0);
+	}
+
+
+	private class TestDocumentListener implements DocumentListener {
+		TestDocumentListener() {
+			super();
+		}
+		@Override
+		public void changedUpdate(DocumentEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void insertUpdate(DocumentEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void removeUpdate(DocumentEvent e) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/DocumentAdapterUITest.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/DocumentAdapterUITest.java
new file mode 100644
index 0000000..4c3b74e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/DocumentAdapterUITest.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.WindowConstants;
+import javax.swing.text.AbstractDocument;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.PlainDocument;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.DocumentAdapter;
+
+/**
+ * Play around with a set of entry fields.
+ */
+@SuppressWarnings("nls")
+public class DocumentAdapterUITest {
+
+	private TestModel testModel;
+		private static final String DEFAULT_NAME = "Scooby Doo";
+	private ModifiablePropertyValueModel<TestModel> testModelHolder;
+	private ModifiablePropertyValueModel<String> nameHolder;
+	private Document nameDocument;
+	private Document upperCaseNameDocument;
+
+	public static void main(String[] args) throws Exception {
+		new DocumentAdapterUITest().exec();
+	}
+
+	private DocumentAdapterUITest() {
+		super();
+	}
+
+	private void exec() throws Exception {
+		this.testModel = new TestModel(DEFAULT_NAME);
+		this.testModelHolder = new SimplePropertyValueModel<TestModel>(this.testModel);
+		this.nameHolder = this.buildNameHolder(this.testModelHolder);
+		this.nameDocument = this.buildNameDocument(this.nameHolder);
+		this.upperCaseNameDocument = this.buildUpperCaseNameDocument(this.nameHolder);
+		this.openWindow();
+	}
+
+	private ModifiablePropertyValueModel<String> buildNameHolder(PropertyValueModel<TestModel> vm) {
+		return new PropertyAspectAdapter<TestModel, String>(vm, TestModel.NAME_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getName();
+			}
+			@Override
+			protected void setValue_(String value) {
+				this.subject.setName(value);
+			}
+		};
+	}
+
+	private Document buildNameDocument(ModifiablePropertyValueModel<String> stringHolder) {
+		return new DocumentAdapter(stringHolder);
+	}
+
+	private Document buildUpperCaseNameDocument(ModifiablePropertyValueModel<String> stringHolder) {
+		return new DocumentAdapter(stringHolder, this.buildUpperCaseNameDocumentDelegate());
+	}
+
+	private AbstractDocument buildUpperCaseNameDocumentDelegate() {
+		return new PlainDocument() {
+			@Override
+			public void insertString(int offset, String string, AttributeSet a) throws BadLocationException {
+				if (string == null) {
+					return;
+				}
+				char[] upper = string.toCharArray();
+				for (int i = 0; i < upper.length; i++) {
+					upper[i] = Character.toUpperCase(upper[i]);
+				}
+				super.insertString(offset, new String(upper), a);
+			}
+		};
+	}
+
+	private void openWindow() {
+		JFrame window = new JFrame(this.getClass().getName());
+		window.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+		window.addWindowListener(this.buildWindowListener());
+		window.getContentPane().add(this.buildMainPanel(), "Center");
+		window.setSize(400, 100);
+		window.setVisible(true);
+	}
+
+	private WindowListener buildWindowListener() {
+		return new WindowAdapter() {
+			@Override
+			public void windowClosing(WindowEvent e) {
+				e.getWindow().setVisible(false);
+				System.exit(0);
+			}
+		};
+	}
+
+	private Component buildMainPanel() {
+		JPanel mainPanel = new JPanel(new BorderLayout());
+		mainPanel.add(this.buildTextFieldPanel(), BorderLayout.NORTH);
+		mainPanel.add(this.buildControlPanel(), BorderLayout.SOUTH);
+		return mainPanel;
+	}
+
+	private Component buildTextFieldPanel() {
+		JPanel taskListPanel = new JPanel(new GridLayout(1, 0));
+		taskListPanel.add(this.buildNameTextField());
+		taskListPanel.add(this.buildReadOnlyNameTextField());
+		taskListPanel.add(this.buildUpperCaseNameTextField());
+		return taskListPanel;
+	}
+
+	private JTextField buildNameTextField() {
+		return new JTextField(this.nameDocument, null, 0);
+	}
+
+	private JTextField buildReadOnlyNameTextField() {
+		JTextField nameTextField = this.buildNameTextField();
+		nameTextField.setEditable(false);
+		return nameTextField;
+	}
+
+	private JTextField buildUpperCaseNameTextField() {
+		return new JTextField(this.upperCaseNameDocument, null, 0);
+	}
+
+	private Component buildControlPanel() {
+		JPanel controlPanel = new JPanel(new GridLayout(1, 0));
+		controlPanel.add(this.buildResetNameButton());
+		controlPanel.add(this.buildClearModelButton());
+		controlPanel.add(this.buildRestoreModelButton());
+		controlPanel.add(this.buildPrintModelButton());
+		return controlPanel;
+	}
+
+	private JButton buildResetNameButton() {
+		return new JButton(this.buildResetNameAction());
+	}
+
+	private Action buildResetNameAction() {
+		Action action = new AbstractAction("reset name") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				DocumentAdapterUITest.this.resetName();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void resetName() {
+		this.testModel.setName(DEFAULT_NAME);
+	}
+
+	private JButton buildClearModelButton() {
+		return new JButton(this.buildClearModelAction());
+	}
+
+	private Action buildClearModelAction() {
+		Action action = new AbstractAction("clear model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				DocumentAdapterUITest.this.clearModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void clearModel() {
+		this.testModelHolder.setValue(null);
+	}
+
+	private JButton buildRestoreModelButton() {
+		return new JButton(this.buildRestoreModelAction());
+	}
+
+	private Action buildRestoreModelAction() {
+		Action action = new AbstractAction("restore model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				DocumentAdapterUITest.this.restoreModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void restoreModel() {
+		this.testModelHolder.setValue(this.testModel);
+	}
+
+	private JButton buildPrintModelButton() {
+		return new JButton(this.buildPrintModelAction());
+	}
+
+	private Action buildPrintModelAction() {
+		Action action = new AbstractAction("print model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				DocumentAdapterUITest.this.printModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void printModel() {
+		System.out.println("name: " + this.testModel.getName());
+	}
+
+
+	private class TestModel extends AbstractModel {
+		private String name;
+			public static final String NAME_PROPERTY = "name";
+
+		public TestModel(String name) {
+			this.name = name;
+		}
+		public String getName() {
+			return this.name;
+		}
+		public void setName(String name) {
+			Object old = this.name;
+			this.name = name;
+			this.firePropertyChanged(NAME_PROPERTY, old, name);
+		}
+		@Override
+		public String toString() {
+			return "TestModel(" + this.getName() + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ListModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ListModelAdapterTests.java
new file mode 100644
index 0000000..ad6728e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ListModelAdapterTests.java
@@ -0,0 +1,321 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import javax.swing.ListModel;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.Bag;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SortedListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.SortedListValueModelWrapper;
+import org.eclipse.persistence.tools.utility.model.value.swing.ListModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.model.value.CoordinatedList;
+
+@SuppressWarnings("nls")
+public class ListModelAdapterTests extends TestCase {
+
+	public ListModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		// nothing yet...
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		// nothing yet...
+		super.tearDown();
+	}
+
+	private ListModelAdapter buildListModel(ListValueModel<String> listHolder) {
+		return new ListModelAdapter(listHolder) {
+			@Override
+			protected ListChangeListener buildListChangeListener() {
+				return this.buildListChangeListener_();
+			}
+		};
+	}
+
+	private ListModel buildListModel(CollectionValueModel<String> collectionHolder) {
+		return new ListModelAdapter(collectionHolder) {
+			@Override
+			protected ListChangeListener buildListChangeListener() {
+				return this.buildListChangeListener_();
+			}
+		};
+	}
+
+	public void testCollectionSynchronization() {
+		SimpleCollectionValueModel<String> collectionHolder = this.buildCollectionHolder();
+		ListModel listModel = this.buildListModel(collectionHolder);
+		CoordinatedList<String> synchList = new CoordinatedList<String>(listModel);
+		assertEquals(6, synchList.size());
+		this.compare(listModel, synchList);
+
+		collectionHolder.add("tom");
+		collectionHolder.add("dick");
+		collectionHolder.add("harry");
+		collectionHolder.add(null);
+		assertEquals(10, synchList.size());
+		this.compare(listModel, synchList);
+
+		collectionHolder.remove("foo");
+		collectionHolder.remove("jar");
+		collectionHolder.remove("harry");
+		collectionHolder.remove(null);
+		assertEquals(6, synchList.size());
+		this.compare(listModel, synchList);
+	}
+
+	public void testListSynchronization() {
+		SimpleListValueModel<String> listHolder = this.buildListHolder();
+		ListModel listModel = this.buildListModel(listHolder);
+		CoordinatedList<String> synchList = new CoordinatedList<String>(listModel);
+		assertEquals(6, synchList.size());
+		this.compare(listModel, synchList);
+
+		listHolder.add(6, "tom");
+		listHolder.add(7, "dick");
+		listHolder.add(8, "harry");
+		listHolder.add(9, null);
+		assertEquals(10, synchList.size());
+		this.compare(listModel, synchList);
+
+		listHolder.remove(9);
+		listHolder.remove(8);
+		listHolder.remove(4);
+		listHolder.remove(0);
+		assertEquals(6, synchList.size());
+		this.compare(listModel, synchList);
+	}
+
+	public void testSetModel() {
+		SimpleListValueModel<String> listHolder1 = this.buildListHolder();
+		ListModelAdapter listModel = this.buildListModel(listHolder1);
+		CoordinatedList<String> synchList = new CoordinatedList<String>(listModel);
+		assertTrue(listHolder1.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		assertEquals(6, synchList.size());
+		this.compare(listModel, synchList);
+
+		SimpleListValueModel<String> listHolder2 = this.buildListHolder2();
+		listModel.setModel(listHolder2);
+		assertEquals(3, synchList.size());
+		this.compare(listModel, synchList);
+		assertTrue(listHolder1.hasNoListChangeListeners(ListValueModel.LIST_VALUES));
+		assertTrue(listHolder2.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		listModel.setModel(new SimpleListValueModel<String>());
+		assertEquals(0, synchList.size());
+		this.compare(listModel, synchList);
+		assertTrue(listHolder1.hasNoListChangeListeners(ListValueModel.LIST_VALUES));
+		assertTrue(listHolder2.hasNoListChangeListeners(ListValueModel.LIST_VALUES));
+	}
+
+	private void compare(ListModel listModel, List<String> list) {
+		assertEquals(listModel.getSize(), list.size());
+		for (int i = 0; i < listModel.getSize(); i++) {
+			assertEquals(listModel.getElementAt(i), list.get(i));
+		}
+	}
+
+	public void testCollectionSort() {
+		this.verifyCollectionSort(null);
+	}
+
+	public void testListSort() {
+		this.verifyListSort(null);
+	}
+
+	public void testCustomCollectionSort() {
+		this.verifyCollectionSort(this.buildCustomComparator());
+	}
+
+	public void testCustomListSort() {
+		this.verifyListSort(this.buildCustomComparator());
+	}
+
+	private Comparator<String> buildCustomComparator() {
+		// sort with reverse order
+		return new Comparator<String>() {
+			@Override
+			public int compare(String s1, String s2) {
+				return s2.compareTo(s1);
+			}
+		};
+	}
+
+	private void verifyCollectionSort(Comparator<String> comparator) {
+		SimpleCollectionValueModel<String> collectionHolder = this.buildCollectionHolder();
+		ListModel listModel = this.buildListModel(new SortedListValueModelAdapter<String>(collectionHolder, comparator));
+		CoordinatedList<String> synchList = new CoordinatedList<String>(listModel);
+		assertEquals(6, synchList.size());
+		this.compareSort(listModel, synchList, comparator);
+
+		collectionHolder.add("tom");
+		collectionHolder.add("dick");
+		collectionHolder.add("harry");
+		assertEquals(9, synchList.size());
+		this.compareSort(listModel, synchList, comparator);
+
+		collectionHolder.remove("foo");
+		collectionHolder.remove("jar");
+		collectionHolder.remove("harry");
+		assertEquals(6, synchList.size());
+		this.compareSort(listModel, synchList, comparator);
+	}
+
+	private void verifyListSort(Comparator<String> comparator) {
+		SimpleListValueModel<String> listHolder = this.buildListHolder();
+		ListModel listModel = this.buildListModel(new SortedListValueModelWrapper<String>(listHolder, comparator));
+		CoordinatedList<String> synchList = new CoordinatedList<String>(listModel);
+		assertEquals(6, synchList.size());
+		this.compareSort(listModel, synchList, comparator);
+
+		listHolder.add(0, "tom");
+		listHolder.add(0, "dick");
+		listHolder.add(0, "harry");
+		assertEquals(9, synchList.size());
+		this.compareSort(listModel, synchList, comparator);
+
+		listHolder.remove(8);
+		listHolder.remove(4);
+		listHolder.remove(0);
+		listHolder.remove(5);
+		assertEquals(5, synchList.size());
+		this.compareSort(listModel, synchList, comparator);
+	}
+
+	private void compareSort(ListModel listModel, List<String> list, Comparator<String> comparator) {
+		SortedSet<String> ss = new TreeSet<String>(comparator);
+		for (int i = 0; i < listModel.getSize(); i++) {
+			ss.add((String) listModel.getElementAt(i));
+		}
+		assertEquals(ss.size(), list.size());
+		for (Iterator<String> stream1 = ss.iterator(), stream2 = list.iterator(); stream1.hasNext(); ) {
+			assertEquals(stream1.next(), stream2.next());
+		}
+	}
+
+	public void testHasListeners() throws Exception {
+		SimpleListValueModel<String> listHolder = this.buildListHolder();
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+
+		ListModel listModel = this.buildListModel(listHolder);
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		this.verifyHasNoListeners(listModel);
+
+		CoordinatedList<String> synchList = new CoordinatedList<String>(listModel);
+		assertTrue(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		this.verifyHasListeners(listModel);
+
+		listModel.removeListDataListener(synchList);
+		assertFalse(listHolder.hasAnyListChangeListeners(ListValueModel.LIST_VALUES));
+		this.verifyHasNoListeners(listModel);
+	}
+
+	public void testGetSize() throws Exception {
+		SimpleListValueModel<String> listHolder = this.buildListHolder();
+		ListModel listModel = this.buildListModel(listHolder);
+		this.verifyHasNoListeners(listModel);
+		assertEquals(6, listModel.getSize());
+
+		CoordinatedList<String> synchList = new CoordinatedList<String>(listModel);
+		this.verifyHasListeners(listModel);
+		assertEquals(6, listModel.getSize());
+
+		listModel.removeListDataListener(synchList);
+		this.verifyHasNoListeners(listModel);
+		assertEquals(6, listModel.getSize());
+	}
+
+	public void testGetElementAt() throws Exception {
+		SimpleListValueModel<String> listHolder = this.buildListHolder();
+		ListModel listModel = this.buildListModel(new SortedListValueModelWrapper<String>(listHolder));
+		CoordinatedList<String> synchList = new CoordinatedList<String>(listModel);
+		this.verifyHasListeners(listModel);
+		assertEquals("bar", listModel.getElementAt(0));
+		assertEquals("bar", synchList.get(0));
+	}
+
+	private void verifyHasNoListeners(ListModel listModel) throws Exception {
+		boolean hasNoListeners = ((Boolean) ObjectTools.execute(listModel, "hasNoListDataListeners")).booleanValue();
+		assertTrue(hasNoListeners);
+	}
+
+	private void verifyHasListeners(ListModel listModel) throws Exception {
+		boolean hasListeners = ((Boolean) ObjectTools.execute(listModel, "hasListDataListeners")).booleanValue();
+		assertTrue(hasListeners);
+	}
+
+	private SimpleCollectionValueModel<String> buildCollectionHolder() {
+		return new SimpleCollectionValueModel<String>(this.buildCollection());
+	}
+
+	private Collection<String> buildCollection() {
+		Bag<String> bag = new HashBag<String>();
+		this.populateCollection(bag);
+		return bag;
+	}
+
+	private SimpleListValueModel<String> buildListHolder() {
+		return new SimpleListValueModel<String>(this.buildList());
+	}
+
+	private List<String> buildList() {
+		List<String> list = new ArrayList<String>();
+		this.populateCollection(list);
+		return list;
+	}
+
+	private void populateCollection(Collection<String> c) {
+		c.add("foo");
+		c.add("bar");
+		c.add("baz");
+		c.add("joo");
+		c.add("jar");
+		c.add("jaz");
+	}
+
+	private SimpleListValueModel<String> buildListHolder2() {
+		return new SimpleListValueModel<String>(this.buildList2());
+	}
+
+	private List<String> buildList2() {
+		List<String> list = new ArrayList<String>();
+		this.populateCollection2(list);
+		return list;
+	}
+
+	private void populateCollection2(Collection<String> c) {
+		c.add("tom");
+		c.add("dick");
+		c.add("harry");
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ListModelAdapterUITest.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ListModelAdapterUITest.java
new file mode 100644
index 0000000..be9d2b1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ListModelAdapterUITest.java
@@ -0,0 +1,378 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridLayout;
+import java.awt.TextField;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.ListIterator;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.ListModel;
+import javax.swing.WindowConstants;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.value.ListAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SortedListValueModelWrapper;
+import org.eclipse.persistence.tools.utility.model.value.swing.ListModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.model.Displayable;
+
+/**
+ * an example UI for testing various permutations of the ListModelAdapter
+ */
+@SuppressWarnings("nls")
+public class ListModelAdapterUITest {
+
+	private ModifiablePropertyValueModel<TaskList> taskListHolder;
+	private TextField taskTextField;
+
+	public static void main(String[] args) throws Exception {
+		new ListModelAdapterUITest().exec(args);
+	}
+
+	private ListModelAdapterUITest() {
+		super();
+	}
+
+	private void exec(@SuppressWarnings("unused") String[] args) throws Exception {
+		this.taskListHolder = new SimplePropertyValueModel<TaskList>(new TaskList());
+		this.openWindow();
+	}
+
+	private void openWindow() {
+		JFrame window = new JFrame(this.getClass().getName());
+		window.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+		window.addWindowListener(this.buildWindowListener());
+		window.getContentPane().add(this.buildMainPanel(), "Center");
+		window.setSize(800, 400);
+		window.setVisible(true);
+	}
+
+	private WindowListener buildWindowListener() {
+		return new WindowAdapter() {
+			@Override
+			public void windowClosing(WindowEvent e) {
+				e.getWindow().setVisible(false);
+				System.exit(0);
+			}
+		};
+	}
+
+	private Component buildMainPanel() {
+		JPanel mainPanel = new JPanel(new BorderLayout());
+		mainPanel.add(this.buildTaskListPanel(), BorderLayout.CENTER);
+		mainPanel.add(this.buildControlPanel(), BorderLayout.SOUTH);
+		return mainPanel;
+	}
+
+	private Component buildTaskListPanel() {
+		JPanel taskListPanel = new JPanel(new GridLayout(0, 1));
+		taskListPanel.add(this.buildPrimitiveTaskListPanel());
+		taskListPanel.add(this.buildDisplayableTaskListPanel());
+		return taskListPanel;
+	}
+
+	private Component buildPrimitiveTaskListPanel() {
+		JPanel taskListPanel = new JPanel(new GridLayout(1, 0));
+		taskListPanel.add(this.buildUnsortedPrimitiveListPanel());
+		taskListPanel.add(this.buildStandardSortedPrimitiveListPanel());
+		taskListPanel.add(this.buildCustomSortedPrimitiveListPanel());
+		return taskListPanel;
+	}
+
+	private Component buildDisplayableTaskListPanel() {
+		JPanel taskListPanel = new JPanel(new GridLayout(1, 0));
+		taskListPanel.add(this.buildUnsortedDisplayableListPanel());
+		taskListPanel.add(this.buildStandardSortedDisplayableListPanel());
+		taskListPanel.add(this.buildCustomSortedDisplayableListPanel());
+		return taskListPanel;
+	}
+
+	private Component buildUnsortedPrimitiveListPanel() {
+		return this.buildListPanel("primitive unsorted", this.buildUnsortedPrimitiveListModel());
+	}
+
+	private Component buildStandardSortedPrimitiveListPanel() {
+		return this.buildListPanel("primitive sorted", this.buildStandardSortedPrimitiveListModel());
+	}
+
+	private Component buildCustomSortedPrimitiveListPanel() {
+		return this.buildListPanel("primitive reverse sorted", this.buildCustomSortedPrimitiveListModel());
+	}
+
+	private Component buildUnsortedDisplayableListPanel() {
+		return this.buildListPanel("displayable unsorted", this.buildUnsortedDisplayableListModel());
+	}
+
+	private Component buildStandardSortedDisplayableListPanel() {
+		return this.buildListPanel("displayable sorted", this.buildStandardSortedDisplayableListModel());
+	}
+
+	private Component buildCustomSortedDisplayableListPanel() {
+		return this.buildListPanel("displayable reverse sorted", this.buildCustomSortedDisplayableListModel());
+	}
+
+	private ListModel buildUnsortedPrimitiveListModel() {
+		return new ListModelAdapter(this.buildPrimitiveTaskListAdapter());
+	}
+
+	private ListModel buildStandardSortedPrimitiveListModel() {
+		return new ListModelAdapter(new SortedListValueModelWrapper<String>(this.buildPrimitiveTaskListAdapter()));
+	}
+
+	private ListModel buildCustomSortedPrimitiveListModel() {
+		return new ListModelAdapter(new SortedListValueModelWrapper<String>(this.buildPrimitiveTaskListAdapter(), this.buildCustomStringComparator()));
+	}
+
+	private ListModel buildUnsortedDisplayableListModel() {
+		return new ListModelAdapter(this.buildDisplayableTaskListAdapter());
+	}
+
+	private ListModel buildStandardSortedDisplayableListModel() {
+		return new ListModelAdapter(new SortedListValueModelWrapper<Task>(this.buildDisplayableTaskListAdapter()));
+	}
+
+	private ListModel buildCustomSortedDisplayableListModel() {
+		return new ListModelAdapter(new SortedListValueModelWrapper<Task>(this.buildDisplayableTaskListAdapter(), this.buildCustomTaskObjectComparator()));
+	}
+
+	private Component buildListPanel(String label, ListModel listModel) {
+		JPanel listPanel = new JPanel(new BorderLayout());
+		JLabel listLabel = new JLabel("  " + label);
+		listPanel.add(listLabel, BorderLayout.NORTH);
+
+		JList listBox = new JList();
+		listBox.setModel(listModel);
+		listBox.setDoubleBuffered(true);
+		listLabel.setLabelFor(listBox);
+		listPanel.add(new JScrollPane(listBox), BorderLayout.CENTER);
+		return listPanel;
+	}
+
+	private Comparator<String> buildCustomStringComparator() {
+		return new Comparator<String>() {
+			@Override
+			public int compare(String s1, String s2) {
+				return s2.compareTo(s1);
+			}
+		};
+	}
+
+	private Comparator<Task> buildCustomTaskObjectComparator() {
+		return new Comparator<Task>() {
+			@Override
+			public int compare(Task to1, Task to2) {
+				return to2.displayString().compareTo(to1.displayString());
+			}
+		};
+	}
+
+	private ListValueModel<String> buildPrimitiveTaskListAdapter() {
+		return new ListAspectAdapter<TaskList, String>(TaskList.TASK_NAMES_LIST, this.taskList()) {
+			@Override
+			protected ListIterator<String> listIterator_() {
+				return this.subject.taskNames();
+			}
+		};
+	}
+
+	private ListValueModel<Task> buildDisplayableTaskListAdapter() {
+		return new ListAspectAdapter<TaskList, Task>(TaskList.TASKS_LIST, this.taskList()) {
+			@Override
+			protected ListIterator<Task> listIterator_() {
+				return this.subject.tasks();
+			}
+		};
+	}
+
+	private Component buildControlPanel() {
+		JPanel controlPanel = new JPanel(new BorderLayout());
+		controlPanel.add(this.buildAddRemoveTaskPanel(), BorderLayout.CENTER);
+		controlPanel.add(this.buildClearButton(), BorderLayout.EAST);
+		return controlPanel;
+	}
+
+	private Component buildAddRemoveTaskPanel() {
+		JPanel addRemoveTaskPanel = new JPanel(new BorderLayout());
+		addRemoveTaskPanel.add(this.buildAddButton(), BorderLayout.WEST);
+		addRemoveTaskPanel.add(this.buildTaskTextField(), BorderLayout.CENTER);
+		addRemoveTaskPanel.add(this.buildRemoveButton(), BorderLayout.EAST);
+		return addRemoveTaskPanel;
+	}
+
+	private String getTask() {
+		return this.taskTextField.getText();
+	}
+
+	private TaskList taskList() {
+		return this.taskListHolder.getValue();
+	}
+
+	void addTask() {
+		String task = this.getTask();
+		if (task.length() != 0) {
+			this.taskList().addTask(task);
+		}
+	}
+
+	void removeTask() {
+		String task = this.getTask();
+		if (task.length() != 0) {
+			this.taskList().removeTask(task);
+		}
+	}
+
+	void clearTasks() {
+		this.taskList().clearTasks();
+	}
+
+	private TextField buildTaskTextField() {
+		this.taskTextField = new TextField();
+		return this.taskTextField;
+	}
+
+	private JButton buildAddButton() {
+		return new JButton(this.buildAddAction());
+	}
+
+	private Action buildAddAction() {
+		Action action = new AbstractAction("add") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				ListModelAdapterUITest.this.addTask();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	private JButton buildRemoveButton() {
+		return new JButton(this.buildRemoveAction());
+	}
+
+	private Action buildRemoveAction() {
+		Action action = new AbstractAction("remove") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				ListModelAdapterUITest.this.removeTask();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	private JButton buildClearButton() {
+		return new JButton(this.buildClearAction());
+	}
+
+	private Action buildClearAction() {
+		Action action = new AbstractAction("clear") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				ListModelAdapterUITest.this.clearTasks();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	public class TaskList extends AbstractModel {
+		private List<String> taskNames = new ArrayList<String>();
+		private List<Task> taskObjects = new ArrayList<Task>();
+		public static final String TASK_NAMES_LIST = "taskNames";
+		public static final String TASKS_LIST = "tasks";
+		TaskList() {
+			super();
+		}
+		public ListIterator<String> taskNames() {
+			return this.taskNames.listIterator();
+		}
+		public ListIterator<Task> tasks() {
+			return this.taskObjects.listIterator();
+		}
+		public void addTask(String taskName) {
+			int index = this.taskNames.size();
+			this.taskNames.add(index, taskName);
+			this.fireItemAdded(TASK_NAMES_LIST, index, taskName);
+
+			Task taskObject = new Task(taskName);
+			this.taskObjects.add(index, taskObject);
+			this.fireItemAdded(TASKS_LIST, index, taskObject);
+		}
+		public void removeTask(String taskName) {
+			int index = this.taskNames.indexOf(taskName);
+			if (index != -1) {
+				Object removedTask = this.taskNames.remove(index);
+				this.fireItemRemoved(TASK_NAMES_LIST, index, removedTask);
+				// assume the indexes match...
+				Object removedTaskObject = this.taskObjects.remove(index);
+				this.fireItemRemoved(TASKS_LIST, index, removedTaskObject);
+			}
+		}
+		public void clearTasks() {
+			this.taskNames.clear();
+			this.fireListChanged(TASK_NAMES_LIST, this.taskNames);
+			this.taskObjects.clear();
+			this.fireListChanged(TASKS_LIST, this.taskObjects);
+		}
+	}
+
+	public class Task extends AbstractModel implements Displayable {
+		private String name;
+		private Date creationTimeStamp;
+		public Task(String name) {
+			this.name = name;
+			this.creationTimeStamp = new Date();
+		}
+		@Override
+		public String displayString() {
+			return this.name + ": " + this.creationTimeStamp.getTime();
+		}
+		@Override
+		public Icon icon() {
+			return null;
+		}
+		public String getName() {
+			return this.name;
+		}
+		public void setName(String name) {
+			Object old = this.name;
+			this.name = name;
+			this.firePropertyChanged(DISPLAY_STRING_PROPERTY, old, name);
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.toString(this, this.displayString());
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ListSpinnerModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ListSpinnerModelAdapterTests.java
new file mode 100644
index 0000000..1384c53
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ListSpinnerModelAdapterTests.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import javax.swing.SpinnerModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.ListSpinnerModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class ListSpinnerModelAdapterTests extends TestCase {
+	private ModifiablePropertyValueModel<Object> valueHolder;
+	private SpinnerModel spinnerModelAdapter;
+	boolean eventFired;
+	private static final String[] VALUE_LIST = {"red", "green", "blue"};
+	private static final String DEFAULT_VALUE = VALUE_LIST[0];
+
+	public ListSpinnerModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.valueHolder = new SimplePropertyValueModel<Object>(DEFAULT_VALUE);
+		this.spinnerModelAdapter = new ListSpinnerModelAdapter(this.valueHolder, VALUE_LIST) {
+			@Override
+			protected PropertyChangeListener buildValueChangeListener() {
+				return this.buildValueChangeListener_();
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testSetValueSpinnerModel() throws Exception {
+		this.eventFired = false;
+		this.spinnerModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				ListSpinnerModelAdapterTests.this.eventFired = true;
+			}
+		});
+		assertEquals(DEFAULT_VALUE, this.valueHolder.getValue());
+		this.spinnerModelAdapter.setValue(VALUE_LIST[2]);
+		assertTrue(this.eventFired);
+		assertEquals(VALUE_LIST[2], this.valueHolder.getValue());
+	}
+
+	public void testSetValueValueHolder() throws Exception {
+		this.eventFired = false;
+		this.spinnerModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				ListSpinnerModelAdapterTests.this.eventFired = true;
+			}
+		});
+		assertEquals(DEFAULT_VALUE, this.spinnerModelAdapter.getValue());
+		this.valueHolder.setValue(VALUE_LIST[2]);
+		assertTrue(this.eventFired);
+		assertEquals(VALUE_LIST[2], this.spinnerModelAdapter.getValue());
+	}
+
+	public void testDefaultValue() throws Exception {
+		this.eventFired = false;
+		this.spinnerModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				ListSpinnerModelAdapterTests.this.eventFired = true;
+			}
+		});
+		assertEquals(DEFAULT_VALUE, this.spinnerModelAdapter.getValue());
+
+		this.valueHolder.setValue(VALUE_LIST[2]);
+		assertTrue(this.eventFired);
+		assertEquals(VALUE_LIST[2], this.spinnerModelAdapter.getValue());
+
+		this.eventFired = false;
+		this.valueHolder.setValue(null);
+		assertTrue(this.eventFired);
+		assertEquals(VALUE_LIST[0], this.spinnerModelAdapter.getValue());
+	}
+
+	public void testHasListeners() throws Exception {
+		SimplePropertyValueModel<Object> localValueHolder = (SimplePropertyValueModel<Object>) this.valueHolder;
+		assertFalse(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(this.spinnerModelAdapter);
+
+		ChangeListener listener = new TestChangeListener();
+		this.spinnerModelAdapter.addChangeListener(listener);
+		assertTrue(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasListeners(this.spinnerModelAdapter);
+
+		this.spinnerModelAdapter.removeChangeListener(listener);
+		assertFalse(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(this.spinnerModelAdapter);
+	}
+
+	private void verifyHasNoListeners(SpinnerModel adapter) throws Exception {
+		assertEquals(0, ((ListSpinnerModelAdapter) adapter).getChangeListeners().length);
+	}
+
+	private void verifyHasListeners(Object adapter) throws Exception {
+		assertFalse(((ListSpinnerModelAdapter) adapter).getChangeListeners().length == 0);
+	}
+
+
+	private class TestChangeListener implements ChangeListener {
+		TestChangeListener() {
+			super();
+		}
+		@Override
+		public void stateChanged(ChangeEvent e) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/NumberSpinnerModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/NumberSpinnerModelAdapterTests.java
new file mode 100644
index 0000000..06121b7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/NumberSpinnerModelAdapterTests.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import javax.swing.SpinnerModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.NumberSpinnerModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class NumberSpinnerModelAdapterTests extends TestCase {
+	private ModifiablePropertyValueModel<Number> valueHolder;
+	private SpinnerModel spinnerModelAdapter;
+	boolean eventFired;
+
+	public NumberSpinnerModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.valueHolder = new SimplePropertyValueModel<Number>(new Integer(0));
+		this.spinnerModelAdapter = new NumberSpinnerModelAdapter(this.valueHolder, -33, 33, 1) {
+			@Override
+			protected PropertyChangeListener buildNumberChangeListener() {
+				return this.buildNumberChangeListener_();
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testSetValueSpinnerModel() throws Exception {
+		this.eventFired = false;
+		this.spinnerModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				NumberSpinnerModelAdapterTests.this.eventFired = true;
+			}
+		});
+		this.spinnerModelAdapter.setValue(new Integer(5));
+		assertTrue(this.eventFired);
+		assertEquals(new Integer(5), this.valueHolder.getValue());
+	}
+
+	public void testSetValueValueHolder() throws Exception {
+		this.eventFired = false;
+		this.spinnerModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				NumberSpinnerModelAdapterTests.this.eventFired = true;
+			}
+		});
+		assertEquals(new Integer(0), this.spinnerModelAdapter.getValue());
+		this.valueHolder.setValue(new Integer(7));
+		assertTrue(this.eventFired);
+		assertEquals(new Integer(7), this.spinnerModelAdapter.getValue());
+	}
+
+	public void testDefaultValue() throws Exception {
+		this.eventFired = false;
+		this.spinnerModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				NumberSpinnerModelAdapterTests.this.eventFired = true;
+			}
+		});
+		assertEquals(new Integer(0), this.spinnerModelAdapter.getValue());
+		this.valueHolder.setValue(null);
+		assertTrue(this.eventFired);
+		assertEquals(new Integer(-33), this.spinnerModelAdapter.getValue());
+	}
+
+	public void testHasListeners() throws Exception {
+		SimplePropertyValueModel<Number> localValueHolder = (SimplePropertyValueModel<Number>) this.valueHolder;
+		assertFalse(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(this.spinnerModelAdapter);
+
+		ChangeListener listener = new TestChangeListener();
+		this.spinnerModelAdapter.addChangeListener(listener);
+		assertTrue(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasListeners(this.spinnerModelAdapter);
+
+		this.spinnerModelAdapter.removeChangeListener(listener);
+		assertFalse(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(this.spinnerModelAdapter);
+	}
+
+	private void verifyHasNoListeners(SpinnerModel adapter) throws Exception {
+		assertEquals(0, ((NumberSpinnerModelAdapter) adapter).getChangeListeners().length);
+	}
+
+	private void verifyHasListeners(Object adapter) throws Exception {
+		assertFalse(((NumberSpinnerModelAdapter) adapter).getChangeListeners().length == 0);
+	}
+
+	public void testNullInitialValue() {
+		this.valueHolder = new SimplePropertyValueModel<Number>();
+		this.spinnerModelAdapter = new NumberSpinnerModelAdapter(this.valueHolder, new Integer(-33), new Integer(33), new Integer(1), new Integer(0)) {
+			@Override
+			protected PropertyChangeListener buildNumberChangeListener() {
+				return this.buildNumberChangeListener_();
+			}
+		};
+
+		this.eventFired = false;
+		this.spinnerModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				NumberSpinnerModelAdapterTests.this.eventFired = true;
+			}
+		});
+		assertEquals(new Integer(0), this.spinnerModelAdapter.getValue());
+		this.valueHolder.setValue(new Integer(7));
+		assertTrue(this.eventFired);
+		assertEquals(new Integer(7), this.spinnerModelAdapter.getValue());
+	}
+
+
+	// ********** inner class **********
+	private class TestChangeListener implements ChangeListener {
+		TestChangeListener() {
+			super();
+		}
+		@Override
+		public void stateChanged(ChangeEvent e) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ObjectListSelectionModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ObjectListSelectionModelTests.java
new file mode 100644
index 0000000..f9996b3
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ObjectListSelectionModelTests.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import javax.swing.DefaultListModel;
+import javax.swing.ListModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+
+@SuppressWarnings("nls")
+public class ObjectListSelectionModelTests extends TestCase {
+	private DefaultListModel listModel;
+	private ObjectListSelectionModel selectionModel;
+
+	public ObjectListSelectionModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.listModel = this.buildListModel();
+		this.selectionModel = this.buildSelectionModel(this.listModel);
+	}
+
+	private DefaultListModel buildListModel() {
+		DefaultListModel lm = new DefaultListModel();
+		lm.addElement("foo");
+		lm.addElement("bar");
+		lm.addElement("baz");
+		return lm;
+	}
+
+	private ObjectListSelectionModel buildSelectionModel(ListModel lm) {
+		return new ObjectListSelectionModel(lm);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testListDataListener() {
+		this.selectionModel.addListSelectionListener(this.buildListSelectionListener());
+		this.selectionModel.setSelectionInterval(0, 0);
+		assertEquals("foo", this.selectionModel.selectedValue());
+		this.listModel.set(0, "jar");
+		assertEquals("jar", this.selectionModel.selectedValue());
+	}
+
+	public void testGetSelectedValue() {
+		this.selectionModel.setSelectionInterval(0, 0);
+		assertEquals("foo", this.selectionModel.selectedValue());
+	}
+
+	public void testGetSelectedValues() {
+		this.selectionModel.setSelectionInterval(0, 0);
+		this.selectionModel.addSelectionInterval(2, 2);
+		assertEquals(2, this.selectionModel.selectedValues().length);
+		assertTrue(ArrayTools.contains(this.selectionModel.selectedValues(), "foo"));
+		assertTrue(ArrayTools.contains(this.selectionModel.selectedValues(), "baz"));
+	}
+
+	public void testSetSelectedValue() {
+		this.selectionModel.setSelectedValue("foo");
+		assertEquals(0, this.selectionModel.getMinSelectionIndex());
+		assertEquals(0, this.selectionModel.getMaxSelectionIndex());
+	}
+
+	public void testSetSelectedValues() {
+		this.selectionModel.setSelectedValues(new Object[] {"foo", "baz"});
+		assertEquals(0, this.selectionModel.getMinSelectionIndex());
+		assertEquals(2, this.selectionModel.getMaxSelectionIndex());
+	}
+
+	public void testAddSelectedValue() {
+		this.listModel.addElement("joo");
+		this.listModel.addElement("jar");
+		this.listModel.addElement("jaz");
+		this.selectionModel.setSelectedValue("foo");
+		this.selectionModel.addSelectedValue("jaz");
+		assertEquals(0, this.selectionModel.getMinSelectionIndex());
+		assertEquals(5, this.selectionModel.getMaxSelectionIndex());
+		assertTrue(this.selectionModel.isSelectedIndex(0));
+		assertFalse(this.selectionModel.isSelectedIndex(1));
+		assertFalse(this.selectionModel.isSelectedIndex(2));
+		assertFalse(this.selectionModel.isSelectedIndex(3));
+		assertFalse(this.selectionModel.isSelectedIndex(4));
+		assertTrue(this.selectionModel.isSelectedIndex(5));
+	}
+
+	public void testAddSelectedValues() {
+		this.listModel.addElement("joo");
+		this.listModel.addElement("jar");
+		this.listModel.addElement("jaz");
+		this.selectionModel.setSelectedValue("foo");
+		this.selectionModel.addSelectedValues(new Object[] {"bar", "jar"});
+		assertEquals(0, this.selectionModel.getMinSelectionIndex());
+		assertEquals(4, this.selectionModel.getMaxSelectionIndex());
+		assertTrue(this.selectionModel.isSelectedIndex(0));
+		assertTrue(this.selectionModel.isSelectedIndex(1));
+		assertFalse(this.selectionModel.isSelectedIndex(2));
+		assertFalse(this.selectionModel.isSelectedIndex(3));
+		assertTrue(this.selectionModel.isSelectedIndex(4));
+		assertFalse(this.selectionModel.isSelectedIndex(5));
+	}
+
+	public void testRemoveSelectedValue() {
+		this.listModel.addElement("joo");
+		this.listModel.addElement("jar");
+		this.listModel.addElement("jaz");
+		this.selectionModel.setSelectedValues(new Object[] {"foo", "baz", "jar"});
+		this.selectionModel.removeSelectedValue("jar");
+		assertEquals(0, this.selectionModel.getMinSelectionIndex());
+		assertEquals(2, this.selectionModel.getMaxSelectionIndex());
+		assertTrue(this.selectionModel.isSelectedIndex(0));
+		assertFalse(this.selectionModel.isSelectedIndex(1));
+		assertTrue(this.selectionModel.isSelectedIndex(2));
+		assertFalse(this.selectionModel.isSelectedIndex(3));
+		assertFalse(this.selectionModel.isSelectedIndex(4));
+		assertFalse(this.selectionModel.isSelectedIndex(5));
+	}
+
+	public void testRemoveSelectedValues() {
+		this.listModel.addElement("joo");
+		this.listModel.addElement("jar");
+		this.listModel.addElement("jaz");
+		this.selectionModel.setSelectedValues(new Object[] {"foo", "baz", "joo", "jar"});
+		this.selectionModel.removeSelectedValues(new Object[] {"foo", "joo"});
+		assertEquals(2, this.selectionModel.getMinSelectionIndex());
+		assertEquals(4, this.selectionModel.getMaxSelectionIndex());
+		assertFalse(this.selectionModel.isSelectedIndex(0));
+		assertFalse(this.selectionModel.isSelectedIndex(1));
+		assertTrue(this.selectionModel.isSelectedIndex(2));
+		assertFalse(this.selectionModel.isSelectedIndex(3));
+		assertTrue(this.selectionModel.isSelectedIndex(4));
+		assertFalse(this.selectionModel.isSelectedIndex(5));
+	}
+
+	public void testGetAnchorSelectedValue() {
+		this.selectionModel.setAnchorSelectionIndex(1);
+		assertEquals("bar", this.selectionModel.getAnchorSelectedValue());
+	}
+
+	public void testGetLeadSelectedValue() {
+		this.selectionModel.setSelectedValue("bar");
+		assertEquals("bar", this.selectionModel.getLeadSelectedValue());
+		this.selectionModel.setSelectedValues(new Object[] {"foo", "baz"});
+		assertEquals("baz", this.selectionModel.getLeadSelectedValue());
+	}
+
+	public void testGetMinMaxSelectedValue() {
+		this.listModel.addElement("joo");
+		this.listModel.addElement("jar");
+		this.listModel.addElement("jaz");
+		this.selectionModel.setSelectedValue("foo");
+		this.selectionModel.addSelectedValues(new Object[] {"bar", "jar"});
+		assertEquals("foo", this.selectionModel.getMinSelectedValue());
+		assertEquals("jar", this.selectionModel.getMaxSelectedValue());
+	}
+
+	public void testValueIsSelected() {
+		this.listModel.addElement("joo");
+		this.listModel.addElement("jar");
+		this.listModel.addElement("jaz");
+		this.selectionModel.setSelectedValue("foo");
+		this.selectionModel.addSelectedValues(new Object[] {"bar", "jar"});
+		assertTrue(this.selectionModel.valueIsSelected("foo"));
+		assertTrue(this.selectionModel.valueIsSelected("bar"));
+		assertTrue(this.selectionModel.valueIsSelected("jar"));
+		assertFalse(this.selectionModel.valueIsSelected("baz"));
+	}
+
+	public void testHasListeners() throws Exception {
+		ListSelectionListener listener = this.buildListSelectionListener();
+		assertEquals(0, this.listModel.getListDataListeners().length);
+		this.selectionModel.addListSelectionListener(listener);
+		assertEquals(1, this.listModel.getListDataListeners().length);
+		this.selectionModel.removeListSelectionListener(listener);
+		assertEquals(0, this.listModel.getListDataListeners().length);
+	}
+
+	private ListSelectionListener buildListSelectionListener() {
+		return new ListSelectionListener() {
+			@Override
+			public void valueChanged(ListSelectionEvent e) {
+				// do nothing for now...
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/PrimitiveListTreeModelTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/PrimitiveListTreeModelTests.java
new file mode 100644
index 0000000..d1cc289
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/PrimitiveListTreeModelTests.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ListIterator;
+import javax.swing.event.TreeModelEvent;
+import javax.swing.event.TreeModelListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreeModel;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyListIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ListAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.PrimitiveListTreeModel;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class PrimitiveListTreeModelTests extends TestCase {
+	TestModel testModel;
+	private TreeModel treeModel;
+
+	public PrimitiveListTreeModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.testModel = this.buildTestModel();
+		this.treeModel = this.buildTreeModel();
+	}
+
+	private TestModel buildTestModel() {
+		return new TestModel();
+	}
+
+	private TreeModel buildTreeModel() {
+		return new PrimitiveListTreeModel(this.buildListValueModel()) {
+			@Override
+			protected void primitiveChanged(int index, Object newValue) {
+				if ( ! newValue.equals("")) {
+					PrimitiveListTreeModelTests.this.testModel.replaceName(index, (String) newValue);
+				}
+			}
+			@Override
+			protected ListChangeListener buildListChangeListener() {
+				return this.buildListChangeListener_();
+			}
+		};
+	}
+
+	private ListValueModel<?> buildListValueModel() {
+		return new ListAspectAdapter<TestModel, String>(TestModel.NAMES_LIST, this.testModel) {
+			@Override
+			protected ListIterator<String> listIterator_() {
+				return this.subject.names();
+			}
+			@Override
+			public String get(int index) {
+				return this.subject.getName(index);
+			}
+			@Override
+			public int size() {
+				return this.subject.namesSize();
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testAddPrimitive() {
+		this.treeModel.addTreeModelListener(new TestTreeModelListener() {
+			@Override
+			public void treeNodesInserted(TreeModelEvent e) {
+				PrimitiveListTreeModelTests.this.verifyTreeModelEvent(e, new int[] {0}, new String[] {"foo"});
+			}
+		});
+		this.testModel.addName("foo");
+	}
+
+	public void testRemovePrimitive() {
+		this.testModel.addName("foo");
+		this.testModel.addName("bar");
+		this.testModel.addName("baz");
+		this.treeModel.addTreeModelListener(new TestTreeModelListener() {
+			@Override
+			public void treeNodesRemoved(TreeModelEvent e) {
+				PrimitiveListTreeModelTests.this.verifyTreeModelEvent(e, new int[] {1}, new String[] {"bar"});
+			}
+		});
+		String name = this.testModel.removeName(1);
+		assertEquals("bar", name);
+	}
+
+	public void testReplacePrimitive() {
+		this.testModel.addName("foo");
+		this.testModel.addName("bar");
+		this.testModel.addName("baz");
+		this.treeModel.addTreeModelListener(new TestTreeModelListener() {
+			@Override
+			public void treeNodesChanged(TreeModelEvent e) {
+				PrimitiveListTreeModelTests.this.verifyTreeModelEvent(e, new int[] {1}, new String[] {"jar"});
+			}
+		});
+		String name = this.testModel.replaceName(1, "jar");
+		assertEquals("bar", name);
+	}
+
+	void verifyTreeModelEvent(TreeModelEvent e, int[] expectedChildIndices, String[] expectedNames) {
+		assertTrue(Arrays.equals(expectedChildIndices, e.getChildIndices()));
+		Object[] actualChildren = e.getChildren();
+		assertEquals(expectedNames.length, actualChildren.length);
+		for (int i = 0; i < expectedNames.length; i++) {
+			DefaultMutableTreeNode node = (DefaultMutableTreeNode) actualChildren[i];
+			assertEquals(expectedNames[i], node.getUserObject());
+		}
+		assertEquals(1, e.getPath().length);
+		assertEquals(this.treeModel.getRoot(), e.getPath()[0]);
+		assertEquals(this.treeModel, e.getSource());
+	}
+
+
+// ********** inner classes **********
+
+	class TestModel extends AbstractModel {
+		private final List<String> names;
+			static final String NAMES_LIST = "names";
+
+		TestModel() {
+			super();
+			this.names = new ArrayList<String>();
+		}
+
+		public ListIterator<String> names() {
+			return new ReadOnlyListIterator<String>(this.names);
+		}
+		public int namesSize() {
+			return this.names.size();
+		}
+		public String getName(int index) {
+			return this.names.get(index);
+		}
+		public void addName(int index, String name) {
+			this.addItemToList(index, name, this.names, NAMES_LIST);
+		}
+		public void addName(String name) {
+			this.addName(this.namesSize(), name);
+		}
+		public void addNames(int index, List<String> list) {
+			this.addItemsToList(index, this.names, list, NAMES_LIST);
+		}
+		public void addNames(List<String> list) {
+			this.addNames(this.namesSize(), list);
+		}
+		public String removeName(int index) {
+			return this.removeItemFromList(index, this.names, NAMES_LIST);
+		}
+		public List<String> removeNames(int index, int length) {
+			return this.removeItemsFromList(index, length, this.names, NAMES_LIST);
+		}
+		public String replaceName(int index, String newName) {
+			return this.setItemInList(index, newName, this.names, NAMES_LIST);
+		}
+	}
+
+
+	public class TestTreeModelListener implements TreeModelListener {
+		@Override
+		public void treeNodesChanged(TreeModelEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void treeNodesInserted(TreeModelEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void treeNodesRemoved(TreeModelEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void treeStructureChanged(TreeModelEvent e) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/RadioButtonModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/RadioButtonModelAdapterTests.java
new file mode 100644
index 0000000..5f598fa
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/RadioButtonModelAdapterTests.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import javax.swing.ButtonModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.RadioButtonModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class RadioButtonModelAdapterTests extends TestCase {
+	private ModifiablePropertyValueModel<Object> valueHolder;
+
+	private ButtonModel redButtonModelAdapter;
+	private ChangeListener redListener;
+	boolean redEventFired;
+
+	private ButtonModel greenButtonModelAdapter;
+	private ChangeListener greenListener;
+	boolean greenEventFired;
+
+	private ButtonModel blueButtonModelAdapter;
+	private ChangeListener blueListener;
+	boolean blueEventFired;
+
+//	private ButtonGroup buttonGroup;	// DO NOT use a ButtonGroup
+
+	private static final String RED = "red";
+	private static final String GREEN = "green";
+	private static final String BLUE = "blue";
+
+	public RadioButtonModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.valueHolder = new SimplePropertyValueModel<Object>(null);
+//		buttonGroup = new ButtonGroup();
+
+		this.redButtonModelAdapter = this.buildButtonModel(this.valueHolder, RED);
+//		this.redButtonModelAdapter.setGroup(buttonGroup);
+		this.redListener = new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				RadioButtonModelAdapterTests.this.redEventFired = true;
+			}
+		};
+
+		this.greenButtonModelAdapter = this.buildButtonModel(this.valueHolder, GREEN);
+//		this.greenButtonModelAdapter.setGroup(buttonGroup);
+		this.greenListener = new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				RadioButtonModelAdapterTests.this.greenEventFired = true;
+			}
+		};
+
+		this.blueButtonModelAdapter = this.buildButtonModel(this.valueHolder, BLUE);
+//		this.blueButtonModelAdapter.setGroup(buttonGroup);
+		this.blueListener = new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				RadioButtonModelAdapterTests.this.blueEventFired = true;
+			}
+		};
+
+		this.clearFlags();
+	}
+
+	private ButtonModel buildButtonModel(ModifiablePropertyValueModel<Object> pvm, Object buttonValue) {
+		return new RadioButtonModelAdapter(pvm, buttonValue) {
+			@Override
+			protected PropertyChangeListener buildBooleanChangeListener() {
+				return this.buildBooleanChangeListener_();
+			}
+		};
+	}
+
+	private void listenToModelAdapters() {
+		this.redButtonModelAdapter.addChangeListener(this.redListener);
+		this.greenButtonModelAdapter.addChangeListener(this.greenListener);
+		this.blueButtonModelAdapter.addChangeListener(this.blueListener);
+	}
+
+	private void clearFlags() {
+		this.redEventFired = false;
+		this.greenEventFired = false;
+		this.blueEventFired = false;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testSetSelected() throws Exception {
+		this.listenToModelAdapters();
+
+		this.greenButtonModelAdapter.setSelected(true);
+		assertFalse(this.redEventFired);
+		assertTrue(this.greenEventFired);
+		assertFalse(this.blueEventFired);
+		assertEquals(GREEN, this.valueHolder.getValue());
+
+		this.clearFlags();
+		this.blueButtonModelAdapter.setSelected(true);
+		assertFalse(this.redEventFired);
+		assertTrue(this.greenEventFired);
+		assertTrue(this.blueEventFired);
+		assertEquals(BLUE, this.valueHolder.getValue());
+
+		this.clearFlags();
+		this.redButtonModelAdapter.setSelected(true);
+		assertTrue(this.redEventFired);
+		assertFalse(this.greenEventFired);
+		assertTrue(this.blueEventFired);
+		assertEquals(RED, this.valueHolder.getValue());
+	}
+
+	public void testSetValue() throws Exception {
+		this.listenToModelAdapters();
+
+		this.greenButtonModelAdapter.setSelected(true);
+
+		this.clearFlags();
+		this.valueHolder.setValue(BLUE);
+		assertFalse(this.redEventFired);
+		assertTrue(this.greenEventFired);
+		assertTrue(this.blueEventFired);
+		assertFalse(this.redButtonModelAdapter.isSelected());
+		assertFalse(this.greenButtonModelAdapter.isSelected());
+		assertTrue(this.blueButtonModelAdapter.isSelected());
+
+		this.clearFlags();
+		this.valueHolder.setValue(RED);
+		assertTrue(this.redEventFired);
+		assertFalse(this.greenEventFired);
+		assertTrue(this.blueEventFired);
+		assertTrue(this.redButtonModelAdapter.isSelected());
+		assertFalse(this.greenButtonModelAdapter.isSelected());
+		assertFalse(this.blueButtonModelAdapter.isSelected());
+	}
+
+	public void testDefaultValue() throws Exception {
+		this.listenToModelAdapters();
+
+		this.valueHolder.setValue(GREEN);
+		assertFalse(this.redButtonModelAdapter.isSelected());
+		assertTrue(this.greenButtonModelAdapter.isSelected());
+		assertFalse(this.blueButtonModelAdapter.isSelected());
+
+		this.clearFlags();
+		this.valueHolder.setValue(null);
+		assertFalse(this.redEventFired);
+		assertTrue(this.greenEventFired);
+		assertFalse(this.blueEventFired);
+		assertFalse(this.redButtonModelAdapter.isSelected());
+		assertFalse(this.greenButtonModelAdapter.isSelected());
+		assertFalse(this.blueButtonModelAdapter.isSelected());
+
+		this.clearFlags();
+		this.valueHolder.setValue(BLUE);
+		assertFalse(this.redEventFired);
+		assertFalse(this.greenEventFired);
+		assertTrue(this.blueEventFired);
+		assertFalse(this.redButtonModelAdapter.isSelected());
+		assertFalse(this.greenButtonModelAdapter.isSelected());
+		assertTrue(this.blueButtonModelAdapter.isSelected());
+	}
+
+	public void testHasListeners() throws Exception {
+		SimplePropertyValueModel<Object> localValueHolder = (SimplePropertyValueModel<Object>) this.valueHolder;
+		assertFalse(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(this.redButtonModelAdapter);
+		this.verifyHasNoListeners(this.greenButtonModelAdapter);
+		this.verifyHasNoListeners(this.blueButtonModelAdapter);
+
+		ChangeListener listener = new TestChangeListener();
+		this.redButtonModelAdapter.addChangeListener(listener);
+		assertTrue(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasListeners(this.redButtonModelAdapter);
+		this.verifyHasNoListeners(this.greenButtonModelAdapter);
+		this.verifyHasNoListeners(this.blueButtonModelAdapter);
+
+		this.redButtonModelAdapter.removeChangeListener(listener);
+		assertFalse(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(this.redButtonModelAdapter);
+		this.verifyHasNoListeners(this.greenButtonModelAdapter);
+		this.verifyHasNoListeners(this.blueButtonModelAdapter);
+	}
+
+	private void verifyHasNoListeners(Object model) throws Exception {
+		EventListenerList listenerList = (EventListenerList) ObjectTools.get(model, "listenerList");
+		assertEquals(0, listenerList.getListenerList().length);
+	}
+
+	private void verifyHasListeners(Object model) throws Exception {
+		EventListenerList listenerList = (EventListenerList) ObjectTools.get(model, "listenerList");
+		assertFalse(listenerList.getListenerList().length == 0);
+	}
+
+
+	private class TestChangeListener implements ChangeListener {
+		TestChangeListener() {
+			super();
+		}
+		@Override
+		public void stateChanged(ChangeEvent e) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/RadioButtonModelAdapterUITest.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/RadioButtonModelAdapterUITest.java
new file mode 100644
index 0000000..a1d7c14
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/RadioButtonModelAdapterUITest.java
@@ -0,0 +1,264 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ButtonModel;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.WindowConstants;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.RadioButtonModelAdapter;
+
+/**
+ * Play around with a set of radio buttons.
+ */
+@SuppressWarnings("nls")
+public class RadioButtonModelAdapterUITest {
+
+	private TestModel testModel;
+	private ModifiablePropertyValueModel<TestModel> testModelHolder;
+	private ModifiablePropertyValueModel<Object> colorHolder;
+	private ButtonModel redButtonModel;
+	private ButtonModel greenButtonModel;
+	private ButtonModel blueButtonModel;
+
+	public static void main(String[] args) throws Exception {
+		new RadioButtonModelAdapterUITest().exec();
+	}
+
+	private RadioButtonModelAdapterUITest() {
+		super();
+	}
+
+	private void exec() throws Exception {
+		this.testModel = new TestModel();
+		this.testModelHolder = new SimplePropertyValueModel<TestModel>(this.testModel);
+		this.colorHolder = this.buildColorHolder(this.testModelHolder);
+		this.redButtonModel = this.buildRadioButtonModelAdapter(this.colorHolder, TestModel.RED);
+		this.greenButtonModel = this.buildRadioButtonModelAdapter(this.colorHolder, TestModel.GREEN);
+		this.blueButtonModel = this.buildRadioButtonModelAdapter(this.colorHolder, TestModel.BLUE);
+		this.openWindow();
+	}
+
+	private ModifiablePropertyValueModel<Object> buildColorHolder(PropertyValueModel<TestModel> subjectHolder) {
+		return new PropertyAspectAdapter<TestModel, Object>(subjectHolder, TestModel.COLOR_PROPERTY) {
+			@Override
+			protected Object buildValue_() {
+				return this.subject.getColor();
+			}
+			@Override
+			protected void setValue_(Object value) {
+				this.subject.setColor((String) value);
+			}
+		};
+	}
+
+	private ButtonModel buildRadioButtonModelAdapter(ModifiablePropertyValueModel<Object> colorPVM, String color) {
+		return new RadioButtonModelAdapter(colorPVM, color);
+	}
+
+	private void openWindow() {
+		JFrame window = new JFrame(this.getClass().getName());
+		window.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+		window.addWindowListener(this.buildWindowListener());
+		window.getContentPane().add(this.buildMainPanel(), "Center");
+		window.setSize(400, 100);
+		window.setLocation(200, 200);
+		window.setVisible(true);
+	}
+
+	private WindowListener buildWindowListener() {
+		return new WindowAdapter() {
+			@Override
+			public void windowClosing(WindowEvent e) {
+				e.getWindow().setVisible(false);
+				System.exit(0);
+			}
+		};
+	}
+
+	private Component buildMainPanel() {
+		JPanel mainPanel = new JPanel(new BorderLayout());
+		mainPanel.add(this.buildRadioButtonPanel(), BorderLayout.NORTH);
+		mainPanel.add(this.buildControlPanel(), BorderLayout.SOUTH);
+		return mainPanel;
+	}
+
+	private Component buildRadioButtonPanel() {
+		JPanel taskListPanel = new JPanel(new GridLayout(1, 0));
+		taskListPanel.add(this.buildRedRadioButton());
+		taskListPanel.add(this.buildGreenRadioButton());
+		taskListPanel.add(this.buildBlueRadioButton());
+		return taskListPanel;
+	}
+
+	private JRadioButton buildRedRadioButton() {
+		JRadioButton radioButton = new JRadioButton();
+		radioButton.setText("red");
+		radioButton.setModel(this.redButtonModel);
+		return radioButton;
+	}
+
+	private JRadioButton buildGreenRadioButton() {
+		JRadioButton radioButton = new JRadioButton();
+		radioButton.setText("green");
+		radioButton.setModel(this.greenButtonModel);
+		return radioButton;
+	}
+
+	private JRadioButton buildBlueRadioButton() {
+		JRadioButton radioButton = new JRadioButton();
+		radioButton.setText("blue");
+		radioButton.setModel(this.blueButtonModel);
+		return radioButton;
+	}
+
+	private Component buildControlPanel() {
+		JPanel controlPanel = new JPanel(new GridLayout(1, 0));
+		controlPanel.add(this.buildResetColorButton());
+		controlPanel.add(this.buildClearModelButton());
+		controlPanel.add(this.buildRestoreModelButton());
+		controlPanel.add(this.buildPrintModelButton());
+		return controlPanel;
+	}
+
+	private JButton buildResetColorButton() {
+		return new JButton(this.buildResetColorAction());
+	}
+
+	private Action buildResetColorAction() {
+		Action action = new AbstractAction("reset color") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				RadioButtonModelAdapterUITest.this.resetColor();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void resetColor() {
+		this.testModel.setColor(TestModel.DEFAULT_COLOR);
+	}
+
+	private JButton buildClearModelButton() {
+		return new JButton(this.buildClearModelAction());
+	}
+
+	private Action buildClearModelAction() {
+		Action action = new AbstractAction("clear model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				RadioButtonModelAdapterUITest.this.clearModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void clearModel() {
+		this.testModelHolder.setValue(null);
+	}
+
+	private JButton buildRestoreModelButton() {
+		return new JButton(this.buildRestoreModelAction());
+	}
+
+	private Action buildRestoreModelAction() {
+		Action action = new AbstractAction("restore model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				RadioButtonModelAdapterUITest.this.restoreModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void restoreModel() {
+		this.testModelHolder.setValue(this.testModel);
+	}
+
+	private JButton buildPrintModelButton() {
+		return new JButton(this.buildPrintModelAction());
+	}
+
+	private Action buildPrintModelAction() {
+		Action action = new AbstractAction("print model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				RadioButtonModelAdapterUITest.this.printModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void printModel() {
+		System.out.println(this.testModel);
+	}
+
+
+	private static class TestModel extends AbstractModel {
+		private String color;
+			public static final String COLOR_PROPERTY = "color";
+			public static final String RED = "red";
+			public static final String GREEN = "green";
+			public static final String BLUE = "blue";
+			public static final String DEFAULT_COLOR = RED;
+			public static final String[] VALID_COLORS = {
+				RED,
+				GREEN,
+				BLUE
+			};
+
+		public TestModel() {
+			this(DEFAULT_COLOR);
+		}
+		public TestModel(String color) {
+			this.color = color;
+		}
+		public String getColor() {
+			return this.color;
+		}
+		public void setColor(String color) {
+			if ( ! ArrayTools.contains(VALID_COLORS, color)) {
+				throw new IllegalArgumentException(color);
+			}
+			Object old = this.color;
+			this.color = color;
+			this.firePropertyChanged(COLOR_PROPERTY, old, color);
+		}
+		@Override
+		public String toString() {
+			return "TestModel(" + this.color + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ReadOnlyTableModelAdapterUITest.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ReadOnlyTableModelAdapterUITest.java
new file mode 100644
index 0000000..dbfc8f2
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/ReadOnlyTableModelAdapterUITest.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import org.eclipse.persistence.tools.utility.model.value.swing.TableModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.model.value.swing.TableModelAdapterTests.PersonColumnAdapter;
+
+/**
+ * Make it easy to test the table model adapter and
+ * renderers without any editing allowed.
+ */
+public class ReadOnlyTableModelAdapterUITest
+	extends TableModelAdapterUITest
+{
+	public static void main(String[] args) throws Exception {
+		new ReadOnlyTableModelAdapterUITest().exec(args);
+	}
+
+	protected ReadOnlyTableModelAdapterUITest() {
+		super();
+	}
+
+	@Override
+	protected TableModelAdapter.ColumnAdapter buildColumnAdapter() {
+		return new PersonColumnAdapter() {
+			@Override
+			public boolean columnIsEditable(int index) {
+				return false;
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/SpinnerModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/SpinnerModelAdapterTests.java
new file mode 100644
index 0000000..90c5462
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/SpinnerModelAdapterTests.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import javax.swing.SpinnerModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.SpinnerModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class SpinnerModelAdapterTests extends TestCase {
+	private ModifiablePropertyValueModel<Object> valueHolder;
+	SpinnerModel spinnerModelAdapter;
+	boolean eventFired;
+
+	public SpinnerModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.valueHolder = new SimplePropertyValueModel<Object>(new Integer(0));
+		this.spinnerModelAdapter = new SpinnerModelAdapter(this.valueHolder) {
+			@Override
+			protected PropertyChangeListener buildValueListener() {
+				return this.buildValueListener_();
+			}
+		};
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testSetValueSpinnerModel() throws Exception {
+		this.eventFired = false;
+		this.spinnerModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				SpinnerModelAdapterTests.this.eventFired = true;
+				assertEquals(SpinnerModelAdapterTests.this.spinnerModelAdapter, e.getSource());
+			}
+		});
+		this.spinnerModelAdapter.setValue(new Integer(5));
+		assertTrue(this.eventFired);
+		assertEquals(new Integer(5), this.valueHolder.getValue());
+	}
+
+	public void testSetValueValueHolder() throws Exception {
+		this.eventFired = false;
+		this.spinnerModelAdapter.addChangeListener(new TestChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				SpinnerModelAdapterTests.this.eventFired = true;
+				assertEquals(SpinnerModelAdapterTests.this.spinnerModelAdapter, e.getSource());
+			}
+		});
+		assertEquals(new Integer(0), this.spinnerModelAdapter.getValue());
+		this.valueHolder.setValue(new Integer(7));
+		assertTrue(this.eventFired);
+		assertEquals(new Integer(7), this.spinnerModelAdapter.getValue());
+	}
+
+	public void testHasListeners() throws Exception {
+		SimplePropertyValueModel<Object> localValueHolder = (SimplePropertyValueModel<Object>) this.valueHolder;
+		assertFalse(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(this.spinnerModelAdapter);
+
+		ChangeListener listener = new TestChangeListener();
+		this.spinnerModelAdapter.addChangeListener(listener);
+		assertTrue(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasListeners(this.spinnerModelAdapter);
+
+		this.spinnerModelAdapter.removeChangeListener(listener);
+		assertFalse(localValueHolder.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE));
+		this.verifyHasNoListeners(this.spinnerModelAdapter);
+	}
+
+	private void verifyHasNoListeners(Object adapter) throws Exception {
+		Object delegate = ObjectTools.get(adapter, "delegate");
+		Object[] listeners = (Object[]) ObjectTools.execute(delegate, "getChangeListeners");
+		assertEquals(0, listeners.length);
+	}
+
+	private void verifyHasListeners(Object adapter) throws Exception {
+		Object delegate = ObjectTools.get(adapter, "delegate");
+		Object[] listeners = (Object[]) ObjectTools.execute(delegate, "getChangeListeners");
+		assertFalse(listeners.length == 0);
+	}
+
+
+	private class TestChangeListener implements ChangeListener {
+		TestChangeListener() {
+			super();
+		}
+		@Override
+		public void stateChanged(ChangeEvent e) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/SpinnerModelAdapterUITest.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/SpinnerModelAdapterUITest.java
new file mode 100644
index 0000000..a117c36
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/SpinnerModelAdapterUITest.java
@@ -0,0 +1,349 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.util.Calendar;
+import java.util.Date;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JSpinner;
+import javax.swing.SpinnerModel;
+import javax.swing.WindowConstants;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.DateSpinnerModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.swing.ListSpinnerModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.swing.NumberSpinnerModelAdapter;
+
+/**
+ * Play around with a set of spinners.
+ */
+@SuppressWarnings("nls")
+public class SpinnerModelAdapterUITest {
+
+	private TestModel testModel;
+	private ModifiablePropertyValueModel<TestModel> testModelHolder;
+
+	private ModifiablePropertyValueModel<Object> birthDateHolder;
+	private SpinnerModel birthDateSpinnerModel;
+
+	private ModifiablePropertyValueModel<Number> ageHolder;
+	private SpinnerModel ageSpinnerModel;
+
+	private ModifiablePropertyValueModel<Object> eyeColorHolder;
+	private SpinnerModel eyeColorSpinnerModel;
+
+
+	public static void main(String[] args) throws Exception {
+		new SpinnerModelAdapterUITest().exec();
+	}
+
+	private SpinnerModelAdapterUITest() {
+		super();
+	}
+
+	private void exec() throws Exception {
+		this.testModel = new TestModel();
+		this.testModelHolder = new SimplePropertyValueModel<TestModel>(this.testModel);
+
+		this.birthDateHolder = this.buildBirthDateHolder(this.testModelHolder);
+		this.birthDateSpinnerModel = this.buildBirthDateSpinnerModel(this.birthDateHolder);
+
+		this.ageHolder = this.buildAgeHolder(this.testModelHolder);
+		this.ageSpinnerModel = this.buildAgeSpinnerModel(this.ageHolder);
+
+		this.eyeColorHolder = this.buildEyeColorHolder(this.testModelHolder);
+		this.eyeColorSpinnerModel = this.buildEyeColorSpinnerModel(this.eyeColorHolder);
+
+		this.openWindow();
+	}
+
+	private ModifiablePropertyValueModel<Object> buildBirthDateHolder(PropertyValueModel<TestModel> vm) {
+		return new PropertyAspectAdapter<TestModel, Object>(vm, TestModel.BIRTH_DATE_PROPERTY) {
+			@Override
+			protected Object buildValue_() {
+				return this.subject.getBirthDate();
+			}
+			@Override
+			protected void setValue_(Object value) {
+				this.subject.setBirthDate((Date) value);
+			}
+		};
+	}
+
+	private SpinnerModel buildBirthDateSpinnerModel(ModifiablePropertyValueModel<Object> valueHolder) {
+		return new DateSpinnerModelAdapter(valueHolder);
+	}
+
+	private ModifiablePropertyValueModel<Number> buildAgeHolder(PropertyValueModel<TestModel> vm) {
+		return new PropertyAspectAdapter<TestModel, Number>(vm, TestModel.AGE_PROPERTY) {
+			@Override
+			protected Number buildValue_() {
+				return new Integer(this.subject.getAge());
+			}
+			@Override
+			protected void setValue_(Number value) {
+				this.subject.setAge(value.intValue());
+			}
+		};
+	}
+
+	private SpinnerModel buildAgeSpinnerModel(ModifiablePropertyValueModel<Number> valueHolder) {
+		return new NumberSpinnerModelAdapter(valueHolder, valueHolder.getValue().intValue(), TestModel.MIN_AGE, TestModel.MAX_AGE, 1);
+	}
+
+	private ModifiablePropertyValueModel<Object> buildEyeColorHolder(PropertyValueModel<TestModel> vm) {
+		return new PropertyAspectAdapter<TestModel, Object>(vm, TestModel.EYE_COLOR_PROPERTY) {
+			@Override
+			protected Object buildValue_() {
+				return this.subject.getEyeColor();
+			}
+			@Override
+			protected void setValue_(Object value) {
+				this.subject.setEyeColor((String) value);
+			}
+		};
+	}
+
+	private SpinnerModel buildEyeColorSpinnerModel(ModifiablePropertyValueModel<Object> valueHolder) {
+		return new ListSpinnerModelAdapter(valueHolder, TestModel.VALID_EYE_COLORS);
+	}
+
+	private void openWindow() {
+		JFrame window = new JFrame(this.getClass().getName());
+		window.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+		window.addWindowListener(this.buildWindowListener());
+		window.getContentPane().add(this.buildMainPanel(), "Center");
+		window.setSize(600, 100);
+		window.setVisible(true);
+	}
+
+	private WindowListener buildWindowListener() {
+		return new WindowAdapter() {
+			@Override
+			public void windowClosing(WindowEvent e) {
+				e.getWindow().setVisible(false);
+				System.exit(0);
+			}
+		};
+	}
+
+	private Component buildMainPanel() {
+		JPanel mainPanel = new JPanel(new BorderLayout());
+		mainPanel.add(this.buildSpinnerPanel(), BorderLayout.NORTH);
+		mainPanel.add(this.buildControlPanel(), BorderLayout.SOUTH);
+		return mainPanel;
+	}
+
+	private Component buildSpinnerPanel() {
+		JPanel taskListPanel = new JPanel(new GridLayout(1, 0));
+		taskListPanel.add(this.buildBirthDateSpinner());
+		taskListPanel.add(this.buildAgeSpinner());
+		taskListPanel.add(this.buildEyeColorSpinner());
+		return taskListPanel;
+	}
+
+	private JSpinner buildBirthDateSpinner() {
+		return new JSpinner(this.birthDateSpinnerModel);
+	}
+
+	private JSpinner buildAgeSpinner() {
+		return new JSpinner(this.ageSpinnerModel);
+	}
+
+	private JSpinner buildEyeColorSpinner() {
+		return new JSpinner(this.eyeColorSpinnerModel);
+	}
+
+	private Component buildControlPanel() {
+		JPanel controlPanel = new JPanel(new GridLayout(1, 0));
+		controlPanel.add(this.buildResetModelButton());
+		controlPanel.add(this.buildClearModelButton());
+		controlPanel.add(this.buildRestoreModelButton());
+		controlPanel.add(this.buildPrintModelButton());
+		return controlPanel;
+	}
+
+	private JButton buildResetModelButton() {
+		return new JButton(this.buildResetModelAction());
+	}
+
+	private Action buildResetModelAction() {
+		Action action = new AbstractAction("reset model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				SpinnerModelAdapterUITest.this.resetModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void resetModel() {
+		this.testModel.setBirthDate(TestModel.DEFAULT_BIRTH_DATE);
+		this.testModel.setEyeColor(TestModel.DEFAULT_EYE_COLOR);
+	}
+
+	private JButton buildClearModelButton() {
+		return new JButton(this.buildClearModelAction());
+	}
+
+	private Action buildClearModelAction() {
+		Action action = new AbstractAction("clear model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				SpinnerModelAdapterUITest.this.clearModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void clearModel() {
+		this.testModelHolder.setValue(null);
+	}
+
+	private JButton buildRestoreModelButton() {
+		return new JButton(this.buildRestoreModelAction());
+	}
+
+	private Action buildRestoreModelAction() {
+		Action action = new AbstractAction("restore model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				SpinnerModelAdapterUITest.this.restoreModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void restoreModel() {
+		this.testModelHolder.setValue(this.testModel);
+	}
+
+	private JButton buildPrintModelButton() {
+		return new JButton(this.buildPrintModelAction());
+	}
+
+	private Action buildPrintModelAction() {
+		Action action = new AbstractAction("print model") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				SpinnerModelAdapterUITest.this.printModel();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void printModel() {
+		System.out.println("birth date: " + this.testModel.getBirthDate());
+		System.out.println("age: " + this.testModel.getAge());
+		System.out.println("eyes: " + this.testModel.getEyeColor());
+	}
+
+
+	static class TestModel extends AbstractModel {
+		private Calendar birthCal = Calendar.getInstance();
+			// "virtual" properties
+			public static final String BIRTH_DATE_PROPERTY = "birthDate";
+			public static final String AGE_PROPERTY = "age";
+			public static final Date DEFAULT_BIRTH_DATE = new Date();
+			public static final int DEFAULT_AGE = 0;
+			public static final int MIN_AGE = 0;
+			public static final int MAX_AGE = 150;
+		private String eyeColor;
+			public static final String EYE_COLOR_PROPERTY = "eyeColor";
+			public static final String[] VALID_EYE_COLORS = {"blue", "brown", "green", "hazel", "pink"};
+			public static final String DEFAULT_EYE_COLOR = VALID_EYE_COLORS[3];
+
+		TestModel() {
+			this(DEFAULT_BIRTH_DATE, DEFAULT_EYE_COLOR);
+		}
+		public TestModel(Date birthDate, String eyeColor) {
+			this.setBirthDate(birthDate);
+			this.setEyeColor(eyeColor);
+		}
+		public Date getBirthDate() {
+			return (Date) this.birthCal.getTime().clone();
+		}
+		public void setBirthDate(Date birthDate) {
+			Date oldBirthDate = this.getBirthDate();
+			int oldAge = this.getAge();
+			this.birthCal.setTimeInMillis(birthDate.getTime());
+			int newAge = this.getAge();
+			if (newAge < MIN_AGE || newAge > MAX_AGE) {
+				throw new IllegalArgumentException(birthDate.toString());
+			}
+			this.firePropertyChanged(BIRTH_DATE_PROPERTY, oldBirthDate, this.getBirthDate());
+			this.firePropertyChanged(AGE_PROPERTY, oldAge, newAge);
+		}
+		public int getAge() {
+			Calendar currentCal = Calendar.getInstance();
+			int age = currentCal.get(Calendar.YEAR) - this.birthCal.get(Calendar.YEAR);
+			if (currentCal.get(Calendar.MONTH) < this.birthCal.get(Calendar.MONTH)) {
+				age--;
+			} else if (currentCal.get(Calendar.MONTH) == this.birthCal.get(Calendar.MONTH)) {
+				if (currentCal.get(Calendar.DAY_OF_MONTH) < this.birthCal.get(Calendar.DAY_OF_MONTH)) {
+					age--;
+				}
+			}
+			return age;
+		}
+		public void setAge(int newAge) {
+			if (newAge < MIN_AGE || newAge > MAX_AGE) {
+				throw new IllegalArgumentException(String.valueOf(newAge));
+			}
+
+			int oldAge = this.getAge();
+			int delta = newAge - oldAge;
+
+			Calendar newBirthCal = Calendar.getInstance();
+			newBirthCal.setTimeInMillis(this.birthCal.getTime().getTime());
+			// if the age increased, the birth date must be "decreased"; and vice versa
+			newBirthCal.set(Calendar.YEAR, newBirthCal.get(Calendar.YEAR) - delta);
+			this.setBirthDate(newBirthCal.getTime());
+		}
+		public String getEyeColor() {
+			return this.eyeColor;
+		}
+		public void setEyeColor(String eyeColor) {
+			if ( ! ArrayTools.contains(VALID_EYE_COLORS, eyeColor)) {
+				throw new IllegalArgumentException(eyeColor);
+			}
+			Object old = this.eyeColor;
+			this.eyeColor = eyeColor;
+			this.firePropertyChanged(EYE_COLOR_PROPERTY, old, eyeColor);
+		}
+		@Override
+		public String toString() {
+			return "TestModel(birth: " + this.getBirthDate() + " - eyes: " + this.eyeColor + ")";
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/TableModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/TableModelAdapterTests.java
new file mode 100644
index 0000000..e1e783e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/TableModelAdapterTests.java
@@ -0,0 +1,653 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterator.CloneIterator;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.CollectionAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.SortedListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.swing.TableModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class TableModelAdapterTests extends TestCase {
+	private Crowd crowd;
+	TableModelEvent event;
+
+	public TableModelAdapterTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.crowd = this.buildCrowd();
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testGetRowCount() throws Exception {
+		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
+		assertEquals(0, tableModelAdapter.getRowCount());
+		// we need to add a listener to wake up the adapter
+		tableModelAdapter.addTableModelListener(this.buildTableModelListener());
+		assertEquals(this.crowd.peopleSize(), tableModelAdapter.getRowCount());
+	}
+
+	public void testGetColumnCount() throws Exception {
+		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
+		assertEquals(PersonColumnAdapter.COLUMN_COUNT, tableModelAdapter.getColumnCount());
+	}
+
+	public void testGetValueAt() throws Exception {
+		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
+		tableModelAdapter.addTableModelListener(this.buildTableModelListener());
+
+		List<String> sortedNames = this.sortedNames();
+		for (int i = 0; i < this.crowd.peopleSize(); i++) {
+			assertEquals(sortedNames.get(i), tableModelAdapter.getValueAt(i, PersonColumnAdapter.NAME_COLUMN));
+		}
+	}
+
+	public void testSetValueAt() throws Exception {
+		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
+		this.event = null;
+		tableModelAdapter.addTableModelListener(new TestTableModelListener() {
+			@Override
+			public void tableChanged(TableModelEvent e) {
+				TableModelAdapterTests.this.event = e;
+			}
+		});
+
+		Person person = this.crowd.personNamed("Gollum");
+		assertEquals(Person.EYE_COLOR_BLUE, person.getEyeColor());
+		assertFalse(person.isEvil());
+		assertEquals(0, person.getRank());
+
+		for (int i = 0; i < tableModelAdapter.getRowCount(); i++) {
+			if (tableModelAdapter.getValueAt(i, PersonColumnAdapter.NAME_COLUMN).equals("Gollum")) {
+				tableModelAdapter.setValueAt(Person.EYE_COLOR_HAZEL, i, PersonColumnAdapter.EYE_COLOR_COLUMN);
+				tableModelAdapter.setValueAt(Boolean.TRUE, i, PersonColumnAdapter.EVIL_COLUMN);
+				tableModelAdapter.setValueAt(new Integer(-1), i, PersonColumnAdapter.RANK_COLUMN);
+				break;
+			}
+		}
+		assertNotNull(this.event);
+		assertEquals(Person.EYE_COLOR_HAZEL, person.getEyeColor());
+		assertTrue(person.isEvil());
+		assertEquals(-1, person.getRank());
+	}
+
+	public void testAddRow() throws Exception {
+		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
+		this.event = null;
+		tableModelAdapter.addTableModelListener(this.buildSingleEventListener());
+		// add a person to the end of the list so we only trigger one event
+		this.crowd.addPerson("Zzzzz");
+		assertNotNull(this.event);
+		assertEquals(TableModelEvent.INSERT, this.event.getType());
+		assertEquals(TableModelEvent.ALL_COLUMNS, this.event.getColumn());
+	}
+
+	public void testRemoveRow() throws Exception {
+		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
+		this.event = null;
+		tableModelAdapter.addTableModelListener(this.buildSingleEventListener());
+		// removing a person should only trigger one event, since a re-sort is not needed
+		this.crowd.removePerson(this.crowd.personNamed("Gollum"));
+		assertNotNull(this.event);
+		assertEquals(TableModelEvent.DELETE, this.event.getType());
+		assertEquals(TableModelEvent.ALL_COLUMNS, this.event.getColumn());
+	}
+
+	public void testChangeCell() throws Exception {
+		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
+		this.event = null;
+		tableModelAdapter.addTableModelListener(this.buildSingleEventListener());
+		// add a person to the end of the list so we only trigger one event
+		Person person = this.crowd.personNamed("Gollum");
+		person.setEvil(true);
+		assertNotNull(this.event);
+		assertEquals(TableModelEvent.UPDATE, this.event.getType());
+		assertEquals(PersonColumnAdapter.EVIL_COLUMN, this.event.getColumn());
+	}
+
+	public void testLazyListListener() throws Exception {
+		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
+		TableModelListener listener = this.buildTableModelListener();
+		assertTrue(this.crowd.hasNoCollectionChangeListeners(Crowd.PEOPLE_COLLECTION));
+		tableModelAdapter.addTableModelListener(listener);
+		assertTrue(this.crowd.hasAnyCollectionChangeListeners(Crowd.PEOPLE_COLLECTION));
+		tableModelAdapter.removeTableModelListener(listener);
+		assertTrue(this.crowd.hasNoCollectionChangeListeners(Crowd.PEOPLE_COLLECTION));
+	}
+
+	public void testLazyCellListener() throws Exception {
+		TableModelAdapter<Person> tableModelAdapter =  this.buildTableModelAdapter();
+		TableModelListener listener = this.buildTableModelListener();
+		Person person = this.crowd.personNamed("Gollum");
+		assertTrue(person.hasNoPropertyChangeListeners(Person.NAME_PROPERTY));
+		assertTrue(person.hasNoPropertyChangeListeners(Person.BIRTH_DATE_PROPERTY));
+		assertTrue(person.hasNoPropertyChangeListeners(Person.EYE_COLOR_PROPERTY));
+		assertTrue(person.hasNoPropertyChangeListeners(Person.EVIL_PROPERTY));
+		assertTrue(person.hasNoPropertyChangeListeners(Person.RANK_PROPERTY));
+
+		tableModelAdapter.addTableModelListener(listener);
+		assertTrue(person.hasAnyPropertyChangeListeners(Person.NAME_PROPERTY));
+		assertTrue(person.hasAnyPropertyChangeListeners(Person.BIRTH_DATE_PROPERTY));
+		assertTrue(person.hasAnyPropertyChangeListeners(Person.EYE_COLOR_PROPERTY));
+		assertTrue(person.hasAnyPropertyChangeListeners(Person.EVIL_PROPERTY));
+		assertTrue(person.hasAnyPropertyChangeListeners(Person.RANK_PROPERTY));
+
+		tableModelAdapter.removeTableModelListener(listener);
+		assertTrue(person.hasNoPropertyChangeListeners(Person.NAME_PROPERTY));
+		assertTrue(person.hasNoPropertyChangeListeners(Person.BIRTH_DATE_PROPERTY));
+		assertTrue(person.hasNoPropertyChangeListeners(Person.EYE_COLOR_PROPERTY));
+		assertTrue(person.hasNoPropertyChangeListeners(Person.EVIL_PROPERTY));
+		assertTrue(person.hasNoPropertyChangeListeners(Person.RANK_PROPERTY));
+	}
+
+	private TableModelAdapter<Person> buildTableModelAdapter() {
+		return new TableModelAdapter<Person>(this.buildSortedPeopleAdapter(), this.buildColumnAdapter()) {
+			@Override
+			protected PropertyChangeListener buildCellListener() {
+				return this.buildCellListener_();
+			}
+			@Override
+			protected ListChangeListener buildListChangeListener() {
+				return this.buildListChangeListener_();
+			}
+		};
+	}
+
+	private ListValueModel<Person> buildSortedPeopleAdapter() {
+		return new SortedListValueModelAdapter<Person>(this.buildPeopleAdapter());
+	}
+
+	private CollectionValueModel<Person> buildPeopleAdapter() {
+		return new CollectionAspectAdapter<Crowd, Person>(Crowd.PEOPLE_COLLECTION, this.crowd) {
+			@Override
+			protected Iterator<Person> iterator_() {
+				return this.subject.people();
+			}
+			@Override
+			protected int size_() {
+				return this.subject.peopleSize();
+			}
+		};
+	}
+
+	private Crowd buildCrowd() {
+		Crowd result = new Crowd();
+		result.addPerson("Bilbo");
+		result.addPerson("Gollum");
+		result.addPerson("Frodo");
+		result.addPerson("Samwise");
+		return result;
+	}
+
+	private TableModelAdapter.ColumnAdapter buildColumnAdapter() {
+		return new PersonColumnAdapter();
+	}
+
+	private TableModelListener buildTableModelListener() {
+		return new TestTableModelListener();
+	}
+
+	private List<String> sortedNames() {
+		return new ArrayList<String>(CollectionTools.sortedSet(this.crowd.peopleNames()));
+	}
+
+	private TableModelListener buildSingleEventListener() {
+		return new TestTableModelListener() {
+			@Override
+			public void tableChanged(TableModelEvent e) {
+				// we expect only a single event
+				if (TableModelAdapterTests.this.event == null) {
+					TableModelAdapterTests.this.event = e;
+				} else {
+					fail("unexpected event");
+				}
+			}
+		};
+	}
+
+
+	// ********** classes **********
+
+	public static class PersonColumnAdapter
+		implements TableModelAdapter.ColumnAdapter
+	{
+		public static final int COLUMN_COUNT = 7;
+
+		public static final int NAME_COLUMN = 0;
+		public static final int BIRTH_DATE_COLUMN = 1;
+		public static final int GONE_WEST_DATE_COLUMN = 2;
+		public static final int EYE_COLOR_COLUMN = 3;
+		public static final int EVIL_COLUMN = 4;
+		public static final int RANK_COLUMN = 5;
+		public static final int ADVENTURE_COUNT_COLUMN = 6;
+
+		private static final String[] COLUMN_NAMES = new String[] {
+			"Name",
+			"Birth",
+			"Gone West",
+			"Eyes",
+			"Evil",
+			"Rank",
+			"Adventures"
+		};
+
+
+		@Override
+		public int columnCount() {
+			return COLUMN_COUNT;
+		}
+
+		@Override
+		public String columnName(int index) {
+			return COLUMN_NAMES[index];
+		}
+
+		@Override
+		public Class<?> columnClass(int index) {
+			switch (index) {
+				case NAME_COLUMN:					return Object.class;
+				case BIRTH_DATE_COLUMN:			return Date.class;
+				case GONE_WEST_DATE_COLUMN:	return Date.class;
+				case EYE_COLOR_COLUMN:			return Object.class;
+				case EVIL_COLUMN:					return Boolean.class;
+				case RANK_COLUMN:					return Integer.class;
+				case ADVENTURE_COUNT_COLUMN:return Integer.class;
+				default: 									return Object.class;
+			}
+		}
+
+		@Override
+		public boolean columnIsEditable(int index) {
+			return index != NAME_COLUMN;
+		}
+
+		@Override
+		public ModifiablePropertyValueModel<Object>[] cellModels(Object subject) {
+			Person person = (Person) subject;
+			@SuppressWarnings("unchecked")
+			ModifiablePropertyValueModel<Object>[] result = new ModifiablePropertyValueModel[COLUMN_COUNT];
+
+			result[NAME_COLUMN] = this.buildNameAdapter(person);
+			result[BIRTH_DATE_COLUMN] = this.buildBirthDateAdapter(person);
+			result[GONE_WEST_DATE_COLUMN] = this.buildGoneWestDateAdapter(person);
+			result[EYE_COLOR_COLUMN] = this.buildEyeColorAdapter(person);
+			result[EVIL_COLUMN] = this.buildEvilAdapter(person);
+			result[RANK_COLUMN] = this.buildRankAdapter(person);
+			result[ADVENTURE_COUNT_COLUMN] = this.buildAdventureCountAdapter(person);
+
+			return result;
+		}
+
+		private ModifiablePropertyValueModel<Object> buildNameAdapter(Person person) {
+			return new PropertyAspectAdapter<Person, Object>(Person.NAME_PROPERTY, person) {
+				@Override
+				protected String buildValue_() {
+					return this.subject.getName();
+				}
+				@Override
+				protected void setValue_(Object value) {
+					this.subject.setName((String) value);
+				}
+			};
+		}
+
+		private ModifiablePropertyValueModel<Object> buildBirthDateAdapter(Person person) {
+			return new PropertyAspectAdapter<Person, Object>(Person.BIRTH_DATE_PROPERTY, person) {
+				@Override
+				protected Date buildValue_() {
+					return this.subject.getBirthDate();
+				}
+				@Override
+				protected void setValue_(Object value) {
+					this.subject.setBirthDate((Date) value);
+				}
+			};
+		}
+
+		private ModifiablePropertyValueModel<Object> buildGoneWestDateAdapter(Person person) {
+			return new PropertyAspectAdapter<Person, Object>(Person.GONE_WEST_DATE_PROPERTY, person) {
+				@Override
+				protected Date buildValue_() {
+					return this.subject.getGoneWestDate();
+				}
+				@Override
+				protected void setValue_(Object value) {
+					this.subject.setGoneWestDate((Date) value);
+				}
+			};
+		}
+
+		private ModifiablePropertyValueModel<Object> buildEyeColorAdapter(Person person) {
+			return new PropertyAspectAdapter<Person, Object>(Person.EYE_COLOR_PROPERTY, person) {
+				@Override
+				protected String buildValue_() {
+					return this.subject.getEyeColor();
+				}
+				@Override
+				protected void setValue_(Object value) {
+					this.subject.setEyeColor((String) value);
+				}
+			};
+		}
+
+		private ModifiablePropertyValueModel<Object> buildEvilAdapter(Person person) {
+			return new PropertyAspectAdapter<Person, Object>(Person.EVIL_PROPERTY, person) {
+				@Override
+				protected Boolean buildValue_() {
+					return Boolean.valueOf(this.subject.isEvil());
+				}
+				@Override
+				protected void setValue_(Object value) {
+					this.subject.setEvil(((Boolean)value).booleanValue());
+				}
+			};
+		}
+
+		private ModifiablePropertyValueModel<Object> buildRankAdapter(Person person) {
+			return new PropertyAspectAdapter<Person, Object>(Person.RANK_PROPERTY, person) {
+				@Override
+				protected Integer buildValue_() {
+					return new Integer(this.subject.getRank());
+				}
+				@Override
+				protected void setValue_(Object value) {
+					this.subject.setRank(((Integer) value).intValue());
+				}
+			};
+		}
+
+		private ModifiablePropertyValueModel<Object> buildAdventureCountAdapter(Person person) {
+			return new PropertyAspectAdapter<Person, Object>(Person.ADVENTURE_COUNT_PROPERTY, person) {
+				@Override
+				protected Integer buildValue_() {
+					return new Integer(this.subject.getAdventureCount());
+				}
+				@Override
+				protected void setValue_(Object value) {
+					this.subject.setAdventureCount(((Integer) value).intValue());
+				}
+			};
+		}
+
+	}
+
+
+	public static class Crowd extends AbstractModel {
+		private final Collection<Person> people;
+			public static final String PEOPLE_COLLECTION = "people";
+
+		public Crowd() {
+			super();
+			this.people = new ArrayList<Person>();
+		}
+
+
+		public Iterator<Person> people() {
+			return new CloneIterator<Person>(this.people, new CloneIterator.Remover<Person>() {
+				@Override
+				public void remove(Person person) {
+					Crowd.this.removePerson(person);
+				}
+			});
+		}
+
+		public int peopleSize() {
+			return this.people.size();
+		}
+
+		public Person addPerson(String name) {
+			this.checkPersonName(name);
+			return this.addPerson(new Person(this, name));
+		}
+
+		private Person addPerson(Person person) {
+			this.addItemToCollection(person, this.people, PEOPLE_COLLECTION);
+			return person;
+		}
+
+		public void removePerson(Person person) {
+			this.removeItemFromCollection(person, this.people, PEOPLE_COLLECTION);
+		}
+
+		public void removePeople(Collection<Person> persons) {
+			this.removeItemsFromCollection(persons, this.people, PEOPLE_COLLECTION);
+		}
+
+		public void removePeople(Iterator<Person> persons) {
+			this.removeItemsFromCollection(persons, this.people, PEOPLE_COLLECTION);
+		}
+
+		void checkPersonName(String personName) {
+			if (personName == null) {
+				throw new NullPointerException();
+			}
+			if (IteratorTools.contains(this.peopleNames(), personName)) {
+				throw new IllegalArgumentException(personName);
+			}
+		}
+
+		public Iterator<String> peopleNames() {
+			return new TransformationIterator<Person, String>(this.people.iterator()) {
+				@Override
+				protected String transform(Person person) {
+					return person.getName();
+				}
+			};
+		}
+
+		public Person personNamed(String name) {
+			for (Iterator<Person> stream = this.people.iterator(); stream.hasNext(); ) {
+				Person person = stream.next();
+				if (person.getName().equals(name)) {
+					return person;
+				}
+			}
+			return null;
+		}
+
+		@Override
+		public String toString() {
+			return ObjectTools.toString(this, String.valueOf(this.people.size()) + " people");
+		}
+
+	}
+
+
+	public static class Person extends AbstractModel implements Comparable<Person> {
+		private Crowd crowd;
+		private String name;
+			public static final String NAME_PROPERTY= "name";
+		private Date birthDate;
+			public static final String BIRTH_DATE_PROPERTY= "birthDate";
+		private Date goneWestDate;
+			public static final String GONE_WEST_DATE_PROPERTY= "goneWestDate";
+		private String eyeColor;
+			public static final String EYE_COLOR_PROPERTY= "eyeColor";
+			public static final String EYE_COLOR_BLUE = "blue";
+			public static final String EYE_COLOR_GREEN = "green";
+			public static final String EYE_COLOR_BROWN = "brown";
+			public static final String EYE_COLOR_HAZEL = "hazel";
+			public static final String EYE_COLOR_PINK = "pink";
+			private static Collection<String> validEyeColors;
+			public static final String DEFAULT_EYE_COLOR = EYE_COLOR_BLUE;
+		private boolean evil;
+			public static final String EVIL_PROPERTY= "evil";
+		private int rank;
+			public static final String RANK_PROPERTY= "rank";
+		private int adventureCount;
+			public static final String ADVENTURE_COUNT_PROPERTY= "adventureCount";
+
+		Person(Crowd crowd, String name) {
+			super();
+			this.crowd = crowd;
+			this.name = name;
+			this.birthDate = new Date();
+			Calendar c = Calendar.getInstance();
+			c.add(Calendar.YEAR, 250);
+			this.goneWestDate = new Date(c.getTimeInMillis());
+			this.eyeColor = DEFAULT_EYE_COLOR;
+			this.evil = false;
+			this.rank = 0;
+			this.adventureCount = 0;
+		}
+
+		public static Collection<String> getValidEyeColors() {
+			if (validEyeColors == null) {
+				validEyeColors = buildValidEyeColors();
+			}
+			return validEyeColors;
+		}
+
+		private static Collection<String> buildValidEyeColors() {
+			Collection<String> result = new ArrayList<String>();
+			result.add(EYE_COLOR_BLUE);
+			result.add(EYE_COLOR_GREEN);
+			result.add(EYE_COLOR_BROWN);
+			result.add(EYE_COLOR_HAZEL);
+			result.add(EYE_COLOR_PINK);
+			return result;
+		}
+
+		public Crowd getCrowd() {
+			return this.crowd;
+		}
+
+		public String getName() {
+			return this.name;
+		}
+		public void setName(String name) {
+			this.crowd.checkPersonName(name);
+			Object old = this.name;
+			this.name = name;
+			this.firePropertyChanged(NAME_PROPERTY, old, name);
+		}
+
+		public Date getBirthDate() {
+			return this.birthDate;
+		}
+		public void setBirthDate(Date birthDate) {
+			Object old = this.birthDate;
+			this.birthDate = birthDate;
+			this.firePropertyChanged(BIRTH_DATE_PROPERTY, old, birthDate);
+		}
+
+		public Date getGoneWestDate() {
+			return this.goneWestDate;
+		}
+		public void setGoneWestDate(Date goneWestDate) {
+			Object old = this.goneWestDate;
+			this.goneWestDate = goneWestDate;
+			this.firePropertyChanged(GONE_WEST_DATE_PROPERTY, old, goneWestDate);
+		}
+
+		public String getEyeColor() {
+			return this.eyeColor;
+		}
+		public void setEyeColor(String eyeColor) {
+			if (! getValidEyeColors().contains(eyeColor)) {
+				throw new IllegalArgumentException(eyeColor);
+			}
+			Object old = this.eyeColor;
+			this.eyeColor = eyeColor;
+			this.firePropertyChanged(EYE_COLOR_PROPERTY, old, eyeColor);
+		}
+
+		public boolean isEvil() {
+			return this.evil;
+		}
+		public void setEvil(boolean evil) {
+			boolean old = this.evil;
+			this.evil = evil;
+			this.firePropertyChanged(EVIL_PROPERTY, old, evil);
+		}
+
+		public int getRank() {
+			return this.rank;
+		}
+		public void setRank(int rank) {
+			int old = this.rank;
+			this.rank = rank;
+			this.firePropertyChanged(RANK_PROPERTY, old, rank);
+		}
+
+		public int getAdventureCount() {
+			return this.adventureCount;
+		}
+		public void setAdventureCount(int adventureCount) {
+			int old = this.adventureCount;
+			this.adventureCount = adventureCount;
+			this.firePropertyChanged(ADVENTURE_COUNT_PROPERTY, old, adventureCount);
+		}
+
+		@Override
+		public int compareTo(Person p) {
+			return this.name.compareToIgnoreCase(p.name);
+		}
+
+		@Override
+		public String toString() {
+			return this.name +
+						"\tborn: " + DateFormat.getDateInstance().format(this.birthDate) +
+						"\tgone west: " + DateFormat.getDateInstance().format(this.goneWestDate) +
+						"\teyes: " + this.eyeColor +
+						"\tevil: " + this.evil +
+						"\trank: " + this.rank +
+						"\tadventures: " + this.adventureCount
+			;
+		}
+
+	}
+
+
+	private class TestTableModelListener implements TableModelListener {
+		TestTableModelListener() {
+			super();
+		}
+		@Override
+		public void tableChanged(TableModelEvent e) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/TableModelAdapterUITest.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/TableModelAdapterUITest.java
new file mode 100644
index 0000000..41ee4a9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/TableModelAdapterUITest.java
@@ -0,0 +1,740 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ButtonModel;
+import javax.swing.ComboBoxModel;
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSpinner;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.ListCellRenderer;
+import javax.swing.ListSelectionModel;
+import javax.swing.SpinnerModel;
+import javax.swing.UIManager;
+import javax.swing.WindowConstants;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableModel;
+import javax.swing.text.Document;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.model.value.CollectionAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.SimpleCollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SortedListValueModelWrapper;
+import org.eclipse.persistence.tools.utility.model.value.swing.CheckBoxModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.swing.ComboBoxModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.swing.DateSpinnerModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.swing.DocumentAdapter;
+import org.eclipse.persistence.tools.utility.model.value.swing.ListModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.swing.NumberSpinnerModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.swing.ObjectListSelectionModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.TableModelAdapter;
+import org.eclipse.persistence.tools.utility.swing.CheckBoxTableCellRenderer;
+import org.eclipse.persistence.tools.utility.swing.ComboBoxTableCellRenderer;
+import org.eclipse.persistence.tools.utility.swing.SpinnerTableCellRenderer;
+import org.eclipse.persistence.tools.utility.swing.TableCellEditorAdapter;
+import org.eclipse.persistence.tools.utility.tests.model.value.swing.TableModelAdapterTests.Crowd;
+import org.eclipse.persistence.tools.utility.tests.model.value.swing.TableModelAdapterTests.Person;
+import org.eclipse.persistence.tools.utility.tests.model.value.swing.TableModelAdapterTests.PersonColumnAdapter;
+
+/**
+ * an example UI for testing the TableModelAdapter
+ * 	"name" column is read-only text field
+ * 	"birth date" column is date text field
+ * 	"gone west date" column is date spinner
+ * 	"eye color" column is combo-box
+ * 	"evil" column is check box
+ * 	"rank" column is number text field
+ * 	"adventure count" column is number spinner
+ *
+ * Note that the table model and row selection model share the same
+ * list value model (the sorted people adapter)
+ */
+@SuppressWarnings("nls")
+public class TableModelAdapterUITest {
+	private SimpleCollectionValueModel<Object> eyeColorsHolder;  // Object because it adapts to a combo-box
+	private ModifiablePropertyValueModel<Crowd> crowdHolder;
+	private ModifiablePropertyValueModel<Person> selectedPersonHolder;
+	private ListValueModel<Person> sortedPeopleAdapter;
+	private TableModel tableModel;
+	private ObjectListSelectionModel rowSelectionModel;
+	private Action removeAction;
+	private Action renameAction;
+
+	public static void main(String[] args) throws Exception {
+		new TableModelAdapterUITest().exec(args);
+	}
+
+	protected TableModelAdapterUITest() {
+		super();
+	}
+
+	protected void exec(@SuppressWarnings("unused") String[] args) throws Exception {
+		UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+		this.eyeColorsHolder = this. buildEyeColorCollectionHolder();
+		this.crowdHolder = this.buildCrowdHolder();
+		this.selectedPersonHolder = this.buildSelectedPersonHolder();
+		this.sortedPeopleAdapter = this.buildSortedPeopleAdapter();
+		this.tableModel = this.buildTableModel();
+		this.rowSelectionModel = this.buildRowSelectionModel();
+		this.openWindow();
+	}
+
+	private SimpleCollectionValueModel<Object> buildEyeColorCollectionHolder() {
+		return new SimpleCollectionValueModel<Object>(new ArrayList<Object>(Person.getValidEyeColors()));
+	}
+
+	private ModifiablePropertyValueModel<Crowd> buildCrowdHolder() {
+		return new SimplePropertyValueModel<Crowd>(this.buildCrowd());
+	}
+
+	private Crowd buildCrowd() {
+		Crowd crowd = new Crowd();
+
+		Person p = crowd.addPerson("Bilbo");
+		p.setEyeColor(Person.EYE_COLOR_BROWN);
+		p.setRank(22);
+		p.setAdventureCount(1);
+
+		p = crowd.addPerson("Gollum");
+		p.setEyeColor(Person.EYE_COLOR_PINK);
+		p.setEvil(true);
+		p.setRank(2);
+		p.setAdventureCount(50);
+
+		p = crowd.addPerson("Frodo");
+		p.setEyeColor(Person.EYE_COLOR_BLUE);
+		p.setRank(34);
+		p.setAdventureCount(1);
+
+		p = crowd.addPerson("Samwise");
+		p.setEyeColor(Person.EYE_COLOR_GREEN);
+		p.setRank(19);
+		p.setAdventureCount(1);
+
+		return crowd;
+	}
+
+	private ModifiablePropertyValueModel<Person> buildSelectedPersonHolder() {
+		return new SimplePropertyValueModel<Person>();
+	}
+
+	private ListValueModel<Person> buildSortedPeopleAdapter() {
+		return new SortedListValueModelWrapper<Person>(this.buildPeopleNameAdapter());
+	}
+
+	// the list will need to be re-sorted if a name changes
+	private ListValueModel<Person> buildPeopleNameAdapter() {
+		return new ItemPropertyListValueModelAdapter<Person>(this.buildPeopleAdapter(), Person.NAME_PROPERTY);
+	}
+
+	private CollectionValueModel<Person> buildPeopleAdapter() {
+		return new CollectionAspectAdapter<Crowd, Person>(this.crowdHolder, Crowd.PEOPLE_COLLECTION) {
+			@Override
+			protected Iterator<Person> iterator_() {
+				return this.subject.people();
+			}
+			@Override
+			protected int size_() {
+				return this.subject.peopleSize();
+			}
+		};
+	}
+
+	private TableModel buildTableModel() {
+		return new TableModelAdapter<Person>(this.sortedPeopleAdapter, this.buildColumnAdapter());
+	}
+
+	protected TableModelAdapter.ColumnAdapter buildColumnAdapter() {
+		return new PersonColumnAdapter();
+	}
+
+	private ObjectListSelectionModel buildRowSelectionModel() {
+		ObjectListSelectionModel rsm = new ObjectListSelectionModel(new ListModelAdapter(this.sortedPeopleAdapter));
+		rsm.addListSelectionListener(this.buildRowSelectionListener());
+		rsm.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+		return rsm;
+	}
+
+	private ListSelectionListener buildRowSelectionListener() {
+		return new ListSelectionListener() {
+			@Override
+			public void valueChanged(ListSelectionEvent e) {
+				if (e.getValueIsAdjusting()) {
+					return;
+				}
+				TableModelAdapterUITest.this.rowSelectionChanged(e);
+			}
+		};
+	}
+
+	void rowSelectionChanged(@SuppressWarnings("unused") ListSelectionEvent event) {
+		Person selection = (Person) this.rowSelectionModel.selectedValue();
+		this.selectedPersonHolder.setValue(selection);
+		boolean personSelected = (selection != null);
+		this.removeAction.setEnabled(personSelected);
+		this.renameAction.setEnabled(personSelected);
+	}
+
+	private void openWindow() {
+		JFrame window = new JFrame(this.getClass().getSimpleName());
+		window.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+		window.addWindowListener(this.buildWindowListener());
+		window.getContentPane().add(this.buildMainPanel(), "Center");
+		window.setLocation(200, 200);
+		window.setSize(600, 400);
+		window.setVisible(true);
+	}
+
+	private WindowListener buildWindowListener() {
+		return new WindowAdapter() {
+			@Override
+			public void windowClosing(WindowEvent e) {
+				e.getWindow().setVisible(false);
+				System.exit(0);
+			}
+		};
+	}
+
+	private Component buildMainPanel() {
+		JPanel mainPanel = new JPanel(new BorderLayout());
+		mainPanel.add(this.buildTablePane(), BorderLayout.CENTER);
+		mainPanel.add(this.buildControlPanel(), BorderLayout.SOUTH);
+		return mainPanel;
+	}
+
+	private Component buildTablePane() {
+		return new JScrollPane(this.buildTable());
+	}
+
+	private JTable buildTable() {
+		JTable table = new JTable(this.tableModel);
+		table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);	// see Java bug 5007652
+		table.setSelectionModel(this.rowSelectionModel);
+		table.setDoubleBuffered(true);
+		table.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
+		int rowHeight = 20;	// start with minimum of 20
+
+		// gone west column (spinner)
+		TableColumn column = table.getColumnModel().getColumn(PersonColumnAdapter.GONE_WEST_DATE_COLUMN);
+		SpinnerTableCellRenderer spinnerRenderer = this.buildDateSpinnerRenderer();
+		column.setCellRenderer(spinnerRenderer);
+		column.setCellEditor(new TableCellEditorAdapter(this.buildDateSpinnerRenderer()));
+		rowHeight = Math.max(rowHeight, spinnerRenderer.preferredHeight());
+
+		// eye color column (combo-box)
+		// the jdk combo-box renderer looks like a text field
+		// until the user starts an edit - use a custom one
+		column = table.getColumnModel().getColumn(PersonColumnAdapter.EYE_COLOR_COLUMN);
+		ComboBoxTableCellRenderer eyeColorRenderer = this.buildEyeColorComboBoxRenderer();
+		column.setCellRenderer(eyeColorRenderer);
+		column.setCellEditor(new TableCellEditorAdapter(this.buildEyeColorComboBoxRenderer()));
+		rowHeight = Math.max(rowHeight, eyeColorRenderer.preferredHeight());
+
+		// evil (check box)
+		// the jdk check box renderer and editor suck - use a custom ones
+		column = table.getColumnModel().getColumn(PersonColumnAdapter.EVIL_COLUMN);
+		CheckBoxTableCellRenderer evilRenderer = new CheckBoxTableCellRenderer();
+		column.setCellRenderer(evilRenderer);
+		column.setCellEditor(new TableCellEditorAdapter(new CheckBoxTableCellRenderer()));
+		rowHeight = Math.max(rowHeight, evilRenderer.preferredHeight());
+
+		// adventure count column (spinner)
+		column = table.getColumnModel().getColumn(PersonColumnAdapter.ADVENTURE_COUNT_COLUMN);
+		spinnerRenderer = this.buildNumberSpinnerRenderer();
+		column.setCellRenderer(spinnerRenderer);
+		column.setCellEditor(new TableCellEditorAdapter(this.buildNumberSpinnerRenderer()));
+		rowHeight = Math.max(rowHeight, spinnerRenderer.preferredHeight());
+
+		table.setRowHeight(rowHeight);
+		return table;
+	}
+
+	private SpinnerTableCellRenderer buildDateSpinnerRenderer() {
+		return new SpinnerTableCellRenderer(new DateSpinnerModelAdapter(new SimplePropertyValueModel<Object>()));
+	}
+
+	private SpinnerTableCellRenderer buildNumberSpinnerRenderer() {
+		return new SpinnerTableCellRenderer(new NumberSpinnerModelAdapter(new SimplePropertyValueModel<Number>()));
+	}
+
+	private ComboBoxTableCellRenderer buildEyeColorComboBoxRenderer() {
+		return new ComboBoxTableCellRenderer(this.buildReadOnlyEyeColorComboBoxModel(), this.buildEyeColorRenderer());
+	}
+
+	private ComboBoxModel buildReadOnlyEyeColorComboBoxModel() {
+		return new ComboBoxModelAdapter(this.eyeColorsHolder, new SimplePropertyValueModel<Object>());
+	}
+
+	private ListCellRenderer buildEyeColorRenderer() {
+		return new EyeColorRenderer();
+	}
+
+	private Component buildControlPanel() {
+		JPanel controlPanel = new JPanel(new GridLayout(0, 1));
+		controlPanel.add(this.buildButtonPanel());
+		controlPanel.add(this.buildPersonPanel());
+		return controlPanel;
+	}
+
+	private Component buildButtonPanel() {
+		JPanel buttonPanel = new JPanel(new GridLayout(1, 0));
+		buttonPanel.add(this.buildAddButton());
+		buttonPanel.add(this.buildRemoveButton());
+		buttonPanel.add(this.buildRenameButton());
+		buttonPanel.add(this.buildAddEyeColorButton());
+		buttonPanel.add(this.buildPrintButton());
+		buttonPanel.add(this.buildResetButton());
+		return buttonPanel;
+	}
+
+	private Component buildPersonPanel() {
+		JPanel personPanel = new JPanel(new GridLayout(1, 0));
+		personPanel.add(this.buildNameTextField());
+		personPanel.add(this.buildBirthDateSpinner());
+		personPanel.add(this.buildGoneWestDateSpinner());
+		personPanel.add(this.buildEyeColorComboBox());
+		personPanel.add(this.buildEvilCheckBox());
+		personPanel.add(this.buildRankSpinner());
+		personPanel.add(this.buildAdventureCountSpinner());
+		return personPanel;
+	}
+
+
+	// ********** add button **********
+
+	private JButton buildAddButton() {
+		return new JButton(this.buildAddAction());
+	}
+
+	private Action buildAddAction() {
+		Action action = new AbstractAction("add") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				TableModelAdapterUITest.this.addPerson();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void addPerson() {
+		String name = this.getNameFromUser();
+		if (name != null) {
+			this.setSelectedPerson(this.crowd().addPerson(name));
+		}
+	}
+
+
+	// ********** remove button **********
+
+	private JButton buildRemoveButton() {
+		return new JButton(this.buildRemoveAction());
+	}
+
+	private Action buildRemoveAction() {
+		this.removeAction = new AbstractAction("remove") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				TableModelAdapterUITest.this.removePerson();
+			}
+		};
+		this.removeAction.setEnabled(false);
+		return this.removeAction;
+	}
+
+	void removePerson() {
+		Person person = this.selectedPerson();
+		if (person != null) {
+			this.crowd().removePerson(person);
+		}
+	}
+
+
+	// ********** rename button **********
+
+	private JButton buildRenameButton() {
+		return new JButton(this.buildRenameAction());
+	}
+
+	private Action buildRenameAction() {
+		this.renameAction = new AbstractAction("rename") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				TableModelAdapterUITest.this.renamePerson();
+			}
+		};
+		this.renameAction.setEnabled(false);
+		return this.renameAction;
+	}
+
+	void renamePerson() {
+		Person person = this.selectedPerson();
+		if (person != null) {
+			String name = this.promptUserForName(person.getName());
+			if (name != null) {
+				person.setName(name);
+				this.setSelectedPerson(person);
+			}
+		}
+	}
+
+
+	// ********** add eye color button **********
+
+	private JButton buildAddEyeColorButton() {
+		return new JButton(this.buildAddEyeColorAction());
+	}
+
+	private Action buildAddEyeColorAction() {
+		Action action = new AbstractAction("add eye color") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				TableModelAdapterUITest.this.addEyeColor();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void addEyeColor() {
+		String color = this.promptUserForEyeColor();
+		if (color != null) {
+			this.eyeColorsHolder.add(color);
+		}
+	}
+
+	private String promptUserForEyeColor() {
+		while (true) {
+			String eyeColor = JOptionPane.showInputDialog("Eye Color");
+			if (eyeColor == null) {
+				return null;		// user pressed <Cancel>
+			}
+			if ((eyeColor.length() == 0)) {
+				JOptionPane.showMessageDialog(null, "The eye color is required.", "Invalid Eye Color", JOptionPane.ERROR_MESSAGE);
+			} else if (IteratorTools.contains(this.eyeColorsHolder.iterator(), eyeColor)) {
+				JOptionPane.showMessageDialog(null, "The eye color already exists.", "Invalid Eye Color", JOptionPane.ERROR_MESSAGE);
+			} else {
+				return eyeColor;
+			}
+		}
+	}
+
+
+	// ********** print button **********
+
+	private JButton buildPrintButton() {
+		return new JButton(this.buildPrintAction());
+	}
+
+	private Action buildPrintAction() {
+		Action action = new AbstractAction("print") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				TableModelAdapterUITest.this.printCrowd();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void printCrowd() {
+		System.out.println(this.crowd());
+		for (Iterator<Person> stream = this.crowd().people(); stream.hasNext(); ) {
+			System.out.println("\t" + stream.next());
+		}
+	}
+
+
+	// ********** reset button **********
+
+	private JButton buildResetButton() {
+		return new JButton(this.buildResetAction());
+	}
+
+	private Action buildResetAction() {
+		Action action = new AbstractAction("reset") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				TableModelAdapterUITest.this.reset();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	void reset() {
+		this.crowdHolder.setValue(this.buildCrowd());
+	}
+
+
+	// ********** new name dialog **********
+
+	private String getNameFromUser() {
+		return this.promptUserForName(null);
+	}
+
+	private String promptUserForName(@SuppressWarnings("unused") String originalName) {
+		while (true) {
+			String name = JOptionPane.showInputDialog("Person Name");
+			if (name == null) {
+				return null;		// user pressed <Cancel>
+			}
+			if ((name.length() == 0)) {
+				JOptionPane.showMessageDialog(null, "The name is required.", "Invalid Name", JOptionPane.ERROR_MESSAGE);
+			} else if (IteratorTools.contains(this.crowd().peopleNames(), name)) {
+				JOptionPane.showMessageDialog(null, "The name already exists.", "Invalid Name", JOptionPane.ERROR_MESSAGE);
+			} else {
+				return name;
+			}
+		}
+	}
+
+
+	// ********** name text field **********
+
+	private Component buildNameTextField() {
+		JTextField textField = new JTextField(this.buildNameDocument(), null, 0);
+		textField.setEditable(false);
+		return textField;
+	}
+
+	private Document buildNameDocument() {
+		return new DocumentAdapter(this.buildNameAdapter());
+	}
+
+	private ModifiablePropertyValueModel<String> buildNameAdapter() {
+		return new PropertyAspectAdapter<Person, String>(this.selectedPersonHolder, Person.NAME_PROPERTY) {
+			@Override
+			protected String buildValue_() {
+				return this.subject.getName();
+			}
+			@Override
+			protected void setValue_(String value) {
+				this.subject.setName(value);
+			}
+		};
+	}
+
+
+	// ********** birth date spinner **********
+
+	private JSpinner buildBirthDateSpinner() {
+		return new JSpinner(this.buildBirthDateSpinnerModel());
+	}
+
+	private SpinnerModel buildBirthDateSpinnerModel() {
+		return new DateSpinnerModelAdapter(this.buildBirthDateAdapter());
+	}
+
+	private ModifiablePropertyValueModel<Object> buildBirthDateAdapter() {
+		return new PropertyAspectAdapter<Person, Object>(this.selectedPersonHolder, Person.BIRTH_DATE_PROPERTY) {
+			@Override
+			protected Date buildValue_() {
+				return this.subject.getBirthDate();
+			}
+			@Override
+			protected void setValue_(Object value) {
+				this.subject.setBirthDate((Date) value);
+			}
+		};
+	}
+
+
+	// ********** gone west date spinner **********
+
+	private JSpinner buildGoneWestDateSpinner() {
+		return new JSpinner(this.buildGoneWestDateSpinnerModel());
+	}
+
+	private SpinnerModel buildGoneWestDateSpinnerModel() {
+		return new DateSpinnerModelAdapter(this.buildGoneWestDateAdapter());
+	}
+
+	private ModifiablePropertyValueModel<Object> buildGoneWestDateAdapter() {
+		return new PropertyAspectAdapter<Person, Object>(this.selectedPersonHolder, Person.GONE_WEST_DATE_PROPERTY) {
+			@Override
+			protected Date buildValue_() {
+				return this.subject.getGoneWestDate();
+			}
+			@Override
+			protected void setValue_(Object value) {
+				this.subject.setGoneWestDate((Date) value);
+			}
+		};
+	}
+
+
+	// ********** eye color combo-box **********
+
+	private JComboBox buildEyeColorComboBox() {
+		return new JComboBox(this.buildEyeColorComboBoxModel());
+	}
+
+	private ComboBoxModel buildEyeColorComboBoxModel() {
+		return new ComboBoxModelAdapter(this.eyeColorsHolder, this.buildEyeColorAdapter());
+	}
+
+	private ModifiablePropertyValueModel<Object> buildEyeColorAdapter() {
+		return new PropertyAspectAdapter<Person, Object>(this.selectedPersonHolder, Person.EYE_COLOR_PROPERTY) {
+			@Override
+			protected Object buildValue_() {
+				return this.subject.getEyeColor();
+			}
+			@Override
+			protected void setValue_(Object value) {
+				this.subject.setEyeColor((String) value);
+			}
+		};
+	}
+
+
+	// ********** evil check box **********
+
+	private JCheckBox buildEvilCheckBox() {
+		JCheckBox checkBox = new JCheckBox();
+		checkBox.setText("evil");
+		checkBox.setModel(this.buildEvilCheckBoxModel());
+		return checkBox;
+	}
+
+	private ButtonModel buildEvilCheckBoxModel() {
+		return new CheckBoxModelAdapter(this.buildEvilAdapter());
+	}
+
+	private ModifiablePropertyValueModel<Boolean> buildEvilAdapter() {
+		return new PropertyAspectAdapter<Person, Boolean>(this.selectedPersonHolder, Person.EVIL_PROPERTY) {
+			@Override
+			protected Boolean buildValue_() {
+				return Boolean.valueOf(this.subject.isEvil());
+			}
+			@Override
+			protected void setValue_(Boolean value) {
+				this.subject.setEvil(value.booleanValue());
+			}
+		};
+	}
+
+
+	// ********** rank spinner **********
+
+	private JSpinner buildRankSpinner() {
+		return new JSpinner(this.buildRankSpinnerModel());
+	}
+
+	private SpinnerModel buildRankSpinnerModel() {
+		return new NumberSpinnerModelAdapter(this.buildRankAdapter());
+	}
+
+	private ModifiablePropertyValueModel<Number> buildRankAdapter() {
+		return new PropertyAspectAdapter<Person, Number>(this.selectedPersonHolder, Person.RANK_PROPERTY) {
+			@Override
+			protected Number buildValue_() {
+				return new Integer(this.subject.getRank());
+			}
+			@Override
+			protected void setValue_(Number value) {
+				this.subject.setRank(value.intValue());
+			}
+		};
+	}
+
+
+	// ********** adventure count spinner **********
+
+	private JSpinner buildAdventureCountSpinner() {
+		return new JSpinner(this.buildAdventureCountSpinnerModel());
+	}
+
+	private SpinnerModel buildAdventureCountSpinnerModel() {
+		return new NumberSpinnerModelAdapter(this.buildAdventureCountAdapter());
+	}
+
+	private ModifiablePropertyValueModel<Number> buildAdventureCountAdapter() {
+		return new PropertyAspectAdapter<Person, Number>(this.selectedPersonHolder, Person.ADVENTURE_COUNT_PROPERTY) {
+			@Override
+			protected Number buildValue_() {
+				return new Integer(this.subject.getAdventureCount());
+			}
+			@Override
+			protected void setValue_(Number value) {
+				this.subject.setAdventureCount(value.intValue());
+			}
+		};
+	}
+
+
+	// ********** queries **********
+
+	private Crowd crowd() {
+		return this.crowdHolder.getValue();
+	}
+
+	private Person selectedPerson() {
+		if (this.rowSelectionModel.isSelectionEmpty()) {
+			return null;
+		}
+		return (Person) this.rowSelectionModel.selectedValue();
+	}
+
+	private void setSelectedPerson(Person person) {
+		this.rowSelectionModel.setSelectedValue(person);
+	}
+
+
+	// ********** custom renderer **********
+
+	/**
+	 * This is simply an example of a renderer for the embedded combo-box.
+	 * It does nothing special unless you uncomment the code below....
+	 */
+	private class EyeColorRenderer extends DefaultListCellRenderer {
+		EyeColorRenderer() {
+			super();
+		}
+		@Override
+		public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+			// just do something to show the renderer is working...
+	//		value = ">" + value;
+			return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/TreeModelAdapterTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/TreeModelAdapterTests.java
new file mode 100644
index 0000000..5afbbd4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/TreeModelAdapterTests.java
@@ -0,0 +1,831 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import javax.swing.Icon;
+import javax.swing.JTree;
+import javax.swing.event.TreeModelEvent;
+import javax.swing.event.TreeModelListener;
+import javax.swing.tree.TreeModel;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.io.IndentingPrintWriter;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.AbstractTreeNodeValueModel;
+import org.eclipse.persistence.tools.utility.model.value.CollectionAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ItemPropertyListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.NullListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyAspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimpleListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SortedListValueModelWrapper;
+import org.eclipse.persistence.tools.utility.model.value.StaticPropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.TransformationListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.TreeNodeValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.TreeModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.model.Displayable;
+
+@SuppressWarnings("nls")
+public class TreeModelAdapterTests extends TestCase {
+	boolean eventFired;
+
+	public TreeModelAdapterTests(String name) {
+		super(name);
+	}
+
+	public void testGetRoot() {
+		TreeModel treeModel = this.buildSortedTreeModel();
+		treeModel.addTreeModelListener(new TestTreeModelListener());
+		TestNode rootNode = (TestNode) treeModel.getRoot();
+		TestModel root = rootNode.getTestModel();
+		assertEquals("root", root.getName());
+//		root.dump();
+//		rootNode.dump();
+	}
+
+	public void testGetChild() {
+		TreeModel treeModel = this.buildSortedTreeModel();
+		treeModel.addTreeModelListener(new TestTreeModelListener());
+		TestNode rootNode = (TestNode) treeModel.getRoot();
+
+		TestNode expected = rootNode.childNamed("node 1");
+		TestNode actual = (TestNode) treeModel.getChild(rootNode, 1);
+		assertEquals(expected, actual);
+
+		expected = rootNode.childNamed("node 2");
+		actual = (TestNode) treeModel.getChild(rootNode, 2);
+		assertEquals(expected, actual);
+	}
+
+	public void testGetChildCount() {
+		TreeModel treeModel = this.buildSortedTreeModel();
+		treeModel.addTreeModelListener(new TestTreeModelListener());
+		TestNode rootNode = (TestNode) treeModel.getRoot();
+
+		assertEquals(5, treeModel.getChildCount(rootNode));
+
+		TestNode node = rootNode.childNamed("node 1");
+		assertEquals(1, treeModel.getChildCount(node));
+	}
+
+	public void testGetIndexOfChild() {
+		TreeModel treeModel = this.buildSortedTreeModel();
+		treeModel.addTreeModelListener(new TestTreeModelListener());
+		TestNode rootNode = (TestNode) treeModel.getRoot();
+
+		TestNode child = rootNode.childNamed("node 0");
+		assertEquals(0, treeModel.getIndexOfChild(rootNode, child));
+
+		child = rootNode.childNamed("node 1");
+		assertEquals(1, treeModel.getIndexOfChild(rootNode, child));
+
+		child = rootNode.childNamed("node 2");
+		assertEquals(2, treeModel.getIndexOfChild(rootNode, child));
+		TestNode grandchild = child.childNamed("node 2.2");
+		assertEquals(2, treeModel.getIndexOfChild(child, grandchild));
+	}
+
+	public void testIsLeaf() {
+		TreeModel treeModel = this.buildSortedTreeModel();
+		treeModel.addTreeModelListener(new TestTreeModelListener());
+		TestNode rootNode = (TestNode) treeModel.getRoot();
+		assertFalse(treeModel.isLeaf(rootNode));
+		TestNode node = rootNode.childNamed("node 1");
+		assertFalse(treeModel.isLeaf(node));
+		node = rootNode.childNamed("node 3");
+		assertTrue(treeModel.isLeaf(node));
+	}
+
+
+	public void testTreeNodesChanged() {
+		// the only way to trigger a "node changed" event is to use an unsorted tree;
+		// a sorted tree will will trigger only "node removed" and "node inserted" events
+		TreeModel treeModel = this.buildUnsortedTreeModel();
+		this.eventFired = false;
+		treeModel.addTreeModelListener(new TestTreeModelListener() {
+			@Override
+			public void treeNodesChanged(TreeModelEvent e) {
+				TreeModelAdapterTests.this.eventFired = true;
+			}
+		});
+		TestNode rootNode = (TestNode) treeModel.getRoot();
+		TestNode node = rootNode.childNamed("node 1");
+		TestModel tm = node.getTestModel();
+		tm.setName("node 1++");
+		assertTrue(this.eventFired);
+
+		this.eventFired = false;
+		node = node.childNamed("node 1.1");
+		tm = node.getTestModel();
+		tm.setName("node 1.1++");
+		assertTrue(this.eventFired);
+	}
+
+	public void testTreeNodesInserted() {
+		// use an unsorted tree so the nodes are not re-shuffled...
+		TreeModel treeModel = this.buildUnsortedTreeModel();
+		this.eventFired = false;
+		treeModel.addTreeModelListener(new TestTreeModelListener() {
+			@Override
+			public void treeNodesInserted(TreeModelEvent e) {
+				TreeModelAdapterTests.this.eventFired = true;
+			}
+		});
+		TestNode rootNode = (TestNode) treeModel.getRoot();
+		TestNode node = rootNode.childNamed("node 1");
+		TestModel tm = node.getTestModel();
+		tm.addChild("new child...");
+		assertTrue(this.eventFired);
+
+		this.eventFired = false;
+		node = node.childNamed("node 1.1");
+		tm = node.getTestModel();
+		tm.addChild("another new child...");
+		assertTrue(this.eventFired);
+	}
+
+	public void testTreeNodesRemoved() {
+		TreeModel treeModel = this.buildUnsortedTreeModel();
+		this.eventFired = false;
+		treeModel.addTreeModelListener(new TestTreeModelListener() {
+			@Override
+			public void treeNodesRemoved(TreeModelEvent e) {
+				TreeModelAdapterTests.this.eventFired = true;
+			}
+		});
+		TestNode rootNode = (TestNode) treeModel.getRoot();
+		TestModel root = rootNode.getTestModel();
+		root.removeChild(root.childNamed("node 3"));
+		assertTrue(this.eventFired);
+
+		this.eventFired = false;
+		TestNode node = rootNode.childNamed("node 2");
+		TestModel tm = node.getTestModel();
+		tm.removeChild(tm.childNamed("node 2.2"));
+		assertTrue(this.eventFired);
+	}
+
+	public void testTreeStructureChanged() {
+		ModifiablePropertyValueModel<TreeNodeValueModel<Object>> nodeHolder = new SimplePropertyValueModel<TreeNodeValueModel<Object>>(this.buildSortedRootNode());
+		TreeModel treeModel = this.buildTreeModel(nodeHolder);
+		this.eventFired = false;
+		treeModel.addTreeModelListener(new TestTreeModelListener() {
+			@Override
+			public void treeNodesInserted(TreeModelEvent e) {
+				// do nothing
+			}
+			@Override
+			public void treeNodesRemoved(TreeModelEvent e) {
+				// do nothing
+			}
+			@Override
+			public void treeStructureChanged(TreeModelEvent e) {
+				TreeModelAdapterTests.this.eventFired = true;
+			}
+		});
+		nodeHolder.setValue(this.buildUnsortedRootNode());
+		assertTrue(this.eventFired);
+	}
+
+	/**
+	 * test a problem we had where removing a child from a tree would cause
+	 * the JTree to call #equals(Object) on each node removed (actually, it was
+	 * TreePath, but that was because its own #equals(Object) was called by
+	 * JTree); and since we had already removed the last listener from the
+	 * aspect adapter, the aspect adapter would say its value was null; this
+	 * would cause a NPE until we tweaked TreeModelAdapter to remove its
+	 * listeners from a node only *after* the node had been completely
+	 * removed from the JTree
+	 * @see TreeModelAdapter#removeNode(Object[], int, TreeNodeValueModel)
+	 * @see TreeModelAdapter#addNode(Object[], int, TreeNodeValueModel)
+	 */
+	public void testLazyInitialization() {
+		TreeModel treeModel = this.buildSpecialTreeModel();
+		JTree jTree = new JTree(treeModel);
+		TestNode rootNode = (TestNode) treeModel.getRoot();
+		TestModel root = rootNode.getTestModel();
+		// this would cause a NPE:
+		root.removeChild(root.childNamed("node 3"));
+		assertEquals(treeModel, jTree.getModel());
+	}
+
+
+	private TreeModel buildSortedTreeModel() {
+		return this.buildTreeModel(this.buildSortedRootNode());
+	}
+
+	private TestNode buildSortedRootNode() {
+		return new SortedTestNode(this.buildRoot());
+	}
+
+	private TreeModel buildUnsortedTreeModel() {
+		return this.buildTreeModel(this.buildUnsortedRootNode());
+	}
+
+	private TestNode buildUnsortedRootNode() {
+		return new UnsortedTestNode(this.buildRoot());
+	}
+
+	private TreeModel buildSpecialTreeModel() {
+		return this.buildTreeModel(this.buildSpecialRootNode());
+	}
+
+	private TestNode buildSpecialRootNode() {
+		return new SpecialTestNode(this.buildRoot());
+	}
+
+	private TestModel buildRoot() {
+		TestModel root = new TestModel("root");
+		/*Node node_0 = */root.addChild("node 0");
+		TestModel node_1 = root.addChild("node 1");
+		TestModel node_1_1 = node_1.addChild("node 1.1");
+		/*Node node_1_1_1 = */node_1_1.addChild("node 1.1.1");
+		TestModel node_2 = root.addChild("node 2");
+		/*Node node_2_0 = */node_2.addChild("node 2.0");
+		/*Node node_2_1 = */node_2.addChild("node 2.1");
+		/*Node node_2_2 = */node_2.addChild("node 2.2");
+		/*Node node_2_3 = */node_2.addChild("node 2.3");
+		/*Node node_2_4 = */node_2.addChild("node 2.4");
+		/*Node node_2_5 = */node_2.addChild("node 2.5");
+		/*Node node_3 = */root.addChild("node 3");
+		/*Node node_4 = */root.addChild("node 4");
+		return root;
+	}
+
+
+	// ********** member classes **********
+
+	/**
+	 * This is a typical model class with the typical change notifications
+	 * for #name and #children.
+	 */
+	public static class TestModel extends AbstractModel {
+
+		// the  parent is immutable; the root's parent is null
+		private final TestModel parent;
+
+		// the name is mutable; so I guess it isn't the "primary key" :-)
+		private String name;
+			public static final String NAME_PROPERTY = "name";
+
+		private final Collection<TestModel> children;
+			public static final String CHILDREN_COLLECTION = "children";
+
+
+		public TestModel(String name) {	// root ctor
+			this(null, name);
+		}
+		private TestModel(TestModel parent, String name) {
+			super();
+			this.parent = parent;
+			this.name = name;
+			this.children = new HashBag<TestModel>();
+		}
+
+		public TestModel getParent() {
+			return this.parent;
+		}
+
+		public String getName() {
+			return this.name;
+		}
+		public void setName(String name) {
+			Object old = this.name;
+			this.name = name;
+			this.firePropertyChanged(NAME_PROPERTY, old, name);
+		}
+
+		public Iterator<TestModel> children() {
+			return new ReadOnlyIterator<TestModel>(this.children);
+		}
+		public int childrenSize() {
+			return this.children.size();
+		}
+		public TestModel addChild(String childName) {
+			TestModel child = new TestModel(this, childName);
+			this.addItemToCollection(child, this.children, CHILDREN_COLLECTION);
+			return child;
+		}
+		public TestModel[] addChildren(String[] childNames) {
+			TestModel[] newChildren = new TestModel[childNames.length];
+			for (int i = 0; i < childNames.length; i++) {
+				newChildren[i] = new TestModel(this, childNames[i]);
+			}
+			this.addItemsToCollection(newChildren, this.children, CHILDREN_COLLECTION);
+			return newChildren;
+		}
+		public void removeChild(TestModel child) {
+			this.removeItemFromCollection(child, this.children, CHILDREN_COLLECTION);
+		}
+		public void removeChildren(TestModel[] testModels) {
+			this.removeItemsFromCollection(testModels, this.children, CHILDREN_COLLECTION);
+		}
+		public void clearChildren() {
+			this.clearCollection(this.children, CHILDREN_COLLECTION);
+		}
+		public TestModel childNamed(String childName) {
+			for (TestModel child : this.children) {
+				if (child.getName().equals(childName)) {
+					return child;
+				}
+			}
+			throw new RuntimeException("child not found: " + childName);
+		}
+
+		@SuppressWarnings("resource")
+		public String dumpString() {
+			StringWriter sw = new StringWriter();
+			IndentingPrintWriter ipw = new IndentingPrintWriter(sw);
+			this.dumpOn(ipw);
+			return sw.toString();
+		}
+		public void dumpOn(IndentingPrintWriter writer) {
+			writer.println(this);
+			writer.indent();
+			for (TestModel child : this.children) {
+				child.dumpOn(writer);
+			}
+			writer.undent();
+		}
+		@SuppressWarnings("resource")
+		public void dumpOn(OutputStream stream) {
+			IndentingPrintWriter writer = new IndentingPrintWriter(new OutputStreamWriter(stream));
+			this.dumpOn(writer);
+			writer.flush();
+		}
+		public void dump() {
+			this.dumpOn(System.out);
+		}
+
+		@Override
+		public String toString() {
+			return ObjectTools.toString(this, this.name);
+		}
+
+	}
+
+
+	/**
+	 * This Node wraps a TestModel and converts into something that can
+	 * be used by TreeModelAdapter. It converts changes to the TestModel's
+	 * name into "state changes" to the Node; and converts the
+	 * TestModel's children into a ListValueModel of Nodes whose order is
+	 * determined by subclass implementations.
+	 */
+	public static abstract class TestNode extends AbstractTreeNodeValueModel<Object> implements Displayable, Comparable<TestNode> {
+		/** the model object wrapped by this node */
+		private final TestModel testModel;
+		/** this node's parent node; null for the root node */
+		private final TestNode parent;
+		/** this node's child nodes */
+		private final ListValueModel<TreeNodeValueModel<Object>> childrenModel;
+		/** a listener that notifies us when the model object's "internal state" changes */
+		private final PropertyChangeListener testModelListener;
+
+
+		// ********** constructors/initialization **********
+
+		/**
+		 * root node constructor
+		 */
+		public TestNode(TestModel testModel) {
+			this(null, testModel);
+		}
+
+		/**
+		 * branch or leaf node constructor
+		 */
+		public TestNode(TestNode parent, TestModel testModel) {
+			super();
+			this.parent = parent;
+			this.testModel = testModel;
+			this.childrenModel = this.buildChildrenModel(testModel);
+			this.testModelListener = this.buildTestModelListener();
+		}
+
+		private PropertyChangeListener buildTestModelListener() {
+			return new PropertyChangeListener() {
+				@Override
+				public void propertyChanged(PropertyChangeEvent e) {
+					TestNode.this.testModelChanged(e);
+				}
+			};
+		}
+
+		/**
+		 * subclasses decide the order of the child nodes
+		 */
+		protected abstract ListValueModel<TreeNodeValueModel<Object>> buildChildrenModel(TestModel model);
+
+		/**
+		 * used by subclasses;
+		 * transform the test model children into nodes
+		 */
+		protected ListValueModel<TreeNodeValueModel<Object>> buildNodeAdapter(TestModel model) {
+			return new TransformationListValueModel<TestModel, TreeNodeValueModel<Object>>(this.buildChildrenAdapter(model)) {
+				@Override
+				protected TestNode transformItem(TestModel item) {
+					return TestNode.this.buildChildNode(item);
+				}
+			};
+		}
+
+		/**
+		 * subclasses must build a concrete node for the specified test model
+		 */
+		protected abstract TestNode buildChildNode(TestModel childTestModel);
+
+		/**
+		 * return a collection value model on the specified model's children
+		 */
+		protected CollectionValueModel<TestModel> buildChildrenAdapter(TestModel model) {
+			return new CollectionAspectAdapter<TestModel, TestModel>(TestModel.CHILDREN_COLLECTION, model) {
+				@Override
+				protected Iterator<TestModel> iterator_() {
+					return this.subject.children();
+				}
+				@Override
+				protected int size_() {
+					return this.subject.childrenSize();
+				}
+			};
+		}
+
+
+		// ********** TreeNodeValueModel implementation **********
+
+		@Override
+		public TestModel getValue() {
+			return this.testModel;
+		}
+
+		@Override
+		public TreeNodeValueModel<Object> parent() {
+			return this.parent;
+		}
+
+		@Override
+		public ListValueModel<TreeNodeValueModel<Object>> childrenModel() {
+			return this.childrenModel;
+		}
+
+
+		// ********** AbstractTreeNodeValueModel implementation **********
+
+		@Override
+		protected void engageValue() {
+			this.testModel.addPropertyChangeListener(TestModel.NAME_PROPERTY, this.testModelListener);
+		}
+
+		@Override
+		protected void disengageValue() {
+			this.testModel.removePropertyChangeListener(TestModel.NAME_PROPERTY, this.testModelListener);
+		}
+
+
+		// ********** Displayable implementation **********
+
+		@Override
+		public String displayString() {
+			return this.testModel.getName();
+		}
+
+		@Override
+		public Icon icon() {
+			return null;
+		}
+
+
+		// ********** debugging support **********
+
+		@SuppressWarnings("resource")
+		public String dumpString() {
+			StringWriter sw = new StringWriter();
+			IndentingPrintWriter ipw = new IndentingPrintWriter(sw);
+			this.dumpOn(ipw);
+			return sw.toString();
+		}
+
+		public void dumpOn(IndentingPrintWriter writer) {
+			writer.println(this);
+			writer.indent();
+			for (Iterator<TreeNodeValueModel<Object>> stream = this.childrenModel.iterator(); stream.hasNext(); ) {
+				// cast to a TestNode (i.e. this won't work with a NameTestNode in the tree)
+				((TestNode) stream.next()).dumpOn(writer);
+			}
+			writer.undent();
+		}
+
+		@SuppressWarnings("resource")
+		public void dumpOn(OutputStream stream) {
+			IndentingPrintWriter writer = new IndentingPrintWriter(new OutputStreamWriter(stream));
+			this.dumpOn(writer);
+			writer.flush();
+		}
+
+		public void dump() {
+			this.dumpOn(System.out);
+		}
+
+
+		// ********** behavior **********
+
+		/**
+		 * the model's name has changed, forward the event to our listeners
+		 */
+		protected void testModelChanged(PropertyChangeEvent e) {
+			// we need to notify listeners that our "internal state" has changed
+			this.fireStateChanged();
+			// our display string stays in synch with the model's name
+			this.firePropertyChanged(DISPLAY_STRING_PROPERTY, e.getOldValue(), e.getNewValue());
+		}
+
+
+		// ********** queries **********
+
+		public TestModel getTestModel() {
+			return this.testModel;
+		}
+
+		/**
+		 * testing convenience method
+		 */
+		public TestNode childNamed(String name) {
+			for (Iterator<TreeNodeValueModel<Object>> stream = this.childrenModel.iterator(); stream.hasNext(); ) {
+				TreeNodeValueModel<Object> childNode = stream.next();
+				if (childNode instanceof TestNode) {
+					if (((TestNode) childNode).getTestModel().getName().equals(name)) {
+						return (TestNode) childNode;
+					}
+				}
+			}
+			throw new IllegalArgumentException("child not found: " + name);
+		}
+
+
+		// ********** standard methods **********
+
+		@Override
+		public int compareTo(TestNode o) {
+			return this.displayString().compareTo(o.displayString());
+		}
+
+		@Override
+		public String toString() {
+			return "Node(" + this.testModel + ")";
+		}
+
+	}
+
+	/**
+	 * concrete implementation that keeps its children sorted
+	 */
+	public static class SortedTestNode extends TestNode {
+
+		// ********** constructors **********
+		public SortedTestNode(TestModel testModel) {
+			super(testModel);
+		}
+		public SortedTestNode(TestNode parent, TestModel testModel) {
+			super(parent, testModel);
+		}
+
+		// ********** initialization **********
+		/** the list should be sorted */
+		@Override
+		protected ListValueModel<TreeNodeValueModel<Object>> buildChildrenModel(TestModel testModel) {
+			return new SortedListValueModelWrapper<TreeNodeValueModel<Object>>(this.buildDisplayStringAdapter(testModel));
+		}
+		/** the display string (name) of each node can change */
+		protected ListValueModel<TreeNodeValueModel<Object>> buildDisplayStringAdapter(TestModel testModel) {
+			return new ItemPropertyListValueModelAdapter<TreeNodeValueModel<Object>>(this.buildNodeAdapter(testModel), DISPLAY_STRING_PROPERTY);
+		}
+		/** children are also sorted nodes */
+		@Override
+		protected TestNode buildChildNode(TestModel childNode) {
+			return new SortedTestNode(this, childNode);
+		}
+
+	}
+
+
+	/**
+	 * concrete implementation that leaves its children unsorted
+	 */
+	public static class UnsortedTestNode extends TestNode {
+
+		// ********** constructors **********
+		public UnsortedTestNode(TestModel testModel) {
+			super(testModel);
+		}
+		public UnsortedTestNode(TestNode parent, TestModel testModel) {
+			super(parent, testModel);
+		}
+
+		// ********** initialization **********
+		/** the list should NOT be sorted */
+		@Override
+		protected ListValueModel<TreeNodeValueModel<Object>> buildChildrenModel(TestModel testModel) {
+			return this.buildNodeAdapter(testModel);
+		}
+		/** children are also unsorted nodes */
+		@Override
+		protected TestNode buildChildNode(TestModel childNode) {
+			return new UnsortedTestNode(this, childNode);
+		}
+
+	}
+
+
+	/**
+	 * concrete implementation that leaves its children unsorted
+	 * and has a special set of children for "node 3"
+	 */
+	public static class SpecialTestNode extends UnsortedTestNode {
+
+		// ********** constructors **********
+		public SpecialTestNode(TestModel testModel) {
+			super(testModel);
+		}
+		public SpecialTestNode(TestNode parent, TestModel testModel) {
+			super(parent, testModel);
+		}
+
+		// ********** initialization **********
+		/** return a different list of children for "node 3" */
+		@Override
+		protected ListValueModel<TreeNodeValueModel<Object>> buildChildrenModel(TestModel testModel) {
+			if (testModel.getName().equals("node 3")) {
+				return this.buildSpecialChildrenModel();
+			}
+			return super.buildChildrenModel(testModel);
+		}
+		protected ListValueModel<TreeNodeValueModel<Object>> buildSpecialChildrenModel() {
+			TreeNodeValueModel<Object>[] children = new NameTestNode[1];
+			children[0] = new NameTestNode(this);
+			return new SimpleListValueModel<TreeNodeValueModel<Object>>(Arrays.asList(children));
+		}
+		/** children are also special nodes */
+		@Override
+		protected TestNode buildChildNode(TestModel childNode) {
+			return new SpecialTestNode(this, childNode);
+		}
+
+	}
+
+
+	public static class NameTestNode extends AbstractTreeNodeValueModel<Object> {
+		private final ModifiablePropertyValueModel<String> nameAdapter;
+		private final SpecialTestNode specialNode;		// parent node
+		private final PropertyChangeListener nameListener;
+		private final ListValueModel<TreeNodeValueModel<Object>> childrenModel;
+
+		// ********** construction/initialization **********
+
+		public NameTestNode(SpecialTestNode specialNode) {
+			super();
+			this.nameListener = this.buildNameListener();
+			this.specialNode = specialNode;
+			this.nameAdapter = this.buildNameAdapter();
+			this.childrenModel = new NullListValueModel<TreeNodeValueModel<Object>>();
+		}
+		protected PropertyChangeListener buildNameListener() {
+			return new PropertyChangeListener() {
+				@Override
+				public void propertyChanged(PropertyChangeEvent e) {
+					NameTestNode.this.nameChanged(e);
+				}
+			};
+		}
+		protected ModifiablePropertyValueModel<String> buildNameAdapter() {
+			return new PropertyAspectAdapter<TestModel, String>(TestModel.NAME_PROPERTY, this.getTestModel()) {
+				@Override
+				protected String buildValue_() {
+					return this.subject.getName();
+				}
+				@Override
+				protected void setValue_(String value) {
+					this.subject.setName(value);
+				}
+			};
+		}
+
+		public TestModel getTestModel() {
+			return this.specialNode.getTestModel();
+		}
+
+		// ********** TreeNodeValueModel implementation **********
+
+		@Override
+		public String getValue() {
+			return this.nameAdapter.getValue();
+		}
+		@Override
+		public void setValue(Object value) {
+			this.nameAdapter.setValue((String) value);
+		}
+		@Override
+		public TreeNodeValueModel<Object> parent() {
+			return this.specialNode;
+		}
+		@Override
+		public ListValueModel<TreeNodeValueModel<Object>> childrenModel() {
+			return this.childrenModel;
+		}
+
+		// ********** AbstractTreeNodeValueModel implementation **********
+
+		@Override
+		protected void engageValue() {
+			this.nameAdapter.addPropertyChangeListener(PropertyValueModel.VALUE, this.nameListener);
+		}
+		@Override
+		protected void disengageValue() {
+			this.nameAdapter.removePropertyChangeListener(PropertyValueModel.VALUE, this.nameListener);
+		}
+
+		// ********** behavior **********
+
+		protected void nameChanged(PropertyChangeEvent e) {
+			// we need to notify listeners that our "value" has changed
+			this.firePropertyChanged(VALUE, e.getOldValue(), e.getNewValue());
+		}
+	}
+
+	private TreeModel buildTreeModel(TestNode root) {
+		return this.buildTreeModel(new StaticPropertyValueModel<TreeNodeValueModel<Object>>(root));
+	}
+
+	private TreeModel buildTreeModel(PropertyValueModel<TreeNodeValueModel<Object>> rootHolder) {
+		return new TreeModelAdapter<Object>(rootHolder) {
+			@Override
+			protected ListChangeListener buildChildrenListener() {
+				return this.buildChildrenListener_();
+			}
+			@Override
+			protected StateChangeListener buildNodeStateListener() {
+				return this.buildNodeStateListener_();
+			}
+			@Override
+			protected PropertyChangeListener buildNodeValueListener() {
+				return this.buildNodeValueListener_();
+			}
+			@Override
+			protected PropertyChangeListener buildRootListener() {
+				return this.buildRootListener_();
+			}
+		};
+	}
+
+
+
+	/**
+	 * listener that will blow up with any event;
+	 * override and implement expected event methods
+	 */
+	public class TestTreeModelListener implements TreeModelListener {
+		@Override
+		public void treeNodesChanged(TreeModelEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void treeNodesInserted(TreeModelEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void treeNodesRemoved(TreeModelEvent e) {
+			fail("unexpected event");
+		}
+		@Override
+		public void treeStructureChanged(TreeModelEvent e) {
+			fail("unexpected event");
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/TreeModelAdapterUITest.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/TreeModelAdapterUITest.java
new file mode 100644
index 0000000..b30cca8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/TreeModelAdapterUITest.java
@@ -0,0 +1,434 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridLayout;
+import java.awt.TextField;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTree;
+import javax.swing.WindowConstants;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultTreeSelectionModel;
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.TreeSelectionModel;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.EnumerationIterator;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.SimplePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.TreeNodeValueModel;
+import org.eclipse.persistence.tools.utility.model.value.swing.TreeModelAdapter;
+import org.eclipse.persistence.tools.utility.tests.model.Displayable;
+import org.eclipse.persistence.tools.utility.tests.model.value.swing.TreeModelAdapterTests.SortedTestNode;
+import org.eclipse.persistence.tools.utility.tests.model.value.swing.TreeModelAdapterTests.TestModel;
+import org.eclipse.persistence.tools.utility.tests.model.value.swing.TreeModelAdapterTests.TestNode;
+import org.eclipse.persistence.tools.utility.tests.model.value.swing.TreeModelAdapterTests.UnsortedTestNode;
+
+/**
+ * an example UI for testing the TreeModelAdapter
+ */
+@SuppressWarnings("nls")
+public class TreeModelAdapterUITest {
+
+	// hold the tree so we can restore its expansion state
+	private JTree tree;
+	private ModifiablePropertyValueModel<TreeNodeValueModel<Object>> rootNodeHolder;
+	private boolean sorted;
+	private TreeModel treeModel;
+	private TreeSelectionModel treeSelectionModel;
+	private TextField nameTextField;
+
+	public static void main(String[] args) throws Exception {
+		new TreeModelAdapterUITest().exec();
+	}
+
+	private TreeModelAdapterUITest() {
+		super();
+	}
+
+	private void exec() throws Exception {
+		this.rootNodeHolder = this.buildRootNodeHolder();
+		this.sorted = this.rootNodeHolder.getValue() instanceof SortedTestNode;
+		this.treeModel = this.buildTreeModel();
+		this.treeSelectionModel = this.buildTreeSelectionModel();
+		this.nameTextField = new TextField();
+		this.openWindow();
+	}
+
+	private ModifiablePropertyValueModel<TreeNodeValueModel<Object>> buildRootNodeHolder() {
+		return new SimplePropertyValueModel<TreeNodeValueModel<Object>>(this.buildSortedRootNode());
+	}
+
+	private TestNode buildSortedRootNode() {
+		return new SortedTestNode(this.buildRoot());
+	}
+
+	private TestNode buildUnsortedRootNode() {
+		return new UnsortedTestNode(this.buildRoot());
+	}
+
+	private TestModel buildRoot() {
+		TestModel root = new TestModel("root");
+
+		TestModel node_1 = root.addChild("node 1");
+		/*Node node_1_1 = */node_1.addChild("node 1.1");
+
+		TestModel node_2 = root.addChild("node 2");
+		/*Node node_2_1 = */node_2.addChild("node 2.1");
+		TestModel node_2_2 = node_2.addChild("node 2.2");
+		/*Node node_2_2_1 = */node_2_2.addChild("node 2.2.1");
+		/*Node node_2_2_2 = */node_2_2.addChild("node 2.2.2");
+		/*Node node_2_3 = */node_2.addChild("node 2.3");
+		/*Node node_2_4 = */node_2.addChild("node 2.4");
+		/*Node node_2_5 = */node_2.addChild("node 2.5");
+
+		TestModel node_3 = root.addChild("node 3");
+		TestModel node_3_1 = node_3.addChild("node 3.1");
+		TestModel node_3_1_1 = node_3_1.addChild("node 3.1.1");
+		/*Node node_3_1_1_1 = */node_3_1_1.addChild("node 3.1.1.1");
+
+		/*Node node_4 = */root.addChild("node 4");
+
+		return root;
+	}
+
+	private TreeModel buildTreeModel() {
+		return new TreeModelAdapter<Object>(this.rootNodeHolder);
+	}
+
+	private TreeSelectionModel buildTreeSelectionModel() {
+		TreeSelectionModel tsm = new DefaultTreeSelectionModel();
+		tsm.addTreeSelectionListener(this.buildTreeSelectionListener());
+		tsm.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+		return tsm;
+	}
+
+	private TreeSelectionListener buildTreeSelectionListener() {
+		return new TreeSelectionListener() {
+			@Override
+			public void valueChanged(TreeSelectionEvent e) {
+				TreeModelAdapterUITest.this.treeSelectionChanged(e);
+			}
+		};
+	}
+
+	void treeSelectionChanged(@SuppressWarnings("unused") TreeSelectionEvent e) {
+		TestModel selectedTestModel = this.selectedTestModel();
+		if (selectedTestModel != null) {
+			this.nameTextField.setText(selectedTestModel.getName());
+		}
+	}
+
+	private void openWindow() {
+		JFrame window = new JFrame(this.getClass().getName());
+		window.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+		window.addWindowListener(this.buildWindowListener());
+		window.getContentPane().add(this.buildMainPanel(), "Center");
+		window.setLocation(300, 300);
+		window.setSize(400, 400);
+		window.setVisible(true);
+	}
+
+	private WindowListener buildWindowListener() {
+		return new WindowAdapter() {
+			@Override
+			public void windowClosing(WindowEvent e) {
+				e.getWindow().setVisible(false);
+				System.exit(0);
+			}
+		};
+	}
+
+	private Component buildMainPanel() {
+		JPanel mainPanel = new JPanel(new BorderLayout());
+		mainPanel.add(this.buildTreePane(), BorderLayout.CENTER);
+		mainPanel.add(this.buildControlPanel(), BorderLayout.SOUTH);
+		return mainPanel;
+	}
+
+	private Component buildTreePane() {
+		return new JScrollPane(this.buildTree());
+	}
+
+	private JTree buildTree() {
+		this.tree = new JTree(this.treeModel) {
+			@Override
+			public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+				return ((Displayable) value).displayString();
+			}
+		};
+		this.tree.setSelectionModel(this.treeSelectionModel);
+		this.tree.setRootVisible(true);
+		this.tree.setShowsRootHandles(true);
+		this.tree.setRowHeight(20);
+		this.tree.setDoubleBuffered(true);
+		return this.tree;
+	}
+
+	private Component buildControlPanel() {
+		JPanel controlPanel = new JPanel(new GridLayout(0, 1));
+		controlPanel.add(this.buildAddRenameNodePanel());
+		controlPanel.add(this.buildMiscPanel());
+		return controlPanel;
+	}
+
+	private Component buildAddRenameNodePanel() {
+		JPanel addRenameNodePanel = new JPanel(new BorderLayout());
+		addRenameNodePanel.add(this.buildAddButton(), BorderLayout.WEST);
+		addRenameNodePanel.add(this.nameTextField, BorderLayout.CENTER);
+		addRenameNodePanel.add(this.buildRenameButton(), BorderLayout.EAST);
+		return addRenameNodePanel;
+	}
+
+	private Component buildMiscPanel() {
+		JPanel miscPanel = new JPanel(new GridLayout(1, 0));
+		miscPanel.add(this.buildClearChildrenButton());
+		miscPanel.add(this.buildRemoveButton());
+		miscPanel.add(this.buildResetButton());
+		return miscPanel;
+	}
+
+	private String getName() {
+		return this.nameTextField.getText();
+	}
+
+	// ********** queries **********
+	private TestNode selectedNode() {
+		if (this.treeSelectionModel.isSelectionEmpty()) {
+			return null;
+		}
+		return (TestNode) this.treeSelectionModel.getSelectionPath().getLastPathComponent();
+	}
+
+	private TestModel selectedTestModel() {
+		if (this.treeSelectionModel.isSelectionEmpty()) {
+			return null;
+		}
+		return this.selectedNode().getValue();
+	}
+
+	private TestNode rootNode() {
+		return (TestNode) this.treeModel.getRoot();
+	}
+
+	private TestModel root() {
+		return this.rootNode().getValue();
+	}
+
+	private Collection<TreePath> expandedPaths() {
+		Enumeration<TreePath> stream = this.tree.getExpandedDescendants(new TreePath(this.rootNode()));
+		if (stream == null) {
+			return Collections.emptyList();
+		}
+		return ListTools.list(new EnumerationIterator<TreePath>(stream));
+	}
+
+	// ********** behavior **********
+	private void setSelectedNode(TestNode selectedNode) {
+		this.treeSelectionModel.setSelectionPath(new TreePath(selectedNode.path()));
+	}
+
+	private void expandPaths(Collection<TreePath> paths) {
+		for (TreePath path : paths) {
+			this.tree.expandPath(path);
+		}
+	}
+
+	// ********** add **********
+	private JButton buildAddButton() {
+		return new JButton(this.buildAddAction());
+	}
+
+	private Action buildAddAction() {
+		Action action = new AbstractAction("add") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				TreeModelAdapterUITest.this.addNode();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	/**
+	 * adding causes the tree to be sorted and nodes to be
+	 * removed and re-added; so we have to fiddle with the expansion state
+	 */
+	void addNode() {
+		TestModel selectedTestModel = this.selectedTestModel();
+		if (selectedTestModel != null) {
+			String name = this.getName();
+			// save the expansion state and restore it after the add
+			Collection<TreePath> paths = this.expandedPaths();
+
+			selectedTestModel.addChild(name);
+
+			this.expandPaths(paths);
+			this.setSelectedNode(this.selectedNode().childNamed(name));
+		}
+	}
+
+	// ********** remove **********
+	private JButton buildRemoveButton() {
+		return new JButton(this.buildRemoveAction());
+	}
+
+	private Action buildRemoveAction() {
+		Action action = new AbstractAction("remove") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				TreeModelAdapterUITest.this.removeNode();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	/**
+	 * we need to figure out which node to select after
+	 * the selected node is deleted
+	 */
+	void removeNode() {
+		TestModel selectedTestModel = this.selectedTestModel();
+		// do not allow the root to be removed
+		if ((selectedTestModel != null) && (selectedTestModel != this.root())) {
+			// save the parent and index, so we can select another, nearby, node
+			// once the selected node is removed
+			TestNode parentNode = (TestNode) this.selectedNode().parent();
+			int childIndex = parentNode.indexOfChild(this.selectedNode());
+
+			selectedTestModel.getParent().removeChild(selectedTestModel);
+
+			int childrenSize = parentNode.childrenSize();
+			if (childIndex < childrenSize) {
+				// select the child that moved up and replaced the just-deleted child
+				this.setSelectedNode((TestNode) parentNode.child(childIndex));
+			} else {
+				if (childrenSize == 0) {
+					// if there are no more children, select the parent
+					this.setSelectedNode(parentNode);
+				} else {
+					// if the child at the bottom of the list was deleted, select the next child up
+					this.setSelectedNode((TestNode) parentNode.child(childIndex - 1));
+				}
+			}
+		}
+	}
+
+	// ********** rename **********
+	private JButton buildRenameButton() {
+		return new JButton(this.buildRenameAction());
+	}
+
+	private Action buildRenameAction() {
+		Action action = new AbstractAction("rename") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				TreeModelAdapterUITest.this.renameNode();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	/**
+	 * renaming causes the tree to be sorted and nodes to be
+	 * removed and re-added; so we have to fiddle with the expansion state
+	 */
+	void renameNode() {
+		TestModel selectedTestModel = this.selectedTestModel();
+		if (selectedTestModel != null) {
+			// save the node and re-select it after the rename
+			TestNode selectedNode = this.selectedNode();
+			// save the expansion state and restore it after the rename
+			Collection<TreePath> paths = this.expandedPaths();
+
+			selectedTestModel.setName(this.getName());
+
+			this.expandPaths(paths);
+			this.setSelectedNode(selectedNode);
+		}
+	}
+
+	// ********** clear children **********
+	private JButton buildClearChildrenButton() {
+		return new JButton(this.buildClearChildrenAction());
+	}
+
+	private Action buildClearChildrenAction() {
+		Action action = new AbstractAction("clear children") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				TreeModelAdapterUITest.this.clearChildren();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	/**
+	 * nothing special, we just want to test #fireCollectionChanged(String)
+	 */
+	void clearChildren() {
+		TestModel selectedTestModel = this.selectedTestModel();
+		if (selectedTestModel != null) {
+			selectedTestModel.clearChildren();
+		}
+	}
+
+	// ********** reset **********
+	private JButton buildResetButton() {
+		return new JButton(this.buildResetAction());
+	}
+
+	private Action buildResetAction() {
+		Action action = new AbstractAction("reset") {
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				TreeModelAdapterUITest.this.reset();
+			}
+		};
+		action.setEnabled(true);
+		return action;
+	}
+
+	/**
+	 * test the adapter's root node holder;
+	 * toggle between sorted and unsorted lists
+	 */
+	void reset() {
+		this.sorted = ! this.sorted;
+		if (this.sorted) {
+			this.rootNodeHolder.setValue(this.buildSortedRootNode());
+		} else {
+			this.rootNodeHolder.setValue(this.buildUnsortedRootNode());
+		}
+		this.tree.expandPath(new TreePath(this.rootNode()));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/UtilityModelValueSwingTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/UtilityModelValueSwingTests.java
new file mode 100644
index 0000000..e8b623d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/model/value/swing/UtilityModelValueSwingTests.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.model.value.swing;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class UtilityModelValueSwingTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(UtilityModelValueSwingTests.class.getPackage().getName());
+
+		suite.addTestSuite(CheckBoxModelAdapterTests.class);
+		suite.addTestSuite(ComboBoxModelAdapterTests.class);
+		suite.addTestSuite(DateSpinnerModelAdapterTests.class);
+		suite.addTestSuite(DocumentAdapterTests.class);
+		suite.addTestSuite(ListModelAdapterTests.class);
+		suite.addTestSuite(ListSpinnerModelAdapterTests.class);
+		suite.addTestSuite(NumberSpinnerModelAdapterTests.class);
+		suite.addTestSuite(ObjectListSelectionModelTests.class);
+		suite.addTestSuite(PrimitiveListTreeModelTests.class);
+		suite.addTestSuite(RadioButtonModelAdapterTests.class);
+		suite.addTestSuite(SpinnerModelAdapterTests.class);
+		suite.addTestSuite(TableModelAdapterTests.class);
+		suite.addTestSuite(TreeModelAdapterTests.class);
+
+		return suite;
+	}
+
+	private UtilityModelValueSwingTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/node/AbstractNodeTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/node/AbstractNodeTests.java
new file mode 100644
index 0000000..129c264
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/node/AbstractNodeTests.java
@@ -0,0 +1,496 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.node;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.iterator.CloneIterator;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.node.AbstractNode;
+import org.eclipse.persistence.tools.utility.node.Node;
+import org.eclipse.persistence.tools.utility.node.Problem;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class AbstractNodeTests extends TestCase {
+	private TestWorkbenchModel root;
+
+	public AbstractNodeTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.root = this.buildRoot();
+	}
+
+	private TestWorkbenchModel buildRoot() {
+		TestWorkbenchModel r = new RootTestWorkbenchModel("root");
+			TestWorkbenchModel node1 = r.addTestChildNamed("node 1");
+				TestWorkbenchModel node1_1 = node1.addTestChildNamed("node 1.1");
+					node1_1.addTestChildNamed("node 1.1.1");
+					node1_1.addTestChildNamed("node 1.1.2");
+					node1_1.addTestChildNamed("node 1.1.3");
+				node1.addTestChildNamed("node 1.2");
+			TestWorkbenchModel node2 = r.addTestChildNamed("node 2");
+				node2.addTestChildNamed("node 2.1");
+				node2.addTestChildNamed("node 2.2");
+			r.addTestChildNamed("node 3");
+			r.addTestChildNamed("node 4");
+
+		// mark the entire tree clean
+		r.markEntireBranchClean();
+		return r;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testTestWorkbenchModel() {
+		// make sure our test class works OK...
+		assertNull(this.root.testChildNamed(""));
+		assertNotNull(this.root.testChildNamed("node 1"));
+		assertTrue(this.root.testChildNamed("node 1").isClean());
+		assertTrue(this.root.testChildNamed("node 1").isCleanBranch());
+		assertNotNull(this.root.testChildNamed("node 2"));
+		assertTrue(this.root.testChildNamed("node 2").isClean());
+		assertTrue(this.root.testChildNamed("node 2").isCleanBranch());
+		assertNull(this.root.testChildNamed("node 2.1"));
+
+		assertNull(this.root.testDescendantNamed(""));
+		assertNotNull(this.root.testDescendantNamed("node 1"));
+		assertNotNull(this.root.testDescendantNamed("node 2"));
+		assertNotNull(this.root.testDescendantNamed("node 2.1"));
+		assertTrue(this.root.testDescendantNamed("node 2.1").isClean());
+		assertTrue(this.root.testDescendantNamed("node 2.1").isCleanBranch());
+		assertNotNull(this.root.testDescendantNamed("node 1.1.3"));
+		assertTrue(this.root.testDescendantNamed("node 1.1.3").isClean());
+		assertTrue(this.root.testDescendantNamed("node 1.1.3").isCleanBranch());
+	}
+
+	public void testParentAndChildren() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		assertEquals("node 1.1.3", node.getName());
+		assertEquals(0, IteratorTools.size(node.children()));
+
+		node = (TestWorkbenchModel) node.getParent();
+		assertEquals("node 1.1", node.getName());
+		assertEquals(3, IteratorTools.size(node.children()));
+
+		node = (TestWorkbenchModel) node.getParent();
+		assertEquals("node 1", node.getName());
+		assertEquals(2, IteratorTools.size(node.children()));
+
+		node = (TestWorkbenchModel) node.getParent();
+		assertEquals("root", node.getName());
+		assertEquals(4, IteratorTools.size(node.children()));
+
+		node = (TestWorkbenchModel) node.getParent();
+		assertNull(node);
+	}
+
+	public void testDirty() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setSize(42);
+		assertTrue(node.isDirty());
+
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
+		assertTrue(parent.isClean());
+		assertTrue(this.root.isClean());
+	}
+
+	public void testDirtyUnchangedAttribute() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setSize(42);
+		assertTrue(node.isDirty());
+
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
+		assertTrue(parent.isClean());
+		assertTrue(this.root.isClean());
+
+		this.root.markEntireBranchClean();
+		// set size to same number - should stay clean
+		node.setSize(42);
+		assertTrue(node.isClean());
+		assertTrue(parent.isClean());
+		assertTrue(this.root.isClean());
+	}
+
+	public void testDirtyBranch() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setSize(42);
+		assertTrue(node.isDirtyBranch());
+
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
+		assertTrue(parent.isDirtyBranch());
+		assertTrue(this.root.isDirtyBranch());
+
+		parent.setSize(77);
+		assertTrue(parent.isDirty());
+		assertTrue(parent.isDirtyBranch());
+
+		node.markEntireBranchClean();
+		assertTrue(parent.isDirty());
+		assertTrue(parent.isDirtyBranch());
+	}
+
+	public void testDirtyBranchCleanChildDirtyParent() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setSize(42);
+
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
+		parent.setSize(77);
+		assertTrue(parent.isDirty());
+		assertTrue(parent.isDirtyBranch());
+
+		// now, clean the child, but leave the parent dirty
+		node.markEntireBranchClean();
+		assertTrue(parent.isDirty());
+		assertTrue(parent.isDirtyBranch());
+	}
+
+	public void testDirtyBranchCleanChildDirtyChild() {
+		TestWorkbenchModel node1 = this.root.testDescendantNamed("node 1.1.1");
+		node1.setSize(41);
+		TestWorkbenchModel node2 = this.root.testDescendantNamed("node 1.1.2");
+		node2.setSize(42);
+
+		TestWorkbenchModel parent = (TestWorkbenchModel) node1.getParent();
+		assertTrue(parent.isClean());
+		assertTrue(parent.isDirtyBranch());
+
+		// now, clean the first child, but leave the second child dirty
+		node1.markEntireBranchClean();
+		assertTrue(parent.isClean());
+		assertTrue(parent.isDirtyBranch());
+	}
+
+	public void testDirtyBranchForced() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
+
+		assertTrue(node.isClean());
+		assertTrue(node.isCleanBranch());
+		assertTrue(parent.isClean());
+		assertTrue(parent.isCleanBranch());
+		assertTrue(this.root.isClean());
+		assertTrue(this.root.isCleanBranch());
+
+		this.root.markEntireBranchDirty();
+
+		assertTrue(node.isDirty());
+		assertTrue(node.isDirtyBranch());
+		assertTrue(parent.isDirty());
+		assertTrue(parent.isDirtyBranch());
+		assertTrue(this.root.isDirty());
+		assertTrue(this.root.isDirtyBranch());
+	}
+
+	public void testDirtyTransientAttribute() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setName("BOGUS");
+		assertTrue(node.isDirty());
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
+		assertTrue(parent.isClean());
+		assertTrue(parent.isDirtyBranch());
+		assertTrue(this.root.isClean());
+		assertTrue(this.root.isDirtyBranch());
+
+		this.root.markEntireBranchClean();
+
+		this.root.validateBranch();
+
+		assertTrue(this.root.problemsSize() == 0);
+		assertTrue(node.branchProblems().hasNext());
+		assertTrue(parent.problemsSize() == 0);
+		assertTrue(parent.branchProblems().hasNext());
+		assertTrue(node.problemsSize() > 0);
+
+		// since problems are transient, everything should still be clean
+		assertTrue(node.isClean());
+		assertTrue(node.isCleanBranch());
+		assertTrue(parent.isClean());
+		assertTrue(parent.isCleanBranch());
+		assertTrue(this.root.isClean());
+		assertTrue(this.root.isCleanBranch());
+	}
+
+	public void testProblems() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setName("BOGUS");
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
+
+		this.root.validateBranch();
+
+		assertEquals(0, this.root.problemsSize());
+		assertTrue(node.branchProblems().hasNext());
+		assertEquals(0, parent.problemsSize());
+		assertTrue(parent.branchProblems().hasNext());
+		assertEquals(1, node.problemsSize());
+		Problem problem1 = node.problems().next();
+
+		// now create another problem that should remove the old problem
+		node.setName("STILL BOGUS");
+		this.root.validateBranch();
+
+		assertEquals(0, this.root.problemsSize());
+		assertTrue(node.branchProblems().hasNext());
+		assertEquals(0, parent.problemsSize());
+		assertTrue(parent.branchProblems().hasNext());
+		assertEquals(1, node.problemsSize());
+		Problem problem2 = node.problems().next();
+		assertFalse(problem1 == problem2);
+		problem1 = problem2;
+
+		// now create another problem that should replace the old problem
+		node.setName("STILL BOGUS");
+		this.root.validateBranch();
+
+		assertEquals(0, this.root.problemsSize());
+		assertTrue(node.branchProblems().hasNext());
+		assertEquals(0, parent.problemsSize());
+		assertTrue(parent.branchProblems().hasNext());
+		assertEquals(1, node.problemsSize());
+		problem2 = node.problems().next();
+		// the same problem should be there
+		assertTrue(problem1.equals(problem2));
+	}
+
+	public void testBranchProblems() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setName("BOGUS");
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
+		parent.setName("BOGUS TOO");
+		this.root.setName("BOGUS TOO TOO");
+
+		this.root.validateBranch();
+
+		assertEquals(1, this.root.problemsSize());
+		assertEquals(3, this.root.branchProblemsSize());
+		assertEquals(1, parent.problemsSize());
+		assertEquals(2, parent.branchProblemsSize());
+		assertEquals(1, node.problemsSize());
+		assertEquals(1, node.branchProblemsSize());
+
+		node.setName("okie-dokie");
+
+		this.root.validateBranch();
+
+		assertEquals(1, this.root.problemsSize());
+		assertEquals(2, this.root.branchProblemsSize());
+		assertEquals(1, parent.problemsSize());
+		assertEquals(1, parent.branchProblemsSize());
+		assertEquals(0, node.problemsSize());
+		assertEquals(0, node.branchProblemsSize());
+	}
+
+	public void testClearAllBranchProblems() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setName("BOGUS");
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
+		parent.setName("BOGUS TOO");
+		this.root.setName("BOGUS TOO TOO");
+
+		this.root.validateBranch();
+
+		assertEquals(1, this.root.problemsSize());
+		assertEquals(3, this.root.branchProblemsSize());
+		assertEquals(1, parent.problemsSize());
+		assertEquals(2, parent.branchProblemsSize());
+		assertEquals(1, node.problemsSize());
+		assertEquals(1, node.branchProblemsSize());
+
+		parent.clearAllBranchProblems();
+
+		assertEquals(1, this.root.problemsSize());
+		assertEquals(1, this.root.branchProblemsSize());
+		assertEquals(0, parent.problemsSize());
+		assertEquals(0, parent.branchProblemsSize());
+		assertEquals(0, node.problemsSize());
+		assertEquals(0, IteratorTools.size(node.branchProblems()));
+	}
+
+	public void testRemovedBranchProblems() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setName("BOGUS");
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.getParent();
+		parent.setName("BOGUS TOO");
+		this.root.setName("BOGUS TOO TOO");
+
+		this.root.validateBranch();
+
+		assertEquals(1, this.root.problemsSize());
+		assertEquals(3, IteratorTools.size(this.root.branchProblems()));
+		assertEquals(1, parent.problemsSize());
+		assertEquals(2, parent.branchProblemsSize());
+		assertEquals(1, node.problemsSize());
+		assertEquals(1, IteratorTools.size(node.branchProblems()));
+
+		// completely remove a node that has problems -
+		// the entire tree should recalculate its "branch" problems
+		parent.removeTestChild(node);
+
+		this.root.validateBranch();
+
+		assertEquals(1, this.root.problemsSize());
+		assertEquals(2, IteratorTools.size(this.root.branchProblems()));
+		assertEquals(1, parent.problemsSize());
+		assertEquals(1, parent.branchProblemsSize());
+	}
+
+
+	// ********** inner classes **********
+
+	public class TestWorkbenchModel extends AbstractNode {
+		private String name;
+			public static final String NAME_PROPERTY = "name";
+		private int size;
+			public static final String SIZE_PROPERTY = "size";
+		private Collection<TestWorkbenchModel> testChildren;
+			public static final String TEST_CHILDREN_COLLECTION = "children";
+
+		// ********** construction/initialization **********
+		public TestWorkbenchModel(TestWorkbenchModel parent, String name) {
+			super(parent);
+			if (name == null) {
+				throw new NullPointerException();
+			}
+			this.name = name;
+		}
+		@Override
+		protected void initialize() {
+			super.initialize();
+			this.size = 0;
+			this.testChildren = new HashBag<TestWorkbenchModel>();
+		}
+
+		@Override
+		protected void checkParent(Node parent) {
+			// do nothing
+		}
+
+
+		// ********** accessors **********
+		public String getName() {
+			return this.name;
+		}
+		public void setName(String name) {
+			Object old = this.name;
+			this.name = name;
+			this.firePropertyChanged(NAME_PROPERTY, old, name);
+		}
+
+		public int getSize() {
+			return this.size;
+		}
+		public void setSize(int size) {
+			int old = this.size;
+			this.size = size;
+			this.firePropertyChanged(SIZE_PROPERTY, old, size);
+		}
+
+		public Iterator<TestWorkbenchModel> testChildren() {
+			return new CloneIterator<TestWorkbenchModel>(this.testChildren, new CloneIterator.Remover<TestWorkbenchModel>() {
+				@Override
+				public void remove(TestWorkbenchModel current) {
+					TestWorkbenchModel.this.removeTestChild(current);
+				}
+			});
+		}
+		public int testChildrenSize() {
+			return this.testChildren.size();
+		}
+		private TestWorkbenchModel addTestChild(TestWorkbenchModel testChild) {
+			this.addItemToCollection(testChild, this.testChildren, TEST_CHILDREN_COLLECTION);
+			return testChild;
+		}
+		public TestWorkbenchModel addTestChildNamed(String childName) {
+			if (this.testChildNamed(childName) != null) {
+				throw new IllegalArgumentException(childName);
+			}
+			return this.addTestChild(new TestWorkbenchModel(this, childName));
+		}
+		public void removeTestChild(TestWorkbenchModel testChild) {
+			this.removeItemFromCollection(testChild, this.testChildren, TEST_CHILDREN_COLLECTION);
+		}
+
+		// ********** queries **********
+		@Override
+		public String displayString() {
+			return this.name;
+		}
+		public TestWorkbenchModel testChildNamed(String childName) {
+			for (TestWorkbenchModel testChild : this.testChildren) {
+				if (testChild.getName().equals(childName)) {
+					return testChild;
+				}
+			}
+			return null;
+		}
+		public TestWorkbenchModel testDescendantNamed(String descendantName) {
+			for (TestWorkbenchModel testDescendant : this.testChildren) {
+				if (testDescendant.getName().equals(descendantName)) {
+					return testDescendant;
+				}
+				// recurse...
+				testDescendant = testDescendant.testDescendantNamed(descendantName);
+				if (testDescendant != null) {
+					return testDescendant;
+				}
+			}
+			return null;
+		}
+
+		// ********** behavior **********
+		@Override
+		protected void addChildrenTo(List<Node> children) {
+			super.addChildrenTo(children);
+			children.addAll(this.testChildren);
+		}
+		@Override
+		protected void addProblemsTo(List<Problem> currentProblems) {
+			super.addProblemsTo(currentProblems);
+			// names must be all lowercase...
+			for (int i = this.name.length(); i-- > 0; ) {
+				char c = this.name.charAt(i);
+				if (Character.isLetter(c) && ! Character.isLowerCase(c)) {
+					currentProblems.add(this.buildProblem("NAME_MUST_BE_LOWERCASE", 3 ,this.name));
+					return;
+				}
+			}
+		}
+		@Override
+		public void toString(StringBuilder sb) {
+			sb.append(this.name);
+		}
+	}
+
+
+	private class RootTestWorkbenchModel extends TestWorkbenchModel {
+		public RootTestWorkbenchModel(String name) {
+			super(null, name);
+		}
+		@Override
+		public Validator getValidator() {
+			return Node.NULL_VALIDATOR;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/node/CommonUtilityNodeTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/node/CommonUtilityNodeTests.java
new file mode 100644
index 0000000..38bb14e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/node/CommonUtilityNodeTests.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.node;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CommonUtilityNodeTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CommonUtilityNodeTests.class.getPackage().getName());
+
+		suite.addTestSuite(AbstractNodeTests.class);
+
+		return suite;
+	}
+
+	private CommonUtilityNodeTests() {
+		super();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/CommonUtilityReferenceTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/CommonUtilityReferenceTests.java
new file mode 100644
index 0000000..8177a1a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/CommonUtilityReferenceTests.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.reference;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * decentralize test creation code
+ */
+public class CommonUtilityReferenceTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CommonUtilityReferenceTests.class.getPackage().getName());
+
+		suite.addTestSuite(SimpleBooleanReferenceTests.class);
+		suite.addTestSuite(SimpleIntReferenceTests.class);
+		suite.addTestSuite(SimpleObjectReferenceTests.class);
+		suite.addTestSuite(SynchronizedBooleanTests.class);
+		suite.addTestSuite(SynchronizedIntTests.class);
+		suite.addTestSuite(SynchronizedObjectTests.class);
+
+		return suite;
+	}
+
+	private CommonUtilityReferenceTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SimpleBooleanReferenceTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SimpleBooleanReferenceTests.java
new file mode 100644
index 0000000..3ae2f80
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SimpleBooleanReferenceTests.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.reference;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.reference.SimpleBooleanReference;
+
+@SuppressWarnings("nls")
+public class SimpleBooleanReferenceTests extends TestCase {
+
+	public SimpleBooleanReferenceTests(String name) {
+		super(name);
+	}
+
+	public void testGetValue() {
+		SimpleBooleanReference br = new SimpleBooleanReference(true);
+		assertTrue(br.getValue());
+	}
+
+	public void testGetValueDefault() {
+		SimpleBooleanReference br = new SimpleBooleanReference();
+		assertFalse(br.getValue());
+	}
+
+	public void testIs() {
+		SimpleBooleanReference br = new SimpleBooleanReference(true);
+		assertTrue(br.is(true));
+		assertFalse(br.is(false));
+	}
+
+	public void testIsNot() {
+		SimpleBooleanReference br = new SimpleBooleanReference(true);
+		assertFalse(br.isNot(true));
+		assertTrue(br.isNot(false));
+	}
+
+	public void testIsTrue() {
+		SimpleBooleanReference br = new SimpleBooleanReference(true);
+		assertTrue(br.isTrue());
+	}
+
+	public void testIsFalse() {
+		SimpleBooleanReference br = new SimpleBooleanReference(true);
+		assertFalse(br.isFalse());
+		br.setFalse();
+		assertTrue(br.isFalse());
+	}
+
+	public void testSetValue() {
+		SimpleBooleanReference br = new SimpleBooleanReference(true);
+		assertTrue(br.getValue());
+		br.setValue(false);
+		assertFalse(br.getValue());
+	}
+
+	public void testFlip() {
+		SimpleBooleanReference br = new SimpleBooleanReference(true);
+		assertTrue(br.getValue());
+		assertFalse(br.flip());
+		assertFalse(br.getValue());
+		assertTrue(br.flip());
+		assertTrue(br.getValue());
+	}
+
+	public void testSetNotBoolean() {
+		SimpleBooleanReference br = new SimpleBooleanReference(false);
+		assertFalse(br.getValue());
+		br.setNot(true);
+		assertFalse(br.getValue());
+		br.setNot(true);
+		assertFalse(br.getValue());
+		br.setNot(false);
+		assertTrue(br.getValue());
+	}
+
+	public void testSetTrue() {
+		SimpleBooleanReference br = new SimpleBooleanReference(false);
+		assertFalse(br.getValue());
+		br.setTrue();
+		assertTrue(br.getValue());
+	}
+
+	public void testSetFalse() {
+		SimpleBooleanReference br = new SimpleBooleanReference(true);
+		assertTrue(br.getValue());
+		br.setFalse();
+		assertFalse(br.getValue());
+	}
+
+	public void testClone() {
+		SimpleBooleanReference br = new SimpleBooleanReference(true);
+		SimpleBooleanReference clone = br.clone();
+		assertTrue(clone.getValue());
+	}
+
+	public void testToString() {
+		SimpleBooleanReference br1 = new SimpleBooleanReference(true);
+		assertEquals("[true]", br1.toString());
+		br1.setFalse();
+		assertEquals("[false]", br1.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SimpleIntReferenceTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SimpleIntReferenceTests.java
new file mode 100644
index 0000000..9e3a4c3
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SimpleIntReferenceTests.java
@@ -0,0 +1,318 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.reference;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.reference.SimpleIntReference;
+import org.eclipse.persistence.tools.utility.tests.TestTools;
+
+@SuppressWarnings("nls")
+public class SimpleIntReferenceTests extends TestCase {
+
+	public SimpleIntReferenceTests(String name) {
+		super(name);
+	}
+
+	public void testCtors() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference();
+		assertEquals(0, ir.getValue());
+		ir = new SimpleIntReference(7);
+		assertEquals(7, ir.getValue());
+		ir = new SimpleIntReference(-7);
+		assertEquals(-7, ir.getValue());
+	}
+
+	public void testEqualsInt() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference();
+		assertTrue(ir.equals(0));
+		assertFalse(ir.equals(7));
+
+		ir = new SimpleIntReference(7);
+		assertTrue(ir.equals(7));
+		assertFalse(ir.equals(0));
+	}
+
+	public void testNotEqualInt() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference();
+		assertFalse(ir.notEqual(0));
+		assertTrue(ir.notEqual(7));
+
+		ir = new SimpleIntReference(7);
+		assertFalse(ir.notEqual(7));
+		assertTrue(ir.notEqual(0));
+	}
+
+	public void testIsZero() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference();
+		assertTrue(ir.isZero());
+
+		ir = new SimpleIntReference(7);
+		assertFalse(ir.isZero());
+	}
+
+	public void testIsNotZero() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference();
+		assertFalse(ir.isNotZero());
+
+		ir = new SimpleIntReference(7);
+		assertTrue(ir.isNotZero());
+	}
+
+	public void testIsGreaterThanInt() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference();
+		assertTrue(ir.isGreaterThan(-1));
+		assertFalse(ir.isGreaterThan(0));
+		assertFalse(ir.isGreaterThan(7));
+	}
+
+	public void testIsGreaterThanOrEqualInt() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference();
+		assertTrue(ir.isGreaterThanOrEqual(-1));
+		assertTrue(ir.isGreaterThanOrEqual(0));
+		assertFalse(ir.isGreaterThanOrEqual(7));
+	}
+
+	public void testIsLessThanInt() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference();
+		assertFalse(ir.isLessThan(-1));
+		assertFalse(ir.isLessThan(0));
+		assertTrue(ir.isLessThan(7));
+	}
+
+	public void testIsLessThanOrEqualInt() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference();
+		assertFalse(ir.isLessThanOrEqual(-1));
+		assertTrue(ir.isLessThanOrEqual(0));
+		assertTrue(ir.isLessThanOrEqual(7));
+	}
+
+	public void testIsPositive() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(-3);
+		assertFalse(ir.isPositive());
+
+		ir = new SimpleIntReference();
+		assertFalse(ir.isPositive());
+
+		ir = new SimpleIntReference(7);
+		assertTrue(ir.isPositive());
+	}
+
+	public void testIsNotPositive() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(-3);
+		assertTrue(ir.isNotPositive());
+
+		ir = new SimpleIntReference();
+		assertTrue(ir.isNotPositive());
+
+		ir = new SimpleIntReference(7);
+		assertFalse(ir.isNotPositive());
+	}
+
+	public void testIsNegative() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(-3);
+		assertTrue(ir.isNegative());
+
+		ir = new SimpleIntReference();
+		assertFalse(ir.isNegative());
+
+		ir = new SimpleIntReference(7);
+		assertFalse(ir.isNegative());
+	}
+
+	public void testIsNotNegative() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(-3);
+		assertFalse(ir.isNotNegative());
+
+		ir = new SimpleIntReference();
+		assertTrue(ir.isNotNegative());
+
+		ir = new SimpleIntReference(7);
+		assertTrue(ir.isNotNegative());
+	}
+
+	public void testSetValueInt() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(-3);
+		assertEquals(-3, ir.getValue());
+		assertEquals(-3, ir.setValue(4));
+		assertEquals(4, ir.getValue());
+	}
+
+	public void testAbs() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(-3);
+		assertEquals(-3, ir.getValue());
+		assertEquals(3, ir.abs());
+
+		ir.setValue(3);
+		assertEquals(3, ir.getValue());
+		assertEquals(3, ir.abs());
+	}
+
+	public void testNeg() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(-3);
+		assertEquals(-3, ir.getValue());
+		assertEquals(3, ir.neg());
+
+		ir.setValue(3);
+		assertEquals(3, ir.getValue());
+		assertEquals(-3, ir.neg());
+	}
+
+	public void testSetZero() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(-3);
+		assertEquals(-3, ir.getValue());
+		assertEquals(-3, ir.setZero());
+		assertEquals(0, ir.getValue());
+	}
+
+	public void testAddInt() {
+		SimpleIntReference ir;
+		int value;
+		ir = new SimpleIntReference();
+		assertEquals(0, ir.getValue());
+
+		value = ir.add(3);
+		assertEquals(3, value);
+
+		ir.setValue(3);
+		value = ir.add(-7);
+		assertEquals(-4, value);
+	}
+
+	public void testIncrement() {
+		SimpleIntReference ir;
+		int value;
+		ir = new SimpleIntReference();
+		assertEquals(0, ir.getValue());
+
+		value = ir.increment();
+		assertEquals(1, value);
+		assertEquals(1, ir.getValue());
+	}
+
+	public void testSubtractInt() {
+		SimpleIntReference ir;
+		int count;
+		ir = new SimpleIntReference();
+		assertEquals(0, ir.getValue());
+
+		count = ir.subtract(3);
+		assertEquals(-3, count);
+
+		ir.setValue(-3);
+		count = ir.subtract(-7);
+		assertEquals(4, count);
+	}
+
+	public void testDecrement() {
+		SimpleIntReference ir;
+		int count;
+		ir = new SimpleIntReference();
+		assertEquals(0, ir.getValue());
+
+		count = ir.decrement();
+		assertEquals(-1, count);
+		assertEquals(-1, ir.getValue());
+	}
+
+	public void testMultiplyInt() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(3);
+		assertEquals(3, ir.getValue());
+		assertEquals(9, ir.multiply(3));
+	}
+
+	public void testDivideInt() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(24);
+		assertEquals(24, ir.getValue());
+		assertEquals(8, ir.divide(3));
+	}
+
+	public void testRemainderInt() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(25);
+		assertEquals(25, ir.getValue());
+		assertEquals(1, ir.remainder(3));
+	}
+
+	public void testMinInt() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(25);
+		assertEquals(25, ir.getValue());
+		assertEquals(3, ir.min(3));
+		assertEquals(25, ir.min(33));
+	}
+
+	public void testMaxInt() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(25);
+		assertEquals(25, ir.getValue());
+		assertEquals(25, ir.max(3));
+		assertEquals(30, ir.max(30));
+	}
+
+	public void testPowInt() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(5);
+		assertEquals(5, ir.getValue());
+		assertTrue(ir.pow(2) == 25L);
+	}
+
+	public void testCompareToIntReference() {
+		SimpleIntReference ir1 = new SimpleIntReference(44);
+		SimpleIntReference ir2 = new SimpleIntReference(44);
+		assertTrue(ir1.compareTo(ir2) == 0);
+		ir2 = new SimpleIntReference(55);
+		assertTrue(ir1.compareTo(ir2) < 0);
+		ir2 = new SimpleIntReference(33);
+		assertTrue(ir1.compareTo(ir2) > 0);
+	}
+
+	public void testClone() {
+		SimpleIntReference ir1 = new SimpleIntReference(44);
+		SimpleIntReference ir2 = ir1.clone();
+		assertEquals(44, ir2.getValue());
+		assertNotSame(ir1, ir2);
+	}
+
+	public void testSerialization() throws Exception {
+		SimpleIntReference ir1 = new SimpleIntReference(44);
+		SimpleIntReference ir2 = TestTools.serialize(ir1);
+		assertEquals(44, ir2.getValue());
+		assertNotSame(ir1, ir2);
+	}
+
+	public void testToString() {
+		SimpleIntReference ir;
+		ir = new SimpleIntReference(5);
+		assertEquals("[5]", ir.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SimpleObjectReferenceTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SimpleObjectReferenceTests.java
new file mode 100644
index 0000000..a160fb4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SimpleObjectReferenceTests.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.reference;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.reference.SimpleObjectReference;
+
+@SuppressWarnings("nls")
+public class SimpleObjectReferenceTests extends TestCase {
+
+	public SimpleObjectReferenceTests(String name) {
+		super(name);
+	}
+
+	public void testGetValue() {
+		SimpleObjectReference<String> or = new SimpleObjectReference<String>();
+		assertNull(or.getValue());
+		or.setValue("foo");
+		assertEquals("foo", or.getValue());
+	}
+
+	public void testValueEqualsObject() {
+		SimpleObjectReference<String> or = new SimpleObjectReference<String>();
+		assertTrue(or.valueEquals(null));
+		assertFalse(or.valueEquals("foo"));
+
+		or.setValue("foo");
+		assertFalse(or.valueEquals(null));
+		assertTrue(or.valueEquals("foo"));
+	}
+
+	public void testValueNotEqualObject() {
+		SimpleObjectReference<String> or = new SimpleObjectReference<String>();
+		assertFalse(or.valueNotEqual(null));
+		assertTrue(or.valueNotEqual("foo"));
+
+		or.setValue("foo");
+		assertTrue(or.valueNotEqual(null));
+		assertFalse(or.valueNotEqual("foo"));
+	}
+
+	public void testIsNull() {
+		SimpleObjectReference<String> or = new SimpleObjectReference<String>();
+		assertTrue(or.isNull());
+		or.setValue("foo");
+		assertFalse(or.isNull());
+	}
+
+	public void testIsNotNull() {
+		SimpleObjectReference<String> or = new SimpleObjectReference<String>();
+		assertFalse(or.isNotNull());
+		or.setValue("foo");
+		assertTrue(or.isNotNull());
+	}
+
+	public void testSetNull() {
+		SimpleObjectReference<String> or = new SimpleObjectReference<String>();
+		assertNull(or.getValue());
+		or.setValue("foo");
+		assertEquals("foo", or.getValue());
+		or.setNull();
+		assertNull(or.getValue());
+	}
+
+	public void testClone() {
+		SimpleObjectReference<String> or = new SimpleObjectReference<String>("foo");
+		@SuppressWarnings("cast")
+		SimpleObjectReference<String> clone = (SimpleObjectReference<String>) or.clone();
+		assertEquals("foo", clone.getValue());
+		assertNotSame(or, clone);
+	}
+
+	public void testToString() {
+		SimpleObjectReference<String> or = new SimpleObjectReference<String>();
+		assertEquals("[null]", or.toString());
+		or.setValue("foo");
+		assertEquals("[foo]", or.toString());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SynchronizedBooleanTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SynchronizedBooleanTests.java
new file mode 100644
index 0000000..4a22aef
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SynchronizedBooleanTests.java
@@ -0,0 +1,347 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.reference;
+
+import org.eclipse.persistence.tools.utility.reference.SynchronizedBoolean;
+import org.eclipse.persistence.tools.utility.tests.MultiThreadedTestCase;
+
+public class SynchronizedBooleanTests
+	extends MultiThreadedTestCase
+{
+	private volatile SynchronizedBoolean sb;
+	volatile boolean timeoutOccurred;
+	volatile long startTime;
+	volatile long endTime;
+
+	public SynchronizedBooleanTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.sb = new SynchronizedBoolean();
+		this.timeoutOccurred = false;
+		this.startTime = 0;
+		this.endTime = 0;
+	}
+
+	public void testGetValue() throws Exception {
+		assertFalse(this.sb.getValue());
+	}
+
+	public void testIs() throws Exception {
+		assertTrue(this.sb.is(false));
+	}
+
+	public void testIsNot() throws Exception {
+		assertTrue(this.sb.isNot(true));
+	}
+
+	public void testIsTrue() throws Exception {
+		assertFalse(this.sb.isTrue());
+	}
+
+	public void testIsFalse() throws Exception {
+		assertTrue(this.sb.isFalse());
+	}
+
+	public void testSetValueFalse() throws Exception {
+		this.sb.setValue(false);
+		assertFalse(this.sb.getValue());
+		assertFalse(this.sb.isTrue());
+		assertTrue(this.sb.isFalse());
+	}
+
+	public void testSetValueTrue() throws Exception {
+		this.sb.setValue(true);
+		assertTrue(this.sb.getValue());
+		assertTrue(this.sb.isTrue());
+		assertFalse(this.sb.isFalse());
+	}
+
+	public void testFlip() throws Exception {
+		assertTrue(this.sb.flip());
+		assertFalse(this.sb.flip());
+	}
+
+	public void testFalseAndTrue() throws Exception {
+		assertFalse(this.sb.and(true));
+		assertFalse(this.sb.getValue());
+	}
+
+	public void testTrueAndTrue() throws Exception {
+		this.sb.setValue(true);
+		assertTrue(this.sb.and(true));
+		assertTrue(this.sb.getValue());
+	}
+
+	public void testFalseAndFalse() throws Exception {
+		assertFalse(this.sb.and(false));
+		assertFalse(this.sb.getValue());
+	}
+
+	public void testTrueAndFalse() throws Exception {
+		this.sb.setValue(true);
+		assertFalse(this.sb.and(false));
+		assertFalse(this.sb.getValue());
+	}
+
+	public void testFalseOrTrue() throws Exception {
+		assertTrue(this.sb.or(true));
+		assertTrue(this.sb.getValue());
+	}
+
+	public void testTrueOrTrue() throws Exception {
+		this.sb.setValue(true);
+		assertTrue(this.sb.or(true));
+		assertTrue(this.sb.getValue());
+	}
+
+	public void testFalseOrFalse() throws Exception {
+		assertFalse(this.sb.or(false));
+		assertFalse(this.sb.getValue());
+	}
+
+	public void testTrueOrFalse() throws Exception {
+		this.sb.setValue(true);
+		assertTrue(this.sb.or(false));
+		assertTrue(this.sb.getValue());
+	}
+
+	public void testFalseXorTrue() throws Exception {
+		assertTrue(this.sb.xor(true));
+		assertTrue(this.sb.getValue());
+	}
+
+	public void testTrueXorTrue() throws Exception {
+		this.sb.setValue(true);
+		assertFalse(this.sb.xor(true));
+		assertFalse(this.sb.getValue());
+	}
+
+	public void testFalseXorFalse() throws Exception {
+		assertFalse(this.sb.xor(false));
+		assertFalse(this.sb.getValue());
+	}
+
+	public void testTrueXorFalse() throws Exception {
+		this.sb.setValue(true);
+		assertTrue(this.sb.xor(false));
+		assertTrue(this.sb.getValue());
+	}
+
+	public void testSetNotTrue() throws Exception {
+		this.sb.setNot(true);
+		assertFalse(this.sb.getValue());
+		assertFalse(this.sb.isTrue());
+		assertTrue(this.sb.isFalse());
+	}
+
+	public void testSetNotFalse() throws Exception {
+		this.sb.setNot(false);
+		assertTrue(this.sb.getValue());
+		assertTrue(this.sb.isTrue());
+		assertFalse(this.sb.isFalse());
+	}
+
+	public void testSetFalse() throws Exception {
+		this.sb.setFalse();
+		assertFalse(this.sb.getValue());
+		assertFalse(this.sb.isTrue());
+		assertTrue(this.sb.isFalse());
+	}
+
+	public void testSetTrue() throws Exception {
+		this.sb.setTrue();
+		assertTrue(this.sb.getValue());
+		assertTrue(this.sb.isTrue());
+		assertFalse(this.sb.isFalse());
+	}
+
+	public void testCommitFalseSuccess() throws Exception {
+		assertTrue(this.sb.commit(false, false));
+		assertFalse(this.sb.getValue());
+	}
+
+	public void testCommitTrueSuccess() throws Exception {
+		assertTrue(this.sb.commit(false, true));
+		assertTrue(this.sb.getValue());
+	}
+
+	public void testCommitFalseFailure() throws Exception {
+		assertFalse(this.sb.commit(true, false));
+		assertFalse(this.sb.getValue());
+	}
+
+	public void testCommitTrueFailure() throws Exception {
+		assertFalse(this.sb.commit(true, true));
+		assertFalse(this.sb.getValue());
+	}
+
+	public void testSwapSame() throws Exception {
+		assertFalse(this.sb.swap(this.sb));
+		assertFalse(this.sb.getValue());
+	}
+
+	public void testSwapSameValue() throws Exception {
+		SynchronizedBoolean sb2 = new SynchronizedBoolean();
+		assertFalse(this.sb.swap(sb2));
+		assertFalse(this.sb.getValue());
+		assertFalse(sb2.getValue());
+	}
+
+	public void testSwapDifferentValue() throws Exception {
+		SynchronizedBoolean sb2 = new SynchronizedBoolean(true);
+		assertTrue(this.sb.swap(sb2));
+		assertTrue(this.sb.getValue());
+		assertFalse(sb2.getValue());
+	}
+
+	public void testGetMutexThis() throws Exception {
+		assertSame(this.sb, this.sb.getMutex());
+	}
+
+	public void testGetMutexObject() throws Exception {
+		Object mutex = new Object();
+		SynchronizedBoolean syncBool = new SynchronizedBoolean(mutex);
+		assertSame(mutex, syncBool.getMutex());
+	}
+
+	/**
+	 * t2 will wait indefinitely until t1 sets the value to true
+	 */
+	public void testWaitUntilTrue() throws Exception {
+		this.verifyWaitUntilTrue(0);  // 0 = indefinite wait
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and the value should be set to true by t2
+		assertTrue(this.sb.getValue());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.calculateElapsedTime() > TICK);
+	}
+
+	/**
+	 * t2 will time out waiting for t1 to set the value to true
+	 */
+	public void testWaitUntilTrueTimeout() throws Exception {
+		this.verifyWaitUntilTrue(TICK);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the value will eventually be set to true by t1
+		assertTrue(this.sb.getValue());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.calculateElapsedTime() < THREE_TICKS);
+	}
+
+	private void verifyWaitUntilTrue(long t2Timeout) throws Exception {
+		this.executeThreads(this.buildSetTrueCommand(), this.buildWaitUntilTrueCommand(t2Timeout));
+	}
+
+	/**
+	 * t2 will wait indefinitely until t1 sets the value to false
+	 */
+	public void testWaitToSetFalse() throws Exception {
+		this.verifyWaitToSetFalse(0);  // 0 = indefinite wait
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and the value should be set to false by t2
+		assertFalse(this.sb.getValue());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.calculateElapsedTime() > TICK);
+	}
+
+	/**
+	 * t2 will time out waiting for t1 to set the value to false
+	 */
+	public void testWaitToSetFalseTimeout() throws Exception {
+		this.verifyWaitToSetFalse(TICK);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the value will eventually be set to true by t1
+		assertTrue(this.sb.getValue());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.calculateElapsedTime() < THREE_TICKS);
+	}
+
+	private void verifyWaitToSetFalse(long t2Timeout) throws Exception {
+		this.executeThreads(this.buildSetTrueCommand(), this.buildWaitToSetFalseCommand(t2Timeout));
+	}
+
+	private void executeThreads(Command t1Command, Command t2Command) throws Exception {
+		this.sb.setFalse();
+		Runnable r1 = this.buildRunnable(t1Command, this.sb, TWO_TICKS);
+		Runnable r2 = this.buildRunnable(t2Command, this.sb, 0);
+		Thread t1 = this.buildThread(r1);
+		Thread t2 = this.buildThread(r2);
+		t1.start();
+		t2.start();
+		t1.join();
+		t2.join();
+	}
+
+	private Command buildSetTrueCommand() {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedBoolean syncBool) {
+				syncBool.setTrue();
+			}
+		};
+	}
+
+	private Command buildWaitUntilTrueCommand(final long timeout) {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedBoolean syncBool) throws InterruptedException {
+				SynchronizedBooleanTests.this.startTime = System.currentTimeMillis();
+				SynchronizedBooleanTests.this.timeoutOccurred = ! syncBool.waitUntilTrue(timeout);
+				SynchronizedBooleanTests.this.endTime = System.currentTimeMillis();
+			}
+		};
+	}
+
+	private Command buildWaitToSetFalseCommand(final long timeout) {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedBoolean syncBool) throws InterruptedException {
+				SynchronizedBooleanTests.this.startTime = System.currentTimeMillis();
+				SynchronizedBooleanTests.this.timeoutOccurred =  ! syncBool.waitToSetFalse(timeout);
+				SynchronizedBooleanTests.this.endTime = System.currentTimeMillis();
+			}
+		};
+	}
+
+	private Runnable buildRunnable(final Command command, final SynchronizedBoolean syncBool, final long delay) {
+		return new TestRunnable() {
+			@Override
+			public void run_() throws InterruptedException {
+				if (delay != 0) {
+					Thread.sleep(delay);
+				}
+				command.execute(syncBool);
+			}
+		};
+	}
+
+	long calculateElapsedTime() {
+		return this.endTime - this.startTime;
+	}
+
+
+	// ********** Command interface **********
+
+	private interface Command {
+		void execute(SynchronizedBoolean syncBool) throws InterruptedException;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SynchronizedIntTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SynchronizedIntTests.java
new file mode 100644
index 0000000..015c1b3
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SynchronizedIntTests.java
@@ -0,0 +1,372 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.reference;
+
+import org.eclipse.persistence.tools.utility.reference.SynchronizedInt;
+import org.eclipse.persistence.tools.utility.tests.MultiThreadedTestCase;
+
+@SuppressWarnings("nls")
+public class SynchronizedIntTests
+	extends MultiThreadedTestCase
+{
+	private volatile SynchronizedInt si;
+	volatile boolean timeoutOccurred;
+	volatile int value = 7;
+	volatile long startTime;
+	volatile long endTime;
+	volatile int sIntValue;
+
+
+	public SynchronizedIntTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.si = new SynchronizedInt();
+		this.timeoutOccurred = false;
+		this.startTime = 0;
+		this.endTime = 0;
+		this.sIntValue = 0;
+	}
+
+	public void testGetValue() throws Exception {
+		assertEquals(0, this.si.getValue());
+	}
+
+	public void testEqualsInt() throws Exception {
+		assertTrue(this.si.equals(0));
+		this.si.setValue(this.value);
+		assertTrue(this.si.equals(7));
+	}
+
+	public void testNotEqualInt() throws Exception {
+		assertTrue(this.si.notEqual(7));
+		this.si.setValue(this.value);
+		assertTrue(this.si.notEqual(0));
+	}
+
+	public void testIsZero() throws Exception {
+		assertTrue(this.si.isZero());
+		this.si.setValue(this.value);
+		assertFalse(this.si.isZero());
+	}
+
+	public void testIsNotZero() throws Exception {
+		assertFalse(this.si.isNotZero());
+		this.si.setValue(this.value);
+		assertTrue(this.si.isNotZero());
+	}
+
+	public void testIsGreaterThan() throws Exception {
+		assertTrue(this.si.isGreaterThan(-1));
+		assertFalse(this.si.isGreaterThan(0));
+		assertFalse(this.si.isGreaterThan(1));
+		this.si.setValue(this.value);
+		assertTrue(this.si.isGreaterThan(-1));
+		assertFalse(this.si.isGreaterThan(7));
+		assertFalse(this.si.isGreaterThan(8));
+	}
+
+	public void testIsGreaterThanOrEqual() throws Exception {
+		assertTrue(this.si.isGreaterThanOrEqual(-1));
+		assertTrue(this.si.isGreaterThanOrEqual(0));
+		assertFalse(this.si.isGreaterThanOrEqual(1));
+		this.si.setValue(this.value);
+		assertTrue(this.si.isGreaterThanOrEqual(-1));
+		assertTrue(this.si.isGreaterThanOrEqual(7));
+		assertFalse(this.si.isGreaterThanOrEqual(8));
+	}
+
+	public void testIsLessThan() throws Exception {
+		assertFalse(this.si.isLessThan(-1));
+		assertFalse(this.si.isLessThan(0));
+		assertTrue(this.si.isLessThan(1));
+		this.si.setValue(this.value);
+		assertFalse(this.si.isLessThan(-1));
+		assertFalse(this.si.isLessThan(7));
+		assertTrue(this.si.isLessThan(8));
+	}
+
+	public void testIsLessThanOrEqual() throws Exception {
+		assertFalse(this.si.isLessThanOrEqual(-1));
+		assertTrue(this.si.isLessThanOrEqual(0));
+		assertTrue(this.si.isLessThanOrEqual(1));
+		this.si.setValue(this.value);
+		assertFalse(this.si.isLessThanOrEqual(-1));
+		assertTrue(this.si.isLessThanOrEqual(7));
+		assertTrue(this.si.isLessThanOrEqual(8));
+	}
+
+	public void testIsPositive() throws Exception {
+		assertFalse(this.si.isPositive());
+		this.si.setValue(this.value);
+		assertTrue(this.si.isPositive());
+		this.si.setValue(-3);
+		assertFalse(this.si.isPositive());
+	}
+
+	public void testIsNotPositive() throws Exception {
+		assertTrue(this.si.isNotPositive());
+		this.si.setValue(this.value);
+		assertFalse(this.si.isNotPositive());
+		this.si.setValue(-3);
+		assertTrue(this.si.isNotPositive());
+	}
+
+	public void testIsNegative() throws Exception {
+		assertFalse(this.si.isNegative());
+		this.si.setValue(this.value);
+		assertFalse(this.si.isNegative());
+		this.si.setValue(-3);
+		assertTrue(this.si.isNegative());
+	}
+
+	public void testIsNotNegative() throws Exception {
+		assertTrue(this.si.isNotNegative());
+		this.si.setValue(this.value);
+		assertTrue(this.si.isNotNegative());
+		this.si.setValue(-3);
+		assertFalse(this.si.isNotNegative());
+	}
+
+	public void testSetValue() throws Exception {
+		this.si.setValue(0);
+		assertEquals(0, this.si.getValue());
+		assertFalse(this.si.isNotZero());
+		assertTrue(this.si.isZero());
+
+		this.si.setValue(this.value);
+		assertEquals(this.value, this.si.getValue());
+		assertTrue(this.si.isNotZero());
+		assertFalse(this.si.isZero());
+	}
+
+	public void testAbs() throws Exception {
+		assertEquals(0, this.si.abs());
+		assertEquals(0, this.si.getValue());
+		this.si.setValue(this.value);
+		assertEquals(this.value, this.si.abs());
+		assertEquals(this.value, this.si.getValue());
+		this.si.setValue(-this.value);
+		assertEquals(this.value, this.si.abs());
+	}
+
+	public void testNeg() throws Exception {
+		assertEquals(0, this.si.neg());
+		assertEquals(0, this.si.getValue());
+		this.si.setValue(this.value);
+		assertEquals(-this.value, this.si.neg());
+		this.si.setValue(-this.value);
+		assertEquals(this.value, this.si.neg());
+	}
+
+	public void testSetZero() throws Exception {
+		this.si.setZero();
+		assertEquals(0, this.si.getValue());
+		assertFalse(this.si.isNotZero());
+		assertTrue(this.si.isZero());
+	}
+
+	public void testGetMutexThis() throws Exception {
+		assertSame(this.si, this.si.getMutex());
+	}
+
+	/**
+	 * t2 will wait indefinitely until t1 sets the value to 0
+	 */
+	public void testWaitUntilZero() throws Exception {
+		this.verifyWaitUntilZero(0);  // 0 = indefinite wait
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and the value should be set to 0 by t2
+		assertEquals(0, this.si.getValue());
+		// make a reasonable guess about how long t2 took
+		long time = this.calculateElapsedTime();
+		assertTrue("t2 finished a bit early (expected value should be > " + TICK + "): " + time, time > TICK);
+	}
+
+	/**
+	 * t2 will time out waiting for t1 to set the value to 0
+	 */
+	public void testWaitUntilZeroTimeout() throws Exception {
+		this.verifyWaitUntilZero(TICK);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the value will eventually be set to 0 by t1
+		assertEquals(0, this.si.getValue());
+		// make a reasonable guess about how long t2 took
+		long time = this.calculateElapsedTime();
+		assertTrue("t2 finished a bit late (expected value should be < " + THREE_TICKS + "): " + time, time < THREE_TICKS);
+	}
+
+	private void verifyWaitUntilZero(long t2Timeout) throws Exception {
+		this.executeThreads(this.buildSetZeroCommand(), this.buildWaitUntilZeroCommand(t2Timeout));
+	}
+
+	/**
+	 * t2 will wait indefinitely until t1 sets the value to 0;
+	 * then t2 will set the value to 7
+	 */
+	public void testWaitToSetValue() throws Exception {
+		this.verifyWaitToSetValue(0);  // 0 = indefinite wait
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and the value should be set to an object by t2
+		assertTrue(this.si.isNotZero());
+		// make a reasonable guess about how long t2 took
+		long time = this.calculateElapsedTime();
+		assertTrue("t2 finished a bit early (expected value should be > " + TICK + "): " + time, time > TICK);
+	}
+
+	/**
+	 * t2 will time out waiting for t1 to set the value to 0
+	 */
+	public void testWaitToSetValueTimeout() throws Exception {
+		this.verifyWaitToSetValue(TICK);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the value will eventually be set to zero by t1
+		assertTrue(this.si.isZero());
+		// make a reasonable guess about how long t2 took
+		long time = this.calculateElapsedTime();
+		assertTrue("t2 finished a bit late (expected value should be < " + THREE_TICKS + "): " + time, time < THREE_TICKS);
+	}
+
+	private void verifyWaitToSetValue(long t2Timeout) throws Exception {
+		this.executeThreads(this.buildSetZeroCommand(), this.buildWaitToSetValueCommand(t2Timeout));
+	}
+
+	/**
+	 * t2 will wait until t1 is finished "initializing" the value;
+	 * then t2 will get the newly-initialized value (42)
+	 */
+	public void testExecute() throws Exception {
+		this.si.setValue(0);
+		Runnable r1 = this.buildRunnable(this.buildInitializeValueCommand(), this.si, 0);
+		// give t1 a head start
+		Runnable r2 = this.buildRunnable(this.buildGetValueCommand(), this.si, TICK);
+		Thread t1 = this.buildThread(r1);
+		Thread t2 = this.buildThread(r2);
+		t1.start();
+		t2.start();
+		t1.join();
+		t2.join();
+		assertEquals(42, this.si.getValue());
+		assertEquals(42, this.sIntValue);
+		// make a reasonable guess about how long t2 took
+		long time = this.calculateElapsedTime();
+		assertTrue("t2 finished a bit early (expected value should be > " + TWO_TICKS + "): " + time, time > TWO_TICKS);
+	}
+
+	private void executeThreads(Command t1Command, Command t2Command) throws Exception {
+		this.si.setValue(this.value);
+		Runnable r1 = this.buildRunnable(t1Command, this.si, TWO_TICKS);
+		Runnable r2 = this.buildRunnable(t2Command, this.si, 0);
+		Thread t1 = this.buildThread(r1);
+		Thread t2 = this.buildThread(r2);
+		t1.start();
+		t2.start();
+		t1.join();
+		t2.join();
+	}
+
+	private Command buildSetZeroCommand() {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedInt sInt) {
+				sInt.setZero();
+			}
+		};
+	}
+
+	private Command buildWaitUntilZeroCommand(final long timeout) {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedInt sInt) throws InterruptedException {
+				SynchronizedIntTests.this.startTime = System.currentTimeMillis();
+				SynchronizedIntTests.this.timeoutOccurred = ! sInt.waitUntilZero(timeout);
+				SynchronizedIntTests.this.endTime = System.currentTimeMillis();
+			}
+		};
+	}
+
+	private Command buildWaitToSetValueCommand(final long timeout) {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedInt sInt) throws InterruptedException {
+				SynchronizedIntTests.this.startTime = System.currentTimeMillis();
+				SynchronizedIntTests.this.timeoutOccurred = ! sInt.waitToSetValue(SynchronizedIntTests.this.value, timeout);
+				SynchronizedIntTests.this.endTime = System.currentTimeMillis();
+			}
+		};
+	}
+
+	private Command buildInitializeValueCommand() {
+		return new Command() {
+			@Override
+			public void execute(final SynchronizedInt sInt) throws InterruptedException {
+				sInt.execute(
+					new org.eclipse.persistence.tools.utility.command.Command() {
+						@Override
+						public void execute() {
+							// pretend to perform some long initialization process
+							try {
+								Thread.sleep(5 * TICK);
+							} catch (InterruptedException ex) {
+								throw new RuntimeException(ex);
+							}
+							sInt.setValue(42);
+						}
+					}
+				);
+			}
+		};
+	}
+
+	private Command buildGetValueCommand() {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedInt sInt) throws InterruptedException {
+				SynchronizedIntTests.this.startTime = System.currentTimeMillis();
+				SynchronizedIntTests.this.sIntValue = sInt.getValue();
+				SynchronizedIntTests.this.endTime = System.currentTimeMillis();
+			}
+		};
+	}
+
+	private Runnable buildRunnable(final Command command, final SynchronizedInt sInt, final long sleep) {
+		return new TestRunnable() {
+			@Override
+			protected void run_() throws InterruptedException {
+				if (sleep != 0) {
+					Thread.sleep(sleep);
+				}
+				command.execute(sInt);
+			}
+		};
+	}
+
+	private long calculateElapsedTime() {
+		return this.endTime - this.startTime;
+	}
+
+
+	// ********** Command interface **********
+
+	private interface Command {
+		void execute(SynchronizedInt sInt) throws InterruptedException;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SynchronizedObjectTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SynchronizedObjectTests.java
new file mode 100644
index 0000000..bd1c734
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/reference/SynchronizedObjectTests.java
@@ -0,0 +1,249 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.reference;
+
+import org.eclipse.persistence.tools.utility.reference.SynchronizedObject;
+import org.eclipse.persistence.tools.utility.tests.MultiThreadedTestCase;
+
+@SuppressWarnings("nls")
+public class SynchronizedObjectTests
+	extends MultiThreadedTestCase
+{
+	private volatile SynchronizedObject<Object> so;
+	volatile boolean timeoutOccurred;
+	volatile Object value = new Object();
+	volatile long startTime;
+	volatile long endTime;
+	volatile Object soValue;
+
+
+	public SynchronizedObjectTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.so = new SynchronizedObject<Object>();
+		this.timeoutOccurred = false;
+		this.startTime = 0;
+		this.endTime = 0;
+		this.soValue = null;
+	}
+
+	public void testAccessors() throws Exception {
+		this.so.setValue(null);
+		assertNull(this.so.getValue());
+		assertFalse(this.so.isNotNull());
+		assertTrue(this.so.isNull());
+
+		this.so.setValue(this.value);
+		assertEquals(this.value, this.so.getValue());
+		assertTrue(this.so.isNotNull());
+		assertFalse(this.so.isNull());
+
+		this.so.setNull();
+		assertNull(this.so.getValue());
+		assertFalse(this.so.isNotNull());
+		assertTrue(this.so.isNull());
+
+		assertSame(this.so, this.so.getMutex());
+	}
+
+	/**
+	 * t2 will wait indefinitely until t1 sets the value to null
+	 */
+	public void testWaitUntilNull() throws Exception {
+		this.verifyWaitUntilNull(0);
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and the value should be set to null by t2
+		assertNull(this.so.getValue());
+		// make a reasonable guess about how long t2 took
+		long time = this.calculateElapsedTime();
+		assertTrue("t2 finished a bit early (expected value should be > " + TICK + "): " + time, time > TICK);
+	}
+
+	/**
+	 * t2 will time out waiting for t1 to set the value to null
+	 */
+	public void testWaitUntilNullTimeout() throws Exception {
+		this.verifyWaitUntilNull(TICK);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the value will eventually be set to null by t1
+		assertNull(this.so.getValue());
+		// make a reasonable guess about how long t2 took
+		long time = this.calculateElapsedTime();
+		assertTrue("t2 finished a bit late (expected value should be < " + THREE_TICKS + "): " + time, time < THREE_TICKS);
+	}
+
+	private void verifyWaitUntilNull(long t2Timeout) throws Exception {
+		this.executeThreads(this.buildSetNullCommand(), this.buildWaitUntilNullCommand(t2Timeout));
+	}
+
+	/**
+	 * t2 will wait indefinitely until t1 sets the value to null;
+	 * then t2 will set the value to an object
+	 */
+	public void testWaitToSetValue() throws Exception {
+		this.verifyWaitToSetValue(0);
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and the value should be set to an object by t2
+		assertTrue(this.so.isNotNull());
+		// make a reasonable guess about how long t2 took
+		long time = this.calculateElapsedTime();
+		assertTrue("t2 finished a bit early (expected value should be > " + TICK + "): " + time, time > TICK);
+	}
+
+	/**
+	 * t2 will time out waiting for t1 to set the value to null
+	 */
+	public void testWaitToSetValueTimeout() throws Exception {
+		this.verifyWaitToSetValue(TICK);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the value will eventually be set to null by t1
+		assertTrue(this.so.isNull());
+		// make a reasonable guess about how long t2 took
+		long time = this.calculateElapsedTime();
+		assertTrue("t2 finished a bit late (expected value should be < " + THREE_TICKS + "): " + time, time < THREE_TICKS);
+	}
+
+	private void verifyWaitToSetValue(long t2Timeout) throws Exception {
+		this.executeThreads(this.buildSetNullCommand(), this.buildWaitToSetValueCommand(t2Timeout));
+	}
+
+	/**
+	 * t2 will wait until t1 is finished "initializing" the value;
+	 * then t2 will get the newly-initialized value ("foo")
+	 */
+	public void testExecute() throws Exception {
+		this.so.setValue(null);
+		Runnable r1 = this.buildRunnable(this.buildInitializeValueCommand(), this.so, 0);
+		// give t1 a head start of 100 ms
+		Runnable r2 = this.buildRunnable(this.buildGetValueCommand(), this.so, TICK);
+		Thread t1 = this.buildThread(r1);
+		Thread t2 = this.buildThread(r2);
+		t1.start();
+		t2.start();
+		t1.join();
+		t2.join();
+		assertEquals("foo", this.so.getValue());
+		assertEquals("foo", this.soValue);
+		// make a reasonable guess about how long t2 took
+		long time = this.calculateElapsedTime();
+		assertTrue("t2 finished a bit early (expected value should be > " + TWO_TICKS + "): " + time, time > TWO_TICKS);
+	}
+
+	private void executeThreads(Command t1Command, Command t2Command) throws Exception {
+		this.so.setValue(this.value);
+		Runnable r1 = this.buildRunnable(t1Command, this.so, TWO_TICKS);
+		Runnable r2 = this.buildRunnable(t2Command, this.so, 0);
+		Thread t1 = this.buildThread(r1);
+		Thread t2 = this.buildThread(r2);
+		t1.start();
+		t2.start();
+		t1.join();
+		t2.join();
+	}
+
+	private Command buildSetNullCommand() {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedObject<Object> sObject) {
+				sObject.setNull();
+			}
+		};
+	}
+
+	private Command buildWaitUntilNullCommand(final long timeout) {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedObject<Object> sObject) throws InterruptedException {
+				SynchronizedObjectTests.this.startTime = System.currentTimeMillis();
+				SynchronizedObjectTests.this.timeoutOccurred = ! sObject.waitUntilNull(timeout);
+				SynchronizedObjectTests.this.endTime = System.currentTimeMillis();
+			}
+		};
+	}
+
+	private Command buildWaitToSetValueCommand(final long timeout) {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedObject<Object> sObject) throws InterruptedException {
+				SynchronizedObjectTests.this.startTime = System.currentTimeMillis();
+				SynchronizedObjectTests.this.timeoutOccurred = ! sObject.waitToSetValue(SynchronizedObjectTests.this.value, timeout);
+				SynchronizedObjectTests.this.endTime = System.currentTimeMillis();
+			}
+		};
+	}
+
+	private Command buildInitializeValueCommand() {
+		return new Command() {
+			@Override
+			public void execute(final SynchronizedObject<Object> sObject) throws InterruptedException {
+				sObject.execute(
+					new org.eclipse.persistence.tools.utility.command.Command() {
+						@Override
+						public void execute() {
+							// pretend to perform some long initialization process
+							try {
+								Thread.sleep(5 * TICK);
+							} catch (Exception ex) {
+								throw new RuntimeException(ex);
+							}
+							sObject.setValue("foo");
+						}
+					}
+				);
+			}
+		};
+	}
+
+	private Command buildGetValueCommand() {
+		return new Command() {
+			@Override
+			public void execute(SynchronizedObject<Object> sObject) throws InterruptedException {
+				SynchronizedObjectTests.this.startTime = System.currentTimeMillis();
+				SynchronizedObjectTests.this.soValue = sObject.getValue();
+				SynchronizedObjectTests.this.endTime = System.currentTimeMillis();
+			}
+		};
+	}
+
+	private Runnable buildRunnable(final Command command, final SynchronizedObject<Object> sObject, final long sleep) {
+		return new TestRunnable() {
+			@Override
+			protected void run_() throws InterruptedException {
+				if (sleep != 0) {
+					Thread.sleep(sleep);
+				}
+				command.execute(sObject);
+			}
+		};
+	}
+
+	private long calculateElapsedTime() {
+		return this.endTime - this.startTime;
+	}
+
+
+	// ********** Command interface **********
+
+	private interface Command {
+		void execute(SynchronizedObject<Object> so) throws InterruptedException;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/swing/FilteringListPanelUITest.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/swing/FilteringListPanelUITest.java
new file mode 100644
index 0000000..7c4ac59
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/swing/FilteringListPanelUITest.java
@@ -0,0 +1,351 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Font;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.UIManager;
+import javax.swing.WindowConstants;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.ClassNameTools;
+import org.eclipse.persistence.tools.utility.Classpath;
+import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.iterable.TransformationIterable;
+import org.eclipse.persistence.tools.utility.swing.FilteringListPanel;
+import org.eclipse.persistence.tools.utility.swing.SimpleListCellRenderer;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+import org.eclipse.persistence.tools.utility.transformer.TransformerAdapter;
+
+/**
+ * Simple test class for playing around with {@link FilteringListPanel}.
+ * <p>
+ * Optional command line parm:<ul>
+ * <li>the name of a jar (or class folder) to use to populate the list box
+ * </ul>
+ */
+@SuppressWarnings("nls")
+public class FilteringListPanelUITest {
+	private Type[] completeList1;
+	private Type[] completeList2;
+	private FilteringListPanel<Type> filteringListPanel;
+	private Font font;
+
+
+	public static void main(String[] args) {
+		new FilteringListPanelUITest().exec(args);
+	}
+
+	private FilteringListPanelUITest() {
+		super();
+		this.initialize();
+	}
+
+	private void initialize() {
+		this.font = this.buildFont();
+	}
+
+	private Font buildFont() {
+		return new Font("Dialog", Font.PLAIN, 12);
+	}
+
+	private void exec(String[] args) {
+		this.completeList1 = this.buildTypeList(args);
+		this.completeList2 = this.buildCompleteList2();
+		JFrame frame = new JFrame(this.getClass().getSimpleName());
+		frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+		frame.addWindowListener(this.buildWindowListener());
+		frame.getContentPane().add(this.buildMainPanel(), "Center");
+		frame.setLocation(300, 300);
+		frame.setSize(400, 400);
+		frame.setVisible(true);
+	}
+
+	private Type[] buildTypeList(String[] args) {
+		return ArrayTools.sort(ArrayTools.array(this.buildTypes(args), Type.class));
+	}
+
+	private Type[] buildCompleteList2() {
+		String classpathEntry = Classpath.locationFor(this.getClass());
+		return ArrayTools.sort(ArrayTools.array(this.buildTypes(new String[] {classpathEntry}), Type.class));
+	}
+
+	private Iterable<Type> buildTypes(String[] args) {
+		return new TransformationIterable<String, Type>(this.buildClassNames(args), TYPE_STRING_TRANSFORMER);
+	}
+
+	private static final Transformer<String, Type> TYPE_STRING_TRANSFORMER = new TypeStringTransformer();
+	/* CU private */ static class TypeStringTransformer
+		extends TransformerAdapter<String, Type>
+	{
+		@Override
+		public Type transform(String string) {
+			return new Type(string);
+		}
+	}
+
+	private Iterable<String> buildClassNames(String[] args) {
+		return ((args == null) || (args.length == 0)) ?
+				Classpath.bootClasspath().getClassNames() :
+				new Classpath(new String[] { args[0] }).getClassNames();
+	}
+
+	private WindowListener buildWindowListener() {
+		return new WindowAdapter() {
+			@Override
+			public void windowClosing(WindowEvent e) {
+				e.getWindow().setVisible(false);
+				System.exit(0);
+			}
+		};
+	}
+
+	private JPanel buildMainPanel() {
+		JPanel panel = new JPanel(new BorderLayout());
+		this.filteringListPanel = this.buildFilteringListPanel();
+		panel.add(this.filteringListPanel, BorderLayout.CENTER);
+		panel.add(this.buildControlPanel(), BorderLayout.SOUTH);
+		return panel;
+	}
+
+	private FilteringListPanel<Type> buildFilteringListPanel() {
+		Type initialSelection = this.getTypeNamed(this.completeList1, "java.lang.Object");
+		FilteringListPanel<Type> panel = new FilteringListPanel<Type>(this.completeList1, initialSelection, TYPE_NAME_TRANSFORMER);
+		panel.setTextFieldLabelText("Choose a Type (? = any char, * = any string):");
+		panel.setListBoxLabelText("Matching Types:");
+		panel.setComponentsFont(this.font);
+		panel.setListBoxCellRenderer(new TypeCellRenderer());
+		return panel;
+	}
+
+	private static final Transformer<Type, String> TYPE_NAME_TRANSFORMER = new TypeNameTransformer();
+	/* CU private */ static class TypeNameTransformer
+		extends TransformerAdapter<Type, String>
+	{
+		@Override
+		public String transform(Type type) {
+			return (type == null) ? StringTools.EMPTY_STRING : type.getName();
+		}
+	}
+
+	/* CU private */ class TypeCellRenderer
+		extends SimpleListCellRenderer
+	{
+		private static final long serialVersionUID = 1L;
+		@Override
+		protected Icon buildIcon(Object value) {
+			return UIManager.getIcon("Tree.leafIcon");
+		}
+		@Override
+		protected String buildText(Object value) {
+			return ((Type) value).getName();
+		}
+	}
+
+	private JPanel buildControlPanel() {
+		JPanel panel = new JPanel(new GridLayout(1, 0));
+		panel.add(this.buildSwapButton());
+		panel.add(this.buildStringButton());
+		panel.add(this.buildNullButton());
+		panel.add(this.buildMax10Button());
+		panel.add(this.buildPrintButton());
+		return panel;
+	}
+
+	// ********** swap button **********
+
+	private JButton buildSwapButton() {
+		JButton button = new JButton(this.buildSwapAction());
+		button.setFont(this.font);
+		return button;
+	}
+
+	private Action buildSwapAction() {
+		return new AbstractAction("swap") {
+			private static final long serialVersionUID = 1L;
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				FilteringListPanelUITest.this.swap();
+			}
+		};
+	}
+
+	/**
+	 * swap in a new list
+	 */
+	void swap() {
+		if (this.filteringListPanel.getCompleteList() == this.completeList1) {
+			this.filteringListPanel.setCompleteList(this.completeList2);
+		} else {
+			this.filteringListPanel.setCompleteList(this.completeList1);
+		}
+	}
+
+	// ********** string button **********
+
+	private JButton buildStringButton() {
+		JButton button = new JButton(this.buildStringAction());
+		button.setFont(this.font);
+		return button;
+	}
+
+	private Action buildStringAction() {
+		return new AbstractAction("String") {
+			private static final long serialVersionUID = 1L;
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				FilteringListPanelUITest.this.selectStringType();
+			}
+		};
+	}
+
+	/**
+	 * force a selection from "outside" the filtering list panel
+	 */
+	void selectStringType() {
+		this.filteringListPanel.setSelection(this.typeNamed("java.lang.String"));
+	}
+
+	private Type typeNamed(String name) {
+		return this.getTypeNamed(this.filteringListPanel.getCompleteList(), name);
+	}
+
+	private Type getTypeNamed(Type[] types, String name) {
+		for (int i = types.length; i-- > 0; ) {
+			Type type = types[i];
+			if (type.getName().equals(name)) {
+				return type;
+			}
+		}
+		return null;
+	}
+
+	// ********** null button **********
+
+	private JButton buildNullButton() {
+		JButton button = new JButton(this.buildNullAction());
+		button.setFont(this.font);
+		return button;
+	}
+
+	private Action buildNullAction() {
+		return new AbstractAction("null") {
+			private static final long serialVersionUID = 1L;
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				FilteringListPanelUITest.this.selectNull();
+			}
+		};
+	}
+
+	/**
+	 * set the current selection to null
+	 */
+	void selectNull() {
+		this.filteringListPanel.setSelection(null);
+	}
+
+	// ********** null button **********
+
+	private JButton buildMax10Button() {
+		JButton button = new JButton(this.buildMax10Action());
+		button.setFont(this.font);
+		return button;
+	}
+
+	private Action buildMax10Action() {
+		return new AbstractAction("max = 10") {
+			private static final long serialVersionUID = 1L;
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				FilteringListPanelUITest.this.setMax10();
+			}
+		};
+	}
+
+	/**
+	 * toggle between allowing only 10 entries in the list box
+	 * and no limit
+	 */
+	void setMax10() {
+		if (this.filteringListPanel.getMaxListSize() == 10) {
+			this.filteringListPanel.setMaxListSize(-1);
+		} else {
+			this.filteringListPanel.setMaxListSize(10);
+		}
+	}
+
+	// ********** print button **********
+
+	private JButton buildPrintButton() {
+		JButton button = new JButton(this.buildPrintAction());
+		button.setFont(this.font);
+		return button;
+	}
+
+	private Action buildPrintAction() {
+		return new AbstractAction("print") {
+			private static final long serialVersionUID = 1L;
+			@Override
+			public void actionPerformed(ActionEvent event) {
+				FilteringListPanelUITest.this.printType();
+			}
+		};
+	}
+
+	/**
+	 * print the currently selected type to the console
+	 */
+	void printType() {
+		System.out.println("selected item: " + this.filteringListPanel.getSelection());
+	}
+
+
+	// ********** type **********
+
+	/* CU private */ static class Type
+		implements Comparable<Type>
+	{
+		private String name;
+
+		Type(String name) {
+			super();
+			this.name = name;
+		}
+		public String shortName() {
+			return ClassNameTools.simpleName(this.name);
+		}
+		public String getName() {
+			return this.name;
+		}
+		@Override
+		public String toString() {
+			return "Type: " + this.name ;
+		}
+		@Override
+		public int compareTo(Type type) {
+			return this.name.compareTo(type.name);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/transformer/CommonUtilityTransformerTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/transformer/CommonUtilityTransformerTests.java
new file mode 100644
index 0000000..89dd262
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/transformer/CommonUtilityTransformerTests.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.transformer;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * decentralize test creation code
+ */
+public class CommonUtilityTransformerTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(CommonUtilityTransformerTests.class.getPackage().getName());
+
+		suite.addTestSuite(XMLStringDecoderTests.class);
+		suite.addTestSuite(XMLStringEncoderTests.class);
+
+		return suite;
+	}
+
+	private CommonUtilityTransformerTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/transformer/XMLStringDecoderTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/transformer/XMLStringDecoderTests.java
new file mode 100644
index 0000000..c909ba4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/transformer/XMLStringDecoderTests.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.transformer;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.io.FileTools;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+import org.eclipse.persistence.tools.utility.transformer.XMLStringDecoder;
+import org.eclipse.persistence.tools.utility.transformer.XMLStringEncoder;
+
+@SuppressWarnings("nls")
+public class XMLStringDecoderTests
+	extends TestCase
+{
+	public XMLStringDecoderTests(String name) {
+		super(name);
+	}
+
+	public void testDenormalizeValidFileName() {
+		Transformer<String, String> decoder = XMLStringDecoder.instance();
+
+		String s = "foo";
+		assertEquals(s, decoder.transform(s));
+
+		s = "123foo123";
+		assertEquals(s, decoder.transform(s));
+	}
+
+	public void testDenormalizeInvalidFileName() {
+		Transformer<String, String> decoder = XMLStringDecoder.instance();
+
+		String s = "&#x3f;foo&#x3f;";
+		String expected = "?foo?";
+		assertEquals(expected, decoder.transform(s));
+
+		s = "&#x3f;foo&#x26;123";
+		expected = "?foo&123";
+		assertEquals(expected, decoder.transform(s));
+	}
+
+	public void testRoundTripNoCharacterSequences() {
+		this.verifyRoundTrip("foo");
+		this.verifyRoundTrip("123foo456");
+	}
+
+	public void testRoundTripCharacterSequences() {
+		this.verifyRoundTrip("?foo?");
+		this.verifyRoundTrip("?foo&123&&&&&&>>>>");
+	}
+
+	private void verifyRoundTrip(String s) {
+		XMLStringEncoder encoder = new XMLStringEncoder(FileTools.INVALID_FILENAME_CHARACTERS);
+		String actual = encoder.transform(s);
+		Transformer<String, String> decoder = XMLStringDecoder.instance();
+		assertEquals(s, decoder.transform(actual));
+	}
+
+	public void testInvalidCharacterSequence1() {
+		this.verifyIllegalStateException("foo&");
+	}
+
+	public void testInvalidCharacterSequence2() {
+		this.verifyIllegalStateException("foo&#");
+	}
+
+	public void testInvalidCharacterSequence3() {
+		this.verifyIllegalStateException("foo&#x");
+	}
+
+	public void testInvalidCharacterSequence4() {
+		this.verifyIllegalStateException("foo&#x3");
+	}
+
+	public void testInvalidCharacterSequence5() {
+		this.verifyIllegalStateException("foo&#x;");
+	}
+
+	public void testInvalidCharacterSequence6() {
+		this.verifyIllegalStateException("foo&A");
+	}
+
+	public void testInvalidCharacterSequence7() {
+		this.verifyIllegalStateException("foo&#A");
+	}
+
+	private void verifyIllegalStateException(String s) {
+		Transformer<String, String> decoder = XMLStringDecoder.instance();
+		boolean exCaught = false;
+		try {
+			s = decoder.transform(s);
+			fail(s);
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testInvalidCharacterSequence8() {
+		String s = "foo&#xZZZZ;";
+		Transformer<String, String> decoder = XMLStringDecoder.instance();
+		boolean exCaught = false;
+		try {
+			s = decoder.transform(s);
+			fail(s);
+		} catch (NumberFormatException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/transformer/XMLStringEncoderTests.java b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/transformer/XMLStringEncoderTests.java
new file mode 100644
index 0000000..820fa4a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility.tests/src/org/eclipse/persistence/tools/utility/tests/transformer/XMLStringEncoderTests.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.tests.transformer;
+
+import junit.framework.TestCase;
+import org.eclipse.persistence.tools.utility.io.FileTools;
+import org.eclipse.persistence.tools.utility.transformer.XMLStringEncoder;
+
+@SuppressWarnings("nls")
+public class XMLStringEncoderTests
+	extends TestCase
+{
+	public XMLStringEncoderTests(String name) {
+		super(name);
+	}
+
+	public void testEncodeNoCharacterSequences() {
+		XMLStringEncoder encoder = new XMLStringEncoder(FileTools.INVALID_FILENAME_CHARACTERS);
+
+		String s = "foo";
+		assertEquals(s, encoder.transform(s));
+
+		s = "123foo123";
+		assertEquals(s, encoder.transform(s));
+	}
+
+	public void testEncodeCharacterSequences() {
+		XMLStringEncoder encoder = new XMLStringEncoder(FileTools.INVALID_FILENAME_CHARACTERS);
+
+		String s = "?foo?";
+		String expected = "&#x3f;foo&#x3f;";
+		assertEquals(expected, encoder.transform(s));
+
+		s = "?foo&123";
+		expected = "&#x3f;foo&#x26;123";
+		assertEquals(expected, encoder.transform(s));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/.classpath b/tools/org.eclipse.persistence.tools.utility/.classpath
index 24e46dc..80e27fb 100644
--- a/tools/org.eclipse.persistence.tools.utility/.classpath
+++ b/tools/org.eclipse.persistence.tools.utility/.classpath
@@ -1,10 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
-		<attributes>
-			<attribute name="owner.project.facets" value="java"/>
-		</attributes>
-	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
 	<classpathentry kind="output" path="build/classes"/>
 </classpath>
diff --git a/tools/org.eclipse.persistence.tools.utility/.settings/org.eclipse.jdt.core.prefs b/tools/org.eclipse.persistence.tools.utility/.settings/org.eclipse.jdt.core.prefs
index 8000cd6..54e493c 100644
--- a/tools/org.eclipse.persistence.tools.utility/.settings/org.eclipse.jdt.core.prefs
+++ b/tools/org.eclipse.persistence.tools.utility/.settings/org.eclipse.jdt.core.prefs
@@ -1,11 +1,11 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.6
+eclipse.preferences.version=1

+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled

+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6

+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve

+org.eclipse.jdt.core.compiler.compliance=1.6

+org.eclipse.jdt.core.compiler.debug.lineNumber=generate

+org.eclipse.jdt.core.compiler.debug.localVariable=generate

+org.eclipse.jdt.core.compiler.debug.sourceFile=generate

+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

+org.eclipse.jdt.core.compiler.source=1.6

diff --git a/tools/org.eclipse.persistence.tools.utility/.settings/org.eclipse.ltk.core.refactoring.prefs b/tools/org.eclipse.persistence.tools.utility/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000..cfcd1d3
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1

+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false

diff --git a/tools/org.eclipse.persistence.tools.utility/.settings/org.eclipse.wst.common.component b/tools/org.eclipse.persistence.tools.utility/.settings/org.eclipse.wst.common.component
index 8ed294a..b2adfa5 100644
--- a/tools/org.eclipse.persistence.tools.utility/.settings/org.eclipse.wst.common.component
+++ b/tools/org.eclipse.persistence.tools.utility/.settings/org.eclipse.wst.common.component
@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project-modules id="moduleCoreId" project-version="1.5.0">
-    <wb-module deploy-name="org.eclipse.persistence.tools.utility">
-        <wb-resource deploy-path="/" source-path="/src"/>
-    </wb-module>
-</project-modules>
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">

+    <wb-module deploy-name="org.eclipse.persistence.tools.utility">

+        <wb-resource deploy-path="/" source-path="/src"/>

+    </wb-module>

+</project-modules>

diff --git a/tools/org.eclipse.persistence.tools.utility/META-INF/MANIFEST.MF b/tools/org.eclipse.persistence.tools.utility/META-INF/MANIFEST.MF
index 46c90f7..982ee8a 100644
--- a/tools/org.eclipse.persistence.tools.utility/META-INF/MANIFEST.MF
+++ b/tools/org.eclipse.persistence.tools.utility/META-INF/MANIFEST.MF
@@ -1,15 +1,27 @@
 Manifest-Version: 1.0
 Export-Package: org.eclipse.persistence.tools.utility;version="2.5.0",
+ org.eclipse.persistence.tools.utility.collection;version="2.5.0",
  org.eclipse.persistence.tools.utility.command;version="2.5.0",
- org.eclipse.persistence.tools.utility.enumerations;version="2.5.0",
- org.eclipse.persistence.tools.utility.iterables;version="2.5.0",
- org.eclipse.persistence.tools.utility.iterators;version="2.5.0",
+ org.eclipse.persistence.tools.utility.enumeration;version="2.5.0",
+ org.eclipse.persistence.tools.utility.filter;version="2.5.0",
+ org.eclipse.persistence.tools.utility.io;version="2.5.0",
+ org.eclipse.persistence.tools.utility.iterable;version="2.5.0",
+ org.eclipse.persistence.tools.utility.iterator;version="2.5.0",
+ org.eclipse.persistence.tools.utility.jdbc;version="2.5.0",
+ org.eclipse.persistence.tools.utility.log;version="2.5.0",
  org.eclipse.persistence.tools.utility.model;version="2.5.0",
  org.eclipse.persistence.tools.utility.model.event;version="2.5.0",
  org.eclipse.persistence.tools.utility.model.listener;version="2.5.0",
+ org.eclipse.persistence.tools.utility.model.listener.awt;version="2.5.0",
+ org.eclipse.persistence.tools.utility.model.value;version="2.5.0",
+ org.eclipse.persistence.tools.utility.model.value.prefs;version="2.5.0",
+ org.eclipse.persistence.tools.utility.model.value.swing;version="2.5.0",
  org.eclipse.persistence.tools.utility.node;version="2.5.0",
+ org.eclipse.persistence.tools.utility.prefs;version="2.5.0",
+ org.eclipse.persistence.tools.utility.reference;version="2.5.0",
  org.eclipse.persistence.tools.utility.status;version="2.5.0",
- org.eclipse.persistence.tools.utility.synchronizers;version="2.5.0"
+ org.eclipse.persistence.tools.utility.swing;version="2.5.0",
+ org.eclipse.persistence.tools.utility.transformer;version="2.5.0"
 Bundle-ClassPath: .
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-SymbolicName: org.eclipse.persistence.tools.utility
diff --git a/tools/org.eclipse.persistence.tools.utility/pom.xml b/tools/org.eclipse.persistence.tools.utility/pom.xml
index a63a20a..55c43f1 100644
--- a/tools/org.eclipse.persistence.tools.utility/pom.xml
+++ b/tools/org.eclipse.persistence.tools.utility/pom.xml
@@ -16,4 +16,18 @@
         <relativePath>../org.eclipse.persistence.tools.parent/pom.xml</relativePath>
     </parent>
 
+    <build>
+	   <plugins>
+	      <plugin>
+	         <groupId>org.eclipse.tycho</groupId>
+	         <artifactId>tycho-compiler-plugin</artifactId>
+	         <version>${tycho.version}</version>
+	         <configuration>
+	         	<!-- Remove the restriction to access restricted classes, such as Swing classes. -->
+	           <compilerArgument>-err:-forbidden</compilerArgument>
+	         </configuration>
+	       </plugin> 
+	    </plugins>
+    </build>
+
 </project>
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/AbstractAssociation.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/AbstractAssociation.java
index d0060bf..a00b206 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/AbstractAssociation.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/AbstractAssociation.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/AbstractBooleanReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/AbstractBooleanReference.java
deleted file mode 100644
index a2f564f..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/AbstractBooleanReference.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-/**
- * Convenience abstract class for boolean reference implementations.
- * Subclasses need only implement<ul>
- * <li>{@link #getValue()}
- * <li>{@link #setValue(boolean)}
- * </ul>
- */
-public abstract class AbstractBooleanReference
-	implements ModifiableBooleanReference
-{
-	protected AbstractBooleanReference() {
-		super();
-	}
-
-	@Override
-	public boolean is(boolean value) {
-		return this.getValue() == value;
-	}
-
-	@Override
-	public boolean isNot(boolean value) {
-		return this.getValue() != value;
-	}
-
-	@Override
-	public boolean isTrue() {
-		return this.getValue();
-	}
-
-	@Override
-	public boolean isFalse() {
-		return ! this.getValue();
-	}
-
-	@Override
-	public boolean flip() {
-		return this.setValue( ! this.getValue());
-	}
-
-	@Override
-	public boolean setNot(boolean value) {
-		return this.setValue( ! value);
-	}
-
-	@Override
-	public boolean setTrue() {
-		return this.setValue(true);
-	}
-
-	@Override
-	public boolean setFalse() {
-		return this.setValue(false);
-	}
-
-
-	// ********** standard methods **********
-
-	/**
-	 * Object identity is critical to boolean references.
-	 * There is no reason for two different boolean references to be
-	 * <em>equal</em>.
-	 * 
-	 * @see #is(boolean)
-	 */
-	@Override
-	public boolean equals(Object obj) {
-		return super.equals(obj);
-	}
-
-	/**
-	 * @see #equals(Object)
-	 */
-	@Override
-	public int hashCode() {
-		return super.hashCode();
-	}
-
-	@Override
-	public String toString() {
-		return '[' + String.valueOf(this.getValue()) + ']';
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/AbstractCompositeExceptionHandler.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/AbstractCompositeExceptionHandler.java
new file mode 100644
index 0000000..3614317
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/AbstractCompositeExceptionHandler.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+import java.util.Vector;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterable.SnapshotCloneIterable;
+
+/**
+ * An exception handler that forwards exceptions to a collection of other
+ * exception handlers.
+ */
+@SuppressWarnings("nls")
+public abstract class AbstractCompositeExceptionHandler<H extends ExceptionHandler>
+	implements ExceptionHandler
+{
+	private final Vector<H> exceptionHandlers = new Vector<H>();
+
+
+	protected AbstractCompositeExceptionHandler() {
+		super();
+	}
+
+	protected AbstractCompositeExceptionHandler(H... exceptionHandlers) {
+		super();
+		CollectionTools.addAll(this.exceptionHandlers, exceptionHandlers);
+		this.checkExceptionHandlers();
+	}
+
+	protected AbstractCompositeExceptionHandler(Iterable<? extends H> exceptionHandlers) {
+		super();
+		CollectionTools.addAll(this.exceptionHandlers, exceptionHandlers);
+		this.checkExceptionHandlers();
+	}
+
+	private void checkExceptionHandlers() {
+		for (H exceptionHandler : this.exceptionHandlers) {
+			if (exceptionHandler == null) {
+				throw new NullPointerException();
+			}
+		}
+	}
+
+	/**
+	 * Forward the exception to the current list of exception handlers.
+	 */
+	@Override
+	public void handleException(Throwable t) {
+		for (H handler : this.getExceptionHandlers()) {
+			handler.handleException(t);
+		}
+	}
+
+	/**
+	 * Return the current list of exception handlers.
+	 */
+	public Iterable<H> getExceptionHandlers() {
+		return new SnapshotCloneIterable<H>(this.exceptionHandlers);
+	}
+
+	/**
+	 * Add the specified exception handler to the list of exception handlers.
+	 */
+	public void addExceptionHandler(H exceptionHandler) {
+		if (exceptionHandler == null) {
+			throw new NullPointerException(); // better sooner than later
+		}
+		synchronized (this.exceptionHandlers) {
+			if (this.exceptionHandlers.contains(exceptionHandler)) {
+				throw new IllegalArgumentException("duplicate handler: " + exceptionHandler);
+			}
+			this.exceptionHandlers.add(exceptionHandler);
+		}
+	}
+
+	/**
+	 * Remove the specified exception handler from the list of exception
+	 * handlers.
+	 */
+	public void removeExceptionHandler(H exceptionHandler) {
+		if ( ! this.exceptionHandlers.remove(exceptionHandler)) {
+			throw new IllegalArgumentException("handler not registered: " + exceptionHandler);
+		}
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.exceptionHandlers);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/AbstractTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/AbstractTransformer.java
deleted file mode 100644
index 89c4763..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/AbstractTransformer.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-/**
- * Convenience transformer that returns <code>null</code> if the original
- * object is <code>null</code>; otherwise it calls {@link #transform_(Object)},
- * which is to be implemented by subclasses.
- */
-public abstract class AbstractTransformer<T1, T2>
-	extends TransformerAdapter<T1, T2>
-{
-	@Override
-	public final T1 transform(T2 o) {
-		return (o == null) ? null : this.transform_(o);
-	}
-
-	/**
-	 * Transform the specified object; its value is guaranteed to be not
-	 * <code>null</code>.
-	 */
-	protected abstract T1 transform_(T2 o);
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ArrayTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ArrayTools.java
index 1ddac08..f2cb85a 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ArrayTools.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ArrayTools.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,83 +14,91 @@
 package org.eclipse.persistence.tools.utility;
 
 import java.lang.reflect.Array;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.Random;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.command.InterruptibleParameterizedCommand;
+import org.eclipse.persistence.tools.utility.command.ParameterizedCommand;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
+import org.eclipse.persistence.tools.utility.iterator.ArrayIterator;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
 
 /**
- * Array-related utility methods.
- *
- * @version 2.5
+ * {@link Array} utility methods.
+ * There are a number of other useful utility methods in {@link ListTools}
+ * that can be use by converting an array to a list ({@link Arrays#asList(Object...)}).
+ * @see CharArrayTools
+ * @see CollectionTools
+ * @see org.eclipse.jpt.common.utility.internal.iterable.IterableTools
+ * @see org.eclipse.jpt.common.utility.internal.iterator.IteratorTools
+ * @see ListTools
  */
 @SuppressWarnings("nls")
 public final class ArrayTools {
-
-	public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
-	public static final char[] EMPTY_CHAR_ARRAY = new char[0];
 	public static final int[] EMPTY_INT_ARRAY = new int[0];
-	private static final Class<Object> OBJECT_CLASS = Object.class;
 
 	// ********** instantiation **********
 
 	/**
-	 * Returns a new array with the same length and the same component type as the specified array.
+	 * Return a new array with the same length
+	 * and the same component type as the specified array.
 	 * <p>
-	 * <code>Arrays.newArray(Object[] array)</code>
+	 * <strong>NB:</strong> The array's reified component type may be a sub-type of
+	 * the array's <em>declared</em> component type.
+	 * @see Array#newInstance(Class, int)
 	 */
-	public static <E> E[] newArray(E[] array) {
-		return newArray(array, array.length);
+	public static <E> E[] newInstance(E[] array) {
+		return newInstance(array, array.length);
 	}
 
 	/**
-	 * Returns a new array with the specified length and the same component type as the specified array.
+	 * Return a new array with the specified length
+	 * and the same component type as the specified array.
 	 * <p>
-	 * <code>Arrays.newArray(Object[] array, int length)</code>
+	 * <strong>NB:</strong> The array's reified component type may be a sub-type of
+	 * the array's <em>declared</em> component type.
+	 * @see Array#newInstance(Class, int)
 	 */
-	public static <E> E[] newArray(E[] array, int length) {
-		return newArray(componentType(array), length);
+	public static <E> E[] newInstance(E[] array, int length) {
+		return newInstance(componentType(array), length);
 	}
 
 	/**
-	 * Returns the specified array's component type, with appropriate support for generics.
+	 * Return a new array with the specified component type and length,
+	 * with appropriate support for generics. The component type cannot be a
+	 * primitive type.
+	 * @see Array#newInstance(Class, int)
 	 */
-	@SuppressWarnings("unchecked")
-	public static <E> Class<? extends E> componentType(E[] array) {
-		Class<?> rawComponentType = array.getClass().getComponentType();
-		return (Class<? extends E>) rawComponentType;
-	}
-
-	/**
-	 * Returns a new array with the specified component type and length, with appropriate support for
-	 * generics. The component type cannot be a primitive type.
-	 */
-	public static <E> E[] newArray(Class<? extends E> componentType, int length) {
+	public static <E> E[] newInstance(Class<E> componentType, int length) {
 		if (componentType.isPrimitive()) {
 			throw new IllegalArgumentException("Array class cannot be primitive: " + componentType);
 		}
-		return newArray_(componentType, length);
+		return newInstance_(componentType, length);
 	}
 
 	/**
-	 * assume the component type is not a primitive class
+	 * pre-condition: the component type is not a primitive class
 	 */
 	@SuppressWarnings("unchecked")
-	private static <E> E[] newArray_(Class<? extends E> componentType, int length) {
+	private static <E> E[] newInstance_(Class<E> componentType, int length) {
 		return (E[]) ((componentType == OBJECT_CLASS) ?
-				new Object[length] :
+				(length == 0) ? ObjectTools.EMPTY_OBJECT_ARRAY : new Object[length] :
 				Array.newInstance(componentType, length));
 	}
+	private static final Class<Object> OBJECT_CLASS = Object.class;
 
-	// ********** conversion **********
+
+	// ********** factory methods **********
 
 	/**
-	 * Returns an array corresponding to the specified iterable.
-	 * <p>
-	 * <code>Iterable.toArray()</code>
+	 * Return an array corresponding to the specified iterable.
 	 * @see Collection#toArray()
 	 */
 	public static Object[] array(Iterable<?> iterable) {
@@ -98,10 +106,8 @@
 	}
 
 	/**
-	 * Returns an array corresponding to the specified iterable.
+	 * Return an array corresponding to the specified iterable.
 	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Iterable.toArray()</code>
 	 * @see Collection#toArray()
 	 */
 	public static Object[] array(Iterable<?> iterable, int iterableSize) {
@@ -109,13 +115,30 @@
 	}
 
 	/**
-	 * Returns an array corresponding to the specified iterable;
+	 * Return an array corresponding to the specified iterable with the
+	 * specified component type.
+	 * @see Collection#toArray(Object[])
+	 */
+	public static <E> E[] array(Iterable<?> iterable, Class<E> componentType) {
+		return array(iterable.iterator(), componentType);
+	}
+
+	/**
+	 * Return an array corresponding to the specified iterable with the
+	 * specified component type.
+	 * The specified iterable size is a performance hint.
+	 * @see Collection#toArray(Object[])
+	 */
+	public static <E> E[] array(Iterable<?> iterable, int iterableSize, Class<E> componentType) {
+		return array(iterable.iterator(), iterableSize, componentType);
+	}
+
+	/**
+	 * Return an array corresponding to the specified iterable;
 	 * the runtime type of the returned array is that of the specified array.
 	 * If the iterable fits in the specified array, it is returned therein.
 	 * Otherwise, a new array is allocated with the runtime type of the
 	 * specified array and the size of the iterable.
-	 * <p>
-	 * <code>Iterable.toArray(Object[])</code>
 	 * @see Collection#toArray(Object[])
 	 */
 	public static <E> E[] array(Iterable<? extends E> iterable, E[] array) {
@@ -123,14 +146,12 @@
 	}
 
 	/**
-	 * Returns an array corresponding to the specified iterable;
+	 * Return an array corresponding to the specified iterable;
 	 * the runtime type of the returned array is that of the specified array.
 	 * If the iterable fits in the specified array, it is returned therein.
 	 * Otherwise, a new array is allocated with the runtime type of the
 	 * specified array and the size of the iterable.
 	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Iterable.toArray(Object[])</code>
 	 * @see Collection#toArray(Object[])
 	 */
 	public static <E> E[] array(Iterable<? extends E> iterable, int iterableSize, E[] array) {
@@ -138,66 +159,82 @@
 	}
 
 	/**
-	 * Returns an array corresponding to the specified iterator.
-	 * <p>
-	 * <code>Iterator.toArray()</code>
+	 * Return an array corresponding to the specified iterator.
 	 * @see Collection#toArray()
 	 */
 	public static Object[] array(Iterator<?> iterator) {
 		return iterator.hasNext() ?
-				CollectionTools.list(iterator).toArray() :
-				EMPTY_OBJECT_ARRAY;
+				ListTools.list(iterator).toArray() :
+				ObjectTools.EMPTY_OBJECT_ARRAY;
 	}
 
 	/**
-	 * Returns an array corresponding to the specified iterator.
+	 * Return an array corresponding to the specified iterator.
 	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Iterator.toArray()</code>
 	 * @see Collection#toArray()
 	 */
 	public static Object[] array(Iterator<?> iterator, int iteratorSize) {
 		return iterator.hasNext() ?
-				CollectionTools.list(iterator, iteratorSize).toArray() :
-				EMPTY_OBJECT_ARRAY;
+				ListTools.list(iterator, iteratorSize).toArray() :
+				ObjectTools.EMPTY_OBJECT_ARRAY;
 	}
 
 	/**
-	 * Returns an array corresponding to the specified iterator;
+	 * Return an array corresponding to the specified iterator with the
+	 * specified component type.
+	 * @see Collection#toArray(Object[])
+	 */
+	public static <E> E[] array(Iterator<?> iterator, Class<E> componentType) {
+		E[] array = newInstance(componentType, 0);
+		return iterator.hasNext() ?
+				ListTools.list(iterator).toArray(array) :
+				array;
+	}
+
+	/**
+	 * Return an array corresponding to the specified iterator with the
+	 * specified component type.
+	 * The specified iterator size is a performance hint.
+	 * @see Collection#toArray(Object[])
+	 */
+	public static <E> E[] array(Iterator<?> iterator, int iteratorSize, Class<E> componentType) {
+		return iterator.hasNext() ?
+				ListTools.list(iterator, iteratorSize).toArray(newInstance(componentType, iteratorSize)) :
+				newInstance(componentType, 0);
+	}
+
+	/**
+	 * Return an array corresponding to the specified iterator;
 	 * the runtime type of the returned array is that of the specified array.
 	 * If the iterator fits in the specified array, it is returned therein.
 	 * Otherwise, a new array is allocated with the runtime type of the
 	 * specified array and the size of the iterator.
-	 * <p>
-	 * <code>Iterator.toArray(Object[])</code>
 	 * @see Collection#toArray(Object[])
 	 */
 	public static <E> E[] array(Iterator<? extends E> iterator, E[] array) {
 		return iterator.hasNext() ?
-				CollectionTools.list(iterator).toArray(array) :
+				ListTools.list(iterator).toArray(array) :
 				emptyArray(array);
 	}
 
 	/**
-	 * Returns an array corresponding to the specified iterator;
+	 * Return an array corresponding to the specified iterator;
 	 * the runtime type of the returned array is that of the specified array.
 	 * If the iterator fits in the specified array, it is returned therein.
 	 * Otherwise, a new array is allocated with the runtime type of the
 	 * specified array and the size of the iterator.
 	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Iterator.toArray(Object[])</code>
 	 * @see Collection#toArray(Object[])
 	 */
 	public static <E> E[] array(Iterator<? extends E> iterator, int iteratorSize, E[] array) {
 		return iterator.hasNext() ?
-				CollectionTools.list(iterator, iteratorSize).toArray(array) :
+				ListTools.list(iterator, iteratorSize).toArray(array) :
 				emptyArray(array);
 	}
 
 	/**
-	 * Returns it;
-	 * otherwise, set its first element to null.
+	 * If the specified array is empty, return it;
+	 * otherwise, set its first element to <code>null</code>.
 	 * @see Collection#toArray(Object[])
 	 */
 	private static <E> E[] emptyArray(E[] array) {
@@ -205,7 +242,8 @@
 	}
 
 	/**
-	 * Returns the array.
+	 * Set the specified array's first element to <code>null</code> and and
+	 * return the array.
 	 * Assume the array length > 0.
 	 */
 	private static <E> E[] clearFirst(E[] array) {
@@ -217,14 +255,12 @@
 	// ********** add **********
 
 	/**
-	 * Returns a new array containing the elements in the
+	 * Return a new array containing the elements in the
 	 * specified array followed by the specified object to be added.
-	 * <p>
-	 * <code>Arrays.add(Object[] array, Object o)</code>
 	 */
 	public static <E> E[] add(E[] array, E value) {
 		int len = array.length;
-		E[] result = newArray(array, len + 1);
+		E[] result = newInstance(array, len + 1);
 		if (len > 0) {
 			System.arraycopy(array, 0, result, 0, len);
 		}
@@ -233,14 +269,12 @@
 	}
 
 	/**
-	 * Returns a new array containing the elements in the
+	 * Return a new array containing the elements in the
 	 * specified array with the specified object added at the specified index.
-	 * <p>
-	 * <code>Arrays.add(Object[] array, int index, Object o)</code>
 	 */
 	public static <E> E[] add(E[] array, int index, E value) {
 		int len = array.length;
-		E[] result = newArray(array, len + 1);
+		E[] result = newInstance(array, len + 1);
 		if (index > 0) {
 			System.arraycopy(array, 0, result, 0, index);
 		}
@@ -252,10 +286,8 @@
 	}
 
 	/**
-	 * Returns a new array containing the elements in the
+	 * Return a new array containing the elements in the
 	 * specified array followed by the specified value to be added.
-	 * <p>
-	 * <code>Arrays.add(char[] array, char value)</code>
 	 */
 	public static char[] add(char[] array, char value) {
 		int len = array.length;
@@ -268,10 +300,8 @@
 	}
 
 	/**
-	 * Returns a new array containing the elements in the
+	 * Return a new array containing the elements in the
 	 * specified array with the specified value added at the specified index.
-	 * <p>
-	 * <code>Arrays.add(char[] array, int index, char value)</code>
 	 */
 	public static char[] add(char[] array, int index, char value) {
 		int len = array.length;
@@ -287,10 +317,8 @@
 	}
 
 	/**
-	 * Returns a new array containing the elements in the
+	 * Return a new array containing the elements in the
 	 * specified array followed by the specified value to be added.
-	 * <p>
-	 * <code>Arrays.add(int[] array, int value)</code>
 	 */
 	public static int[] add(int[] array, int value) {
 		int len = array.length;
@@ -303,10 +331,8 @@
 	}
 
 	/**
-	 * Returns a new array containing the elements in the
+	 * Return a new array containing the elements in the
 	 * specified array with the specified value added at the specified index.
-	 * <p>
-	 * <code>Arrays.add(int[] array, int index, int value)</code>
 	 */
 	public static int[] add(int[] array, int index, int value) {
 		int len = array.length;
@@ -325,11 +351,9 @@
 	// ********** add all **********
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * specified array followed by the elements
 	 * in the specified collection.
-	 *<p>
-	 * <code>Arrays.addAll(Object[] array, Collection collection)</code>
 	 */
 	public static <E> E[] addAll(E[] array, Collection<? extends E> collection) {
 		return addAll(array, collection, collection.size());
@@ -361,7 +385,7 @@
 	 */
 	private static <E> E[] addAll(E[] array, Collection<? extends E> collection, int arrayLength, int collectionSize) {
 		return (arrayLength == 0) ?
-				collection.toArray(newArray(array, collectionSize)) :
+				collection.toArray(newInstance(array, collectionSize)) :
 				addAll_(array, collection, arrayLength, collectionSize);
 	}
 
@@ -369,7 +393,7 @@
 	 * assume array length and collection size > zero
 	 */
 	private static <E> E[] addAll_(E[] array, Collection<? extends E> collection, int arrayLength, int collectionSize) {
-		E[] result = newArray(array, arrayLength + collectionSize);
+		E[] result = newInstance(array, arrayLength + collectionSize);
 		System.arraycopy(array, 0, result, 0, arrayLength);
 		int i = arrayLength;
 		for (E element : collection) {
@@ -379,57 +403,47 @@
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * specified array followed by the elements
 	 * in the specified iterable.
-	 * <p>
-	 * <code>Arrays.addAll(Object[] array, Iterable iterable)</code>
 	 */
 	public static <E> E[] addAll(E[] array, Iterable<? extends E> iterable) {
 		return addAll(array, iterable.iterator());
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * specified array followed by the elements
 	 * in the specified iterable.
 	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Arrays.addAll(Object[] array, Iterable iterable)</code>
 	 */
 	public static <E> E[] addAll(E[] array, Iterable<? extends E> iterable, int iterableSize) {
 		return addAll(array, iterable.iterator(), iterableSize);
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * specified array followed by the elements
 	 * in the specified iterator.
-	 * <p>
-	 * <code>Arrays.addAll(Object[] array, Iterator iterator)</code>
 	 */
 	public static <E> E[] addAll(E[] array, Iterator<? extends E> iterator) {
-		return iterator.hasNext() ? addAll_(array, CollectionTools.list(iterator)) : array;
+		return iterator.hasNext() ? addAll_(array, ListTools.list(iterator)) : array;
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * specified array followed by the elements
 	 * in the specified iterator.
 	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Arrays.addAll(Object[] array, Iterator iterator)</code>
 	 */
 	public static <E> E[] addAll(E[] array, Iterator<? extends E> iterator, int iteratorSize) {
-		return iterator.hasNext() ? addAll_(array, CollectionTools.list(iterator, iteratorSize)) : array;
+		return iterator.hasNext() ? addAll_(array, ListTools.list(iterator, iteratorSize)) : array;
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * specified array 1 followed by the elements
 	 * in the specified array 2.
-	 * <p>
-	 * <code>Arrays.addAll(Object[] array1, Object[] array2)</code>
 	 */
 	public static <E> E[] addAll(E[] array1, E... array2) {
 		return addAll(array1, array2, array2.length);
@@ -460,18 +474,16 @@
 	 * assume both array lengths > 0
 	 */
 	private static <E> E[] addAll_(E[] array1, E[] array2, int array1Length, int array2Length) {
-		E[] result = newArray(array1, array1Length + array2Length);
+		E[] result = newInstance(array1, array1Length + array2Length);
 		System.arraycopy(array1, 0, result, 0, array1Length);
 		System.arraycopy(array2, 0, result, array1Length, array2Length);
 		return result;
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * first specified array with the objects in the second
 	 * specified array added at the specified index.
-	 * <p>
-	 * <code>Arrays.addAll(Object[] array1, int index, Object[] array2)</code>
 	 */
 	public static <E> E[] addAll(E[] array1, int index, E... array2) {
 		return addAll(array1, index, array2, array2.length);
@@ -506,7 +518,7 @@
 	 * assume both array lengths > 0 and index != array 1 length
 	 */
 	private static <E> E[] addAll_(E[] array1, int index, E[] array2, int array1Length, int array2Length) {
-		E[] result = newArray(array1, array1Length + array2Length);
+		E[] result = newInstance(array1, array1Length + array2Length);
 		System.arraycopy(array1, 0, result, 0, index);
 		System.arraycopy(array2, 0, result, index, array2Length);
 		System.arraycopy(array1, index, result, index + array2Length, array1Length - index);
@@ -514,11 +526,9 @@
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * specified array with the elements
 	 * in the specified collection inserted at the specified index.
-	 * <p>
-	 * <code>Arrays.addAll(Object[] array, int index, Collection c)</code>
 	 */
 	public static <E> E[] addAll(E[] array, int index, Collection<? extends E> collection) {
 		return addAll(array, index, collection, collection.size());
@@ -544,9 +554,9 @@
 	private static <E> E[] addAll(E[] array, int index, Collection<? extends E> collection, int arrayLength, int collectionSize) {
 		if (arrayLength == 0) {
 			if (index == 0) {
-				return collection.toArray(newArray(array, collectionSize));
+				return collection.toArray(newInstance(array, collectionSize));
 			}
-			throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0"); //$NON-NLS-2$
+			throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0");
 		}
 		return (index == arrayLength) ?  // 'collection' added to end of 'array'
 				addAll_(array, collection, arrayLength, collectionSize) :
@@ -557,7 +567,7 @@
 	 * assume array length and collection size > 0 and index != array length
 	 */
 	private static <E> E[] addAll_(E[] array, int index, Collection<? extends E> collection, int arrayLength, int collectionSize) {
-		E[] result = newArray(array, arrayLength + collectionSize);
+		E[] result = newInstance(array, arrayLength + collectionSize);
 		System.arraycopy(array, 0, result, 0, index);
 		int i = index;
 		for (E item : collection) {
@@ -568,48 +578,40 @@
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * specified array with the elements
 	 * in the specified iterable inserted at the specified index.
-	 * <p>
-	 * <code>Arrays.addAll(Object[] array, int index, Iterable iterable)</code>
 	 */
 	public static <E> E[] addAll(E[] array, int index, Iterable<? extends E> iterable) {
 		return addAll(array, index, iterable.iterator());
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * specified array with the elements
 	 * in the specified iterable inserted at the specified index.
-	 * <p>
-	 * <code>Arrays.addAll(Object[] array, int index, Iterable iterable)</code>
 	 */
 	public static <E> E[] addAll(E[] array, int index, Iterable<? extends E> iterable, int iterableSize) {
 		return addAll(array, index, iterable.iterator(), iterableSize);
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * specified array with the elements
 	 * in the specified iterator inserted at the specified index.
-	 * <p>
-	 * <code>Arrays.addAll(Object[] array, int index, Iterator iterator)</code>
 	 */
 	public static <E> E[] addAll(E[] array, int index, Iterator<? extends E> iterator) {
-		return iterator.hasNext() ? addAll_(array, index, CollectionTools.list(iterator)) : array;
+		return iterator.hasNext() ? addAll_(array, index, ListTools.list(iterator)) : array;
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * specified array with the elements
 	 * in the specified iterator inserted at the specified index.
 	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Arrays.addAll(Object[] array, int index, Iterator iterator)</code>
 	 */
 	public static <E> E[] addAll(E[] array, int index, Iterator<? extends E> iterator, int iteratorSize) {
-		return iterator.hasNext() ? addAll_(array, index, CollectionTools.list(iterator, iteratorSize)) : array;
+		return iterator.hasNext() ? addAll_(array, index, ListTools.list(iterator, iteratorSize)) : array;
 	}
 
 	/**
@@ -620,11 +622,9 @@
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * specified array 1 followed by the elements
 	 * in the specified array 2.
-	 * <p>
-	 * <code>Arrays.addAll(char[] array1, char[] array2)</code>
 	 */
 	public static char[] addAll(char[] array1, char... array2) {
 		return addAll(array1, array2, array2.length);
@@ -662,11 +662,9 @@
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * first specified array with the objects in the second
 	 * specified array added at the specified index.
-	 * <p>
-	 * <code>Arrays.add(char[] array1, int index, char[] array2)</code>
 	 */
 	public static char[] addAll(char[] array1, int index, char... array2) {
 		return addAll(array1, index, array2, array2.length);
@@ -709,11 +707,9 @@
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * specified array 1 followed by the elements
 	 * in the specified array 2.
-	 * <p>
-	 * <code>Arrays.addAll(int[] array1, int[] array2)</code>
 	 */
 	public static int[] addAll(int[] array1, int... array2) {
 		return addAll(array1, array2, array2.length);
@@ -751,11 +747,9 @@
 	}
 
 	/**
-	 * Returns an array containing the elements in the
+	 * Return an array containing the elements in the
 	 * first specified array with the objects in the second
 	 * specified array added at the specified index.
-	 * <p>
-	 * <code>Arrays.add(int[] array1, int index, int[] array2)</code>
 	 */
 	public static int[] addAll(int[] array1, int index, int... array2) {
 		return addAll(array1, index, array2, array2.length);
@@ -801,30 +795,43 @@
 	// ********** clear **********
 
 	/**
-	 * Returns an empty array with the same component type as the specified array.
-	 * <p>
-	 * <code>Arrays.clear(Object[] array)</code>
+	 * Return an empty array with the same component type as the specified array.
 	 */
 	public static <E> E[] clear(E[] array) {
-		return (array.length == 0) ? array : newArray(array, 0);
+		return (array.length == 0) ? array : newInstance(array, 0);
+	}
+
+
+	// ********** component type **********
+
+	/**
+	 * Return the specified array's component type, with appropriate support
+	 * for generics.
+	 * <p>
+	 * <strong>NB:</strong> The array's reified component type may be a sub-type of
+	 * the array's <em>declared</em> component type.
+	 */
+	public static <E> Class<? extends E> componentType(E[] array) {
+		Class<?> rawComponentType = array.getClass().getComponentType();
+		@SuppressWarnings("unchecked")
+		Class<? extends E> componentType = (Class<? extends E>) rawComponentType;
+		return componentType;
 	}
 
 
 	// ********** concatenate **********
 
 	/**
-	 * Returns an array containing all the elements in all the
+	 * Return an array containing all the elements in all the
 	 * specified arrays, concatenated in the specified order.
 	 * This is useful for building constant arrays out of other constant arrays.
-	 * <p>
-	 * <code>Arrays.concatenate(Object[]... arrays)</code>
 	 */
 	public static <E> E[] concatenate(E[]... arrays) {
 		int len = 0;
 		for (E[] array : arrays) {
 			len += array.length;
 		}
-		E[] result = newArray(arrays[0], len);
+		E[] result = newInstance(arrays[0], len);
 		if (len == 0) {
 			return result;
 		}
@@ -840,11 +847,9 @@
 	}
 
 	/**
-	 * Returns an array containing all the elements in  all the
+	 * Return an array containing all the elements in  all the
 	 * specified arrays, concatenated in the specified order.
 	 * This is useful for building constant arrays out other constant arrays.
-	 * <p>
-	 * <code>Arrays.concatenate(char[]... arrays)</code>
 	 */
 	public static char[] concatenate(char[]... arrays) {
 		int len = 0;
@@ -852,7 +857,7 @@
 			len += array.length;
 		}
 		if (len == 0) {
-			return EMPTY_CHAR_ARRAY;
+			return CharArrayTools.EMPTY_CHAR_ARRAY;
 		}
 		char[] result = new char[len];
 		int current = 0;
@@ -867,11 +872,9 @@
 	}
 
 	/**
-	 * Returns an array containing all the elements in  all the
+	 * Return an array containing all the elements in  all the
 	 * specified arrays, concatenated in the specified order.
 	 * This is useful for building constant arrays out other constant arrays.
-	 * <p>
-	 * <code>Arrays.concatenate(int[]... arrays)</code>
 	 */
 	public static int[] concatenate(int[]... arrays) {
 		int len = 0;
@@ -897,10 +900,8 @@
 	// ********** contains **********
 
 	/**
-	 * Returns whether the specified array contains the
+	 * Return whether the specified array contains the
 	 * specified element.
-	 * <p>
-	 * <code>Arrays.contains(Object[] array, Object o)</code>
 	 */
 	public static boolean contains(Object[] array, Object value) {
 		return contains(array, value, array.length);
@@ -916,7 +917,7 @@
 	/**
 	 * assume array length > 0
 	 */
-	public static boolean contains_(Object[] array, Object value, int arrayLength) {
+	private static boolean contains_(Object[] array, Object value, int arrayLength) {
 		if (value == null) {
 			for (int i = arrayLength; i-- > 0; ) {
 				if (array[i] == null) {
@@ -934,10 +935,8 @@
 	}
 
 	/**
-	 * Returns whether the specified array contains the
+	 * Return whether the specified array contains the
 	 * specified element.
-	 * <p>
-	 * <code>Arrays.contains(char[] array, char value)</code>
 	 */
 	public static boolean contains(char[] array, char value) {
 		return contains(array, value, array.length);
@@ -963,10 +962,8 @@
 	}
 
 	/**
-	 * Returns whether the specified array contains the
+	 * Return whether the specified array contains the
 	 * specified element.
-	 * <p>
-	 * <code>Arrays.contains(int[] array, int value)</code>
 	 */
 	public static boolean contains(int[] array, int value) {
 		return contains(array, value, array.length);
@@ -995,30 +992,24 @@
 	// ********** contains all **********
 
 	/**
-	 * Returns whether the specified array contains all of the
+	 * Return whether the specified array contains all of the
 	 * elements in the specified collection.
-	 * <p>
-	 * <code>Arrays.containsAll(Object[] array, Collection collection)</code>
 	 */
 	public static boolean containsAll(Object[] array, Collection<?> collection) {
 		return containsAll(array, collection.iterator());
 	}
 
 	/**
-	 * Returns whether the specified array contains all of the
+	 * Return whether the specified array contains all of the
 	 * elements in the specified iterable.
-	 * <p>
-	 * <code>Arrays.containsAll(Object[] array, Iterable iterable)</code>
 	 */
 	public static boolean containsAll(Object[] array, Iterable<?> iterable) {
 		return containsAll(array, iterable.iterator());
 	}
 
 	/**
-	 * Returns whether the specified array contains all of the
+	 * Return whether the specified array contains all of the
 	 * elements in the specified iterator.
-	 * <p>
-	 * <code>Arrays.containsAll(Object[] array, Iterator iterator)</code>
 	 */
 	public static boolean containsAll(Object[] array, Iterator<?> iterator) {
 		// use hashed lookup
@@ -1032,10 +1023,8 @@
 	}
 
 	/**
-	 * Returns whether the specified array 1 contains all of the
+	 * Return whether the specified array 1 contains all of the
 	 * elements in the specified array 2.
-	 * <p>
-	 * <code>Arrays.containsAll(Object[] array1, Object[] array2)</code>
 	 */
 	public static boolean containsAll(Object[] array1, Object... array2) {
 		// use hashed lookup
@@ -1049,10 +1038,8 @@
 	}
 
 	/**
-	 * Returns whether the specified array 1 contains all of the
+	 * Return whether the specified array 1 contains all of the
 	 * elements in the specified array 2.
-	 * <p>
-	 * <code>Arrays.containsAll(char[] array1, char[] array2)</code>
 	 */
 	public static boolean containsAll(char[] array1, char... array2) {
 		for (int i = array2.length; i-- > 0; ) {
@@ -1064,10 +1051,8 @@
 	}
 
 	/**
-	 * Returns whether the specified array 1 contains all of the
+	 * Return whether the specified array 1 contains all of the
 	 * elements in the specified array 2.
-	 * <p>
-	 * <code>Arrays.containsAll(int[] array1, int[] array2)</code>
 	 */
 	public static boolean containsAll(int[] array1, int... array2) {
 		for (int i = array2.length; i-- > 0; ) {
@@ -1082,15 +1067,62 @@
 	// ********** diff **********
 
 	/**
-	 * Returns the index of the first elements in the specified
+	 * Return the range of elements in the specified
+	 * arrays that are different.
+	 * If the arrays are identical, return <code>[size, -1]</code>.
+	 * Use the elements' {@link Object#equals(Object)} method to compare the
+	 * elements.
+	 * @see #indexOfDifference(Object[], Object[])
+	 * @see #lastIndexOfDifference(Object[], Object[])
+	 */
+	public static Range differenceRange(Object[] array1, Object[] array2) {
+		int end = lastIndexOfDifference(array1, array2);
+		if (end == -1) {
+			// the lists are identical, the start is the size of the two lists
+			return new Range(array1.length, end);
+		}
+		// the lists are different, calculate the start of the range
+		return new Range(indexOfDifference(array1, array2), end);
+	}
+
+	/**
+	 * Return the index of the first elements in the specified
+	 * arrays that are different. If the arrays are identical, return
+	 * the size of the two arrays (i.e. one past the last index).
+	 * If the arrays are different sizes and all the elements in
+	 * the shorter array match their corresponding elements in
+	 * the longer array, return the size of the shorter array
+	 * (i.e. one past the last index of the shorter array).
+	 * Use the elements' {@link Object#equals(Object)} method to compare the
+	 * elements.
+	 */
+	public static int indexOfDifference(Object[] array1, Object[] array2) {
+		int end = Math.min(array1.length, array2.length);
+		for (int i = 0; i < end; i++) {
+			Object o = array1[i];
+			if (o == null) {
+				if (array2[i] != null) {
+					return i;
+				}
+			} else {
+				if ( ! o.equals(array2[i])) {
+					return i;
+				}
+			}
+		}
+		return end;
+	}
+
+	/**
+	 * Return the index of the first elements in the specified
 	 * arrays that are different, beginning at the end.
-	 * Returns -1.
-	 * Returns the index of the
+	 * If the arrays are identical, return -1.
+	 * If the arrays are different sizes, return the index of the
 	 * last element in the longer array.
 	 * Use the elements' {@link Object#equals(Object)} method to compare the
 	 * elements.
 	 */
-	public static int diffEnd(Object[] array1, Object[] array2) {
+	public static int lastIndexOfDifference(Object[] array1, Object[] array2) {
 		int len1 = array1.length;
 		int len2 = array2.length;
 		if (len1 != len2) {
@@ -1111,65 +1143,56 @@
 		return -1;
 	}
 
-	/**
-	 * Returns the range of elements in the specified
-	 * arrays that are different.
-	 * Returns [size, -1].
-	 * Use the elements' {@link Object#equals(Object)} method to compare the
-	 * elements.
-	 * @see #diffStart(Object[], Object[])
-	 * @see #diffEnd(Object[], Object[])
-	 */
-	public static Range diffRange(Object[] array1, Object[] array2) {
-		int end = diffEnd(array1, array2);
-		if (end == -1) {
-			// the lists are identical, the start is the size of the two lists
-			return new Range(array1.length, end);
-		}
-		// the lists are different, calculate the start of the range
-		return new Range(diffStart(array1, array2), end);
-	}
-
-	/**
-	 * Returns the index of the first elements in the specified
-	 * arrays that are different. If the arrays are identical, return
-	 * the size of the two arrays (i.e. one past the last index).
-	 * If the arrays are different sizes and all the elements in
-	 * the shorter array match their corresponding elements in
-	 * Returns the size of the shorter array
-	 * (i.e. one past the last index of the shorter array).
-	 * Use the elements' {@link Object#equals(Object)} method to compare the
-	 * elements.
-	 */
-	public static int diffStart(Object[] array1, Object[] array2) {
-		int end = Math.min(array1.length, array2.length);
-		for (int i = 0; i < end; i++) {
-			Object o = array1[i];
-			if (o == null) {
-				if (array2[i] != null) {
-					return i;
-				}
-			} else {
-				if ( ! o.equals(array2[i])) {
-					return i;
-				}
-			}
-		}
-		return end;
-	}
-
 
 	// ********** identity diff **********
 
 	/**
-	 * Returns the index of the first elements in the specified
+	 * Return the range of elements in the specified
+	 * arrays that are different.
+	 * If the arrays are identical, return <code>[size, -1]</code>.
+	 * Use object identity to compare the elements.
+	 * @see #indexOfIdentityDifference(Object[], Object[])
+	 * @see #lastIndexOfIdentityDifference(Object[], Object[])
+	 */
+	public static Range identityDifferenceRange(Object[] array1, Object[] array2) {
+		int end = lastIndexOfIdentityDifference(array1, array2);
+		if (end == -1) {
+			// the lists are identical, the start is the size of the two lists
+			return new Range(array1.length, end);
+		}
+		// the lists are different, calculate the start of the range
+		return new Range(indexOfIdentityDifference(array1, array2), end);
+	}
+
+	/**
+	 * Return the index of the first elements in the specified
+	 * arrays that are different. If the arrays are identical, return
+	 * the size of the two arrays (i.e. one past the last index).
+	 * If the arrays are different sizes and all the elements in
+	 * the shorter array match their corresponding elements in
+	 * the longer array, return the size of the shorter array
+	 * (i.e. one past the last index of the shorter array).
+	 * Use object identity to compare the elements.
+	 */
+	public static int indexOfIdentityDifference(Object[] array1, Object[] array2) {
+		int end = Math.min(array1.length, array2.length);
+		for (int i = 0; i < end; i++) {
+			if (array1[i] != array2[i]) {
+				return i;
+			}
+		}
+		return end;
+	}
+
+	/**
+	 * Return the index of the first elements in the specified
 	 * arrays that are different, beginning at the end.
-	 * Returns -1.
-	 * Returns the index of the
+	 * If the arrays are identical, return -1.
+	 * If the arrays are different sizes, return the index of the
 	 * last element in the longer array.
 	 * Use object identity to compare the elements.
 	 */
-	public static int identityDiffEnd(Object[] array1, Object[] array2) {
+	public static int lastIndexOfIdentityDifference(Object[] array1, Object[] array2) {
 		int len1 = array1.length;
 		int len2 = array2.length;
 		if (len1 != len2) {
@@ -1183,51 +1206,11 @@
 		return -1;
 	}
 
-	/**
-	 * Returns the range of elements in the specified
-	 * arrays that are different.
-	 * Returns [size, -1].
-	 * Use object identity to compare the elements.
-	 * @see #identityDiffStart(Object[], Object[])
-	 * @see #identityDiffEnd(Object[], Object[])
-	 */
-	public static Range identityDiffRange(Object[] array1, Object[] array2) {
-		int end = identityDiffEnd(array1, array2);
-		if (end == -1) {
-			// the lists are identical, the start is the size of the two lists
-			return new Range(array1.length, end);
-		}
-		// the lists are different, calculate the start of the range
-		return new Range(identityDiffStart(array1, array2), end);
-	}
-
-	/**
-	 * Returns the index of the first elements in the specified
-	 * arrays that are different. If the arrays are identical, return
-	 * the size of the two arrays (i.e. one past the last index).
-	 * If the arrays are different sizes and all the elements in
-	 * the shorter array match their corresponding elements in
-	 * Returns the size of the shorter array
-	 * (i.e. one past the last index of the shorter array).
-	 * Use object identity to compare the elements.
-	 */
-	public static int identityDiffStart(Object[] array1, Object[] array2) {
-		int end = Math.min(array1.length, array2.length);
-		for (int i = 0; i < end; i++) {
-			if (array1[i] != array2[i]) {
-				return i;
-			}
-		}
-		return end;
-	}
-
 
 	// ********** elements are identical **********
 
 	/**
-	 * Returns whether the specified arrays contain the same elements.
-	 * <p>
-	 * <code>Arrays.identical(Object[] array1, Object[] array2)</code>
+	 * Return whether the specified arrays contain the same elements.
 	 */
 	public static boolean elementsAreIdentical(Object[] array1, Object[] array2) {
 		if (array1 == array2) {
@@ -1252,11 +1235,9 @@
 	// ********** index of **********
 
 	/**
-	 * Returns the index of the first occurrence of the
+	 * Return the index of the first occurrence of the
 	 * specified element in the specified array,
-	 * Returns -1 if there is no such index.
-	 * <p>
-	 * <code>Arrays.indexOf(Object[] array, Object o)</code>
+	 * or return -1 if there is no such index.
 	 */
 	public static int indexOf(Object[] array, Object value) {
 		int len = array.length;
@@ -1277,11 +1258,9 @@
 	}
 
 	/**
-	 * Returns the index of the first occurrence of the
+	 * Return the index of the first occurrence of the
 	 * specified element in the specified array,
-	 * Returns -1 if there is no such index.
-	 * <p>
-	 * <code>Arrays.identityIndexOf(Object[] array, Object o)</code>
+	 * or return -1 if there is no such index.
 	 */
 	public static int identityIndexOf(Object[] array, Object value) {
 		int len = array.length;
@@ -1294,11 +1273,9 @@
 	}
 
 	/**
-	 * Returns the index of the first occurrence of the
+	 * Return the index of the first occurrence of the
 	 * specified element in the specified array,
-	 * Returns -1 if there is no such index.
-	 * <p>
-	 * <code>Arrays.indexOf(char[] array, char value)</code>
+	 * or return -1 if there is no such index.
 	 */
 	public static int indexOf(char[] array, char value) {
 		int len = array.length;
@@ -1311,11 +1288,9 @@
 	}
 
 	/**
-	 * Returns the index of the first occurrence of the
+	 * Return the index of the first occurrence of the
 	 * specified element in the specified array,
-	 * Returns -1 if there is no such index.
-	 * <p>
-	 * <code>Arrays.indexOf(int[] array, int value)</code>
+	 * or return -1 if there is no such index.
 	 */
 	public static int indexOf(int[] array, int value) {
 		int len = array.length;
@@ -1331,13 +1306,102 @@
 	// ********** insertion index of **********
 
 	/**
-	 * Returns the maximum index of where the specified comparable object
+	 * Return the minimum index of where the specified comparable object
 	 * should be inserted into the specified sorted array and still keep
 	 * the array sorted.
 	 */
 	public static <E extends Comparable<? super E>> int insertionIndexOf(E[] sortedArray, Comparable<E> value) {
 		int len = sortedArray.length;
 		for (int i = 0; i < len; i++) {
+			if (value.compareTo(sortedArray[i]) <= 0) {
+				return i;
+			}
+		}
+		return len;
+	}
+
+	/**
+	 * Return the minimum index of where the specified comparable object
+	 * should be inserted into the specified sorted array and still keep
+	 * the array sorted.
+	 */
+	public static <E> int insertionIndexOf(E[] sortedArray, E value, Comparator<? super E> comparator) {
+		int len = sortedArray.length;
+		for (int i = 0; i < len; i++) {
+			if (comparator.compare(value, sortedArray[i]) <= 0) {
+				return i;
+			}
+		}
+		return len;
+	}
+
+
+	// ********** iterable **********
+
+	/**
+	 * Return an iterable corresponding to the specified array.
+	 */
+	public static <E> ArrayIterable<E> iterable(E[] array) {
+		return new ArrayIterable<E>(array);
+	}
+
+	/**
+	 * Return an iterable corresponding to the specified array,
+	 * starting at the specified start index and continuing for
+	 * the rest of the array.
+	 */
+	public static <E> ArrayIterable<E> iterable(E[] array, int start) {
+		return new ArrayIterable<E>(array, start);
+	}
+
+	/**
+	 * Return an iterable corresponding to the specified array,
+	 * starting at the specified start index, inclusive, and continuing to
+	 * the specified end index, exclusive.
+	 */
+	public static <E> ArrayIterable<E> iterable(E[] array, int start, int end) {
+		return new ArrayIterable<E>(array, start, end);
+	}
+
+
+	// ********** iterator **********
+
+	/**
+	 * Return an iterator corresponding to the specified array.
+	 */
+	public static <E> ArrayIterator<E> iterator(E[] array) {
+		return new ArrayIterator<E>(array);
+	}
+
+	/**
+	 * Return an iterator corresponding to the specified array,
+	 * starting at the specified start index and continuing for
+	 * the rest of the array.
+	 */
+	public static <E> ArrayIterator<E> iterator(E[] array, int start) {
+		return new ArrayIterator<E>(array, start);
+	}
+
+	/**
+	 * Return an iterator corresponding to the specified array,
+	 * starting at the specified start index, inclusive, and continuing to
+	 * the specified end index, exclusive.
+	 */
+	public static <E> ArrayIterator<E> iterator(E[] array, int start, int end) {
+		return new ArrayIterator<E>(array, start, end);
+	}
+
+
+	// ********** last insertion index of **********
+
+	/**
+	 * Return the maximum index of where the specified comparable object
+	 * should be inserted into the specified sorted array and still keep
+	 * the array sorted.
+	 */
+	public static <E extends Comparable<? super E>> int lastInsertionIndexOf(E[] sortedArray, Comparable<E> value) {
+		int len = sortedArray.length;
+		for (int i = 0; i < len; i++) {
 			if (value.compareTo(sortedArray[i]) < 0) {
 				return i;
 			}
@@ -1346,11 +1410,11 @@
 	}
 
 	/**
-	 * Returns the maximum index of where the specified comparable object
+	 * Return the maximum index of where the specified comparable object
 	 * should be inserted into the specified sorted array and still keep
 	 * the array sorted.
 	 */
-	public static <E> int insertionIndexOf(E[] sortedArray, E value, Comparator<? super E> comparator) {
+	public static <E> int lastInsertionIndexOf(E[] sortedArray, E value, Comparator<? super E> comparator) {
 		int len = sortedArray.length;
 		for (int i = 0; i < len; i++) {
 			if (comparator.compare(value, sortedArray[i]) < 0) {
@@ -1364,11 +1428,9 @@
 	// ********** last index of **********
 
 	/**
-	 * Returns the index of the last occurrence of the
+	 * Return the index of the last occurrence of the
 	 * specified element in the specified array;
-	 * Returns -1 if there is no such index.
-	 * <p>
-	 * <code>Arrays.lastIndexOf(Object[] array, Object o)</code>
+	 * return -1 if there is no such index.
 	 */
 	public static int lastIndexOf(Object[] array, Object value) {
 		int len = array.length;
@@ -1389,11 +1451,9 @@
 	}
 
 	/**
-	 * Returns the index of the last occurrence of the
+	 * Return the index of the last occurrence of the
 	 * specified element in the specified array,
-	 * Returns -1 if there is no such index.
-	 * <p>
-	 * <code>Arrays.lastIndexOf(char[] array, char value)</code>
+	 * or return -1 if there is no such index.
 	 */
 	public static int lastIndexOf(char[] array, char value) {
 		for (int i = array.length; i-- > 0; ) {
@@ -1405,11 +1465,9 @@
 	}
 
 	/**
-	 * Returns the index of the last occurrence of the
+	 * Return the index of the last occurrence of the
 	 * specified element in the specified array,
-	 * Returns -1 if there is no such index.
-	 * <p>
-	 * <code>Arrays.lastIndexOf(int[] array, int value)</code>
+	 * or return -1 if there is no such index.
 	 */
 	public static int lastIndexOf(int[] array, int value) {
 		for (int i = array.length; i-- > 0; ) {
@@ -1424,9 +1482,45 @@
 	// ********** min/max **********
 
 	/**
-	 * Returns the character from the specified array with the minimum value.
-	 * <p>
-	 * <code>Arrays.min(char[] array)</code>
+	 * Return the element from the specified array with the minimum value.
+	 */
+	public static <E extends Comparable<? super E>> E min(E[] array) {
+		int len = array.length;
+		if (len == 0) {
+			throw new IndexOutOfBoundsException();
+		}
+		int last = len - 1;
+		E min = array[last];
+		for (int i = last; i-- > 0; ) {
+			E e = array[i];
+			if (min.compareTo(e) > 0) {
+				min = e;
+			}
+		}
+		return min;
+	}
+
+	/**
+	 * Return the element from the specified array with the minimum value.
+	 */
+	public static <E extends Comparable<? super E>> E min(E[] array, Comparator<? super E> comparator) {
+		int len = array.length;
+		if (len == 0) {
+			throw new IndexOutOfBoundsException();
+		}
+		int last = len - 1;
+		E min = array[last];
+		for (int i = last; i-- > 0; ) {
+			E e = array[i];
+			if (comparator.compare(min, e) > 0) {
+				min = e;
+			}
+		}
+		return min;
+	}
+
+	/**
+	 * Return the character from the specified array with the minimum value.
 	 */
 	public static char min(char... array) {
 		int len = array.length;
@@ -1445,9 +1539,7 @@
 	}
 
 	/**
-	 * Returns the integer from the specified array with the minimum value.
-	 * <p>
-	 * <code>Arrays.min(int[] array)</code>
+	 * Return the integer from the specified array with the minimum value.
 	 */
 	public static int min(int... array) {
 		int len = array.length;
@@ -1466,9 +1558,45 @@
 	}
 
 	/**
-	 * Returns the character from the specified array with the maximum value.
-	 * <p>
-	 * <code>Arrays.max(char[] array)</code>
+	 * Return the element from the specified array with the maximum value.
+	 */
+	public static <E extends Comparable<? super E>> E max(E[] array) {
+		int len = array.length;
+		if (len == 0) {
+			throw new IndexOutOfBoundsException();
+		}
+		int last = len - 1;
+		E max = array[last];
+		for (int i = last; i-- > 0; ) {
+			E e = array[i];
+			if (max.compareTo(e) < 0) {
+				max = e;
+			}
+		}
+		return max;
+	}
+
+	/**
+	 * Return the element from the specified array with the maximum value.
+	 */
+	public static <E extends Comparable<? super E>> E max(E[] array, Comparator<? super E> comparator) {
+		int len = array.length;
+		if (len == 0) {
+			throw new IndexOutOfBoundsException();
+		}
+		int last = len - 1;
+		E max = array[last];
+		for (int i = last; i-- > 0; ) {
+			E e = array[i];
+			if (comparator.compare(max, e) < 0) {
+				max = e;
+			}
+		}
+		return max;
+	}
+
+	/**
+	 * Return the character from the specified array with the maximum value.
 	 */
 	public static char max(char... array) {
 		int len = array.length;
@@ -1487,9 +1615,7 @@
 	}
 
 	/**
-	 * Returns the integer from the specified array with the maximum value.
-	 * <p>
-	 * <code>Arrays.max(int[] array)</code>
+	 * Return the integer from the specified array with the maximum value.
 	 */
 	public static int max(int... array) {
 		int len = array.length;
@@ -1512,9 +1638,7 @@
 
 	/**
 	 * Move an element from the specified source index to the specified target
-	 * Returns the altered array.
-	 * <p>
-	 * <code>Arrays.move(Object[] array, int targetIndex, int sourceIndex)</code>
+	 * index. Return the altered array.
 	 */
 	public static <E> E[] move(E[] array, int targetIndex, int sourceIndex) {
 		return (targetIndex == sourceIndex) ? array : move_(array, targetIndex, sourceIndex);
@@ -1536,9 +1660,7 @@
 
 	/**
 	 * Move elements from the specified source index to the specified target
-	 * Returns the altered array.
-	 * <p>
-	 * <code>Arrays.move(Object[] array, int targetIndex, int sourceIndex, int length)</code>
+	 * index. Return the altered array.
 	 */
 	public static <E> E[] move(E[] array, int targetIndex, int sourceIndex, int length) {
 		if ((targetIndex == sourceIndex) || (length == 0)) {
@@ -1547,7 +1669,7 @@
 		if (length == 1) {
 			return move_(array, targetIndex, sourceIndex);
 		}
-		E[] temp = newArray(array, length);
+		E[] temp = newInstance(array, length);
 		System.arraycopy(array, sourceIndex, temp, 0, length);
 		if (targetIndex < sourceIndex) {
 			System.arraycopy(array, targetIndex, array, targetIndex + length, sourceIndex - targetIndex);
@@ -1560,9 +1682,7 @@
 
 	/**
 	 * Move an element from the specified source index to the specified target
-	 * Returns the altered array.
-	 * <p>
-	 * <code>Arrays.move(int[] array, int targetIndex, int sourceIndex)</code>
+	 * index. Return the altered array.
 	 */
 	public static int[] move(int[] array, int targetIndex, int sourceIndex) {
 		return (targetIndex == sourceIndex) ? array : move_(array, targetIndex, sourceIndex);
@@ -1584,9 +1704,7 @@
 
 	/**
 	 * Move elements from the specified source index to the specified target
-	 * Returns the altered array.
-	 * <p>
-	 * <code>Arrays.move(int[] array, int targetIndex, int sourceIndex, int length)</code>
+	 * index. Return the altered array.
 	 */
 	public static int[] move(int[] array, int targetIndex, int sourceIndex, int length) {
 		if ((targetIndex == sourceIndex) || (length == 0)) {
@@ -1608,9 +1726,7 @@
 
 	/**
 	 * Move an element from the specified source index to the specified target
-	 * Returns the altered array.
-	 * <p>
-	 * <code>Arrays.move(char[] array, int targetIndex, int sourceIndex)</code>
+	 * index. Return the altered array.
 	 */
 	public static char[] move(char[] array, int targetIndex, int sourceIndex) {
 		return (targetIndex == sourceIndex) ? array : move_(array, targetIndex, sourceIndex);
@@ -1632,9 +1748,7 @@
 
 	/**
 	 * Move elements from the specified source index to the specified target
-	 * Returns the altered array.
-	 * <p>
-	 * <code>Arrays.move(char[] array, int targetIndex, int sourceIndex, int length)</code>
+	 * index. Return the altered array.
 	 */
 	public static char[] move(char[] array, int targetIndex, int sourceIndex, int length) {
 		if ((targetIndex == sourceIndex) || (length == 0)) {
@@ -1658,90 +1772,72 @@
 	// ********** remove **********
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the specified element removed.
-	 * <p>
-	 * <code>Arrays.remove(Object[] array, Object value)</code>
 	 */
 	public static <E> E[] remove(E[] array, Object value) {
 		return removeElementAtIndex(array, indexOf(array, value));
 	}
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the specified element removed.
-	 * <p>
-	 * <code>Arrays.remove(char[] array, char value)</code>
 	 */
 	public static char[] remove(char[] array, char value) {
 		return removeElementAtIndex(array, indexOf(array, value));
 	}
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the specified element removed.
-	 * <p>
-	 * <code>Arrays.remove(int[] array, int value)</code>
 	 */
 	public static int[] remove(int[] array, int value) {
 		return removeElementAtIndex(array, indexOf(array, value));
 	}
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the first element removed.
-	 * <p>
-	 * <code>Arrays.removeFirst(Object[] array)</code>
 	 */
 	public static <E> E[] removeFirst(E[] array) {
 		return removeElementAtIndex(array, 0);
 	}
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the first element removed.
-	 * <p>
-	 * <code>Arrays.removeFirst(char[] array)</code>
 	 */
 	public static char[] removeFirst(char[] array) {
 		return removeElementAtIndex(array, 0);
 	}
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the first element removed.
-	 * <p>
-	 * <code>Arrays.removeFirst(int[] array)</code>
 	 */
 	public static int[] removeFirst(int[] array) {
 		return removeElementAtIndex(array, 0);
 	}
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the last element removed.
-	 * <p>
-	 * <code>Arrays.removeLast(Object[] array)</code>
 	 */
 	public static <E> E[] removeLast(E[] array) {
 		return removeElementAtIndex(array, array.length - 1);
 	}
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the last element removed.
-	 * <p>
-	 * <code>Arrays.removeLast(char[] array)</code>
 	 */
 	public static char[] removeLast(char[] array) {
 		return removeElementAtIndex(array, array.length - 1);
 	}
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the last element removed.
-	 * <p>
-	 * <code>Arrays.removeLast(int[] array)</code>
 	 */
 	public static int[] removeLast(int[] array) {
 		return removeElementAtIndex(array, array.length - 1);
@@ -1752,9 +1848,7 @@
 
 	/**
 	 * Remove from the specified array all the elements in
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays.removeAll(Object[] array, Iterable iterable)</code>
+	 * the specified iterable and return the result.
 	 */
 	public static <E> E[] removeAll(E[] array, Iterable<?> iterable) {
 		return removeAll(array, iterable.iterator());
@@ -1762,10 +1856,8 @@
 
 	/**
 	 * Remove from the specified array all the elements in
-	 * Returns the result.
+	 * the specified iterable and return the result.
 	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Arrays.removeAll(Object[] array, Iterable iterable)</code>
 	 */
 	public static <E> E[] removeAll(E[] array, Iterable<?> iterable, int iterableSize) {
 		return removeAll(array, iterable.iterator(), iterableSize);
@@ -1773,9 +1865,7 @@
 
 	/**
 	 * Remove from the specified array all the elements in
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays.removeAll(Object[] array, Iterator iterator)</code>
+	 * the specified iterator and return the result.
 	 */
 	public static <E> E[] removeAll(E[] array, Iterator<?> iterator) {
 		// convert to a set to take advantage of hashed look-up
@@ -1784,10 +1874,8 @@
 
 	/**
 	 * Remove from the specified array all the elements in
-	 * Returns the result.
+	 * the specified iterator and return the result.
 	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Arrays.removeAll(Object[] array, Iterator iterator)</code>
 	 */
 	public static <E> E[] removeAll(E[] array, Iterator<?> iterator, int iteratorSize) {
 		// convert to a set to take advantage of hashed look-up
@@ -1796,9 +1884,7 @@
 
 	/**
 	 * Remove from the specified array all the elements in
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays.removeAll(Object[] array, Collection collection)</code>
+	 * the specified collection and return the result.
 	 */
 	public static <E> E[] removeAll(E[] array, Collection<?> collection) {
 		return collection.isEmpty() ? array : removeAll_(array, collection);
@@ -1833,7 +1919,7 @@
 		if (j == arrayLength) {
 			return array;  // nothing was removed
 		}
-		E[] result = newArray(array, j);
+		E[] result = newInstance(array, j);
 		int resultLength = result.length;
 		for (int i = 0; i < resultLength; i++) {
 			result[i] = array[indices[i]];
@@ -1843,9 +1929,7 @@
 
 	/**
 	 * Remove from the first specified array all the elements in
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays.removeAll(Object[] array1, Object[] array2)</code>
+	 * the second specified array and return the result.
 	 */
 	public static <E> E[] removeAll(E[] array1, Object... array2) {
 		// convert to a set to take advantage of hashed look-up
@@ -1854,9 +1938,7 @@
 
 	/**
 	 * Remove from the first specified array all the elements in
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays#removeAll(char[] array1, char[] array2)</code>
+	 * the second specified array and return the result.
 	 */
 	public static char[] removeAll(char[] array1, char... array2) {
 		if (array2.length == 0) {
@@ -1886,9 +1968,7 @@
 
 	/**
 	 * Remove from the first specified array all the elements in
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays#removeAll(int[] array1, int[] array2)</code>
+	 * the second specified array and return the result.
 	 */
 	public static int[] removeAll(int[] array1, int... array2) {
 		if (array2.length == 0) {
@@ -1921,9 +2001,7 @@
 
 	/**
 	 * Remove from the specified array all occurrences of
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays.removeAllOccurrences(Object[] array, Object value)</code>
+	 * the specified element and return the result.
 	 */
 	public static <E> E[] removeAllOccurrences(E[] array, Object value) {
 		int arrayLength = array.length;
@@ -1948,7 +2026,7 @@
 		if (j == arrayLength) {
 			return array;  // nothing was removed
 		}
-		E[] result = newArray(array, j);
+		E[] result = newInstance(array, j);
 		int resultLength = result.length;
 		for (int i = 0; i < resultLength; i++) {
 			result[i] = array[indices[i]];
@@ -1958,9 +2036,7 @@
 
 	/**
 	 * Remove from the specified array all occurrences of
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays.removeAllOccurrences(char[] array, char value)</code>
+	 * the specified element and return the result.
 	 */
 	public static char[] removeAllOccurrences(char[] array, char value) {
 		int arrayLength = array.length;
@@ -1987,9 +2063,7 @@
 
 	/**
 	 * Remove from the specified array all occurrences of
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays.removeAllOccurrences(int[] array, int value)</code>
+	 * the specified element and return the result.
 	 */
 	public static int[] removeAllOccurrences(int[] array, int value) {
 		int arrayLength = array.length;
@@ -2026,40 +2100,41 @@
 		if ((len == 0) || (len == 1)) {
 			return array;
 		}
-		ArrayList<E> temp = CollectionTools.list(array);
-		return CollectionTools.removeDuplicateElements(temp, len) ?
-					temp.toArray(newArray(array, temp.size())) :
-					array;
+
+		LinkedHashSet<E> temp = new LinkedHashSet<E>(len);  // take advantage of hashed look-up
+		boolean modified = false;
+		for (E item : array) {
+			if ( ! temp.add(item)) {
+				modified = true;  // duplicate item
+			}
+		}
+		return modified ?
+				temp.toArray(newInstance(array, temp.size())) :
+				array;
 	}
 
 
 	// ********** remove element at index **********
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the specified element removed.
-	 * <p>
-	 * <code>Arrays.removeElementAtIndex(Object[] array, int index)</code>
 	 */
 	public static <E> E[] removeElementAtIndex(E[] array, int index) {
 		return removeElementsAtIndex(array, index, 1);
 	}
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the specified element removed.
-	 * <p>
-	 * <code>Arrays.removeElementAtIndex(char[] array, int index)</code>
 	 */
 	public static char[] removeElementAtIndex(char[] array, int index) {
 		return removeElementsAtIndex(array, index, 1);
 	}
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the specified element removed.
-	 * <p>
-	 * <code>Arrays.removeElementAtIndex(int[] array, int index)</code>
 	 */
 	public static int[] removeElementAtIndex(int[] array, int index) {
 		return removeElementsAtIndex(array, index, 1);
@@ -2069,10 +2144,8 @@
 	// ********** remove elements at index **********
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the specified elements removed.
-	 * <p>
-	 * <code>Arrays.removeElementsAtIndex(Object[] array, int index, int length)</code>
 	 */
 	public static <E> E[] removeElementsAtIndex(E[] array, int index, int length) {
 		if (length == 0) {
@@ -2080,7 +2153,7 @@
 		}
 		int arrayLength = array.length;
 		int newLength = arrayLength - length;
-		E[] result = newArray(array, newLength);
+		E[] result = newInstance(array, newLength);
 		if ((newLength == 0) && (index == 0)) {
 			return result;  // performance tweak
 		}
@@ -2095,10 +2168,8 @@
 	}
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the specified elements removed.
-	 * <p>
-	 * <code>Arrays.removeElementsAtIndex(char[] array, int index, int length)
 	 */
 	public static char[] removeElementsAtIndex(char[] array, int index, int length) {
 		if (length == 0) {
@@ -2107,7 +2178,7 @@
 		int arrayLength = array.length;
 		int newLength = arrayLength - length;
 		if ((newLength == 0) && (index == 0)) {
-			return EMPTY_CHAR_ARRAY;  // performance tweak
+			return CharArrayTools.EMPTY_CHAR_ARRAY;  // performance tweak
 		}
 		char[] result = new char[newLength];
 		if (index != 0) {
@@ -2121,10 +2192,8 @@
 	}
 
 	/**
-	 * Returns a new array that contains the elements in the
+	 * Return a new array that contains the elements in the
 	 * specified array with the specified elements removed.
-	 * <p>
-	 * <code>Arrays.removeElementsAtIndex(int[] array, int index, int length)
 	 */
 	public static int[] removeElementsAtIndex(int[] array, int index, int length) {
 		if (length == 0) {
@@ -2151,9 +2220,7 @@
 
 	/**
 	 * Replace all occurrences of the specified old value with
-	 * Returns the altered array.
-	 * <p>
-	 * <code>Arrays.replaceAll(Object[] array, Object oldValue, Object newValue)</code>
+	 * the specified new value. Return the altered array.
 	 */
 	public static <E> E[] replaceAll(E[] array, Object oldValue, E newValue) {
 		if (oldValue == null) {
@@ -2174,9 +2241,7 @@
 
 	/**
 	 * Replace all occurrences of the specified old value with
-	 * Returns the altered array.
-	 *<p>
-	 * <code> Arrays.replaceAll(int[] array, int oldValue, int newValue)</code>
+	 * the specified new value. Return the altered array.
 	 */
 	public static int[] replaceAll(int[] array, int oldValue, int newValue) {
 		for (int i = array.length; i-- > 0; ) {
@@ -2189,9 +2254,7 @@
 
 	/**
 	 * Replace all occurrences of the specified old value with
-	 * Returns the altered array.
-	 * <p>
-	 * <code>Arrays.replaceAll(char[] array, char oldValue, char newValue)</code>
+	 * the specified new value. Return the altered array.
 	 */
 	public static char[] replaceAll(char[] array, char oldValue, char newValue) {
 		for (int i = array.length; i-- > 0; ) {
@@ -2207,9 +2270,7 @@
 
 	/**
 	 * Retain in the specified array all the elements in
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays.retainAll(Object[] array, Iterable iterable)</code>
+	 * the specified iterable and return the result.
 	 */
 	public static <E> E[] retainAll(E[] array, Iterable<?> iterable) {
 		int arrayLength = array.length;
@@ -2218,10 +2279,8 @@
 
 	/**
 	 * Retain in the specified array all the elements in
-	 * Returns the result.
+	 * the specified iterable and return the result.
 	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Arrays.retainAll(Object[] array, Iterable iterable)</code>
 	 */
 	public static <E> E[] retainAll(E[] array, Iterable<?> iterable, int iterableSize) {
 		int arrayLength = array.length;
@@ -2230,9 +2289,7 @@
 
 	/**
 	 * Retain in the specified array all the elements in
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays.retainAll(Object[] array, Iterator iterator)</code>
+	 * the specified iterator and return the result.
 	 */
 	public static <E> E[] retainAll(E[] array, Iterator<?> iterator) {
 		int arrayLength = array.length;
@@ -2241,10 +2298,8 @@
 
 	/**
 	 * Retain in the specified array all the elements in
-	 * Returns the result.
+	 * the specified iterator and return the result.
 	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Arrays.retainAll(Object[] array, Iterator iterator)</code>
 	 */
 	public static <E> E[] retainAll(E[] array, Iterator<?> iterator, int iteratorSize) {
 		int arrayLength = array.length;
@@ -2257,7 +2312,7 @@
 	private static <E> E[] retainAll(E[] array, int arrayLength, Iterator<?> iterator) {
 		return iterator.hasNext() ?
 				retainAll_(array, CollectionTools.set(iterator), arrayLength) :
-				newArray(array, 0);
+				newInstance(array, 0);
 	}
 
 	/**
@@ -2266,14 +2321,12 @@
 	private static <E> E[] retainAll(E[] array, int arrayLength, Iterator<?> iterator, int iteratorSize) {
 		return iterator.hasNext() ?
 				retainAll_(array, CollectionTools.set(iterator, iteratorSize), arrayLength) :
-				newArray(array, 0);
+				newInstance(array, 0);
 	}
 
 	/**
 	 * Retain in the specified array all the elements in
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays.retainAll(Object[] array, Collection collection)</code>
+	 * the specified collection and return the result.
 	 */
 	public static <E> E[] retainAll(E[] array, Collection<?> collection) {
 		int arrayLength = array.length;
@@ -2285,7 +2338,7 @@
 	 */
 	private static <E> E[] retainAll(E[] array, Collection<?> collection, int arrayLength) {
 		return collection.isEmpty() ?
-				newArray(array, 0) :
+				newInstance(array, 0) :
 				retainAll_(array, collection, arrayLength);
 	}
 
@@ -2303,7 +2356,7 @@
 		if (j == arrayLength) {
 			return array;  // everything was retained
 		}
-		E[] result = newArray(array, j);
+		E[] result = newInstance(array, j);
 		int resultLength = result.length;
 		for (int i = 0; i < resultLength; i++) {
 			result[i] = array[indices[i]];
@@ -2313,24 +2366,20 @@
 
 	/**
 	 * Remove from the first specified array all the elements in
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays.retainAll(Object[] array1, Object[] array2)</code>
+	 * the second specified array and return the result.
 	 */
 	public static <E> E[] retainAll(E[] array1, Object[] array2) {
 		int array1Length = array1.length;
 		return (array1Length == 0) ?
 				array1 :
 				(array2.length == 0) ?
-					newArray(array1, 0) :
+					newInstance(array1, 0) :
 					retainAll(array1, CollectionTools.set(array2), array1Length);
 	}
 
 	/**
 	 * Remove from the first specified array all the elements in
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays.retainAll(char[] array1, char[] array2)</code>
+	 * the second specified array and return the result.
 	 */
 	public static char[] retainAll(char[] array1, char... array2) {
 		int array1Length = array1.length;
@@ -2342,7 +2391,7 @@
 	 */
 	private static char[] retainAll(char[] array1, char[] array2, int array1Length) {
 		int array2Length = array2.length;
-		return (array2Length == 0) ? EMPTY_CHAR_ARRAY : retainAll(array1, array2, array1Length, array2Length);
+		return (array2Length == 0) ? CharArrayTools.EMPTY_CHAR_ARRAY : retainAll(array1, array2, array1Length, array2Length);
 	}
 
 	/**
@@ -2369,9 +2418,7 @@
 
 	/**
 	 * Remove from the first specified array all the elements in
-	 * Returns the result.
-	 * <p>
-	 * <code>Arrays.retainAll(int[] array1, int[] array2)</code>
+	 * the second specified array and return the result.
 	 */
 	public static int[] retainAll(int[] array1, int... array2) {
 		int array1Length = array1.length;
@@ -2412,9 +2459,7 @@
 	// ********** reverse **********
 
 	/**
-	 * Returns the array, reversed.
-	 * <p>
-	 * <code>Arrays.reverse(Object... array)</code>
+	 * Return the array, reversed.
 	 */
 	public static <E> E[] reverse(E... array) {
 		int len = array.length;
@@ -2428,9 +2473,7 @@
 	}
 
 	/**
-	 * Returns the array, reversed.
-	 * <p>
-	 * <code>Arrays.reverse(char... array)</code>
+	 * Return the array, reversed.
 	 */
 	public static char[] reverse(char... array) {
 		int len = array.length;
@@ -2444,9 +2487,7 @@
 	}
 
 	/**
-	 * Returns the array, reversed.
-	 * <p>
-	 * <code>Arrays.reverse(int... array)</code>
+	 * Return the array, reversed.
 	 */
 	public static int[] reverse(int... array) {
 		int len = array.length;
@@ -2463,18 +2504,14 @@
 	// ********** rotate **********
 
 	/**
-	 * Returns the rotated array after rotating it one position.
-	 * <p>
-	 * <code>Arrays.rotate(Object[] array)</code>
+	 * Return the rotated array after rotating it one position.
 	 */
 	public static <E> E[] rotate(E... array) {
 		return rotate(array, 1);
 	}
 
 	/**
-	 * Returns the rotated array after rotating it the specified distance.
-	 * <p>
-	 * <code>Arrays.rotate(Object[] array, int distance)</code>
+	 * Return the rotated array after rotating it the specified distance.
 	 */
 	public static <E> E[] rotate(E[] array, int distance) {
 		int len = array.length;
@@ -2506,18 +2543,14 @@
 	}
 
 	/**
-	 * Returns the rotated array after rotating it one position.
-	 * <p>
-	 * <code>Arrays.rotate(char[] array)</code>
+	 * Return the rotated array after rotating it one position.
 	 */
 	public static char[] rotate(char... array) {
 		return rotate(array, 1);
 	}
 
 	/**
-	 * Returns the rotated array after rotating it the specified distance.
-	 * <p>
-	 * <code>Arrays.rotate(char[] array, int distance)</code>
+	 * Return the rotated array after rotating it the specified distance.
 	 */
 	public static char[] rotate(char[] array, int distance) {
 		int len = array.length;
@@ -2549,18 +2582,14 @@
 	}
 
 	/**
-	 * Returns the rotated array after rotating it one position.
-	 * <p>
-	 * <code>Arrays.rotate(int[] array)</code>
+	 * Return the rotated array after rotating it one position.
 	 */
 	public static int[] rotate(int... array) {
 		return rotate(array, 1);
 	}
 
 	/**
-	 * Returns the rotated array after rotating it the specified distance.
-	 * <p>
-	 * <code>Arrays.rotate(int[] array, int distance)</code>
+	 * Return the rotated array after rotating it the specified distance.
 	 */
 	public static int[] rotate(int[] array, int distance) {
 		int len = array.length;
@@ -2597,18 +2626,14 @@
 	private static final Random RANDOM = new Random();
 
 	/**
-	 * Returns the array after "shuffling" it.
-	 * <p>
-	 * <code>Arrays.shuffle(Object... array)</code>
+	 * Return the array after "shuffling" it.
 	 */
 	public static <E> E[] shuffle(E... array) {
 		return shuffle(array, RANDOM);
 	}
 
 	/**
-	 * Returns the array after "shuffling" it.
-	 * <p>
-	 * <code>Arrays.shuffle(Object[] array, Random r)</code>
+	 * Return the array after "shuffling" it.
 	 */
 	public static <E> E[] shuffle(E[] array, Random random) {
 		int len = array.length;
@@ -2622,18 +2647,14 @@
 	}
 
 	/**
-	 * Returns the array after "shuffling" it.
-	 * <p>
-	 * <code>Arrays.shuffle(char... array)</code>
+	 * Return the array after "shuffling" it.
 	 */
 	public static char[] shuffle(char... array) {
 		return shuffle(array, RANDOM);
 	}
 
 	/**
-	 * Returns the array after "shuffling" it.
-	 * <p>
-	 * <code>Arrays.shuffle(char[] array, Random r)</code>
+	 * Return the array after "shuffling" it.
 	 */
 	public static char[] shuffle(char[] array, Random random) {
 		int len = array.length;
@@ -2647,18 +2668,14 @@
 	}
 
 	/**
-	 * Returns the array after "shuffling" it.
-	 * <p>
-	 * <code>Arrays.shuffle(int... array)</code>
+	 * Return the array after "shuffling" it.
 	 */
 	public static int[] shuffle(int... array) {
 		return shuffle(array, RANDOM);
 	}
 
 	/**
-	 * Returns the array after "shuffling" it.
-	 * <p>
-	 * <code>Arrays.shuffle(int[] array, Random r)</code>
+	 * Return the array after "shuffling" it.
 	 */
 	public static int[] shuffle(int[] array, Random random) {
 		int len = array.length;
@@ -2675,14 +2692,20 @@
 	// ********** sub-array **********
 
 	/**
-	 * Returns a sub-array of the specified array with elements copied from
+	 * Return a sub-array of the specified array with elements copied from
+	 * the specified index to the end of the specified array.
+	 */
+	public static <E> E[] subArray(E[] array, int index) {
+		return subArray(array, index, array.length);
+	}
+
+	/**
+	 * Return a sub-array of the specified array with elements copied from
 	 * the specified range. The "from" index is inclusive; the "to" index is exclusive.
-	 * <p>
-	 * <code>Arrays.subArray(E[] array, int fromIndex, int toIndex)</code>
 	 */
 	public static <E> E[] subArray(E[] array, int fromIndex, int toIndex) {
 		int len = toIndex - fromIndex;
-		E[] result = newArray(array, len);
+		E[] result = newInstance(array, len);
 		if (len > 0) {
 			System.arraycopy(array, fromIndex, result, 0, len);
 		}
@@ -2690,36 +2713,48 @@
 	}
 
 	/**
-	 * Returns a sub-array of the specified array with elements copied from
+	 * Return a sub-array of the specified array with elements copied from
+	 * the specified index to the end of the specified array.
+	 */
+	public static int[] subArray(int[] array, int index) {
+		return subArray(array, index, array.length);
+	}
+
+	/**
+	 * Return a sub-array of the specified array with elements copied from
 	 * the specified range. The "from" index is inclusive; the "to" index is exclusive.
-	 * <p>
-	 * <code>Arrays.subArray(int[] array, int fromIndex, int toIndex)</code>
 	 */
 	public static int[] subArray(int[] array, int fromIndex, int toIndex) {
 		int len = toIndex - fromIndex;
-		if (len == 0) {
-			return EMPTY_INT_ARRAY;
-		}
-		int[] result = new int[len];
-		System.arraycopy(array, fromIndex, result, 0, len);
+		return (len == 0) ? EMPTY_INT_ARRAY : subArray_(array, fromIndex, len);
+	}
+
+	private static int[] subArray_(int[] array, int fromIndex, int length) {
+		int[] result = new int[length];
+		System.arraycopy(array, fromIndex, result, 0, length);
 		return result;
 	}
 
 	/**
-	 * Returns a sub-array of the specified array with elements copied from
+	 * Return a sub-array of the specified array with elements copied from
+	 * the specified index to the end of the specified array.
+	 */
+	public static char[] subArray(char[] array, int index) {
+		return subArray(array, index, array.length);
+	}
+
+	/**
+	 * Return a sub-array of the specified array with elements copied from
 	 * the specified range. The "from" index is inclusive; the "to" index is exclusive.
-	 * <p>
-	 * <code>
-	 * Arrays.subArray(char[] array, int fromIndex, int toIndex)</code>
-	 * </code>
 	 */
 	public static char[] subArray(char[] array, int fromIndex, int toIndex) {
 		int len = toIndex - fromIndex;
-		if (len == 0) {
-			return EMPTY_CHAR_ARRAY;
-		}
-		char[] result = new char[len];
-		System.arraycopy(array, fromIndex, result, 0, len);
+		return (len == 0) ? CharArrayTools.EMPTY_CHAR_ARRAY : subArray_(array, fromIndex, len);
+	}
+
+	static char[] subArray_(char[] array, int fromIndex, int length) {
+		char[] result = new char[length];
+		System.arraycopy(array, fromIndex, result, 0, length);
 		return result;
 	}
 
@@ -2727,9 +2762,7 @@
 	// ********** swap **********
 
 	/**
-	 * Returns the array after the specified elements have been "swapped".
-	 * <p>
-	 * <code>Arrays.swap(Object[] array, int i, int j)</code>
+	 * Return the array after the specified elements have been "swapped".
 	 */
 	public static <E> E[] swap(E[] array, int i, int j) {
 		return (i == j) ? array : swap_(array, i, j);
@@ -2746,9 +2779,7 @@
 	}
 
 	/**
-	 * Returns the array after the specified elements have been "swapped".
-	 * <p>
-	 * <code>Arrays.swap(char[] array, int i, int j)</code>
+	 * Return the array after the specified elements have been "swapped".
 	 */
 	public static char[] swap(char[] array, int i, int j) {
 		return (i == j) ? array : swap_(array, i, j);
@@ -2765,9 +2796,7 @@
 	}
 
 	/**
-	 * Returns the array after the specified elements have been "swapped".
-	 * <p>
-	 * <code>Arrays.swap(int[] array, int i, int j)</code>
+	 * Return the array after the specified elements have been "swapped".
 	 */
 	public static int[] swap(int[] array, int i, int j) {
 		return (i == j) ? array : swap_(array, i, j);
@@ -2784,10 +2813,138 @@
 	}
 
 
+	// ********** execute **********
+
+	/**
+	 * Execute the specified command for each element in the specified array.
+	 */
+	public static <E> void execute(E[] array, ParameterizedCommand<E> command) {
+		for (E e : array) {
+			command.execute(e);
+		}
+	}
+
+	/**
+	 * Execute the specified command for each element in the specified array.
+	 */
+	public static <E> void execute(E[] array, InterruptibleParameterizedCommand<E> command) throws InterruptedException {
+		for (E e : array) {
+			command.execute(e);
+		}
+	}
+
+
+	// ********** filter **********
+
+	/**
+	 * Return a new array with the filtered
+	 * elements of the specified array.
+	 */
+	public static <E> E[] filter(E[] array, Filter<E> filter) {
+		int length = array.length;
+		E[] result = newInstance(array, length);
+		int resultLength = 0;
+		for (int i = 0; i < length; i++) {
+			E e = array[i];
+			if (filter.accept(e)) {
+				result[resultLength++] = e;
+			}
+		}
+		return (resultLength < length) ? subArray(result, 0, resultLength) : result;
+	}
+
+
+	// ********** transform **********
+
+	/**
+	 * Return a new array with transformations of the
+	 * elements in the specified array.
+	 */
+	public static <E> Object[] transform(E[] array, Transformer<E, ?> transformer) {
+		return transform(array, transformer, OBJECT_CLASS);
+	}
+
+	/**
+	 * Return a new array with transformations of the
+	 * elements in the specified array.
+	 */
+	public static <E1, E2> E2[] transform(E1[] array, Transformer<E1, ? extends E2> transformer, Class<E2> componentType) {
+		int length = array.length;
+		E2[] result = newInstance(componentType, length);
+		for (int i = length; i-- > 0; ) {
+			result[i] = transformer.transform(array[i]);
+		}
+		return result;
+	}
+
+
 	// ********** Arrays enhancements **********
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * @see Arrays#equals(boolean[], boolean[])
+	 */
+	public static boolean notEquals(boolean[] array1, boolean[] array2) {
+		return ! Arrays.equals(array1, array2);
+	}
+
+	/**
+	 * @see Arrays#equals(byte[], byte[])
+	 */
+	public static boolean notEquals(byte[] array1, byte[] array2) {
+		return ! Arrays.equals(array1, array2);
+	}
+
+	/**
+	 * @see Arrays#equals(char[], char[])
+	 */
+	public static boolean notEquals(char[] array1, char[] array2) {
+		return ! Arrays.equals(array1, array2);
+	}
+
+	/**
+	 * @see Arrays#equals(double[], double[])
+	 */
+	public static boolean notEquals(double[] array1, double[] array2) {
+		return ! Arrays.equals(array1, array2);
+	}
+
+	/**
+	 * @see Arrays#equals(float[], float[])
+	 */
+	public static boolean notEquals(float[] array1, float[] array2) {
+		return ! Arrays.equals(array1, array2);
+	}
+
+	/**
+	 * @see Arrays#equals(int[], int[])
+	 */
+	public static boolean notEquals(int[] array1, int[] array2) {
+		return ! Arrays.equals(array1, array2);
+	}
+
+	/**
+	 * @see Arrays#equals(Object[], Object[])
+	 */
+	public static boolean notEquals(Object[] array1, Object[] array2) {
+		return ! Arrays.equals(array1, array2);
+	}
+
+	/**
+	 * @see Arrays#equals(long[], long[])
+	 */
+	public static boolean notEquals(long[] array1, long[] array2) {
+		return ! Arrays.equals(array1, array2);
+	}
+
+	/**
+	 * @see Arrays#equals(short[], short[])
+	 */
+	public static boolean notEquals(short[] array1, short[] array2) {
+		return ! Arrays.equals(array1, array2);
+	}
+
+	/**
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(boolean[], boolean)
 	 */
 	public static boolean[] fill(boolean[] array, boolean value) {
@@ -2796,7 +2953,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(boolean[], int, int, boolean)
 	 */
 	public static boolean[] fill(boolean[] array, int fromIndex, int toIndex, boolean value) {
@@ -2805,7 +2962,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(byte[], byte)
 	 */
 	public static byte[] fill(byte[] array, byte value) {
@@ -2814,7 +2971,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(byte[], int, int, byte)
 	 */
 	public static byte[] fill(byte[] array, int fromIndex, int toIndex, byte value) {
@@ -2823,7 +2980,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(char[], char)
 	 */
 	public static char[] fill(char[] array, char value) {
@@ -2832,7 +2989,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(char[], int, int, char)
 	 */
 	public static char[] fill(char[] array, int fromIndex, int toIndex, char value) {
@@ -2841,7 +2998,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(double[], double)
 	 */
 	public static double[] fill(double[] array, double value) {
@@ -2850,7 +3007,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(double[], int, int, double)
 	 */
 	public static double[] fill(double[] array, int fromIndex, int toIndex, double value) {
@@ -2859,7 +3016,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(float[], float)
 	 */
 	public static float[] fill(float[] array, float value) {
@@ -2868,7 +3025,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(float[], int, int, float)
 	 */
 	public static float[] fill(float[] array, int fromIndex, int toIndex, float value) {
@@ -2877,7 +3034,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(int[], int)
 	 */
 	public static int[] fill(int[] array, int value) {
@@ -2886,7 +3043,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(int[], int, int, int)
 	 */
 	public static int[] fill(int[] array, int fromIndex, int toIndex, int value) {
@@ -2895,7 +3052,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(Object[], Object)
 	 */
 	public static <E> E[] fill(E[] array, E value) {
@@ -2904,7 +3061,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(Object[], int, int, Object)
 	 */
 	public static <E> E[] fill(E[] array, int fromIndex, int toIndex, E value) {
@@ -2913,7 +3070,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(long[], long)
 	 */
 	public static long[] fill(long[] array, long value) {
@@ -2922,7 +3079,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(long[], int, int, long)
 	 */
 	public static long[] fill(long[] array, int fromIndex, int toIndex, long value) {
@@ -2931,7 +3088,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(short[], short)
 	 */
 	public static short[] fill(short[] array, short value) {
@@ -2940,7 +3097,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "filled".
+	 * Return the array after it has been "filled".
 	 * @see Arrays#fill(short[], int, int, short)
 	 */
 	public static short[] fill(short[] array, int fromIndex, int toIndex, short value) {
@@ -2949,7 +3106,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(byte[])
 	 */
 	public static byte[] sort(byte... array) {
@@ -2958,7 +3115,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(byte[], int, int)
 	 */
 	public static byte[] sort(byte[] array, int fromIndex, int toIndex) {
@@ -2967,7 +3124,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(char[])
 	 */
 	public static char[] sort(char... array) {
@@ -2976,7 +3133,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(char[], int, int)
 	 */
 	public static char[] sort(char[] array, int fromIndex, int toIndex) {
@@ -2985,7 +3142,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(double[])
 	 */
 	public static double[] sort(double... array) {
@@ -2994,7 +3151,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(double[], int, int)
 	 */
 	public static double[] sort(double[] array, int fromIndex, int toIndex) {
@@ -3003,7 +3160,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(float[])
 	 */
 	public static float[] sort(float... array) {
@@ -3012,7 +3169,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(float[], int, int)
 	 */
 	public static float[] sort(float[] array, int fromIndex, int toIndex) {
@@ -3021,7 +3178,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(int[])
 	 */
 	public static int[] sort(int... array) {
@@ -3030,7 +3187,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(int[], int, int)
 	 */
 	public static int[] sort(int[] array, int fromIndex, int toIndex) {
@@ -3039,7 +3196,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(Object[])
 	 */
 	public static <E> E[] sort(E... array) {
@@ -3048,7 +3205,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(Object[], Comparator)
 	 */
 	public static <E> E[] sort(E[] array, Comparator<? super E> comparator) {
@@ -3057,7 +3214,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(Object[], int, int)
 	 */
 	public static <E> E[] sort(E[] array, int fromIndex, int toIndex) {
@@ -3066,7 +3223,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(Object[], int, int, Comparator)
 	 */
 	public static <E> E[] sort(E[] array, int fromIndex, int toIndex, Comparator<? super E> comparator) {
@@ -3075,7 +3232,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(long[])
 	 */
 	public static long[] sort(long... array) {
@@ -3084,7 +3241,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(long[], int, int)
 	 */
 	public static long[] sort(long[] array, int fromIndex, int toIndex) {
@@ -3093,7 +3250,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(short[])
 	 */
 	public static short[] sort(short... array) {
@@ -3102,7 +3259,7 @@
 	}
 
 	/**
-	 * Returns the array after it has been "sorted".
+	 * Return the array after it has been "sorted".
 	 * @see Arrays#sort(short[], int, int)
 	 */
 	public static short[] sort(short[] array, int fromIndex, int toIndex) {
@@ -3110,6 +3267,78 @@
 		return array;
 	}
 
+	/**
+	 * Return whether the sorted array contains the specified value.
+	 * @see Arrays#binarySearch(byte[], byte)
+	 */
+	public static boolean binarySearch(byte[] array, byte value) {
+		return Arrays.binarySearch(array, value) >= 0;
+	}
+
+	/**
+	 * Return whether the sorted array contains the specified value.
+	 * @see Arrays#binarySearch(char[], char)
+	 */
+	public static boolean binarySearch(char[] array, char value) {
+		return Arrays.binarySearch(array, value) >= 0;
+	}
+
+	/**
+	 * Return whether the sorted array contains the specified value.
+	 * @see Arrays#binarySearch(double[], double)
+	 */
+	public static boolean binarySearch(double[] array, double value) {
+		return Arrays.binarySearch(array, value) >= 0;
+	}
+
+	/**
+	 * Return whether the sorted array contains the specified value.
+	 * @see Arrays#binarySearch(float[], float)
+	 */
+	public static boolean binarySearch(float[] array, float value) {
+		return Arrays.binarySearch(array, value) >= 0;
+	}
+
+	/**
+	 * Return whether the sorted array contains the specified value.
+	 * @see Arrays#binarySearch(int[], int)
+	 */
+	public static boolean binarySearch(int[] array, int value) {
+		return Arrays.binarySearch(array, value) >= 0;
+	}
+
+	/**
+	 * Return whether the sorted array contains the specified value.
+	 * @see Arrays#binarySearch(long[], long)
+	 */
+	public static boolean binarySearch(long[] array, long value) {
+		return Arrays.binarySearch(array, value) >= 0;
+	}
+
+	/**
+	 * Return whether the sorted array contains the specified value.
+	 * @see Arrays#binarySearch(Object[], Object)
+	 */
+	public static boolean binarySearch(Object[] array, Object value) {
+		return Arrays.binarySearch(array, value) >= 0;
+	}
+
+	/**
+	 * Return whether the sorted array contains the specified value.
+	 * @see Arrays#binarySearch(short[], short)
+	 */
+    public static <T> boolean binarySearch(T[] array, T value, Comparator<? super T> comparator) {
+		return Arrays.binarySearch(array, value, comparator) >= 0;
+	}
+
+	/**
+	 * Return whether the sorted array contains the specified value.
+	 * @see Arrays#binarySearch(short[], short)
+	 */
+	public static boolean binarySearch(short[] array, short value) {
+		return Arrays.binarySearch(array, value) >= 0;
+	}
+
 
 	// ********** constructor **********
 
@@ -3120,5 +3349,4 @@
 		super();
 		throw new UnsupportedOperationException();
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Association.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Association.java
index 67b04c8..f830bbb 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Association.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Association.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -16,33 +16,41 @@
 /**
  * Straightforward definition of an object pairing.
  * The key is immutable.
+ * <p>
+ * 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 Association<K, V> {
 
 	/**
-	 * Returns the association's key.
+	 * Return the association's key.
 	 */
 	K getKey();
 
 	/**
-	 * Returns the association's value.
+	 * Return the association's value.
 	 */
 	V getValue();
 
 	/**
 	 * Set the association's value.
-	 * Returns the previous value.
+	 * Return the previous value.
 	 */
 	V setValue(V value);
 
 	/**
-	 * Returns true if the associations' keys and values are equal.
+	 * Return true if the associations' keys and values
+	 * are equal.
 	 */
 	@Override
 	boolean equals(Object o);
 
 	/**
-	 * Returns a hash code based on the association's key and value.
+	 * Return a hash code based on the association's
+	 * key and value.
 	 */
 	@Override
 	int hashCode();
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Bag.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Bag.java
deleted file mode 100644
index 5ded535..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Bag.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-import java.util.AbstractCollection;
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.iterators.EmptyIterator;
-
-/**
- * A collection that allows duplicate elements.
- * <p>
- * The <code>Bag</code> interface places additional stipulations,
- * beyond those inherited from the {@link java.util.Collection} interface,
- * on the contracts of the {@link #equals(Object)} and {@link #hashCode()} methods.
- *
- * @see HashBag
- */
-public interface Bag<E> extends Collection<E> {
-
-	/**
-	 * Add the specified object the specified number of times to the bag.
-	 * Returns whether the bag changed.
-	 */
-	boolean add(E o, int count);
-
-	/**
-	 * Returns the number of times the specified object occurs in the bag.
-	 */
-	int count(Object o);
-
-	/**
-	 * Returns an iterator that returns an entry for each item in the bag
-	 * once and only once, irrespective of how many times
-	 * the item was added to the bag. The entry will indicate the item's
-	 * count.
-	 */
-	Iterator<Entry<E>> entries();
-
-	/**
-	 * Compares the specified object with this bag for equality. Returns
-	 * <code>true</code> if the specified object is also a bag, the two bags
-	 * have the same size, and every member of the specified bag is
-	 * contained in this bag with the same number of occurrences (or equivalently,
-	 * every member of this bag is contained in the specified bag with the same
-	 * number of occurrences). This definition ensures that the
-	 * equals method works properly across different implementations of the
-	 * bag interface.
-	 */
-	@Override
-	boolean equals(Object o);
-
-	/**
-	 * Returns the hash code value for this bag. The hash code of a bag is
-	 * defined to be the sum of the hash codes of the elements in the bag,
-	 * where the hashcode of a <code>null</code> element is defined to be zero.
-	 * This ensures that <code>b1.equals(b2)</code> implies that
-	 * <code>b1.hashCode() == b2.hashCode()</code> for any two bags
-	 * <code>b1</code> and <code>b2</code>, as required by the general
-	 * contract of the {@link Object#hashCode()} method.
-	 */
-	@Override
-	int hashCode();
-
-	/**
-	 * Remove the specified number of occurrences of the specified object
-	 * Returns whether the bag changed.
-	 */
-	boolean remove(Object o, int count);
-
-	/**
-	 * Returns the number of unique items in the bag.
-	 */
-	int uniqueCount();
-
-	/**
-	 * Returns an iterator that returns each item in the bag
-	 * once and only once, irrespective of how many times
-	 * the item was added to the bag.
-	 */
-	Iterator<E> uniqueIterator();
-
-	final class Empty<E> extends AbstractCollection<E> implements Bag<E>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final Bag INSTANCE = new Empty();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Empty() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <T> Bag<T> instance() {
-			return INSTANCE;
-		}
-		@Override
-		public boolean add(E o, int count) {
-			throw new UnsupportedOperationException();
-		}
-		@Override
-		public int count(Object o) {
-			return 0;
-		}
-		@Override
-		public Iterator<Bag.Entry<E>> entries() {
-			return EmptyIterator.instance();
-		}
-		@Override
-		public boolean equals(Object o) {
-			if (o == this) {
-				return true;
-			}
-			if ( ! (o instanceof Bag<?>)) {
-				return false;
-			}
-			return ((Bag<?>) o).size() == 0;
-		}
-		@Override
-		public int hashCode() {
-			return 0;
-		}
-		@Override
-		public Iterator<E> iterator() {
-			return EmptyIterator.instance();
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public boolean remove(Object o, int count) {
-			return false;
-		}
-		@Override
-		public int size() {
-			return 0;
-		}
-		@Override
-		public int uniqueCount() {
-			return 0;
-		}
-		@Override
-		public Iterator<E> uniqueIterator() {
-			return EmptyIterator.instance();
-		}
-	}
-
-	/**
-	 * A bag entry (element-count pair).
-	 * The {@link Bag#entries()} method returns an iterator whose
-	 * elements are of this class. The <em>only</em> way to obtain a reference
-	 * to a bag entry is from the iterator returned by this method. These
-	 * <code>Bag.Entry</code> objects are valid <em>only</em> for the duration
-	 * of the iteration; more formally, the behavior of a bag entry is
-	 * undefined if the backing bag has been modified after the entry was
-	 * returned by the iterator, except through the {@link #setCount(int)}
-	 * operation on the bag entry.
-	 */
-	interface Entry<E> {
-
-		/**
-		 * Returns whether the entry is equal to the specified object;
-		 * i.e. the specified object is a <code>Bag.Entry</code> and its
-		 * element and count are the same as the entry's.
-		 */
-		@Override
-		boolean equals(Object obj);
-
-		/**
-		 * Returns entry's count; i.e. the number of times the entry's element
-		 * occurs in the bag.
-		 * @see Bag#count(Object)
-		 */
-		int getCount();
-
-		/**
-		 * Returns the entry's element.
-		 */
-		E getElement();
-
-		/**
-		 * Returns the entry's hash code.
-		 */
-		@Override
-		int hashCode();
-
-		/**
-		 * Set the entry's count; i.e. the number of times the entry's element
-		 * occurs in the bag. The new count must be a positive number.
-		 * Returns the previous count of the entry's element.
-		 * NB: Use {@link Iterator#remove()} to set the
-		 * count to zero.
-		 */
-		int setCount(int count);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BidiFilter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BidiFilter.java
deleted file mode 100644
index c6d2866..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BidiFilter.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * Used by various "pluggable" classes to filter objects in both directions.
- *
- * If anyone can come up with a better class name
- * and/or method name, I would love to hear it.  ~bjv
- */
-public interface BidiFilter<T> extends Filter<T> {
-
-	/**
-	 * Returns whether the specified object is "accepted" by the "reverse" filter. What that means is
-	 * determined by the client.
-	 */
-	boolean reverseAccept(T object);
-
-	final class Disabled<S> implements BidiFilter<S>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final BidiFilter INSTANCE = new Disabled();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Disabled() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <R> BidiFilter<R> instance() {
-			return INSTANCE;
-		}
-		// throw an exception
-		@Override
-		public boolean accept(S o) {
-			throw new UnsupportedOperationException();
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		// throw an exception
-		@Override
-		public boolean reverseAccept(S o) {
-			throw new UnsupportedOperationException();
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-
-	final class Null<S> implements BidiFilter<S>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final BidiFilter INSTANCE = new Null();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Null() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <R> BidiFilter<R> instance() {
-			return INSTANCE;
-		}
-		// nothing is filtered - everything is accepted
-		@Override
-		public boolean accept(S o) {
-			return true;
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		// nothing is "reverse-filtered" - everything is accepted
-		@Override
-		public boolean reverseAccept(S o) {
-			return true;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-
-	final class Opaque<S> implements BidiFilter<S>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final BidiFilter INSTANCE = new Opaque();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Opaque() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <R> BidiFilter<R> instance() {
-			return INSTANCE;
-		}
-		// everything is filtered - nothing is accepted
-		@Override
-		public boolean accept(S o) {
-			return false;
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		// everything is "reverse-filtered" - nothing is accepted
-		@Override
-		public boolean reverseAccept(S o) {
-			return false;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BidiStringConverter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BidiStringConverter.java
deleted file mode 100644
index b85e6f9..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BidiStringConverter.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * Used by various "pluggable" classes to transform objects
- * into strings and vice versa.
- *
- * If anyone can come up with a better class name
- * and/or method name, I would love to hear it.  ~bjv
- */
-public interface BidiStringConverter<T> extends StringConverter<T> {
-
-	/**
-	 * Converts the specified string into an object. The semantics of "convert to object" is
-	 * determined by the contract between the client and the server. Typically, if the string is
-	 * <code>null</code>, <code>null</code> is returned.
-	 */
-	T convertToObject(String value);
-
-	final class BooleanConverter implements BidiStringConverter<Boolean>, Serializable {
-		public static final BidiStringConverter<Boolean> INSTANCE = new BooleanConverter();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private BooleanConverter() {
-			super();
-		}
-		public static BidiStringConverter<Boolean> instance() {
-			return INSTANCE;
-		}
-		/** * Returns Boolean.FALSE. */
-		@Override
-		public Boolean convertToObject(String s) {
-			return (s == null) ? null : Boolean.valueOf(s);
-		}
-		/** * Returns "false". */
-		@Override
-		public String convertToString(Boolean b) {
-			return (b == null) ? null : b.toString();
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-
-	final class Default<S> implements BidiStringConverter<S>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final BidiStringConverter INSTANCE = new Default();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Default() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <R> BidiStringConverter<R> instance() {
-			return INSTANCE;
-		}
-		// * Returns the string
-		@Override
-		@SuppressWarnings("unchecked")
-		public S convertToObject(String s) {
-			return (S) s;
-		}
-		// * Returns the object's #toString() result
-		@Override
-		public String convertToString(S o) {
-			return (o == null) ? null : o.toString();
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-
-	final class Disabled<S> implements BidiStringConverter<S>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final BidiStringConverter INSTANCE = new Disabled();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Disabled() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <R> BidiStringConverter<R> instance() {
-			return INSTANCE;
-		}
-		// throw an exception
-		@Override
-		public S convertToObject(String s) {
-			throw new UnsupportedOperationException();
-		}
-		// throw an exception
-		@Override
-		public String convertToString(S o) {
-			throw new UnsupportedOperationException();
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-
-	final class IntegerConverter implements BidiStringConverter<Integer>, Serializable {
-		public static final BidiStringConverter<Integer> INSTANCE = new IntegerConverter();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private IntegerConverter() {
-			super();
-		}
-		public static BidiStringConverter<Integer> instance() {
-			return INSTANCE;
-		}
-		/** Convert the string to an Integer, if possible. */
-		@Override
-		public Integer convertToObject(String s) {
-			return (s == null) ? null : Integer.valueOf(s);
-		}
-		/** Integer's #toString() works well. */
-		@Override
-		public String convertToString(Integer integer) {
-			return (integer == null) ? null : integer.toString();
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BidiTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BidiTransformer.java
deleted file mode 100644
index ddd22f7..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BidiTransformer.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * Used by various "pluggable" classes to transform objects in both directions.
- *
- * If anyone can come up with a better class name
- * and/or method name, I would love to hear it.  ~bjv
- */
-public interface BidiTransformer<T1, T2> extends Transformer<T1, T2> {
-
-	/**
-	 * Returns the "reverse-transformed" object. The semantics of "reverse-transform" is determined
-	 * by the contract between the client and the server.
-	 */
-	T2 reverseTransform(T1 object);
-
-	final class Disabled<S1, S2> implements BidiTransformer<S1, S2>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final BidiTransformer INSTANCE = new Disabled();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Disabled() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <R1, R2> BidiTransformer<R1, R2> instance() {
-			return INSTANCE;
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		// throw an exception
-		@Override
-		public S2 reverseTransform(S1 o) {
-			throw new UnsupportedOperationException();
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-		// throw an exception
-		@Override
-		public S1 transform(S2 o) {
-			throw new UnsupportedOperationException();
-		}
-	}
-
-	final class Null<S1, S2> implements BidiTransformer<S1, S2>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final BidiTransformer INSTANCE = new Null();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Null() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <R1, R2> BidiTransformer<R1, R2> instance() {
-			return INSTANCE;
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		// * Returns the object, unchanged
-		@Override
-		@SuppressWarnings("unchecked")
-		public S2 reverseTransform(S1 o) {
-			return (S2) o;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-		// * Returns the object, unchanged
-		@Override
-		@SuppressWarnings("unchecked")
-		public S1 transform(S2 o) {
-			return (S1) o;
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BitTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BitTools.java
index 3ac1257..87d25d4 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BitTools.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BitTools.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -14,93 +14,142 @@
 package org.eclipse.persistence.tools.utility;
 
 /**
- * Assorted bit tools
+ * Bit utility methods.
  */
 public final class BitTools {
 
 	/**
-	 * Returns whether the specified 'flags' has the specified
-	 * 'flagToCheck' set.
+	 * Return whether the specified flags have the specified
+	 * flag to check set.
+	 * @see #setFlag(int, int)
 	 */
 	public static boolean flagIsSet(int flags, int flagToCheck) {
 		return allFlagsAreSet(flags, flagToCheck);
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has the specified
-	 * 'flagToCheck' turned off.
+	 * Set the specified flag in the specified flags.
+	 * Return the new flags.
+	 * @see #flagIsSet(int, int)
+	 */
+	public static int setFlag(int flags, int flagToSet) {
+		return setAllFlags(flags, flagToSet);
+	}
+
+	/**
+	 * Return whether the specified flags have the specified
+	 * flag to check turned off.
+	 * @see #clearFlag(int, int)
 	 */
 	public static boolean flagIsOff(int flags, int flagToCheck) {
 		return allFlagsAreOff(flags, flagToCheck);
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has ONLY the specified
-	 * 'flagToCheck' set.
+	 * Clear the specified flag in the specified flags.
+	 * Return the new flags.
+	 * @see #flagIsOff(int, int)
+	 */
+	public static int clearFlag(int flags, int flagToClear) {
+		return clearAllFlags(flags, flagToClear);
+	}
+
+	/**
+	 * Return whether the specified flags have <em>only</em> the specified
+	 * flag to check set.
+	 * <p>
+	 * No setter method necessary; simply use the flag itself.
 	 */
 	public static boolean onlyFlagIsSet(int flags, int flagToCheck) {
 		return onlyFlagsAreSet(flags, flagToCheck);
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has ONLY the specified
-	 * 'flagToCheck' turned off.
+	 * Return whether the specified flags have <em>only</em> the specified
+	 * flag to check turned off.
+	 * <p>
+	 * No setter method necessary; simply use the flag itself, flipped.
 	 */
 	public static boolean onlyFlagIsOff(int flags, int flagToCheck) {
 		return onlyFlagsAreOff(flags, flagToCheck);
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has all the specified
-	 * 'flagsToCheck' set.
+	 * Return whether the specified flags have all the specified
+	 * flags to check set.
+	 * @see #setAllFlags(int, int)
 	 */
 	public static boolean allFlagsAreSet(int flags, int flagsToCheck) {
 		return (flags & flagsToCheck) == flagsToCheck;
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has all the specified
-	 * 'flagsToCheck' turned off.
+	 * Set the specified flags in the specified flags.
+	 * Return the new flags.
+	 * @see #allFlagsAreSet(int, int)
+	 */
+	public static int setAllFlags(int flags, int flagsToSet) {
+		return flags |= flagsToSet;
+	}
+
+	/**
+	 * Return whether the specified flags have all the specified
+	 * flags to check turned off.
+	 * @see #clearAllFlags(int, int)
 	 */
 	public static boolean allFlagsAreOff(int flags, int flagsToCheck) {
 		return (flags & flagsToCheck) == 0;
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has ONLY the specified
-	 * 'flagsToCheck' set.
+	 * Clear the specified flags in the specified flags.
+	 * Return the new flags.
+	 * @see #allFlagsAreOff(int, int)
+	 */
+	public static int clearAllFlags(int flags, int flagsToClear) {
+		return flags &= ~flagsToClear;
+	}
+
+	/**
+	 * Return whether the specified flags have <em>only</em> the specified
+	 * flags to check set.
+	 * <p>
+	 * No setter method necessary; simply use the flags themselves.
 	 */
 	public static boolean onlyFlagsAreSet(int flags, int flagsToCheck) {
 		return allFlagsAreSet(flags, flagsToCheck) && allFlagsAreOff(flags, ~flagsToCheck);
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has ONLY the specified
-	 * 'flagsToCheck' turned off.
+	 * Return whether the specified flags have <em>only</em> the specified
+	 * flags to check turned off.
+	 * <p>
+	 * No setter method necessary; simply use the flags themselves, flippped.
 	 */
 	public static boolean onlyFlagsAreOff(int flags, int flagsToCheck) {
 		return allFlagsAreOff(flags, flagsToCheck) && allFlagsAreSet(flags, ~flagsToCheck);
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has any one of the specified
-	 * 'flagsToCheck' set.
+	 * Return whether the specified flags have any one of the specified
+	 * flags to check set.
 	 */
 	public static boolean anyFlagsAreSet(int flags, int flagsToCheck) {
 		return (flags & flagsToCheck) != 0;
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has any one of the specified
-	 * 'flagsToCheck' turned off.
+	 * Return whether the specified flags have any one of the specified
+	 * flags to check turned off.
 	 */
 	public static boolean anyFlagsAreOff(int flags, int flagsToCheck) {
 		return (flags & flagsToCheck) != flagsToCheck;
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has all the specified
-	 * 'flagsToCheck' set.
+	 * Return whether the specified flags have all the specified
+	 * flags to check set.
+	 * @see #setAllFlags(int, int...)
 	 */
 	public static boolean allFlagsAreSet(int flags, int... flagsToCheck) {
 		for (int i = flagsToCheck.length; i-- > 0; ) {
@@ -112,8 +161,21 @@
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has all the specified
-	 * 'flagsToCheck' turned off.
+	 * Set the specified flags in the specified flags.
+	 * Return the new flags.
+	 * @see #allFlagsAreSet(int, int...)
+	 */
+	public static int setAllFlags(int flags, int... flagsToSet) {
+		for (int i = flagsToSet.length; i-- > 0; ) {
+			flags |= flagsToSet[i];
+		}
+		return flags;
+	}
+
+	/**
+	 * Return whether the specified flags have all the specified
+	 * flags to check turned off.
+	 * @see #clearAllFlags(int, int...)
 	 */
 	public static boolean allFlagsAreOff(int flags, int... flagsToCheck) {
 		for (int i = flagsToCheck.length; i-- > 0; ) {
@@ -125,8 +187,23 @@
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has ONLY the specified
-	 * 'flagsToCheck' set.
+	 * Clear the specified flags in the specified flags.
+	 * Return the new flags.
+	 * @see #allFlagsAreOff(int, int...)
+	 */
+	public static int clearAllFlags(int flags, int... flagsToClear) {
+		int combinedFlags = 0;
+		for (int i = flagsToClear.length; i-- > 0; ) {
+			combinedFlags |= flagsToClear[i];
+		}
+		return clearAllFlags(flags, combinedFlags);
+	}
+
+	/**
+	 * Return whether the specified flags have <em>only</em> the specified
+	 * flags to check set.
+	 * <p>
+	 * No setter method necessary; simply use the ORed flags themselves.
 	 */
 	public static boolean onlyFlagsAreSet(int flags, int... flagsToCheck) {
 		int combinedFlags = orFlags(flagsToCheck);
@@ -134,8 +211,10 @@
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has ONLY the specified
-	 * 'flagsToCheck' turned off.
+	 * Return whether the specified flags have <em>only</em> the specified
+	 * flags to check turned off.
+	 * <p>
+	 * No setter method necessary; simply use the ORed flags themselves, flipped.
 	 */
 	public static boolean onlyFlagsAreOff(int flags, int... flagsToCheck) {
 		int combinedFlags = orFlags(flagsToCheck);
@@ -143,8 +222,8 @@
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has any one of the specified
-	 * 'flagsToCheck' set.
+	 * Return whether the specified flags have any one of the specified
+	 * flags to check set.
 	 */
 	public static boolean anyFlagsAreSet(int flags, int... flagsToCheck) {
 		for (int i = flagsToCheck.length; i-- > 0; ) {
@@ -156,8 +235,8 @@
 	}
 
 	/**
-	 * Returns whether the specified 'flags' has any one of the specified
-	 * 'flagsToCheck' turned off.
+	 * Return whether the specified flags have any one of the specified
+	 * flags to check turned off.
 	 */
 	public static boolean anyFlagsAreOff(int flags, int... flagsToCheck) {
 		for (int i = flagsToCheck.length; i-- > 0; ) {
@@ -169,7 +248,7 @@
 	}
 
 	/**
-	 * Returns the result.
+	 * OR all the specified flags together and return the result.
 	 */
 	public static int orFlags(int... flags) {
 		int last = flags.length - 1;
@@ -181,7 +260,7 @@
 	}
 
 	/**
-	 * Returns the result.
+	 * AND all the specified flags together and return the result.
 	 */
 	public static int andFlags(int... flags) {
 		int last = flags.length - 1;
@@ -193,7 +272,9 @@
 	}
 
 	/**
-	 * Returns the result.
+	 * XOR all the specified flags together and return the result.
+	 * <p>
+	 * <strong>NB:</strong> The order of the flags is significant.
 	 */
 	public static int xorFlags(int... flags) {
 		int last = flags.length - 1;
@@ -204,6 +285,40 @@
 		return result;
 	}
 
+	/**
+	 * Return whether the specified integer is even.
+	 * @see #isOdd(int)
+	 */
+	public static boolean isEven(int i) {
+		return (i & 1) == 0;
+	}
+
+	/**
+	 * Return whether the specified integer is odd.
+	 * @see #isEven(int)
+	 */
+	public static boolean isOdd(int i) {
+		return (i & 1) == 1;
+	}
+
+	/**
+	 * Return half the specified integer, rounding to negative infinity
+	 * (i.e. <code>half(7) ==> 3</code> and <code>half(-7) ==> -4</code>).
+	 * @see #twice(int)
+	 */
+	public static int half(int i) {
+		return i >> 1;
+	}
+
+	/**
+	 * Return twice the specified integer
+	 * (i.e. <code>twice(7) ==> 14</code> and <code>twice(-7) ==> -14</code>).
+	 * @see #half(int)
+	 */
+	public static int twice(int i) {
+		return i << 1;
+	}
+
 
 	// ********** constructor **********
 
@@ -214,5 +329,4 @@
 		super();
 		throw new UnsupportedOperationException();
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BooleanReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BooleanReference.java
deleted file mode 100644
index 3b44359..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BooleanReference.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * Interface for a container for holding a <code>boolean</code> that cannot be changed by clients.
- * <p>
- * 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.
- *
- * @version 2.5
- */
-@SuppressWarnings("nls")
-public interface BooleanReference {
-
-	/**
-	 * Returns the current <code>boolean</code> value.
-	 */
-	boolean getValue();
-
-	/**
-	 * Returns whether the current <code>boolean</code> value is equal to the
-	 * specified value.
-	 */
-	boolean is(boolean value);
-
-	/**
-	 * Returns whether the current <code>boolean</code> value is not equal to
-	 * the specified value.
-	 */
-	boolean isNot(boolean value);
-
-	/**
-	 * Returns whether the current <code>boolean</code> value is
-	 * <code>true</code>.
-	 */
-	boolean isTrue();
-
-	/**
-	 * Returns whether the current <code>boolean</code> value is
-	 * <code>false</code>.
-	 */
-	boolean isFalse();
-
-	/**
-	 * Convenience method.
-	 */
-	final class Value {
-		public static BooleanReference of(boolean value) {
-			return value ? True.instance() : False.instance();
-		}
-	}
-
-
-	/**
-	 * Singleton implementation of the read-only boolean reference interface
-	 * whose value is always <code>true</code>.
-	 */
-	final class True
-		implements BooleanReference, Serializable
-	{
-		public static final BooleanReference INSTANCE = new True();
-
-		public static BooleanReference instance() {
-			return INSTANCE;
-		}
-
-		// ensure single instance
-		private True() {
-			super();
-		}
-
-		@Override
-		public boolean getValue() {
-			return true;
-		}
-
-		@Override
-		public boolean is(boolean value) {
-			return value;
-		}
-
-		@Override
-		public boolean isNot(boolean value) {
-			return ! value;
-		}
-
-		@Override
-		public boolean isTrue() {
-			return true;
-		}
-
-		@Override
-		public boolean isFalse() {
-			return false;
-		}
-
-		@Override
-		public String toString() {
-			return "[true]";
-		}
-
-		private static final long serialVersionUID = 1L;
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-	}
-
-
-	/**
-	 * Singleton implementation of the read-only boolean reference interface
-	 * whose value is always <code>false</code>.
-	 */
-	final class False
-		implements BooleanReference, Serializable
-	{
-		public static final BooleanReference INSTANCE = new False();
-
-		public static BooleanReference instance() {
-			return INSTANCE;
-		}
-
-		// ensure single instance
-		private False() {
-			super();
-		}
-
-		@Override
-		public boolean getValue() {
-			return false;
-		}
-
-		@Override
-		public boolean is(boolean value) {
-			return ! value;
-		}
-
-		@Override
-		public boolean isNot(boolean value) {
-			return value;
-		}
-
-		@Override
-		public boolean isTrue() {
-			return false;
-		}
-
-		@Override
-		public boolean isFalse() {
-			return false;
-		}
-
-		@Override
-		public String toString() {
-			return "[false]";
-		}
-
-		private static final long serialVersionUID = 1L;
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BooleanTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BooleanTools.java
index d287bf3..0615009 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BooleanTools.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/BooleanTools.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -14,14 +14,13 @@
 package org.eclipse.persistence.tools.utility;
 
 /**
- * Assorted "Capital-B Boolean" operations.
+ * "Capital-B {@link Boolean}" utility methods.
  */
  // commented code is just playing around with building *everything* from NAND
 public final class BooleanTools {
 
 	/**
-	 * Returns the NOT of the specified Boolean.
-	 * Boolean#not()
+	 * Return the NOT of the specified boolean.
 	 */
 	public static Boolean not(Boolean b) {
 		return Boolean.valueOf( ! b.booleanValue());
@@ -29,8 +28,7 @@
 	}
 
 	/**
-	 * Returns the AND of the specified Booleans.
-	 * Boolean#and(Boolean)
+	 * Return the AND of the specified booleans.
 	 */
 	public static Boolean and(Boolean b1, Boolean b2) {
 		return Boolean.valueOf(b1.booleanValue() && b2.booleanValue());
@@ -39,8 +37,7 @@
 	}
 
 	/**
-	 * Returns the OR of the specified Booleans.
-	 * Boolean#or(Boolean)
+	 * Return the OR of the specified booleans.
 	 */
 	public static Boolean or(Boolean b1, Boolean b2) {
 		return Boolean.valueOf(b1.booleanValue() || b2.booleanValue());
@@ -52,8 +49,7 @@
 	}
 
 	/**
-	 * Returns the XOR of the specified Booleans.
-	 * Boolean#xor(Boolean)
+	 * Return the XOR of the specified booleans.
 	 */
 	public static Boolean xor(Boolean b1, Boolean b2) {
 		return and(or(b1, b2), nand(b1, b2));
@@ -62,8 +58,7 @@
 	}
 
 	/**
-	 * Returns the NAND of the specified Booleans.
-	 * Boolean#nand(Boolean)
+	 * Return the NAND of the specified booleans.
 	 */
 	public static Boolean nand(Boolean b1, Boolean b2) {
 		return not(and(b1, b2));
@@ -71,8 +66,7 @@
 	}
 
 	/**
-	 * Returns the NOR of the specified Booleans.
-	 * Boolean#nor(Boolean)
+	 * Return the NOR of the specified booleans.
 	 */
 	public static Boolean nor(Boolean b1, Boolean b2) {
 		return not(or(b1, b2));
@@ -85,8 +79,7 @@
 	}
 
 	/**
-	 * Returns the XNOR of the specified Booleans.
-	 * Boolean#xnor(Boolean)
+	 * Return the XNOR of the specified booleans.
 	 */
 	public static Boolean xnor(Boolean b1, Boolean b2) {
 		return not(xor(b1, b2));
@@ -105,5 +98,4 @@
 		super();
 		throw new UnsupportedOperationException();
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ByteArrayTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ByteArrayTools.java
new file mode 100644
index 0000000..ccbab0c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ByteArrayTools.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+public final class ByteArrayTools {
+
+	public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+
+
+	/**
+	 * Convert the specified byte array to the corresponding string of
+	 * hexadecimal characters.
+	 * @see StringTools#convertHexStringToByteArray(String)
+	 */
+	public static String convertToHexString(byte[] bytes) {
+		int bytesLength = bytes.length;
+		return (bytesLength == 0) ? StringTools.EMPTY_STRING : convertToHexString(bytes, bytesLength);
+	}
+
+	/**
+	 * Pre-condition: the byte array is not empty
+	 */
+	private static String convertToHexString(byte[] bytes, int bytesLength) {
+		return new String(convertToHexCharArray(bytes, bytesLength));
+	}
+
+	/**
+	 * Convert the specified byte array to the corresponding string of
+	 * hexadecimal characters.
+	 * @see CharArrayTools#convertHexStringToByteArray(char[])
+	 */
+	public static char[] convertToHexCharArray(byte[] bytes) {
+		int bytesLength = bytes.length;
+		return (bytesLength == 0) ? CharArrayTools.EMPTY_CHAR_ARRAY : convertToHexCharArray(bytes, bytesLength);
+	}
+
+	/**
+	 * Pre-condition: the byte array is not empty
+	 */
+	private static char[] convertToHexCharArray(byte[] bytes, int bytesLength) {
+		int stringLength = bytesLength << 1;
+		char[] digits = CharacterTools.DIGITS;
+		char[] string = new char[stringLength];
+		for (int bi = bytesLength - 1, si = stringLength - 2; bi >= 0; bi--, si -= 2) {
+			int b = bytes[bi] & 0xFF; // clear any sign bits
+			string[si] = digits[b >> 4]; // first nibble
+			string[si + 1] = digits[b & 0xF]; // second nibble
+		}
+		return string;
+	}
+
+
+	// ********** constructor **********
+
+	/*
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private ByteArrayTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CancelException.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CancelException.java
new file mode 100644
index 0000000..11e8179
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CancelException.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+/**
+ * This exception can be used to interrupt a process (such as in a UI dialog process).
+ */
+public class CancelException extends RuntimeException {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Creates a new <code>CancelException</code>.
+	 */
+	public CancelException() {
+		super();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CharArrayTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CharArrayTools.java
new file mode 100644
index 0000000..75f0588
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CharArrayTools.java
@@ -0,0 +1,1282 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+import org.eclipse.persistence.tools.utility.transformer.TransformerAdapter;
+
+/**
+ * <code>char[]</code> string-related utility methods.
+ *
+ * @see StringTools
+ * @see org.eclipse.jpt.common.utility.internal.io.WriterTools
+ * @see StringBuilderTools
+ * @see StringBufferTools
+ * @see ArrayTools
+ */
+@SuppressWarnings("nls")
+public final class CharArrayTools {
+
+	/** carriage return */
+	public static final char[] CR = StringTools.CR.toCharArray();
+
+	/** empty char array */
+	public static final char[] EMPTY_CHAR_ARRAY = new char[0];
+
+	/** empty char array array */
+	public static final char[][] EMPTY_CHAR_ARRAY_ARRAY = new char[0][0];
+
+
+	// ********** last **********
+
+	/**
+	 * Return the last character of the specified string.
+	 */
+	public static char last(char[] string) {
+		return string[string.length - 1];
+	}
+
+
+	// ********** concatenation **********
+
+	/**
+	 * Return a concatenation of the specified strings.
+	 */
+	public static String concatenate(char[]... strings) {
+		int stringLength = 0;
+		for (char[] string : strings) {
+			stringLength += string.length;
+		}
+		StringBuilder sb = new StringBuilder(stringLength);
+		for (char[] string : strings) {
+			sb.append(string);
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Return a concatenation of the specified strings.
+	 */
+	public static String concatenate(Iterable<char[]> strings) {
+		return concatenate(strings.iterator());
+	}
+
+	/**
+	 * Return a concatenation of the specified strings.
+	 */
+	public static String concatenate(Iterator<char[]> strings) {
+		StringBuilder sb = new StringBuilder();
+		while (strings.hasNext()) {
+			sb.append(strings.next());
+		}
+		return sb.toString();
+	}
+
+
+	// ********** padding/truncating/centering **********
+
+	/**
+	 * @see StringTools#center(String, int)
+	 */
+	public static char[] center(char[] string, int length) {
+		return center(string, length, ' ');
+	}
+
+	/**
+	 * @see StringTools#center(String, int, char)
+	 */
+	public static char[] center(char[] string, int length, char c) {
+		if (length == 0) {
+			return EMPTY_CHAR_ARRAY;
+		}
+		int stringLength = string.length;
+		if (stringLength == length) {
+			return string;
+		}
+		if (stringLength > length) {
+			return ArrayTools.subArray_(string, ((stringLength - length) >> 1), length); // take fewer characters off the front
+		}
+		// stringLength < length
+		char[] result = new char[length];
+		int begin = (length - stringLength) >> 1; // add fewer characters to the front
+		Arrays.fill(result, 0, begin, c);
+		System.arraycopy(string, 0, result, begin, stringLength);
+		Arrays.fill(result, begin + stringLength, length, c);
+		return result;
+	}
+
+	/**
+	 * @see StringTools#pad(String, int)
+	 */
+	public static char[] pad(char[] string, int length) {
+		return pad(string, length, ' ');
+	}
+
+	/**
+	 * @see StringTools#pad(String, int, char)
+	 */
+	public static char[] pad(char[] string, int length, char c) {
+		int stringLength = string.length;
+		if (stringLength > length) {
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
+		}
+		if (stringLength == length) {
+			return string;
+		}
+		return pad(string, length, c, stringLength);
+	}
+
+	/**
+	 * @see StringTools#fit(String, int)
+	 */
+	public static char[] fit(char[] string, int length) {
+		return fit(string, length, ' ');
+	}
+
+	/**
+	 * @see StringTools#fit(String, int, char)
+	 */
+	public static char[] fit(char[] string, int length, char c) {
+		if (length == 0) {
+			return EMPTY_CHAR_ARRAY;
+		}
+		int stringLength = string.length;
+		if (stringLength == length) {
+			return string;
+		}
+		if (stringLength > length) {
+			return ArrayTools.subArray_(string, 0, length);
+		}
+		return pad(string, length, c, stringLength);
+	}
+
+	/**
+	 * no length checks
+	 */
+	private static char[] pad(char[] string, int length, char c, int stringLength) {
+		char[] result = new char[length];
+		System.arraycopy(string, 0, result, 0, stringLength);
+		Arrays.fill(result, stringLength, length, c);
+		return result;
+	}
+
+	/**
+	 * @see StringTools#zeroPad(String, int)
+	 */
+	public static char[] zeroPad(char[] string, int length) {
+		return frontPad(string, length, '0');
+	}
+
+	/**
+	 * @see StringTools#frontPad(String, int, char)
+	 */
+	public static char[] frontPad(char[] string, int length, char c) {
+		int stringLength = string.length;
+		if (stringLength > length) {
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
+		}
+		if (stringLength == length) {
+			return string;
+		}
+		return frontPad(string, length, c, stringLength);
+	}
+
+	/**
+	 * @see StringTools#zeroFit(String, int)
+	 */
+	public static char[] zeroFit(char[] string, int length) {
+		return frontFit(string, length, '0');
+	}
+
+	/**
+	 * @see StringTools#frontFit(String, int, char)
+	 */
+	public static char[] frontFit(char[] string, int length, char c) {
+		if (length == 0) {
+			return EMPTY_CHAR_ARRAY;
+		}
+		int stringLength = string.length;
+		if (stringLength == length) {
+			return string;
+		}
+		if (stringLength > length) {
+			return ArrayTools.subArray_(string, stringLength - length, length);
+		}
+		return frontPad(string, length, c, stringLength);
+	}
+
+	/**
+	 * no length checks
+	 */
+	private static char[] frontPad(char[] string, int length, char c, int stringLength) {
+		char[] result = new char[length];
+		int padLength = length - stringLength;
+		System.arraycopy(string, 0, result, padLength, stringLength);
+		Arrays.fill(result, 0, padLength, c);
+		return result;
+	}
+
+
+	// ********** separating **********
+
+	/**
+	 * @see StringTools#separate(String, char, int)
+	 */
+	public static char[] separate(char[] string, char separator, int segmentSize) {
+		if (segmentSize <= 0) {
+			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
+		}
+		int stringLength = string.length;
+		return (stringLength <= segmentSize) ? string : separate(string, separator, segmentSize, stringLength);
+	}
+
+	/**
+	 * Pre-conditions: string is longer than segment size; segment size is positive
+	 */
+	private static char[] separate(char[] string, char separator, int segmentSize, int stringLength) {
+		int resultLen = stringLength + (stringLength / segmentSize);
+		if ((stringLength % segmentSize) == 0) {
+			resultLen--;  // no separator after the final segment if nothing following it
+		}
+		char[] result = new char[resultLen];
+		int j = 0;
+		int segCount = 0;
+		for (int i = 0; i < stringLength; i++) {
+			char c = string[i];
+			if (segCount == segmentSize) {
+				result[j++] = separator;
+				segCount = 0;
+			}
+			segCount++;
+			result[j++] = c;
+		}
+		return result;
+	}
+
+
+	// ********** delimiting/quoting **********
+
+	/**
+	 * @see StringTools#quote(String)
+	 */
+	public static char[] quote(char[] string) {
+		return delimit(string, CharacterTools.QUOTE);
+	}
+
+	/**
+	 * @see StringTools#delimit(String, char)
+	 */
+	public static char[] delimit(char[] string, char delimiter) {
+		int stringLength = string.length;
+		StringBuilder sb = new StringBuilder(stringLength + 2);
+		StringBuilderTools.delimit(sb, string, delimiter, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see #delimit(char[], char)
+	 */
+	public static class CharDelimiter
+		extends TransformerAdapter<char[], char[]>
+	{
+		private final char delimiter;
+		public CharDelimiter(char delimiter) {
+			super();
+			this.delimiter = delimiter;
+		}
+		@Override
+		public char[] transform(char[] string) {
+			return delimit(string, this.delimiter);
+		}
+	}
+
+	/**
+	 * @see StringTools#delimit(String, String)
+	 */
+	public static char[] delimit(char[] string, char[] delimiter) {
+		return delimit(string, delimiter, delimiter.length);
+	}
+
+	/* CU private */ static char[] delimit(char[] string, char[] delimiter, int delimiterLength) {
+		switch (delimiterLength) {
+			case 0:
+				return string;
+			case 1:
+				return delimit(string, delimiter[0]);
+			default:
+				return delimit_(string, delimiter, delimiterLength);
+		}
+	}
+
+	/**
+	 * No parm check
+	 */
+	private static char[] delimit_(char[] string, char[] delimiter, int delimiterLength) {
+		int stringLength = string.length;
+		char[] result = new char[stringLength+(2*delimiterLength)];
+		System.arraycopy(delimiter, 0, result, 0, delimiterLength);
+		System.arraycopy(string, 0, result, delimiterLength, stringLength);
+		System.arraycopy(delimiter, 0, result, stringLength+delimiterLength, delimiterLength);
+		return result;
+	}
+
+	/**
+	 * @see #delimit(char[], char[])
+	 */
+	public static class CharArrayDelimiter
+		extends TransformerAdapter<char[], char[]>
+	{
+		private final char[] delimiter;
+		private final int delimiterLength;
+		public CharArrayDelimiter(char[] delimiter) {
+			super();
+			this.delimiter = delimiter;
+			this.delimiterLength = delimiter.length;
+		}
+		@Override
+		public char[] transform(char[] string) {
+			return delimit(string, this.delimiter, this.delimiterLength);
+		}
+	}
+
+
+	// ********** delimiting queries **********
+
+	/**
+	 * @see StringTools#isQuoted(String)
+	 */
+	public static boolean isQuoted(char[] string) {
+		return isDelimited(string, CharacterTools.QUOTE);
+	}
+
+	/**
+	 * @see StringTools#isParenthetical(String)
+	 */
+	public static boolean isParenthetical(char[] string) {
+		return isDelimited(string, CharacterTools.OPEN_PARENTHESIS, CharacterTools.CLOSE_PARENTHESIS);
+	}
+
+	/**
+	 * @see StringTools#isBracketed(String)
+	 */
+	public static boolean isBracketed(char[] string) {
+		return isDelimited(string, CharacterTools.OPEN_BRACKET, CharacterTools.CLOSE_BRACKET);
+	}
+
+	/**
+	 * @see StringTools#isBraced(String)
+	 */
+	public static boolean isBraced(char[] string) {
+		return isDelimited(string, CharacterTools.OPEN_BRACE, CharacterTools.CLOSE_BRACE);
+	}
+
+	/**
+	 * @see StringTools#isChevroned(String)
+	 */
+	public static boolean isChevroned(char[] string) {
+		return isDelimited(string, CharacterTools.OPEN_CHEVRON, CharacterTools.CLOSE_CHEVRON);
+	}
+
+	/**
+	 * @see StringTools#isDelimited(String, char)
+	 */
+	public static boolean isDelimited(char[] string, char c) {
+		return isDelimited(string, c, c);
+	}
+
+	/**
+	 * @see StringTools#isDelimited(String, char, char)
+	 */
+	public static boolean isDelimited(char[] string, char start, char end) {
+		int stringLength = string.length;
+		return (stringLength < 2) ?
+				false :
+				isDelimited(string, start, end, stringLength);
+	}
+
+	/**
+	 * no length check
+	 */
+	private static boolean isDelimited(char[] string, char start, char end, int stringLength) {
+		return (string[0] == start) && (string[stringLength - 1] == end);
+	}
+
+
+	// ********** undelimiting **********
+
+	/**
+	 * @see StringTools#undelimit(String)
+	 */
+	public static char[] undelimit(char[] string) {
+		int stringLength = string.length;
+		int resultLength = stringLength - 2;
+		if (resultLength < 0) {
+			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
+		}
+		if (resultLength == 0) {
+			return EMPTY_CHAR_ARRAY;
+		}
+		// delegate to StringBuilderTools to take care of embedded delimiters
+		StringBuilder sb = new StringBuilder(resultLength);
+		StringBuilderTools.undelimit_(sb, string, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see StringTools#undelimit(String, int)
+	 */
+	public static char[] undelimit(char[] string, int count) {
+		if (count == 0) {
+			return string;
+		}
+		int resultLength = string.length - (2 * count);
+		if (resultLength < 0) {
+			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
+		}
+		if (resultLength == 0) {
+			return EMPTY_CHAR_ARRAY;
+		}
+		return undelimit(string, count, resultLength);
+	}
+
+	/**
+	 * No parm checks
+	 */
+	private static char[] undelimit(char[] string, int count, int resultLength) {
+		return ArrayTools.subArray_(string, count, resultLength);
+	}
+
+
+	// ********** removing characters **********
+
+	/**
+	 * @see StringTools#removeFirstOccurrence(String, char)
+	 */
+	public static char[] removeFirstOccurrence(char[] string, char c) {
+		int index = ArrayTools.indexOf(string, c);
+		if (index == -1) {
+			// character not found
+			return string;
+		}
+		int last = string.length - 1;
+		char[] result = new char[last];
+		if (index == 0) {
+			// character found at the front of string
+			System.arraycopy(string, 1, result, 0, last);
+		} else if (index == last) {
+			// character found at the end of string
+			System.arraycopy(string, 0, result, 0, last);
+		} else {
+			// character found somewhere in the middle of the string
+			System.arraycopy(string, 0, result, 0, index);
+			System.arraycopy(string, index + 1, result, index, last - index);
+		}
+		return result;
+	}
+
+	/**
+	 * @see StringTools#removeAllOccurrences(String, char)
+	 */
+	public static char[] removeAllOccurrences(char[] string, char c) {
+		int first = ArrayTools.indexOf(string, c);
+		return (first == -1) ? string : removeAllOccurrences(string, c, first);
+	}
+
+	/**
+	 * no occurrence check
+	 */
+	private static char[] removeAllOccurrences(char[] string, char c, int first) {
+		int stringLength = string.length;
+		StringBuilder sb = new StringBuilder(stringLength);
+		StringBuilderTools.removeAllOccurrences(sb, string, c, first, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see StringTools#removeAllSpaces(String)
+	 */
+	public static char[] removeAllSpaces(char[] string) {
+		return removeAllOccurrences(string, ' ');
+	}
+
+	/**
+	 * @see StringTools#removeAllWhitespace(String)
+	 */
+	public static char[] removeAllWhitespace(char[] string) {
+		int first = indexOfWhitespace(string);
+		return (first == -1) ? string : removeAllWhitespace(string, first);
+	}
+
+	/**
+	 * @see StringTools#indexOfWhitespace(String)
+	 */
+	public static int indexOfWhitespace(char[] string) {
+		int stringLength = string.length;
+		for (int i = 0; i < stringLength; i++) {
+			if (Character.isWhitespace(string[i])) {
+				return i;
+			}
+		}
+		return -1;
+	}
+
+	/**
+	 * no whitespace check
+	 */
+	private static char[] removeAllWhitespace(char[] string, int first) {
+		int stringLength = string.length;
+		StringBuilder sb = new StringBuilder(stringLength);
+		StringBuilderTools.removeAllWhitespace(sb, string, first, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see StringTools#compressWhitespace(String)
+	 */
+	public static char[] compressWhitespace(char[] string) {
+		int first = indexOfWhitespace(string);
+		return (first == -1) ? string : compressWhitespace(string, first);
+	}
+
+	/**
+	 * no whitespace check
+	 */
+	private static char[] compressWhitespace(char[] string, int first) {
+		int stringLength = string.length;
+		StringBuilder sb = new StringBuilder(stringLength);
+		StringBuilderTools.compressWhitespace(sb, string, first, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+
+	// ********** common prefix **********
+
+	/**
+	 * @see StringTools#commonPrefixLength(String, String)
+	 */
+	public static int commonPrefixLength(char[] s1, char[] s2) {
+		return commonPrefixLength(s1, s2, Math.min(s1.length, s2.length));
+	}
+
+	/**
+	 * Return the length of the common prefix shared by the specified strings;
+	 * but limit the length to the specified maximum.
+	 */
+	public static int commonPrefixLength(char[] s1, char[] s2, int max) {
+		for (int i = 0; i < max; i++) {
+			if (s1[i] != s2[i]) {
+				return i;
+			}
+		}
+		return max;	// all the characters up to 'max' are the same
+	}
+
+
+	// ********** capitalization **********
+
+	/**
+	 * @see StringTools#capitalize(String)
+	 * Return a <em>new</em> array if the first letter must be changed.
+	 */
+	public static char[] capitalize(char[] string) {
+		int stringLength = string.length;
+		return ((stringLength == 0) || Character.isUpperCase(string[0])) ?
+				string :
+				capitalize(string, stringLength);
+	}
+
+	/**
+	 * no zero-length check or lower case check
+	 */
+	private static char[] capitalize(char[] string, int stringLength) {
+		char[] result = new char[stringLength];
+		result[0] = Character.toUpperCase(string[0]);
+		System.arraycopy(string, 1, result, 1, stringLength-1);
+		return result;
+	}
+
+	/**
+	 * @see #capitalize(char[])
+	 */
+	public static final Transformer<char[], char[]> CAPITALIZER = new Capitalizer();
+
+	/* CU private */ static class Capitalizer
+		extends TransformerAdapter<char[], char[]>
+		implements Serializable
+	{
+		@Override
+		public char[] transform(char[] string) {
+			return capitalize(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return CAPITALIZER;
+		}
+	}
+
+	/**
+	 * @see StringTools#uncapitalize(String)
+	 * Return a <em>new</em> array if the first letter must be changed.
+	 */
+	public static char[] uncapitalize(char[] string) {
+		int stringLength = string.length;
+		return needNotBeUncapitalized(string, stringLength) ?
+				string :
+				uncapitalize(string, stringLength);
+	}
+
+	/**
+	 * @see StringTools#needNotBeUncapitalized(String, int)
+	 */
+	public static boolean needNotBeUncapitalized(char[] string, int stringLength) {
+		if (stringLength == 0) {
+			return true;
+		}
+		if (Character.isLowerCase(string[0])) {
+			return true;
+		}
+		// if both the first and second characters are capitalized,
+		// return the string unchanged
+		if ((stringLength > 1)
+				&& Character.isUpperCase(string[1])
+				&& Character.isUpperCase(string[0])){
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * no zero-length check or lower case check
+	 */
+	private static char[] uncapitalize(char[] string, int stringLength) {
+		char[] result = new char[stringLength];
+		result[0] = Character.toLowerCase(string[0]);
+		System.arraycopy(string, 1, result, 1, stringLength-1);
+		return result;
+	}
+
+	/**
+	 * @see #uncapitalize(char[])
+	 */
+	public static final Transformer<char[], char[]> UNCAPITALIZER = new Uncapitalizer();
+
+	/* CU private */ static class Uncapitalizer
+		extends TransformerAdapter<char[], char[]>
+		implements Serializable
+	{
+		@Override
+		public char[] transform(char[] string) {
+			return uncapitalize(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return UNCAPITALIZER;
+		}
+	}
+
+
+	// ********** string queries **********
+
+	/**
+	 * @see StringTools#isBlank(String)
+	 */
+	public static boolean isBlank(char[] string) {
+		if (string == null) {
+			return true;
+		}
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			return true;
+		}
+		return isBlank(string, stringLength);
+	}
+
+	/**
+	 * no <code>null</code> or length checks
+	 */
+	private static boolean isBlank(char[] string, int stringLength) {
+		for (int i = stringLength; i-- > 0; ) {
+			if ( ! Character.isWhitespace(string[i])) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * @see StringTools#isNotBlank(String)
+	 */
+	public static boolean isNotBlank(char[] string) {
+		return ! isBlank(string);
+	}
+
+	/**
+	 * @see #isNotBlank(char[])
+	 */
+	public static final Filter<char[]> NON_BLANK_FILTER = new NonBlankFilter();
+
+	/* CU private */ static class NonBlankFilter
+		extends Filter.Adapter<char[]>
+		implements Serializable
+	{
+		@Override
+		public boolean accept(char[] string) {
+			return isNotBlank(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return NON_BLANK_FILTER;
+		}
+	}
+
+	/**
+	 * @see StringTools#equalsIgnoreCase(String, String)
+	 */
+	public static boolean equalsIgnoreCase(char[] s1, char[] s2) {
+		return (s1 == null) ? (s2 == null) : ((s2 != null) && equalsIgnoreCase_(s1, s2));
+	}
+
+	/**
+	 * no <code>null</code> checks
+	 */
+	private static boolean equalsIgnoreCase_(char[] s1, char[] s2) {
+		int stringLength = s1.length;
+		if (stringLength != s2.length) {
+			return false;
+		}
+		for (int i = stringLength; i-- > 0; ) {
+			if ( ! CharacterTools.equalsIgnoreCase(s1[i], s2[i])) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * @see StringTools#startsWithIgnoreCase(String, String)
+	 */
+	public static boolean startsWithIgnoreCase(char[] string, char[] prefix) {
+		int prefixLength = prefix.length;
+		if (string.length < prefixLength) {
+			return false;
+		}
+		for (int i = prefixLength; i-- > 0; ) {
+			if ( ! CharacterTools.equalsIgnoreCase(string[i], prefix[i])) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * @see StringTools#isUppercase(String)
+	 */
+	public static boolean isUppercase(char[] string) {
+		return (string.length != 0) && StringTools.isUppercase_(new String(string));
+	}
+
+	/**
+	 * @see StringTools#isLowercase(String)
+	 */
+	public static boolean isLowercase(char[] string) {
+		return (string.length != 0) && StringTools.isLowercase_(new String(string));
+	}
+
+
+	// ********** byte arrays **********
+
+	/**
+	 * @see StringTools#convertHexStringToByteArray(String)
+	 */
+	public static byte[] convertHexStringToByteArray(char[] hexString) {
+		int hexStringLength = hexString.length;
+		if (hexStringLength == 0) {
+			return ByteArrayTools.EMPTY_BYTE_ARRAY;
+		}
+		if (BitTools.isOdd(hexStringLength)) {
+			throw new IllegalArgumentException("Odd-sized hexadecimal string: " + new String(hexString) + " (" + hexStringLength + " characters)"); //$NON-NLS-3$
+		}
+		return convertHexStringToByteArray(hexString, hexStringLength);
+	}
+
+	/**
+	 * Pre-condition: the string is neither empty nor odd-sized
+	 */
+	private static byte[] convertHexStringToByteArray(char[] hexString, int hexStringLength) {
+		byte[] bytes = new byte[BitTools.half(hexStringLength)];
+		for (int bi = bytes.length - 1, si = hexStringLength - 2; bi >= 0; bi--, si -= 2) {
+			byte digit1 = (byte) Character.digit(hexString[si], 16);
+			if (digit1 == -1) {
+				throw new IllegalArgumentException(buildIllegalHexCharMessage(hexString, si));
+			}
+			byte digit2 = (byte) Character.digit(hexString[si + 1], 16);
+			if (digit2 == -1) {
+				throw new IllegalArgumentException(buildIllegalHexCharMessage(hexString, si + 1));
+			}
+			bytes[bi] = (byte) ((digit1 << 4) + digit2);
+		}
+		return bytes;
+	}
+
+	private static String buildIllegalHexCharMessage(char[] hexString, int index) {
+		return StringTools.buildIllegalHexCharMessage(new String(hexString), index);
+	}
+
+
+	// ********** convert camel case to all caps **********
+
+	/**
+	 * @see StringTools#convertCamelCaseToAllCaps(String)
+	 */
+	public static char[] convertCamelCaseToAllCaps(char[] camelCaseString) {
+		int stringLength = camelCaseString.length;
+		return (stringLength == 0) ?
+				camelCaseString :
+				convertCamelCaseToAllCaps_(camelCaseString, stringLength);
+	}
+
+	/**
+	 * no length check
+	 */
+	private static char[] convertCamelCaseToAllCaps_(char[] camelCaseString, int stringLength) {
+		StringBuilder sb = new StringBuilder(stringLength + (stringLength / 4));
+		StringBuilderTools.convertCamelCaseToAllCaps_(sb, camelCaseString, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see StringTools#convertCamelCaseToAllCaps(String, int)
+	 */
+	public static char[] convertCamelCaseToAllCaps(char[] camelCaseString, int maxLength) {
+		if (maxLength == 0) {
+			return EMPTY_CHAR_ARRAY;
+		}
+		int stringLength = camelCaseString.length;
+		return (stringLength == 0) ?
+				camelCaseString :
+				convertCamelCaseToAllCaps(camelCaseString, maxLength, stringLength);
+	}
+
+	/**
+	 * no check for empty string or zero max length
+	 */
+	private static char[] convertCamelCaseToAllCaps(char[] camelCaseString, int maxLength, int stringLength) {
+		StringBuilder sb = new StringBuilder(maxLength);
+		StringBuilderTools.convertCamelCaseToAllCaps(sb, camelCaseString, maxLength, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+
+	// ********** convert all caps to camel case **********
+
+	/**
+	 * @see StringTools#convertAllCapsToCamelCase(String)
+	 */
+	public static char[] convertAllCapsToCamelCase(char[] allCapsString) {
+		return convertAllCapsToCamelCase(allCapsString, true);  // true => capitalize first letter
+	}
+
+	/**
+	 * @see StringTools#convertAllCapsToCamelCase(String, boolean)
+	 */
+	public static char[] convertAllCapsToCamelCase(char[] allCapsString, boolean capitalizeFirstLetter) {
+		int stringLength = allCapsString.length;
+		return (stringLength == 0) ?
+			allCapsString :
+			convertAllCapsToCamelCase(allCapsString, capitalizeFirstLetter, stringLength);
+	}
+
+	/**
+	 * no length check
+	 */
+	private static char[] convertAllCapsToCamelCase(char[] allCapsString, boolean capitalizeFirstLetter, int stringLength) {
+		StringBuilder sb = new StringBuilder(stringLength);
+		StringBuilderTools.convertAllCapsToCamelCase(sb, allCapsString, capitalizeFirstLetter, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+
+	// ********** convert to Java string literal **********
+
+	public static final char[] EMPTY_JAVA_STRING_LITERAL = StringTools.EMPTY_JAVA_STRING_LITERAL.toCharArray();
+
+	/**
+	 * @see StringTools#convertToJavaStringLiteral(String)
+	 */
+	public static char[] convertToJavaStringLiteral(char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			return EMPTY_JAVA_STRING_LITERAL;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 6);
+		StringBuilderTools.convertToJavaStringLiteral(sb, string, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see #convertToJavaStringLiteral(char[])
+	 */
+	public static final Transformer<char[], char[]> JAVA_STRING_LITERAL_TRANSFORMER = new JavaStringLiteralTransformer();
+
+	/* CU private */ static class JavaStringLiteralTransformer
+		extends TransformerAdapter<char[], char[]>
+		implements Serializable
+	{
+		@Override
+		public char[] transform(char[] string) {
+			return convertToJavaStringLiteral(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return JAVA_STRING_LITERAL_TRANSFORMER;
+		}
+	}
+
+	/**
+	 * @see StringTools#convertToJavaStringLiteralContent(String)
+	 */
+	public static char[] convertToJavaStringLiteralContent(char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			return EMPTY_CHAR_ARRAY;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 6);
+		StringBuilderTools.convertToJavaStringLiteralContent(sb, string, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see #convertToJavaStringLiteralContent(char[])
+	 */
+	public static final Transformer<char[], char[]> JAVA_STRING_LITERAL_CONTENT_TRANSFORMER = new JavaStringLiteralContentTransformer();
+
+	/* CU private */ static class JavaStringLiteralContentTransformer
+		extends TransformerAdapter<char[], char[]>
+		implements Serializable
+	{
+		@Override
+		public char[] transform(char[] string) {
+			return convertToJavaStringLiteralContent(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return JAVA_STRING_LITERAL_CONTENT_TRANSFORMER;
+		}
+	}
+
+
+	// ********** convert to XML **********
+
+	public static final char[] EMPTY_DOUBLE_QUOTED_XML_ATTRIBUTE_VALUE = StringTools.EMPTY_DOUBLE_QUOTED_XML_ATTRIBUTE_VALUE.toCharArray();
+	public static final char[] EMPTY_SINGLE_QUOTED_XML_ATTRIBUTE_VALUE = StringTools.EMPTY_SINGLE_QUOTED_XML_ATTRIBUTE_VALUE.toCharArray();
+	public static final char[] EMPTY_XML_ATTRIBUTE_VALUE = StringTools.EMPTY_XML_ATTRIBUTE_VALUE.toCharArray();
+	public static final char[] XML_ELEMENT_CDATA_START = StringTools.XML_ELEMENT_CDATA_START.toCharArray();
+	public static final char[] XML_ELEMENT_CDATA_END = StringTools.XML_ELEMENT_CDATA_END.toCharArray();
+	public static final char[] EMPTY_XML_ELEMENT_CDATA = StringTools.EMPTY_XML_ELEMENT_CDATA.toCharArray();
+
+	// XML predefined entities
+	public static final char[] XML_QUOTE = StringTools.XML_QUOTE.toCharArray();
+	public static final char[] XML_AMP   = StringTools.XML_AMP.toCharArray();
+	public static final char[] XML_APOS  = StringTools.XML_APOS.toCharArray();
+	public static final char[] XML_LT    = StringTools.XML_LT.toCharArray();
+	public static final char[] XML_GT    = StringTools.XML_GT.toCharArray();
+
+	/**
+	 * @see StringTools#convertToXmlAttributeValue(String)
+	 */
+	public static char[] convertToXmlAttributeValue(char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			return EMPTY_XML_ATTRIBUTE_VALUE;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 12);
+		StringBuilderTools.convertToXmlAttributeValue(sb, string, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see #convertToXmlAttributeValue(char[])
+	 */
+	public static final Transformer<char[], char[]> XML_ATTRIBUTE_VALUE_TRANSFORMER = new XmlAttributeValueTransformer();
+
+	/* CU private */ static class XmlAttributeValueTransformer
+		extends TransformerAdapter<char[], char[]>
+		implements Serializable
+	{
+		@Override
+		public char[] transform(char[] string) {
+			return convertToXmlAttributeValue(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return XML_ATTRIBUTE_VALUE_TRANSFORMER;
+		}
+	}
+
+	/**
+	 * @see StringTools#convertToDoubleQuotedXmlAttributeValue(String)
+	 * @see #convertToXmlAttributeValue(char[])
+	 */
+	public static char[] convertToDoubleQuotedXmlAttributeValue(char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			return EMPTY_DOUBLE_QUOTED_XML_ATTRIBUTE_VALUE;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 12);
+		StringBuilderTools.convertToDoubleQuotedXmlAttributeValue(sb, string, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see #convertToDoubleQuotedXmlAttributeValue(char[])
+	 */
+	public static final Transformer<char[], char[]> DOUBLE_QUOTED_XML_ATTRIBUTE_VALUE_TRANSFORMER = new DoubleQuotedXmlAttributeValueTransformer();
+
+	/* CU private */ static class DoubleQuotedXmlAttributeValueTransformer
+		extends TransformerAdapter<char[], char[]>
+		implements Serializable
+	{
+		@Override
+		public char[] transform(char[] string) {
+			return convertToDoubleQuotedXmlAttributeValue(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return DOUBLE_QUOTED_XML_ATTRIBUTE_VALUE_TRANSFORMER;
+		}
+	}
+
+	/**
+	 * @see StringTools#convertToDoubleQuotedXmlAttributeValueContent(String)
+	 * @see #convertToXmlAttributeValue(char[])
+	 */
+	public static char[] convertToDoubleQuotedXmlAttributeValueContent(char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			return EMPTY_CHAR_ARRAY;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 10);
+		StringBuilderTools.convertToDoubleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see #convertToDoubleQuotedXmlAttributeValueContent(char[])
+	 */
+	public static final Transformer<char[], char[]> XML_DOUBLE_QUOTED_ATTRIBUTE_VALUE_CONTENT_TRANSFORMER = new XmlDoubleQuotedAttributeValueContentTransformer();
+
+	/* CU private */ static class XmlDoubleQuotedAttributeValueContentTransformer
+		extends TransformerAdapter<char[], char[]>
+		implements Serializable
+	{
+		@Override
+		public char[] transform(char[] string) {
+			return convertToDoubleQuotedXmlAttributeValueContent(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return XML_DOUBLE_QUOTED_ATTRIBUTE_VALUE_CONTENT_TRANSFORMER;
+		}
+	}
+
+	/**
+	 * @see StringTools#convertToSingleQuotedXmlAttributeValue(String)
+	 * @see #convertToXmlAttributeValue(char[])
+	 */
+	public static char[] convertToSingleQuotedXmlAttributeValue(char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			return EMPTY_SINGLE_QUOTED_XML_ATTRIBUTE_VALUE;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 12);
+		StringBuilderTools.convertToSingleQuotedXmlAttributeValue(sb, string, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see #convertToSingleQuotedXmlAttributeValue(char[])
+	 */
+	public static final Transformer<char[], char[]> SINGLE_QUOTED_XML_ATTRIBUTE_VALUE_TRANSFORMER = new SingleQuotedXmlAttributeValueTransformer();
+
+	/* CU private */ static class SingleQuotedXmlAttributeValueTransformer
+		extends TransformerAdapter<char[], char[]>
+		implements Serializable
+	{
+		@Override
+		public char[] transform(char[] string) {
+			return convertToSingleQuotedXmlAttributeValue(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return SINGLE_QUOTED_XML_ATTRIBUTE_VALUE_TRANSFORMER;
+		}
+	}
+
+	/**
+	 * @see StringTools#convertToSingleQuotedXmlAttributeValueContent(String)
+	 * @see #convertToXmlAttributeValue(char[])
+	 */
+	public static char[] convertToSingleQuotedXmlAttributeValueContent(char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			return EMPTY_CHAR_ARRAY;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 10);
+		StringBuilderTools.convertToSingleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see #convertToSingleQuotedXmlAttributeValueContent(char[])
+	 */
+	public static final Transformer<char[], char[]> XML_SINGLE_QUOTED_ATTRIBUTE_VALUE_CONTENT_TRANSFORMER = new XmlSingleQuotedAttributeValueContentTransformer();
+
+	/* CU private */ static class XmlSingleQuotedAttributeValueContentTransformer
+		extends TransformerAdapter<char[], char[]>
+		implements Serializable
+	{
+		@Override
+		public char[] transform(char[] string) {
+			return convertToSingleQuotedXmlAttributeValueContent(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return XML_SINGLE_QUOTED_ATTRIBUTE_VALUE_CONTENT_TRANSFORMER;
+		}
+	}
+
+	/**
+	 * @see StringTools#convertToXmlElementText(String)
+	 */
+	public static char[] convertToXmlElementText(char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			return string;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 8);
+		StringBuilderTools.convertToXmlElementText(sb, string, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see #convertToXmlElementText(char[])
+	 */
+	public static final Transformer<char[], char[]> XML_ELEMENT_TEXT_TRANSFORMER = new XmlElementTextTransformer();
+
+	/* CU private */ static class XmlElementTextTransformer
+		extends TransformerAdapter<char[], char[]>
+		implements Serializable
+	{
+		@Override
+		public char[] transform(char[] string) {
+			return convertToXmlElementText(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return XML_ELEMENT_TEXT_TRANSFORMER;
+		}
+	}
+
+	/**
+	 * @see StringTools#convertToXmlElementCDATA(String)
+	 */
+	public static char[] convertToXmlElementCDATA(char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			return EMPTY_XML_ELEMENT_CDATA;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + EMPTY_XML_ELEMENT_CDATA.length + 6);
+		StringBuilderTools.convertToXmlElementCDATA(sb, string, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see #convertToXmlElementCDATA(char[])
+	 */
+	public static final Transformer<char[], char[]> XML_ELEMENT_CDATA_TRANSFORMER = new XmlElementCDATATransformer();
+
+	/* CU private */ static class XmlElementCDATATransformer
+		extends TransformerAdapter<char[], char[]>
+		implements Serializable
+	{
+		@Override
+		public char[] transform(char[] string) {
+			return convertToXmlElementCDATA(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return XML_ELEMENT_CDATA_TRANSFORMER;
+		}
+	}
+
+	/**
+	 * @see StringTools#convertToXmlElementCDATAContent(String)
+	 */
+	public static char[] convertToXmlElementCDATAContent(char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			return EMPTY_CHAR_ARRAY;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 6);
+		StringBuilderTools.convertToXmlElementCDATAContent(sb, string, stringLength);
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+	/**
+	 * @see #convertToXmlElementCDATAContent(char[])
+	 */
+	public static final Transformer<char[], char[]> XML_ELEMENT_CDATA_CONTENT_TRANSFORMER = new XmlElementCDATAContentTransformer();
+
+	/* CU private */ static class XmlElementCDATAContentTransformer
+		extends TransformerAdapter<char[], char[]>
+		implements Serializable
+	{
+		@Override
+		public char[] transform(char[] string) {
+			return convertToXmlElementCDATAContent(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return XML_ELEMENT_CDATA_CONTENT_TRANSFORMER;
+		}
+	}
+
+
+	// ********** constructor **********
+
+	/*
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private CharArrayTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CharacterTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CharacterTools.java
new file mode 100644
index 0000000..7b4c103
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CharacterTools.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+/**
+ * <code>char</code> utility methods.
+ */
+public final class CharacterTools {
+
+	/** quotes */
+	public static final char QUOTE = '"';
+	public static final char DOUBLE_QUOTE = QUOTE;
+	public static final char APOSTROPHE = '\'';
+	public static final char SINGLE_QUOTE = APOSTROPHE;
+
+	/** parentheses */
+	public static final char OPEN_PARENTHESIS = '(';
+	public static final char CLOSE_PARENTHESIS = ')';
+
+	/** brackets */
+	public static final char OPEN_BRACKET = '[';
+	public static final char CLOSE_BRACKET = ']';
+
+	/** braces */
+	public static final char OPEN_BRACE = '{';
+	public static final char CLOSE_BRACE = '}';
+
+	/** chevrons */
+	public static final char OPEN_CHEVRON = '<';
+	public static final char CLOSE_CHEVRON = '>';
+
+	/** Java String characters */
+	public static final char BACKSPACE = '\b';
+	public static final char TAB = '\t';
+	public static final char LINE_FEED = '\n';
+	public static final char FORM_FEED = '\f';
+	public static final char CARRIAGE_RETURN = '\r';
+	public static final char BACKSLASH = '\\';
+
+	/**
+	 * Character array containing the possible digits,
+	 * indexed appropriately.
+	 */
+	public static final char[] DIGITS = {
+		'0','1','2','3','4','5','6','7','8','9',
+		'A','B','C','D','E','F','G','H','I','J',
+		'K','L','M','N','O','P','Q','R','S','T',
+		'U','V','W','X','Y','Z'};
+
+
+	/**
+	 * Return whether the specified characters are are equal, ignoring case.
+	 * @see String#regionMatches(boolean, int, String, int, int)
+	 */
+	public static boolean equalsIgnoreCase(char c1, char c2) {
+		// something about the Georgian alphabet requires us to check lower case also
+		return (c1 == c2)
+				|| (Character.toUpperCase(c1) == Character.toUpperCase(c2))
+				|| (Character.toLowerCase(c1) == Character.toLowerCase(c2));
+	}
+
+
+	// ********** constructor **********
+
+	/*
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private CharacterTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ClassName.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ClassName.java
deleted file mode 100644
index 1e82ecd..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ClassName.java
+++ /dev/null
@@ -1,436 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-/**
- * Convenience methods related to Java class names as returned by
- * {@link java.lang.Class#getName()}.
- */
-@SuppressWarnings("nls")
-public final class ClassName {
-
-	public static final String VOID_CLASS_NAME = ReflectionTools.VOID_CLASS.getName();
-	public static final String VOID_WRAPPER_CLASS_NAME = ReflectionTools.VOID_WRAPPER_CLASS.getName();
-
-	public static final char REFERENCE_CLASS_CODE = 'L';
-	public static final char REFERENCE_CLASS_NAME_DELIMITER = ';';
-
-	/**
-	 * Returns whether the specified class is an array type.
-	 * @see java.lang.Class#getName()
-	 */
-	public static boolean isArray(String className) {
-		return className.charAt(0) == '[';
-	}
-
-	/**
-	 * Returns the "element type" of the specified class.
-	 * The element type is the base type held by an array type.
-	 * Returns themselves.
-	 * @see java.lang.Class#getName()
-	 */
-	public static String getElementTypeName(String className) {
-		int depth = getArrayDepth(className);
-		if (depth == 0) {
-			// the name is in the form: "java.lang.Object" or "int"
-			return className;
-		}
-		return getElementTypeName_(className, depth);
-	}
-
-	/**
-	 * pre-condition: array depth is not zero
-	 */
-	private static String getElementTypeName_(String className, int arrayDepth) {
-		int last = className.length() - 1;
-		if (className.charAt(arrayDepth) == REFERENCE_CLASS_CODE) {
-			// the name is in the form: "[[[Ljava.lang.Object;"
-			return className.substring(arrayDepth + 1, last);	// drop the trailing ';'
-		}
-		// the name is in the form: "[[[I"
-		return forCode(className.charAt(last));
-	}
-
-	/**
-	 * Returns the "array depth" of the specified class.
-	 * The depth is the number of dimensions for an array type.
-	 * Non-array types have a depth of zero.
-	 * @see java.lang.Class#getName()
-	 */
-	public static int getArrayDepth(String className) {
-		int depth = 0;
-		while (className.charAt(depth) == '[') {
-			depth++;
-		}
-		return depth;
-	}
-
-	/**
-	 * Returns the specified class's component type.
-	 * Returns <code>null</code> if the specified class is not an array type.
-	 * @see java.lang.Class#getName()
-	 */
-	public static String getComponentTypeName(String className) {
-		switch (getArrayDepth(className)) {
-			case 0:
-				return null;
-			case 1:
-				return getElementTypeName_(className, 1);
-			default:
-				return className.substring(1);
-		}
-	}
-
-	/**
-	 * Returns the specified class's simple name.
-	 * Returns an empty string if the specified class is anonymous.
-	 * <p>
-	 * The simple name of an array type is the simple name of the
-	 * component type with <code>"[]"</code> appended. In particular,
-	 * the simple name of an array type whose component type is
-	 * anonymous is simply <code>"[]"</code>.
-	 * @see java.lang.Class#getSimpleName()
-	 */
-	public static String getSimpleName(String className) {
-		return isArray(className) ?
-				getSimpleName(getComponentTypeName(className)) + "[]" :
-				getSimpleName_(className);
-	}
-
-	/**
-	 * pre-condition: specified class is not an array type
-	 */
-	private static String getSimpleName_(String className) {
-		int index = className.lastIndexOf('$');
-		if (index == -1) {  // "top-level" class - strip package name
-			return className.substring(className.lastIndexOf('.') + 1);
-		}
-
-		int len = className.length();
-		for (int i = ++index; i < len; i++) {
-			if ( ! charIsAsciiDigit(className.charAt(i))) {
-				return className.substring(i);  // "member" or "local" class
-			}
-		}
-		// all the characters past the '$' are ASCII digits ("anonymous" class)
-		return StringTools.EMPTY_STRING;
-	}
-
-	/**
-	 * Returns the specified class's package name (e.g.
-	 * <code>"java.lang.Object"</code> returns
-	 * <code>"java.lang"</code>).
-	 * Returns an empty string if the specified class is:<ul>
-	 * <li>in the "default" package
-	 * <li>an array class
-	 * <li>a primtive class
-	 * </ul>
-	 * @see java.lang.Class#getPackage()
-	 * @see java.lang.Package#getName()
-	 */
-	public static String getPackageName(String className) {
-		if (isArray(className)) {
-			return StringTools.EMPTY_STRING;
-		}
-		int lastPeriod = className.lastIndexOf('.');
-		return (lastPeriod == -1) ? StringTools.EMPTY_STRING : className.substring(0, lastPeriod);
-	}
-
-	/**
-	 * Returns whether the specified class is a "top-level" class,
-	 * as opposed to a "member", "local", or "anonymous" class,
-	 * using the standard JDK naming conventions (i.e. the class
-	 * name does NOT contain a <code>'$'</code>).
-	 * A "top-level" class can be either the "primary" (public) class defined
-	 * in a file/compilation unit (i.e. the class with the same name as its
-	 * file's simple base name) or a "non-primary" (package visible) class
-	 * (i.e. the other top-level classes defined in a file).
-	 * A "top-level" class can contain any of the other types of classes.
-	 * @see java.lang.Class#getName()
-	 */
-	public static boolean isTopLevel(String className) {
-		if (isArray(className)) {
-			return false;
-		}
-		return className.lastIndexOf('$') == -1;
-	}
-
-	/**
-	 * Returns whether the specified class is a "member" class,
-	 * as opposed to a "top-level", "local", or "anonymous" class,
-	 * using the standard JDK naming convention (i.e. the class
-	 * name ends with a <code>'$'</code> followed by a legal class name; e.g.
-	 * <code>"TopLevelClass$1LocalClass$MemberClass"</code>).
-	 * A "member" class can be either "nested" (static) or "inner";
-	 * but there is no way to determine which from the class's name.
-	 * A "member" class can contain "local", "anonymous", or other
-	 * "member" classes; and vice-versa.
-	 * @see java.lang.Class#getName()
-	 */
-	public static boolean isMember(String className) {
-		if (isArray(className)) {
-			return false;
-		}
-		int index = className.lastIndexOf('$');
-		if (index == -1) {
-			return false;	// "top-level" class
-		}
-		// the character immediately after the dollar sign cannot be an ASCII digit
-		return ! charIsAsciiDigit(className.charAt(++index));
-	}
-
-	/**
-	 * Returns whether the specified class is a "local" class,
-	 * as opposed to a "top-level", "member", or "anonymous" class,
-	 * using the standard JDK naming convention (i.e. the class name
-	 * ends with <code>"$nnnXXX"</code>,
-	 * where the <code>'$'</code> is
-	 * followed by a series of numeric digits which are followed by the
-	 * local class name; e.g. <code>"TopLevelClass$1LocalClass"</code>).
-	 * A "local" class can contain "member", "anonymous", or other
-	 * "local" classes; and vice-versa.
-	 * @see java.lang.Class#getName()
-	 */
-	public static boolean isLocal(String className) {
-		if (isArray(className)) {
-			return false;
-		}
-		int index = className.lastIndexOf('$');
-		if (index == -1) {
-			return false;	// "top-level" class
-		}
-		if ( ! charIsAsciiDigit(className.charAt(++index))) {
-			return false;  // "member" class
-		}
-		int len = className.length();
-		for (int i = ++index; i < len; i++) {
-			if ( ! charIsAsciiDigit(className.charAt(i))) {
-				return true;
-			}
-		}
-		// all the characters past the '$' are ASCII digits ("anonymous" class)
-		return false;
-	}
-
-	/**
-	 * Returns whether the specified class is an "anonymous" class,
-	 * as opposed to a "top-level", "member", or "local" class,
-	 * using the standard JDK naming convention (i.e. the class
-	 * name ends with <code>"$nnn"</code> where all the characters past the
-	 * last <code>'$'</code> are ASCII numeric digits;
-	 * e.g. <code>"TopLevelClass$1"</code>).
-	 * An "anonymous" class can contain "member", "local", or other
-	 * "anonymous" classes; and vice-versa.
-	 * @see java.lang.Class#getName()
-	 */
-	public static boolean isAnonymous(String className) {
-		if (isArray(className)) {
-			return false;
-		}
-		int index = className.lastIndexOf('$');
-		if (index == -1) {
-			return false;	// "top-level" class
-		}
-		if ( ! charIsAsciiDigit(className.charAt(++index))) {
-			return false;  // "member" class
-		}
-		int len = className.length();
-		for (int i = ++index; i < len; i++) {
-			if ( ! charIsAsciiDigit(className.charAt(i))) {
-				return false;  // "local" class
-			}
-		}
-		// all the characters past the '$' are ASCII digits ("anonymous" class)
-		return true;
-	}
-
-	/**
-	 * {@link Character#isDigit(char)} returns <code>true</code> for some non-ASCII
-	 * digits. This method does not.
-	 */
-	private static boolean charIsAsciiDigit(char c) {
-		return ('0' <= c) && (c <= '9');
-	}
-
-	/**
-	 * Returns whether the specified class is a "reference"
-	 * class (i.e. neither <code>void</code> nor one of the primitive variable classes,
-	 * <code>boolean</code>, <code>int</code>, <code>float</code>, etc.).
-	 * <p>
-	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
-	 */
-	public static boolean isReference(String className) {
-		return ! isPrimitive(className);
-	}
-
-	/**
-	 * Returns whether the specified class is a primitive
-	 * class (i.e. <code>void</code> or one of the primitive variable classes,
-	 * <code>boolean</code>, <code>int</code>, <code>float</code>, etc.).
-	 * <p>
-	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
-	 */
-	public static boolean isPrimitive(String className) {
-		if (isArray(className) || (className.length() > ReflectionTools.MAX_PRIMITIVE_CLASS_NAME_LENGTH)) {
-			return false;  // performance tweak
-		}
-		for (ReflectionTools.Primitive primitive : ReflectionTools.PRIMITIVES) {
-			if (className.equals(primitive.javaClass.getName())) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Returns whether the specified class is a primitive wrapper
-	 * class (i.e. <code>java.lang.Void</code> or one of the primitive
-	 * variable wrapper classes, <code>java.lang.Boolean</code>,
-	 * <code>java.lang.Integer</code>, <code>java.lang.Float</code>, etc.).
-	 * <p>
-	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
-	 */
-	public static boolean isPrimitiveWrapper(String className) {
-		if (isArray(className) || (className.length() > ReflectionTools.MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH)) {
-			return false;  // performance tweak
-		}
-		for (ReflectionTools.Primitive primitive : ReflectionTools.PRIMITIVES) {
-			if (className.equals(primitive.wrapperClass.getName())) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Returns whether the specified class is a "variable" primitive
-	 * class (i.e. <code>boolean</code>, <code>int</code>, <code>float</code>, etc.,
-	 * but not <code>void</code>).
-	 * <p>
-	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
-	 */
-	public static boolean isVariablePrimitive(String className) {
-		return isPrimitive(className)
-			&& ( ! className.equals(VOID_CLASS_NAME));
-	}
-
-	/**
-	 * Returns whether the specified class is a "variable" primitive wrapper
-	 * class (i.e. <code>java.lang.Boolean</code>,
-	 * <code>java.lang.Integer</code>, <code>java.lang.Float</code>, etc.,
-	 * but not <code>java.lang.Void</code>).
-	 * <p>
-	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
-	 */
-	public static boolean isVariablePrimitiveWrapper(String className) {
-		return isPrimitiveWrapper(className)
-			&& ( ! className.equals(VOID_WRAPPER_CLASS_NAME));
-	}
-
-	/**
-	 * Returns the name of the primitive wrapper class corresponding to the specified
-	 * Returns <code>null</code> if the specified class is not a primitive.
-	 */
-	public static String getWrapperClassName(String primitiveClassName) {
-		for (ReflectionTools.Primitive primitive : ReflectionTools.PRIMITIVES) {
-			if (primitive.javaClass.getName().equals(primitiveClassName)) {
-				return primitive.wrapperClass.getName();
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the name of the primitive class corresponding to the specified
-	 * Returns <code>null</code> if the specified class
-	 * is not a primitive wrapper.
-	 */
-	public static String getPrimitiveClassName(String primitiveWrapperClassName) {
-		for (ReflectionTools.Primitive primitive : ReflectionTools.PRIMITIVES) {
-			if (primitive.wrapperClass.getName().equals(primitiveWrapperClassName)) {
-				return primitive.javaClass.getName();
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns whether the two class names are equivalent, given autoboxing.
-	 * (e.g. "java.lang.Integer" and "int" should be equivalent)
-	 */
-	public static boolean areAutoboxEquivalents(String className1, String className2) {
-		return Tools.valuesAreEqual(className1, className2)
-			|| Tools.valuesAreEqual(getPrimitiveClassName(className1), className2)
-			|| Tools.valuesAreEqual(getWrapperClassName(className1), className2);
-	}
-
-
-	// ********** primitive codes **********
-
-	/**
-	 * Returns the primitive class name for the specified primitive class code.
-	 * Returns <code>null</code> if the specified code
-	 * is not a primitive class code.
-	 * @see java.lang.Class#getName()
-	 */
-	public static String forCode(int classCode) {
-		return forCode((char) classCode);
-	}
-
-	/**
-	 * Returns the primitive class name for the specified primitive class code.
-	 * Returns <code>null</code> if the specified code
-	 * is not a primitive class code.
-	 * @see java.lang.Class#getName()
-	 */
-	public static String forCode(char classCode) {
-		Class<?> primitiveClass = ReflectionTools.getClassForCode(classCode);
-		return (primitiveClass == null) ? null : primitiveClass.getName();
-	}
-
-	/**
-	 * Returns the class code for the specified primitive class.
-	 * Returns <code>0</code> if the specified class
-	 * is not a primitive class.
-	 * @see java.lang.Class#getName()
-	 */
-	public static char getCodeForClassName(String primitiveClassName) {
-		if (( ! isArray(primitiveClassName)) && (primitiveClassName.length() <= ReflectionTools.MAX_PRIMITIVE_CLASS_NAME_LENGTH)) {
-			for (ReflectionTools.Primitive primitive : ReflectionTools.PRIMITIVES) {
-				if (primitive.javaClass.getName().equals(primitiveClassName)) {
-					return primitive.code;
-				}
-			}
-		}
-		return 0;
-	}
-
-	static void append(String className, StringBuilder sb) {
-		sb.append(REFERENCE_CLASS_CODE);
-		sb.append(className);
-		sb.append(REFERENCE_CLASS_NAME_DELIMITER);
-	}
-
-
-	// ********** suppressed constructor **********
-
-	/**
-	 * Suppress default constructor, ensuring non-instantiability.
-	 */
-	private ClassName() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ClassNameTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ClassNameTools.java
new file mode 100644
index 0000000..ac2706b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ClassNameTools.java
@@ -0,0 +1,898 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+import java.util.Arrays;
+
+/**
+ * Convenience methods related to Java class names as returned by
+ * {@link java.lang.Class#getName()}.
+ */
+@SuppressWarnings("nls")
+public final class ClassNameTools {
+
+	public static final String VOID = ClassTools.VOID.getName();
+	public static final char[] VOID_CHAR_ARRAY = VOID.toCharArray();
+	public static final String VOID_WRAPPER = ClassTools.VOID_WRAPPER.getName();
+	public static final char[] VOID_WRAPPER_CHAR_ARRAY = VOID_WRAPPER.toCharArray();
+
+	public static final char REFERENCE_CLASS_CODE = 'L';
+	public static final char REFERENCE_CLASS_NAME_DELIMITER = ';';
+
+	public static final String BRACKETS = "[]";
+	public static final char[] BRACKETS_CHAR_ARRAY = BRACKETS.toCharArray();
+
+
+	// ********** is array **********
+
+	/**
+	 * Return whether the specified class is an array type.
+	 * @see java.lang.Class#getName()
+	 */
+	public static boolean isArray(String className) {
+		return className.charAt(0) == '[';
+	}
+
+	/**
+	 * @see #isArray(String)
+	 */
+	public static boolean isArray(char[] className) {
+		return className[0] == '[';
+	}
+
+
+	// ********** array depth **********
+
+	/**
+	 * Return the "array depth" of the specified class.
+	 * The depth is the number of dimensions for an array type.
+	 * Non-array types have a depth of zero.
+	 * @see java.lang.Class#getName()
+	 */
+	public static int arrayDepth(String className) {
+		int depth = 0;
+		while (className.charAt(depth) == '[') {
+			depth++;
+		}
+		return depth;
+	}
+
+	/**
+	 * @see #arrayDepth(String)
+	 */
+	public static int arrayDepth(char[] className) {
+		int depth = 0;
+		while (className[depth] == '[') {
+			depth++;
+		}
+		return depth;
+	}
+
+
+	// ********** element type name **********
+
+	/**
+	 * Return the "element type" of the specified class.
+	 * The element type is the base type held by an array type.
+	 * Non-array types simply return themselves.
+	 * @see java.lang.Class#getName()
+	 */
+	public static String elementTypeName(String className) {
+		int depth = arrayDepth(className);
+		return (depth == 0) ?
+				className :  // the name is in the form: "java.lang.Object" or "I"
+				elementTypeName_(className, depth);
+	}
+
+	/**
+	 * Pre-condition: array depth is not zero
+	 */
+	private static String elementTypeName_(String className, int arrayDepth) {
+		int last = className.length() - 1;
+		if (className.charAt(arrayDepth) == REFERENCE_CLASS_CODE) {
+			// the name is in the form: "[[[Ljava.lang.Object;"
+			return className.substring(arrayDepth + 1, last);	// drop the trailing ';'
+		}
+		// the name is in the form: "[[[I"
+		return forCode(className.charAt(last));
+	}
+
+	/**
+	 * @see #elementTypeName(String)
+	 */
+	public static char[] elementTypeName(char[] className) {
+		int depth = arrayDepth(className);
+		return (depth == 0) ?
+				className :  // the name is in the form: "java.lang.Object" or "I"
+				elementTypeName_(className, depth);
+	}
+
+	/**
+	 * Pre-condition: array depth is not zero
+	 */
+	private static char[] elementTypeName_(char[] className, int arrayDepth) {
+		int last = className.length - 1;
+		if (className[arrayDepth] == REFERENCE_CLASS_CODE) {
+			// the name is in the form: "[[[Ljava.lang.Object;"
+			return ArrayTools.subArray(className, arrayDepth + 1, last);	// drop the trailing ';'
+		}
+		// the name is in the form: "[[[I"
+		return forCodeCharArray(className[last]);
+	}
+
+
+	// ********** component type name **********
+
+	/**
+	 * Return the specified class's component type.
+	 * Return <code>null</code> if the specified class is not an array type.
+	 * @see java.lang.Class#getName()
+	 */
+	public static String componentTypeName(String className) {
+		switch (arrayDepth(className)) {
+			case 0:
+				return null;
+			case 1:
+				return elementTypeName_(className, 1);
+			default:
+				return className.substring(1);
+		}
+	}
+
+	/**
+	 * @see #componentTypeName(String)
+	 */
+	public static char[] componentTypeName(char[] className) {
+		switch (arrayDepth(className)) {
+			case 0:
+				return null;
+			case 1:
+				return elementTypeName_(className, 1);
+			default:
+				return ArrayTools.subArray(className, 1, className.length);
+		}
+	}
+
+
+	// ********** type declaration **********
+
+	/**
+	 * Return the type declaration for the specified class name; e.g.<ul>
+	 * <li><code>"int"</code> returns <code>"int"</code>
+	 * <li><code>"[I"</code> returns <code>"int[]"</code>
+	 * <li><code>"java.lang.String"</code> returns <code>"java.lang.String"</code>
+	 * <li><code>"[[[Ljava.lang.String;"</code> returns <code>"java.lang.String[][][]"</code>
+	 * </ul>
+	 * @see java.lang.Class#getName()
+	 */
+	public static String typeDeclaration(String className) {
+		int arrayDepth = arrayDepth(className);
+		return (arrayDepth == 0) ? className : typeDeclaration_(className, arrayDepth);
+	}
+
+	/**
+	 * Pre-condition: array depth is not zero
+	 */
+	private static String typeDeclaration_(String className, int arrayDepth) {
+		String elementTypeName = elementTypeName_(className, arrayDepth);
+		StringBuilder sb = new StringBuilder(elementTypeName.length() + (arrayDepth << 1));
+		sb.append(elementTypeName);
+		for (int i = 0; i < arrayDepth; i++) {
+			sb.append(BRACKETS);
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * @see #typeDeclaration(String)
+	 */
+	public static char[] typeDeclaration(char[] className) {
+		int arrayDepth = arrayDepth(className);
+		return (arrayDepth == 0) ? className : typeDeclaration_(className, arrayDepth);
+	}
+
+	/**
+	 * Pre-condition: array depth is not zero
+	 */
+	private static char[] typeDeclaration_(char[] className, int arrayDepth) {
+		char[] elementTypeName = elementTypeName_(className, arrayDepth);
+		StringBuilder sb = new StringBuilder(elementTypeName.length + (arrayDepth << 1));
+		sb.append(elementTypeName);
+		for (int i = 0; i < arrayDepth; i++) {
+			sb.append(BRACKETS);
+		}
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+
+	// ********** package/simple name **********
+
+	/**
+	 * Return the specified class's simple name.
+	 * Return an empty string if the specified class is anonymous.
+	 * <p>
+	 * The simple name of an array type is the simple name of the
+	 * component type with <code>"[]"</code> appended. In particular,
+	 * the simple name of an array type whose component type is
+	 * anonymous is simply <code>"[]"</code>.
+	 * @see java.lang.Class#getSimpleName()
+	 */
+	public static String simpleName(String className) {
+		return isArray(className) ?
+				simpleName(componentTypeName(className)) + BRACKETS : // recurse
+				simpleName_(className);
+	}
+
+	/**
+	 * Pre-condition: specified class is not an array type
+	 */
+	private static String simpleName_(String className) {
+		int index = className.lastIndexOf('$');
+		if (index == -1) {  // "top-level" class - strip package name
+			return className.substring(className.lastIndexOf('.') + 1);
+		}
+
+		int len = className.length();
+		for (int i = ++index; i < len; i++) {
+			if ( ! charIsAsciiDigit(className.charAt(i))) {
+				return className.substring(i);  // "member" or "local" class
+			}
+		}
+		// all the characters past the '$' are ASCII digits ("anonymous" class)
+		return StringTools.EMPTY_STRING;
+	}
+
+	/**
+	 * @see #simpleName(String)
+	 */
+	public static char[] simpleName(char[] className) {
+		return isArray(className) ?
+				ArrayTools.addAll(simpleName(componentTypeName(className)), BRACKETS_CHAR_ARRAY) : // recurse
+				simpleName_(className);
+	}
+
+	/**
+	 * Pre-condition: specified class is not an array type
+	 */
+	private static char[] simpleName_(char[] className) {
+		int index = ArrayTools.lastIndexOf(className, '$');
+		if (index == -1) {  // "top-level" class - strip package name
+			return ArrayTools.subArray(className, (ArrayTools.lastIndexOf(className, '.') + 1), className.length);
+		}
+
+		int len = className.length;
+		for (int i = ++index; i < len; i++) {
+			if ( ! charIsAsciiDigit(className[i])) {
+				return ArrayTools.subArray(className, i, className.length);  // "member" or "local" class
+			}
+		}
+		// all the characters past the '$' are ASCII digits ("anonymous" class)
+		return CharArrayTools.EMPTY_CHAR_ARRAY;
+	}
+
+	/**
+	 * Return the specified class's package name (e.g.
+	 * <code>"java.lang.Object"</code> returns
+	 * <code>"java.lang"</code>).
+	 * Return an empty string if the specified class is:<ul>
+	 * <li>in the "default" package
+	 * <li>an array class
+	 * <li>a primtive class
+	 * </ul>
+	 * @see java.lang.Class#getPackage()
+	 * @see java.lang.Package#getName()
+	 */
+	public static String packageName(String className) {
+		if (isArray(className)) {
+			return StringTools.EMPTY_STRING;
+		}
+		int lastPeriod = className.lastIndexOf('.');
+		return (lastPeriod == -1) ? StringTools.EMPTY_STRING : className.substring(0, lastPeriod);
+	}
+
+	/**
+	 * @see #packageName(String)
+	 */
+	public static char[] packageName(char[] className) {
+		if (isArray(className)) {
+			return CharArrayTools.EMPTY_CHAR_ARRAY;
+		}
+		int lastPeriod = ArrayTools.lastIndexOf(className, '.');
+		return (lastPeriod == -1) ?
+				CharArrayTools.EMPTY_CHAR_ARRAY :
+				ArrayTools.subArray(className, 0, lastPeriod);
+	}
+
+
+	// ********** top-level/member/local/anonymous **********
+
+	/**
+	 * Return whether the specified class is a "top-level" class,
+	 * as opposed to a "member", "local", or "anonymous" class,
+	 * using the standard JDK naming conventions (i.e. the class
+	 * name does NOT contain a <code>'$'</code>).
+	 * A "top-level" class can be either the "primary" (public) class defined
+	 * in a file/compilation unit (i.e. the class with the same name as its
+	 * file's simple base name) or a "non-primary" (package visible) class
+	 * (i.e. the other top-level classes defined in a file).
+	 * A "top-level" class can contain any of the other types of classes.
+	 * @see java.lang.Class#getName()
+	 */
+	public static boolean isTopLevel(String className) {
+		if (isArray(className)) {
+			return false;
+		}
+		return className.lastIndexOf('$') == -1;
+	}
+
+	/**
+	 * @see #isTopLevel(String)
+	 */
+	public static boolean isTopLevel(char[] className) {
+		if (isArray(className)) {
+			return false;
+		}
+		return ArrayTools.lastIndexOf(className, '$') == -1;
+	}
+
+	/**
+	 * Return whether the specified class is a "member" class,
+	 * as opposed to a "top-level", "local", or "anonymous" class,
+	 * using the standard JDK naming convention (i.e. the class
+	 * name ends with a <code>'$'</code> followed by a legal class name; e.g.
+	 * <code>"TopLevelClass$1LocalClass$MemberClass"</code>).
+	 * A "member" class can be either "nested" (static) or "inner";
+	 * but there is no way to determine which from the class's name.
+	 * A "member" class can contain "local", "anonymous", or other
+	 * "member" classes; and vice-versa.
+	 * @see java.lang.Class#getName()
+	 */
+	public static boolean isMember(String className) {
+		if (isArray(className)) {
+			return false;
+		}
+		int index = className.lastIndexOf('$');
+		if (index == -1) {
+			return false;	// "top-level" class
+		}
+		// the character immediately after the dollar sign cannot be an ASCII digit
+		return ! charIsAsciiDigit(className.charAt(++index));
+	}
+
+	/**
+	 * @see #isMember(String)
+	 */
+	public static boolean isMember(char[] className) {
+		if (isArray(className)) {
+			return false;
+		}
+		int index = ArrayTools.lastIndexOf(className, '$');
+		if (index == -1) {
+			return false;	// "top-level" class
+		}
+		// the character immediately after the dollar sign cannot be an ASCII digit
+		return ! charIsAsciiDigit(className[++index]);
+	}
+
+	/**
+	 * Return whether the specified class is a "local" class,
+	 * as opposed to a "top-level", "member", or "anonymous" class,
+	 * using the standard JDK naming convention (i.e. the class name
+	 * ends with <code>"$nnnXXX"</code>,
+	 * where the <code>'$'</code> is
+	 * followed by a series of numeric digits which are followed by the
+	 * local class name; e.g. <code>"TopLevelClass$1LocalClass"</code>).
+	 * A "local" class can contain "member", "anonymous", or other
+	 * "local" classes; and vice-versa.
+	 * @see java.lang.Class#getName()
+	 */
+	public static boolean isLocal(String className) {
+		if (isArray(className)) {
+			return false;
+		}
+		int index = className.lastIndexOf('$');
+		if (index == -1) {
+			return false;	// "top-level" class
+		}
+		if ( ! charIsAsciiDigit(className.charAt(++index))) {
+			return false;  // "member" class
+		}
+		int len = className.length();
+		for (int i = ++index; i < len; i++) {
+			if ( ! charIsAsciiDigit(className.charAt(i))) {
+				return true;
+			}
+		}
+		// all the characters past the '$' are ASCII digits ("anonymous" class)
+		return false;
+	}
+
+	/**
+	 * @see #isLocal(String)
+	 */
+	public static boolean isLocal(char[] className) {
+		if (isArray(className)) {
+			return false;
+		}
+		int index = ArrayTools.lastIndexOf(className, '$');
+		if (index == -1) {
+			return false;	// "top-level" class
+		}
+		if ( ! charIsAsciiDigit(className[++index])) {
+			return false;  // "member" class
+		}
+		int len = className.length;
+		for (int i = ++index; i < len; i++) {
+			if ( ! charIsAsciiDigit(className[i])) {
+				return true;
+			}
+		}
+		// all the characters past the '$' are ASCII digits ("anonymous" class)
+		return false;
+	}
+
+	/**
+	 * Return whether the specified class is an "anonymous" class,
+	 * as opposed to a "top-level", "member", or "local" class,
+	 * using the standard JDK naming convention (i.e. the class
+	 * name ends with <code>"$nnn"</code> where all the characters past the
+	 * last <code>'$'</code> are ASCII numeric digits;
+	 * e.g. <code>"TopLevelClass$1"</code>).
+	 * An "anonymous" class can contain "member", "local", or other
+	 * "anonymous" classes; and vice-versa.
+	 * @see java.lang.Class#getName()
+	 */
+	public static boolean isAnonymous(String className) {
+		if (isArray(className)) {
+			return false;
+		}
+		int index = className.lastIndexOf('$');
+		if (index == -1) {
+			return false;	// "top-level" class
+		}
+		if ( ! charIsAsciiDigit(className.charAt(++index))) {
+			return false;  // "member" class
+		}
+		int len = className.length();
+		for (int i = ++index; i < len; i++) {
+			if ( ! charIsAsciiDigit(className.charAt(i))) {
+				return false;  // "local" class
+			}
+		}
+		// all the characters past the '$' are ASCII digits ("anonymous" class)
+		return true;
+	}
+
+	/**
+	 * @see #isAnonymous(String)
+	 */
+	public static boolean isAnonymous(char[] className) {
+		if (isArray(className)) {
+			return false;
+		}
+		int index = ArrayTools.lastIndexOf(className, '$');
+		if (index == -1) {
+			return false;	// "top-level" class
+		}
+		if ( ! charIsAsciiDigit(className[++index])) {
+			return false;  // "member" class
+		}
+		int len = className.length;
+		for (int i = ++index; i < len; i++) {
+			if ( ! charIsAsciiDigit(className[i])) {
+				return false;  // "local" class
+			}
+		}
+		// all the characters past the '$' are ASCII digits ("anonymous" class)
+		return true;
+	}
+
+	/**
+	 * {@link Character#isDigit(char)} returns <code>true</code> for some non-ASCII
+	 * digits. This method does not.
+	 */
+	private static boolean charIsAsciiDigit(char c) {
+		return ('0' <= c) && (c <= '9');
+	}
+
+
+	// ********** reference/primitive **********
+
+	/**
+	 * Return whether the specified class is a "reference"
+	 * class (i.e. neither <code>void</code> nor one of the primitive variable classes,
+	 * <code>boolean</code>, <code>int</code>, <code>float</code>, etc.).
+	 * <p>
+	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
+	 */
+	public static boolean isReference(String className) {
+		return ! isPrimitive(className);
+	}
+
+	/**
+	 * @see #isReference(String)
+	 */
+	public static boolean isReference(char[] className) {
+		return ! isPrimitive(className);
+	}
+
+	/**
+	 * Return whether the specified class is a primitive
+	 * class (i.e. <code>void</code> or one of the primitive variable classes,
+	 * <code>boolean</code>, <code>int</code>, <code>float</code>, etc.).
+	 * <p>
+	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
+	 */
+	public static boolean isPrimitive(String className) {
+		if (isArray(className) || (className.length() > ClassTools.MAX_PRIMITIVE_CLASS_NAME_LENGTH)) {
+			return false;  // performance tweak
+		}
+		for (ClassTools.Primitive primitive : ClassTools.PRIMITIVES) {
+			if (className.equals(primitive.javaClass.getName())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * @see #isPrimitive(String)
+	 */
+	public static boolean isPrimitive(char[] className) {
+		if (isArray(className) || (className.length > ClassTools.MAX_PRIMITIVE_CLASS_NAME_LENGTH)) {
+			return false;  // performance tweak
+		}
+		for (ClassTools.Primitive primitive : ClassTools.PRIMITIVES) {
+			if (Arrays.equals(className, primitive.javaClassName)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Return whether the specified class is a primitive wrapper
+	 * class (i.e. <code>java.lang.Void</code> or one of the primitive
+	 * variable wrapper classes, <code>java.lang.Boolean</code>,
+	 * <code>java.lang.Integer</code>, <code>java.lang.Float</code>, etc.).
+	 * <p>
+	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
+	 */
+	public static boolean isPrimitiveWrapper(String className) {
+		if (isArray(className) || (className.length() > ClassTools.MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH)) {
+			return false;  // performance tweak
+		}
+		for (ClassTools.Primitive primitive : ClassTools.PRIMITIVES) {
+			if (className.equals(primitive.wrapperClass.getName())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * @see #isPrimitiveWrapper(String)
+	 */
+	public static boolean isPrimitiveWrapper(char[] className) {
+		if (isArray(className) || (className.length > ClassTools.MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH)) {
+			return false;  // performance tweak
+		}
+		for (ClassTools.Primitive primitive : ClassTools.PRIMITIVES) {
+			if (Arrays.equals(className, primitive.wrapperClassName)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Return whether the specified class is a "variable" primitive
+	 * class (i.e. <code>boolean</code>, <code>int</code>, <code>float</code>, etc.,
+	 * but not <code>void</code>).
+	 * <p>
+	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
+	 */
+	public static boolean isVariablePrimitive(String className) {
+		return isPrimitive(className)
+			&& ( ! className.equals(VOID));
+	}
+
+	/**
+	 * @see #isVariablePrimitive(String)
+	 */
+	public static boolean isVariablePrimitive(char[] className) {
+		return isPrimitive(className)
+			&& ( ! Arrays.equals(className, VOID_CHAR_ARRAY));
+	}
+
+	/**
+	 * Return whether the specified class is a "variable" primitive wrapper
+	 * class (i.e. <code>java.lang.Boolean</code>,
+	 * <code>java.lang.Integer</code>, <code>java.lang.Float</code>, etc.,
+	 * but not <code>java.lang.Void</code>).
+	 * <p>
+	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
+	 */
+	public static boolean isVariablePrimitiveWrapper(String className) {
+		return isPrimitiveWrapper(className)
+			&& ( ! className.equals(VOID_WRAPPER));
+	}
+
+	/**
+	 * @see #isVariablePrimitiveWrapper(String)
+	 */
+	public static boolean isVariablePrimitiveWrapper(char[] className) {
+		return isPrimitiveWrapper(className)
+			&& ( ! Arrays.equals(className, VOID_WRAPPER_CHAR_ARRAY));
+	}
+
+	/**
+	 * Return the name of the primitive wrapper class corresponding to the specified
+	 * primitive class. Return <code>null</code> if the specified class is not a primitive.
+	 */
+	public static String primitiveWrapperClassName(String primitiveClassName) {
+		for (ClassTools.Primitive primitive : ClassTools.PRIMITIVES) {
+			if (primitive.javaClass.getName().equals(primitiveClassName)) {
+				return primitive.wrapperClass.getName();
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @see #primitiveWrapperClassName(String)
+	 */
+	public static char[] primitiveWrapperClassName(char[] primitiveClassName) {
+		for (ClassTools.Primitive primitive : ClassTools.PRIMITIVES) {
+			if (Arrays.equals(primitive.javaClassName, primitiveClassName)) {
+				return primitive.wrapperClassName;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Return the name of the primitive class corresponding to the specified
+	 * primitive wrapper class. Return <code>null</code> if the specified class
+	 * is not a primitive wrapper.
+	 */
+	public static String primitiveClassName(String primitiveWrapperClassName) {
+		for (ClassTools.Primitive primitive : ClassTools.PRIMITIVES) {
+			if (primitive.wrapperClass.getName().equals(primitiveWrapperClassName)) {
+				return primitive.javaClass.getName();
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @see #primitiveClassName(String)
+	 */
+	public static char[] primitiveClassName(char[] primitiveWrapperClassName) {
+		for (ClassTools.Primitive primitive : ClassTools.PRIMITIVES) {
+			if (Arrays.equals(primitive.wrapperClassName, primitiveWrapperClassName)) {
+				return primitive.javaClassName;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Return whether the two class names are equivalent, given autoboxing.
+	 * (e.g. <code>"java.lang.Integer"</code> and <code>"int"</code> are equivalent)
+	 */
+	public static boolean isAutoboxEquivalent(String className1, String className2) {
+		return ObjectTools.equals(className1, className2)
+			|| ObjectTools.equals(primitiveClassName(className1), className2)
+			|| ObjectTools.equals(primitiveWrapperClassName(className1), className2);
+	}
+
+	/**
+	 * @see #isAutoboxEquivalent(String, String)
+	 */
+	public static boolean isAutoboxEquivalent(char[] className1, char[] className2) {
+		return Arrays.equals(className1, className2)
+			|| Arrays.equals(primitiveClassName(className1), className2)
+			|| Arrays.equals(primitiveWrapperClassName(className1), className2);
+	}
+
+
+	// ********** primitive codes **********
+
+	/**
+	 * Return the primitive class name for the specified primitive class code.
+	 * Return <code>null</code> if the specified code
+	 * is not a primitive class code.
+	 * @see java.lang.Class#getName()
+	 */
+	public static String forCode(int classCode) {
+		return forCode((char) classCode);
+	}
+
+	/**
+	 * @see #forCode(int)
+	 */
+	public static char[] forCodeCharArray(int classCode) {
+		return forCodeCharArray((char) classCode);
+	}
+
+	/**
+	 * Return the primitive class name for the specified primitive class code.
+	 * Return <code>null</code> if the specified code
+	 * is not a primitive class code.
+	 * @see java.lang.Class#getName()
+	 */
+	public static String forCode(char classCode) {
+		Class<?> primitiveClass = ClassTools.primitiveForCode(classCode);
+		return (primitiveClass == null) ? null : primitiveClass.getName();
+	}
+
+	/**
+	 * @see #forCode(char)
+	 */
+	public static char[] forCodeCharArray(char classCode) {
+		Class<?> primitiveClass = ClassTools.primitiveForCode(classCode);
+		return (primitiveClass == null) ? null : primitiveClass.getName().toCharArray();
+	}
+
+	/**
+	 * Return the class code for the specified primitive class.
+	 * Return <code>0</code> if the specified class
+	 * is not a primitive class.
+	 * @see java.lang.Class#getName()
+	 */
+	public static char primitiveClassCode(String primitiveClassName) {
+		if (( ! isArray(primitiveClassName)) && (primitiveClassName.length() <= ClassTools.MAX_PRIMITIVE_CLASS_NAME_LENGTH)) {
+			for (ClassTools.Primitive primitive : ClassTools.PRIMITIVES) {
+				if (primitive.javaClass.getName().equals(primitiveClassName)) {
+					return primitive.code;
+				}
+			}
+		}
+		return 0;
+	}
+
+	/**
+	 * @see #primitiveClassCode(String)
+	 */
+	public static char primitiveClassCode(char[] primitiveClassName) {
+		if (( ! isArray(primitiveClassName)) && (primitiveClassName.length <= ClassTools.MAX_PRIMITIVE_CLASS_NAME_LENGTH)) {
+			for (ClassTools.Primitive primitive : ClassTools.PRIMITIVES) {
+				if (Arrays.equals(primitive.javaClassName, primitiveClassName)) {
+					return primitive.code;
+				}
+			}
+		}
+		return 0;
+	}
+
+	static void appendReferenceNameTo(String className, StringBuilder sb) {
+		sb.append(REFERENCE_CLASS_CODE);
+		sb.append(className);
+		sb.append(REFERENCE_CLASS_NAME_DELIMITER);
+	}
+
+	static void appendReferenceNameTo(char[] className, StringBuilder sb) {
+		sb.append(REFERENCE_CLASS_CODE);
+		sb.append(className);
+		sb.append(REFERENCE_CLASS_NAME_DELIMITER);
+	}
+
+
+	// ********** instantiation **********
+
+	/**
+	 * Return a new instance of the specified class,
+	 * using the class's default (zero-argument) constructor.
+	 */
+	public static Object newInstance(String className) {
+		return newInstance(className, null);
+	}
+
+	/**
+	 * @see #newInstance(String)
+	 */
+	public static Object newInstance(char[] className) {
+		return newInstance(className, null);
+	}
+
+	/**
+	 * Return a new instance of the specified class,
+	 * given the constructor parameter type and argument.
+	 */
+	public static Object newInstance(String className, Class<?> parameterType, Object argument) {
+		return newInstance(className, parameterType, argument, null);
+	}
+
+	/**
+	 * @see #newInstance(String, Class, Object)
+	 */
+	public static Object newInstance(char[] className, Class<?> parameterType, Object argument) {
+		return newInstance(className, parameterType, argument, null);
+	}
+
+	/**
+	 * Return a new instance of the specified class,
+	 * given the constructor parameter types and arguments.
+	 */
+	public static Object newInstance(String className, Class<?>[] parameterTypes, Object... arguments) {
+		return newInstance(className, parameterTypes, arguments, null);
+	}
+
+	/**
+	 * @see #newInstance(String, Class[], Object[])
+	 */
+	public static Object newInstance(char[] className, Class<?>[] parameterTypes, Object... arguments) {
+		return newInstance(className, parameterTypes, arguments, null);
+	}
+
+	/**
+	 * Return a new instance of the specified class,
+	 * using the class's default (zero-argument) constructor.
+	 * Use the specified class loader to load the class.
+	 */
+	public static Object newInstance(String className, ClassLoader classLoader) {
+		return ClassTools.newInstance(ClassTools.forName(className, false, classLoader));
+	}
+
+	/**
+	 * @see #newInstance(String, ClassLoader)
+	 */
+	public static Object newInstance(char[] className, ClassLoader classLoader) {
+		return ClassTools.newInstance(ClassTools.forName(className, false, classLoader));
+	}
+
+	/**
+	 * Return a new instance of the specified class,
+	 * given the constructor parameter type and argument.
+	 * Use the specified class loader to load the class.
+	 */
+	public static Object newInstance(String className, Class<?> parameterType, Object argument, ClassLoader classLoader) {
+		return ClassTools.newInstance(ClassTools.forName(className, false, classLoader), parameterType, argument);
+	}
+
+	/**
+	 * @see #newInstance(String, Class, Object, ClassLoader)
+	 */
+	public static Object newInstance(char[] className, Class<?> parameterType, Object argument, ClassLoader classLoader) {
+		return ClassTools.newInstance(ClassTools.forName(className, false, classLoader), parameterType, argument);
+	}
+
+	/**
+	 * Return a new instance of the specified class,
+	 * given the constructor parameter types and arguments.
+	 * Use the specified class loader to load the class.
+	 */
+	public static Object newInstance(String className, Class<?>[] parameterTypes, Object[] arguments, ClassLoader classLoader) {
+		return ClassTools.newInstance(ClassTools.forName(className, false, classLoader), parameterTypes, arguments);
+	}
+
+	/**
+	 * @see #newInstance(String, Class[], Object[], ClassLoader)
+	 */
+	public static Object newInstance(char[] className, Class<?>[] parameterTypes, Object[] arguments, ClassLoader classLoader) {
+		return ClassTools.newInstance(ClassTools.forName(className, false, classLoader), parameterTypes, arguments);
+	}
+
+
+	// ********** suppressed constructor **********
+
+	/**
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private ClassNameTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ClassTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ClassTools.java
new file mode 100644
index 0000000..f3f4f1b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ClassTools.java
@@ -0,0 +1,1126 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+
+/**
+ * {@link Class} utility methods.
+ * <p>
+ * There are a number of convenience reflection methods.
+ * These methods provide shortcuts for manipulating classes via
+ * reflection; particularly when dealing with fields and/or methods that
+ * are not publicly accessible or are inherited.
+ * <p>
+ * In most cases, all exceptions are handled and wrapped in
+ * {@link java.lang.RuntimeException}s; so these methods should
+ * be used when there should be no problems using reflection (i.e.
+ * the referenced members are presumably present etc.).
+ * <p>
+ * There are also a number of methods whose names
+ * end with an underscore. These methods declare the expected checked
+ * exceptions (e.g. {@link NoSuchMethodException}, {@link NoSuchFieldException}).
+ * These methods can be used to probe
+ * for methods, fields, etc. that should be present but might not be.
+ */
+@SuppressWarnings("nls")
+public final class ClassTools {
+
+	public static final Class<?>[] EMPTY_ARRAY = new Class[0];
+
+	public static final Class<?> VOID = void.class;
+	public static final Class<java.lang.Void> VOID_WRAPPER = java.lang.Void.class;
+
+
+	// ********** load class **********
+
+	/**
+	 * Return the specified class (without the checked exception).
+	 * @see Class#forName(String)
+	 */
+	public static Class<?> forName(String className) {
+		try {
+			return Class.forName(className);
+		} catch (ClassNotFoundException ex) {
+			throw new RuntimeException(className, ex);
+		}
+	}
+
+	/**
+	 * @see #forName(String)
+	 */
+	public static Class<?> forName(char[] className) {
+		return forName(String.copyValueOf(className));
+	}
+
+	/**
+	 * @see Class#forName(String)
+	 */
+	public static Class<?> forName_(char[] className) throws ClassNotFoundException {
+		return Class.forName(String.copyValueOf(className));
+	}
+
+	/**
+	 * Return the specified class (without the checked exception).
+	 * @see Class#forName(String, boolean, ClassLoader)
+	 */
+	public static Class<?> forName(String className, boolean initialize, ClassLoader classLoader) {
+		try {
+			return Class.forName(className, initialize, classLoader);
+		} catch (ClassNotFoundException ex) {
+			throw new RuntimeException(className, ex);
+		}
+	}
+
+	/**
+	 * @see #forName(String, boolean, ClassLoader)
+	 */
+	public static Class<?> forName(char[] className, boolean initialize, ClassLoader classLoader) {
+		return forName(String.copyValueOf(className), initialize, classLoader);
+	}
+
+	/**
+	 * @see Class#forName(String, boolean, ClassLoader)
+	 */
+	public static Class<?> forName_(char[] className, boolean initialize, ClassLoader classLoader) throws ClassNotFoundException {
+		return Class.forName(String.copyValueOf(className), initialize, classLoader);
+	}
+
+
+	// ********** string representation **********
+
+	/**
+	 * Return a class name suitable for a "Dali standard"
+	 * {@link Object#toString() toString()} implementation.
+	 * {@link Class#getSimpleName()} isn't quite useful enough:<ul>
+	 * <li>An <em>anonymous</em> class's simple name is an empty string.
+	 *     Return the "Dali standard" name of the anonymous class's super class
+	 *     instead, which is a bit more helpful.
+	 * <li>A <em>member</em> or <em>local</em> class's simple name does not
+	 *     include its context. Prefix the class's simple name with its
+	 *     enclosing class's "Dali standard" name.
+	 * </ul>
+	 * @see Object#toString()
+	 */
+	public static String toStringName(Class<?> javaClass) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.appendToStringName(sb, javaClass);
+		return sb.toString();
+	}
+
+	/**
+	 * Append a class name suitable for a "Dali standard"
+	 * {@link Object#toString() toString()} implementation to the specified
+	 * string builder.
+	 *
+	 * @see #toStringName(Class)
+	 * @see Object#toString()
+	 */
+	static void appendToStringNameTo(Class<?> javaClass, StringBuilder sb) {
+		if (javaClass.isAnonymousClass()) {
+			appendToStringNameTo(javaClass.getSuperclass(), sb);  // recurse
+		} else {
+			Class<?> enclosingClass = javaClass.getEnclosingClass();
+			if (enclosingClass == null) {
+				appendTopLevelToStringNameTo(javaClass, sb);  // top-level class
+			} else {
+				appendToStringNameTo(enclosingClass, sb);  // recurse
+				sb.append('.');
+				sb.append(javaClass.getSimpleName());
+			}
+		}
+	}
+
+	/**
+	 * Pre-condition: the specified class is a top-level class
+	 */
+	private static void appendTopLevelToStringNameTo(Class<?> javaClass, StringBuilder sb) {
+		String fullName = javaClass.getName();
+		int dot = fullName.lastIndexOf('.');
+		if (dot == -1) {
+			sb.append(fullName);  // "default" package
+		} else {
+			sb.append(fullName, dot + 1, fullName.length());  // NB: end index is exclusive
+		}
+	}
+
+
+	// ********** fields **********
+
+	/**
+	 * Return the value of the specified class's static field with the specified
+	 * name. Useful for accessing private, package, or protected fields.
+	 * @see Field#get(Object)
+	 */
+	public static Object get(Class<?> javaClass, String fieldName) {
+		try {
+			return get_(javaClass, fieldName);
+		} catch (NoSuchFieldException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
+		} catch (IllegalAccessException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
+		}
+	}
+
+	/**
+	 * @see #get(Class, String)
+	 */
+	public static Object get_(Class<?> javaClass, String fieldName)
+		throws NoSuchFieldException, IllegalAccessException
+	{
+		return field_(javaClass, fieldName).get(null);
+	}
+
+	/**
+	 * Set the value of the specified class's static field with the specified
+	 * name to the specified value. Useful for accessing private, package, or
+	 * protected fields.
+	 * @see Field#set(Object, Object)
+	 */
+	public static void set(Class<?> javaClass, String fieldName, Object value) {
+		try {
+			set_(javaClass, fieldName, value);
+		} catch (NoSuchFieldException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
+		} catch (IllegalAccessException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
+		}
+	}
+
+	/**
+	 * @see #set(Class, String, Object)
+	 */
+	public static void set_(Class<?> javaClass, String fieldName, Object value)
+		throws NoSuchFieldException, IllegalAccessException
+	{
+		field_(javaClass, fieldName).set(null, value);
+	}
+
+	/**
+	 * Return the specified class's field with the specified name.
+	 * If the class does not directly
+	 * define the field, look for it in the class's superclasses.
+	 * Make any private/package/protected field accessible.
+	 * @see Class#getDeclaredField(String)
+	 */
+	public static Field field(Class<?> javaClass, String fieldName) {
+		try {
+			return field_(javaClass, fieldName);
+		} catch (NoSuchFieldException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
+		}
+	}
+
+	/**
+	 * @see #field(Class, String)
+	 */
+	public static Field field_(Class<?> javaClass, String fieldName)
+		throws NoSuchFieldException
+	{
+		Field field = null;
+		try {
+			field = javaClass.getDeclaredField(fieldName);
+		} catch (NoSuchFieldException ex) {
+			Class<?> superclass = javaClass.getSuperclass();
+			if (superclass == null) {
+				throw ex;
+			}
+			return field_(superclass, fieldName);  // recurse
+		}
+		field.setAccessible(true);
+		return field;
+	}
+
+	/**
+	 * Return all the fields for the
+	 * specified class, including inherited fields.
+	 * Make any private/package/protected fields accessible.
+	 * @see Class#getDeclaredFields()
+	 */
+	public static Iterable<Field> allFields(Class<?> javaClass) {
+		ArrayList<Field> fields = new ArrayList<Field>();
+		for (Class<?> tempClass = javaClass; tempClass != null; tempClass = tempClass.getSuperclass()) {
+			CollectionTools.addAll(fields, declaredFields(tempClass));
+		}
+		return makeAccessible(fields);
+	}
+
+	/**
+	 * Return the declared fields for the specified class.
+	 * Make any private/package/protected fields accessible.
+	 * @see Class#getDeclaredFields()
+	 */
+	public static Iterable<Field> declaredFields(Class<?> javaClass) {
+		return makeAccessible(IterableTools.iterable(javaClass.getDeclaredFields()));
+	}
+
+
+	// ********** methods **********
+
+	/**
+	 * Execute the specified zero-argument static method.
+	 * Return its result.
+	 * Useful for invoking private, package, or protected methods.
+	 */
+	public static Object execute(Class<?> javaClass, String methodName) {
+		return execute(javaClass, methodName, EMPTY_ARRAY, ObjectTools.EMPTY_OBJECT_ARRAY);
+	}
+
+	/**
+	 * @see #execute(Class, String)
+	 */
+	public static Object execute_(Class<?> javaClass, String methodName)
+		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
+	{
+		return execute_(javaClass, methodName, EMPTY_ARRAY, ObjectTools.EMPTY_OBJECT_ARRAY);
+	}
+
+	/**
+	 * Execute the specified one-argument method.
+	 * Return its result.
+	 * Useful for invoking private, package, or protected methods.
+	 */
+	public static Object execute(Class<?> javaClass, String methodName, Class<?> parameterType, Object argument) {
+		return execute(javaClass, methodName, new Class[] {parameterType}, new Object[] {argument});
+	}
+
+	/**
+	 * @see #execute(Class, String, Class, Object)
+	 */
+	public static Object execute_(Class<?> javaClass, String methodName, Class<?> parameterType, Object argument)
+		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
+	{
+		return execute_(javaClass, methodName, new Class[] {parameterType}, new Object[] {argument});
+	}
+
+	/**
+	 * Execute the specified method.
+	 * Return its result.
+	 * Useful for invoking private, package, or protected methods.
+	 */
+	public static Object execute(Class<?> javaClass, String methodName, Class<?>[] parameterTypes, Object[] arguments) {
+		try {
+			return execute_(javaClass, methodName, parameterTypes, arguments);
+		} catch (NoSuchMethodException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), ex);
+		} catch (IllegalAccessException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), ex);
+		} catch (InvocationTargetException ex) {
+			throw new RuntimeException(buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes) + StringTools.CR + ex.getTargetException(), ex);
+		}
+	}
+
+	/**
+	 * @see #execute(Class, String, Class[], Object[])
+	 */
+	public static Object execute_(Class<?> javaClass, String methodName, Class<?>[] parameterTypes, Object[] arguments)
+		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
+	{
+		return staticMethod_(javaClass, methodName, parameterTypes).invoke(null, arguments);
+	}
+
+	/**
+	 * Return the specified class's zero-argument method with the specified
+	 * name. If the class does not directly
+	 * implement the method, look for it in the class's superclasses.
+	 * Make any private/package/protected method accessible.
+	 */
+	public static Method method(Class<?> javaClass, String methodName) {
+		return method(javaClass, methodName, EMPTY_ARRAY);
+	}
+
+	/**
+	 * @see #method(Class, String)
+	 */
+	public static Method method_(Class<?> javaClass, String methodName)
+		throws NoSuchMethodException
+	{
+		return method_(javaClass, methodName, EMPTY_ARRAY);
+	}
+
+	/**
+	 * Return the specified class's one-argument method with the specified
+	 * name and parameter type. If the class does not directly
+	 * implement the method, look for it in the class's superclasses.
+	 * Make any private/package/protected method accessible.
+	 */
+	public static Method method(Class<?> javaClass, String methodName, Class<?> parameterType) {
+		return method(javaClass, methodName, new Class[] {parameterType});
+	}
+
+	/**
+	 * @see #method(Class, String, Class)
+	 */
+	public static Method method_(Class<?> javaClass, String methodName, Class<?> parameterType)
+		throws NoSuchMethodException
+	{
+		return method_(javaClass, methodName, new Class[] {parameterType});
+	}
+
+	/**
+	 * Return the specified class's method with the specified
+	 * name and parameter types. If the class does not directly
+	 * implement the method, look for it in the class's superclasses.
+	 * Make any private/package/protected method accessible.
+	 */
+	public static Method method(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) {
+		try {
+			return method_(javaClass, methodName, parameterTypes);
+		} catch (NoSuchMethodException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), ex);
+		}
+	}
+
+	/**
+	 * @see #method(Class, String, Class[])
+	 */
+	public static Method method_(Class<?> javaClass, String methodName, Class<?>[] parameterTypes)
+		throws NoSuchMethodException
+	{
+		Method method = null;
+		try {
+			method = javaClass.getDeclaredMethod(methodName, parameterTypes);
+		} catch (NoSuchMethodException ex) {
+			Class<?> superclass = javaClass.getSuperclass();
+			if (superclass == null) {
+				throw ex;
+			}
+			// recurse
+			return method_(superclass, methodName, parameterTypes);
+		}
+		method.setAccessible(true);
+		return method;
+	}
+
+	/**
+	 * Return the zero-argument static method for the specified class
+	 * and method name. If the class does not directly
+	 * implement the method, look for it in the class's superclasses.
+	 * Make any private/package/protected method accessible.
+	 */
+	public static Method staticMethod(Class<?> javaClass, String methodName) {
+		return staticMethod(javaClass, methodName, EMPTY_ARRAY);
+	}
+
+	/**
+	 * @see #staticMethod(Class, String)
+	 */
+	public static Method staticMethod_(Class<?> javaClass, String methodName)
+		throws NoSuchMethodException
+	{
+		return staticMethod_(javaClass, methodName, EMPTY_ARRAY);
+	}
+
+	/**
+	 * Return the one-argument static method for the specified class, method name,
+	 * and formal parameter type. If the class does not directly
+	 * implement the method, look for it in the class's superclasses.
+	 * Make any private/package/protected method accessible.
+	 */
+	public static Method staticMethod(Class<?> javaClass, String methodName, Class<?> parameterType) {
+		return staticMethod(javaClass, methodName, new Class[] {parameterType});
+	}
+
+	/**
+	 * @see #staticMethod(Class, String, Class)
+	 */
+	public static Method staticMethod_(Class<?> javaClass, String methodName, Class<?> parameterType)
+		throws NoSuchMethodException
+	{
+		return staticMethod_(javaClass, methodName, new Class[] {parameterType});
+	}
+
+	/**
+	 * Return the static method for the specified class, method name,
+	 * and formal parameter types. If the class does not directly
+	 * implement the method, look for it in the class's superclasses.
+	 * Make any private/package/protected method accessible.
+	 */
+	public static Method staticMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) {
+		try {
+			return staticMethod_(javaClass, methodName, parameterTypes);
+		} catch (NoSuchMethodException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), ex);
+		}
+	}
+
+	/**
+	 * @see #staticMethod(Class, String, Class[])
+	 */
+	public static Method staticMethod_(Class<?> javaClass, String methodName, Class<?>[] parameterTypes)
+		throws NoSuchMethodException
+	{
+		Method method = method_(javaClass, methodName, parameterTypes);
+		if (Modifier.isStatic(method.getModifiers())) {
+			return method;
+		}
+		throw new NoSuchMethodException(buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes));
+	}
+
+	/**
+	 * Return all the methods for the
+	 * specified class, including inherited methods.
+	 * Make any private/package/protected methods accessible.
+	 */
+	public static Iterable<Method> allMethods(Class<?> javaClass) {
+		ArrayList<Method> methods = new ArrayList<Method>();
+		for (Class<?> tempClass = javaClass; tempClass != null; tempClass = tempClass.getSuperclass()) {
+			CollectionTools.addAll(methods, declaredMethods(tempClass));
+		}
+		return makeAccessible(methods);
+	}
+
+	/**
+	 * Return the declared methods for the specified class.
+	 * Make any private/package/protected methods accessible.
+	 */
+	public static Iterable<Method> declaredMethods(Class<?> javaClass) {
+		return makeAccessible(IterableTools.iterable(javaClass.getDeclaredMethods()));
+	}
+
+
+	// ********** constructors **********
+
+	/**
+	 * Return a new instance of the specified class,
+	 * using the class's default (zero-argument) constructor.
+	 */
+	public static <T> T newInstance(Class<T> javaClass) {
+		return newInstance(javaClass, EMPTY_ARRAY, ObjectTools.EMPTY_OBJECT_ARRAY);
+	}
+
+	/**
+	 * @see #newInstance(Class)
+	 */
+	public static <T> T newInstance_(Class<T> javaClass)
+		throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
+	{
+		return newInstance_(javaClass, EMPTY_ARRAY, ObjectTools.EMPTY_OBJECT_ARRAY);
+	}
+
+	/**
+	 * Return a new instance of the specified class,
+	 * given the constructor parameter type and argument.
+	 */
+	public static <T> T newInstance(Class<T> javaClass, Class<?> parameterType, Object argument) {
+		return newInstance(javaClass, new Class[] {parameterType}, new Object[] {argument});
+	}
+
+	/**
+	 * @see #newInstance(Class, Class, Object)
+	 */
+	public static <T> T newInstance_(Class<T> javaClass, Class<?> parameterType, Object argument)
+		throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
+	{
+		return newInstance_(javaClass, new Class[] {parameterType}, new Object[] {argument});
+	}
+
+	/**
+	 * Return a new instance of the specified class,
+	 * given the constructor parameter types and arguments.
+	 */
+	public static <T> T newInstance(Class<T> javaClass, Class<?>[] parameterTypes, Object... arguments) {
+		try {
+			return newInstance_(javaClass, parameterTypes, arguments);
+		} catch (InstantiationException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedConstructorSignature(javaClass, parameterTypes), ex);
+		} catch (IllegalAccessException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedConstructorSignature(javaClass, parameterTypes), ex);
+		} catch (InvocationTargetException ex) {
+			throw new RuntimeException(buildFullyQualifiedConstructorSignature(javaClass, parameterTypes) + StringTools.CR + ex.getTargetException(), ex);
+		} catch (NoSuchMethodException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedConstructorSignature(javaClass, parameterTypes), ex);
+		}
+	}
+
+	/**
+	 * @see #newInstance(Class, Class[], Object[])
+	 */
+	public static <T> T newInstance_(Class<T> javaClass, Class<?>[] parameterTypes, Object... arguments)
+		throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
+	{
+		return constructor_(javaClass, parameterTypes).newInstance(arguments);
+	}
+
+	/**
+	 * Return the default (zero-argument) constructor
+	 * for the specified class.
+	 * Make any private/package/protected constructor accessible.
+	 */
+	public static <T> Constructor<T> defaultConstructor(Class<T> javaClass) {
+		return constructor(javaClass);
+	}
+
+	/**
+	 * @see #defaultConstructor(Class)
+	 */
+	public static <T> Constructor<T> defaultConstructor_(Class<T> javaClass)
+		throws NoSuchMethodException
+	{
+		return constructor_(javaClass);
+	}
+
+	/**
+	 * @see #defaultConstructor(Class)
+	 */
+	public static <T> Constructor<T> constructor(Class<T> javaClass) {
+		return constructor(javaClass, EMPTY_ARRAY);
+	}
+
+	/**
+	 * @see #constructor(Class)
+	 */
+	public static <T> Constructor<T> constructor_(Class<T> javaClass)
+		throws NoSuchMethodException
+	{
+		return constructor_(javaClass, EMPTY_ARRAY);
+	}
+
+	/**
+	 * Return the constructor for the specified class
+	 * and formal parameter type.
+	 * Make any private/package/protected constructor accessible.
+	 */
+	public static <T> Constructor<T> constructor(Class<T> javaClass, Class<?> parameterType) {
+		return constructor(javaClass, new Class[] {parameterType});
+	}
+
+	/**
+	 * @see #constructor(Class, Class)
+	 */
+	public static <T> Constructor<T> constructor_(Class<T> javaClass, Class<?> parameterType)
+		throws NoSuchMethodException
+	{
+		return constructor_(javaClass, new Class[] {parameterType});
+	}
+
+	/**
+	 * Return the constructor for the specified class
+	 * and formal parameter types.
+	 * Make any private/package/protected constructor accessible.
+	 */
+	public static <T> Constructor<T> constructor(Class<T> javaClass, Class<?>[] parameterTypes) {
+		try {
+			return constructor_(javaClass, parameterTypes);
+		} catch (NoSuchMethodException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedConstructorSignature(javaClass, parameterTypes), ex);
+		}
+	}
+
+	/**
+	 * @see #constructor(Class, Class[])
+	 */
+	public static <T> Constructor<T> constructor_(Class<T> javaClass, Class<?>[] parameterTypes)
+		throws NoSuchMethodException
+	{
+		Constructor<T> constructor = javaClass.getDeclaredConstructor(parameterTypes);
+		constructor.setAccessible(true);
+		return constructor;
+	}
+
+	/**
+	 * Return the declared constructors for the specified class.
+	 * Make any private/package/protected constructors accessible.
+	 */
+	public static <T> Iterable<Constructor<T>> declaredConstructors(Class<T> javaClass) {
+		@SuppressWarnings("unchecked")
+		Constructor<T>[] constructors = (Constructor<T>[]) javaClass.getDeclaredConstructors();
+		return makeAccessible(IterableTools.iterable(constructors));
+	}
+
+
+	// ********** arrays **********
+
+	/**
+	 * Return the "array depth" of the specified class.
+	 * The depth is the number of dimensions for an array type.
+	 * Non-array types have a depth of zero.
+	 */
+	public static int arrayDepth(Class<?> javaClass) {
+		int depth = 0;
+		while (javaClass.isArray()) {
+			depth++;
+			javaClass = javaClass.getComponentType();
+		}
+		return depth;
+	}
+
+	/**
+	 * Return the "element type" of the specified class.
+	 * The element type is the base type held by an array type.
+	 * A non-array type simply returns itself.
+	 */
+	public static Class<?> elementType(Class<?> javaClass) {
+		while (javaClass.isArray()) {
+			javaClass = javaClass.getComponentType();
+		}
+		return javaClass;
+	}
+
+
+	// ********** primitives **********
+
+	/**
+	 * Return the wrapper class corresponding to the specified
+	 * primitive class. Return <code>null</code> if the specified class
+	 * is not a primitive class.
+	 */
+	public static Class<?> primitiveWrapper(Class<?> primitiveClass) {
+		for (Primitive primitive : PRIMITIVES) {
+			if (primitive.javaClass == primitiveClass) {
+				return primitive.wrapperClass;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Return whether the specified class is a primitive wrapper
+	 * class (i.e. <code>java.lang.Void</code> or one of the primitive
+	 * variable wrapper classes, <code>java.lang.Boolean</code>,
+	 * <code>java.lang.Integer</code>, <code>java.lang.Float</code>, etc.).
+	 * <p>
+	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
+	 */
+	public static boolean isPrimitiveWrapper(Class<?> javaClass) {
+		if (javaClass.isArray() || (javaClass.getName().length() > MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH)) {
+			return false;  // performance tweak
+		}
+		for (Primitive primitive : PRIMITIVES) {
+			if (javaClass == primitive.wrapperClass) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Return whether the specified class is a "variable" primitive wrapper
+	 * class (i.e. <code>java.lang.Boolean</code>,
+	 * <code>java.lang.Integer</code>, <code>java.lang.Float</code>, etc.,
+	 * but not <code>java.lang.Void</code>).
+	 * <p>
+	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
+	 */
+	public static boolean isVariablePrimitiveWrapper(Class<?> javaClass) {
+		return isPrimitiveWrapper(javaClass)
+			&& (javaClass != VOID_WRAPPER);
+	}
+
+	/**
+	 * Return whether the specified class is a "variable" primitive
+	 * class (i.e. <code>boolean</code>, <code>int</code>,
+	 * <code>float</code>, etc., but not <code>void</code>).
+	 * <p>
+	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
+	 */
+	public static boolean isVariablePrimitive(Class<?> javaClass) {
+		return javaClass.isPrimitive() && (javaClass != VOID);
+	}
+
+	/**
+	 * @see #primitiveForCode(char)
+	 */
+	public static Class<?> primitiveForCode(int classCode) {
+		return primitiveForCode((char) classCode);
+	}
+
+	/**
+	 * Return the primitive class for the specified primitive class code.
+	 * Return <code>null</code> if the specified code
+	 * is not a primitive class code.
+	 * @see java.lang.Class#getName()
+	 */
+	public static Class<?> primitiveForCode(char classCode) {
+		for (Primitive primitive : PRIMITIVES) {
+			if (primitive.code == classCode) {
+				return primitive.javaClass;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Return the class code for the specified primitive class.
+	 * Return zero if the specified class is not a primitive class.
+	 * @see java.lang.Class#getName()
+	 */
+	public static char primitiveCode(Class<?> primitiveClass) {
+		if (( ! primitiveClass.isArray()) && (primitiveClass.getName().length() <= MAX_PRIMITIVE_CLASS_NAME_LENGTH)) {
+			for (Primitive primitive : PRIMITIVES) {
+				if (primitive.javaClass == primitiveClass) {
+					return primitive.code;
+				}
+			}
+		}
+		return 0;
+	}
+
+
+	// ********** primitive constants **********
+
+	static final Iterable<Primitive> PRIMITIVES = buildPrimitives();
+
+	public static final char BYTE_CODE = 'B';
+	public static final char CHAR_CODE = 'C';
+	public static final char DOUBLE_CODE = 'D';
+	public static final char FLOAT_CODE = 'F';
+	public static final char INT_CODE = 'I';
+	public static final char LONG_CODE = 'J';
+	public static final char SHORT_CODE = 'S';
+	public static final char BOOLEAN_CODE = 'Z';
+	public static final char VOID_CODE = 'V';
+
+	static final int MAX_PRIMITIVE_CLASS_NAME_LENGTH = calculateMaxPrimitiveClassNameLength();
+	static final int MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH = calculateMaxPrimitiveWrapperClassNameLength();
+
+	private static int calculateMaxPrimitiveClassNameLength() {
+		int max = -1;
+		for (Primitive primitive : PRIMITIVES) {
+			int len = primitive.javaClassName.length;
+			if (len > max) {
+				max = len;
+			}
+		}
+		return max;
+	}
+
+	private static int calculateMaxPrimitiveWrapperClassNameLength() {
+		int max = -1;
+		for (Primitive primitive : PRIMITIVES) {
+			int len = primitive.wrapperClassName.length;
+			if (len > max) {
+				max = len;
+			}
+		}
+		return max;
+	}
+
+	/**
+	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
+	 */
+	private static Iterable<Primitive> buildPrimitives() {
+		Primitive[] array = new Primitive[9];
+		array[0] = new Primitive(BYTE_CODE, java.lang.Byte.class);
+		array[1] = new Primitive(CHAR_CODE, java.lang.Character.class);
+		array[2] = new Primitive(DOUBLE_CODE, java.lang.Double.class);
+		array[3] = new Primitive(FLOAT_CODE, java.lang.Float.class);
+		array[4] = new Primitive(INT_CODE, java.lang.Integer.class);
+		array[5] = new Primitive(LONG_CODE, java.lang.Long.class);
+		array[6] = new Primitive(SHORT_CODE, java.lang.Short.class);
+		array[7] = new Primitive(BOOLEAN_CODE, java.lang.Boolean.class);
+		array[8] = new Primitive(VOID_CODE, java.lang.Void.class);
+		return IterableTools.iterable(array);
+	}
+
+	static class Primitive {
+		final char code;
+		final Class<?> javaClass;
+		final char[] javaClassName;
+		final Class<?> wrapperClass;
+		final char[] wrapperClassName;
+		private static final String WRAPPER_CLASS_TYPE_FIELD_NAME = "TYPE";
+		// e.g. java.lang.Boolean.TYPE => boolean.class
+		Primitive(char code, Class<?> wrapperClass) {
+			this.code = code;
+			this.javaClass = (Class<?>) get(wrapperClass, WRAPPER_CLASS_TYPE_FIELD_NAME);
+			this.javaClassName = this.javaClass.getName().toCharArray();
+			this.wrapperClass = wrapperClass;
+			this.wrapperClassName = wrapperClass.getName().toCharArray();
+		}
+	}
+
+
+	// ********** type declarations **********
+
+	/**
+	 * Return the class for the specified {@link TypeDeclarationTools type declaration}.
+	 */
+	public static Class<?> forTypeDeclaration(String typeDeclaration) {
+		return forTypeDeclaration(typeDeclaration, null);
+	}
+
+	/**
+	 * @see #forTypeDeclaration(String)
+	 */
+	public static Class<?> forTypeDeclaration(char[] typeDeclaration) {
+		return forTypeDeclaration(typeDeclaration, null);
+	}
+
+	/**
+	 * @see #forTypeDeclaration(String)
+	 */
+	public static Class<?> forTypeDeclaration_(String typeDeclaration)
+		throws ClassNotFoundException
+	{
+		return forTypeDeclaration_(typeDeclaration, null);
+	}
+
+	/**
+	 * @see #forTypeDeclaration_(String)
+	 */
+	public static Class<?> forTypeDeclaration_(char[] typeDeclaration)
+		throws ClassNotFoundException
+	{
+		return forTypeDeclaration_(typeDeclaration, null);
+	}
+
+	/**
+	 * Return the class for the specified {@link TypeDeclarationTools type declaration},
+	 * using the specified class loader.
+	 */
+	public static Class<?> forTypeDeclaration(String typeDeclaration, ClassLoader classLoader) {
+		try {
+			return forTypeDeclaration_(typeDeclaration, classLoader);
+		} catch (ClassNotFoundException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+	/**
+	 * @see #forTypeDeclaration(String, ClassLoader)
+	 */
+	public static Class<?> forTypeDeclaration(char[] typeDeclaration, ClassLoader classLoader) {
+		try {
+			return forTypeDeclaration_(typeDeclaration, classLoader);
+		} catch (ClassNotFoundException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+	/**
+	 * @see #forTypeDeclaration(String, ClassLoader)
+	 */
+	public static Class<?> forTypeDeclaration_(String typeDeclaration, ClassLoader classLoader)
+		throws ClassNotFoundException
+	{
+		typeDeclaration = StringTools.removeAllWhitespace(typeDeclaration);
+		int arrayDepth = TypeDeclarationTools.arrayDepth_(typeDeclaration);
+		String elementTypeName = TypeDeclarationTools.elementTypeName_(typeDeclaration, arrayDepth);
+		return forTypeDeclaration_(elementTypeName, arrayDepth, classLoader);
+	}
+
+	/**
+	 * @see #forTypeDeclaration_(String, ClassLoader)
+	 */
+	public static Class<?> forTypeDeclaration_(char[] typeDeclaration, ClassLoader classLoader)
+		throws ClassNotFoundException
+	{
+		typeDeclaration = CharArrayTools.removeAllWhitespace(typeDeclaration);
+		int arrayDepth = TypeDeclarationTools.arrayDepth_(typeDeclaration);
+		char[] elementTypeName = TypeDeclarationTools.elementTypeName_(typeDeclaration, arrayDepth);
+		return forTypeDeclaration_(elementTypeName, arrayDepth, classLoader);
+	}
+
+	/**
+	 * Return the class for the specified "type declaration".
+	 */
+	public static Class<?> forTypeDeclaration(String elementTypeName, int arrayDepth) {
+		return forTypeDeclaration(elementTypeName, arrayDepth, null);
+	}
+
+	/**
+	 * @see #forTypeDeclaration(String, int)
+	 */
+	public static Class<?> forTypeDeclaration(char[] elementTypeName, int arrayDepth) {
+		return forTypeDeclaration(elementTypeName, arrayDepth, null);
+	}
+
+	/**
+	 * @see #forTypeDeclaration(String, int)
+	 */
+	public static Class<?> forTypeDeclaration_(String elementTypeName, int arrayDepth)
+		throws ClassNotFoundException
+	{
+		return forTypeDeclaration_(elementTypeName, arrayDepth, null);
+	}
+
+	/**
+	 * @see #forTypeDeclaration_(String, int)
+	 */
+	public static Class<?> forTypeDeclaration_(char[] elementTypeName, int arrayDepth)
+		throws ClassNotFoundException
+	{
+		return forTypeDeclaration_(elementTypeName, arrayDepth, null);
+	}
+
+	/**
+	 * Return the class for the specified "type declaration",
+	 * using the specified class loader.
+	 */
+	public static Class<?> forTypeDeclaration(String elementTypeName, int arrayDepth, ClassLoader classLoader) {
+		try {
+			return forTypeDeclaration_(elementTypeName, arrayDepth, classLoader);
+		} catch (ClassNotFoundException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+	/**
+	 * @see #forTypeDeclaration(String, int, ClassLoader)
+	 */
+	public static Class<?> forTypeDeclaration(char[] elementTypeName, int arrayDepth, ClassLoader classLoader) {
+		try {
+			return forTypeDeclaration_(elementTypeName, arrayDepth, classLoader);
+		} catch (ClassNotFoundException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+	/**
+	 * @see #forTypeDeclaration(String, int, ClassLoader)
+	 */
+	// see the "Evaluation" of JDK bug 6446627 for a discussion of loading classes
+	public static Class<?> forTypeDeclaration_(String elementTypeName, int arrayDepth, ClassLoader classLoader)
+		throws ClassNotFoundException
+	{
+		// primitives cannot be loaded via Class.forName(),
+		// so check for a primitive class name first
+		Primitive primitive = null;
+		if (elementTypeName.length() <= MAX_PRIMITIVE_CLASS_NAME_LENGTH) {  // performance tweak
+			for (Primitive p : PRIMITIVES) {
+				if (p.javaClass.getName().equals(elementTypeName)) {
+					primitive = p;
+					break;
+				}
+			}
+		}
+
+		// non-array
+		if (arrayDepth == 0) {
+			return (primitive != null) ? primitive.javaClass : Class.forName(elementTypeName, false, classLoader);
+		}
+
+		// array
+		StringBuilder sb = new StringBuilder(100);
+		for (int i = arrayDepth; i-- > 0; ) {
+			sb.append('[');
+		}
+		if (primitive != null) {
+			sb.append(primitive.code);
+		} else {
+			ClassNameTools.appendReferenceNameTo(elementTypeName, sb);
+		}
+		return Class.forName(sb.toString(), false, classLoader);
+	}
+
+	/**
+	 * @see #forTypeDeclaration_(String, int, ClassLoader)
+	 */
+	public static Class<?> forTypeDeclaration_(char[] elementTypeName, int arrayDepth, ClassLoader classLoader)
+		throws ClassNotFoundException
+	{
+		// primitives cannot be loaded via Class.forName(),
+		// so check for a primitive class name first
+		Primitive primitive = null;
+		if (elementTypeName.length <= MAX_PRIMITIVE_CLASS_NAME_LENGTH) {  // performance tweak
+			for (Primitive p : PRIMITIVES) {
+				if (Arrays.equals(p.javaClassName, elementTypeName)) {
+					primitive = p;
+					break;
+				}
+			}
+		}
+
+		// non-array
+		if (arrayDepth == 0) {
+			return (primitive != null) ? primitive.javaClass : Class.forName(String.copyValueOf(elementTypeName), false, classLoader);
+		}
+
+		// array
+		StringBuilder sb = new StringBuilder(100);
+		for (int i = arrayDepth; i-- > 0; ) {
+			sb.append('[');
+		}
+		if (primitive != null) {
+			sb.append(primitive.code);
+		} else {
+			ClassNameTools.appendReferenceNameTo(elementTypeName, sb);
+		}
+		return Class.forName(sb.toString(), false, classLoader);
+	}
+
+
+	// ********** misc **********
+
+	private static <A extends AccessibleObject> Iterable<A> makeAccessible(Iterable<A> objects) {
+		for (AccessibleObject object : objects) {
+			object.setAccessible(true);
+		}
+		return objects;
+	}
+
+	/**
+	 * Return a string representation of the specified field.
+	 */
+	static String buildFullyQualifiedFieldName(Class<?> javaClass, String fieldName) {
+		StringBuilder sb = new StringBuilder(200);
+		sb.append(javaClass.getName());
+		sb.append('.');
+		sb.append(fieldName);
+		return sb.toString();
+	}
+
+	/**
+	 * Return a string representation of the specified method.
+	 */
+	private static String buildFullyQualifiedMethodSignature(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) {
+		StringBuilder sb = new StringBuilder(200);
+		sb.append(javaClass.getName());
+		// this check allows us to use this code for constructors, where the methodName is null
+		if (methodName != null) {
+			sb.append('.');
+			sb.append(methodName);
+		}
+		sb.append('(');
+		int max = parameterTypes.length - 1;
+		if (max > -1) {
+			// stop one short of the end of the array
+			for (int i = 0; i < max; i++) {
+				sb.append(parameterTypes[i].getName());
+				sb.append(", ");
+			}
+			sb.append(parameterTypes[max].getName());
+		}
+		sb.append(')');
+		return sb.toString();
+	}
+
+	/**
+	 * Return a string representation of the specified constructor.
+	 */
+	private static String buildFullyQualifiedConstructorSignature(Class<?> javaClass, Class<?>[] parameterTypes) {
+		return buildFullyQualifiedMethodSignature(javaClass, null, parameterTypes);
+	}
+
+
+	// ********** suppressed constructor **********
+
+	/**
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private ClassTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Classpath.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Classpath.java
index ccf57e5..b2d010f 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Classpath.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Classpath.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -27,12 +27,15 @@
 import java.util.List;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
-import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
-import org.eclipse.persistence.tools.utility.iterators.CompositeIterator;
-import org.eclipse.persistence.tools.utility.iterators.EmptyIterator;
-import org.eclipse.persistence.tools.utility.iterators.FilteringIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.io.FileTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
+import org.eclipse.persistence.tools.utility.iterator.ArrayIterator;
+import org.eclipse.persistence.tools.utility.iterator.CompositeIterator;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+import org.eclipse.persistence.tools.utility.iterator.FilteringIterator;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
 
 /**
  * <code>Classpath</code> models a Java classpath, which consists of a list of
@@ -50,19 +53,20 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** static methods **********
 
 	// ***** factory methods for "standard" classpaths *****
 
 	/**
-	 * Returns the Java "boot" classpath. This includes <code>rt.jar</code>.
+	 * Return the Java "boot" classpath. This includes <code>rt.jar</code>.
 	 */
 	public static Classpath bootClasspath() {
 		return new Classpath(System.getProperty("sun.boot.class.path"));
 	}
 
 	/**
-	 * Returns a "virtual classpath" that contains all the jars
+	 * Return a "virtual classpath" that contains all the jars
 	 * that would be used by the Java Extension Mechanism.
 	 */
 	public static Classpath javaExtensionClasspath() {
@@ -77,14 +81,14 @@
 	}
 
 	/**
-	 * Returns the Java "system" classpath.
+	 * Return the Java "system" classpath.
 	 */
 	public static Classpath javaClasspath() {
 		return new Classpath(System.getProperty("java.class.path"));
 	}
 
 	/**
-	 * Returns the unretouched "complete" classpath.
+	 * Return the unretouched "complete" classpath.
 	 * This includes the boot classpath, the Java Extension
 	 * Mechanism classpath, and the normal "system" classpath.
 	 */
@@ -97,7 +101,7 @@
 	}
 
 	/**
-	 * Returns a classpath that contains the location of the specified class.
+	 * Return a classpath that contains the location of the specified class.
 	 */
 	public static Classpath classpathFor(Class<?> javaClass) {
 		return new Classpath(locationFor(javaClass));
@@ -315,16 +319,16 @@
 	// ***** utilities *****
 
 	/**
-	 * Returns whether the specified file is an archive file;
+	 * Return whether the specified file is an archive file;
 	 * i.e. its name ends with <code>".zip"</code> or <code>".jar"</code>.
 	 */
 	public static boolean fileNameIsArchive(String fileName) {
 		String ext = FileTools.extension(fileName).toLowerCase();
-		return ext.equals(".jar") || ext.equals(".zip"); //$NON-NLS-2$
+		return ext.equals(".jar") || ext.equals(".zip");
 	}
 
 	/**
-	 * Returns whether the specified file is an archive file;
+	 * Return whether the specified file is an archive file;
 	 * i.e. its name ends with <code>".zip"</code> or <code>".jar"</code>.
 	 */
 	public static boolean fileIsArchive(File file) {
@@ -332,7 +336,7 @@
 	}
 
 	/**
-	 * Returns what should be the fully-qualified file name
+	 * Return what should be the fully-qualified file name
 	 * for the JRE runtime JAR;
 	 * e.g. <code>"C:\jdk1.4.2_04\jre\lib\rt.jar"</code>.
 	 */
@@ -341,7 +345,7 @@
 	}
 
 	/**
-	 * Returns the location from where the specified class was loaded.
+	 * Return the location from where the specified class was loaded.
 	 */
 	public static String locationFor(Class<?> javaClass) {
 		URL url = convertToResource(javaClass);
@@ -352,15 +356,15 @@
 			throw new RuntimeException(ex);
 		}
 		String protocol = url.getProtocol().toLowerCase();
-		if (protocol.equals("jar")) {
+		if (protocol.equals("jar")) { //$NON-NLS-1$
 			// if the class is in a JAR, the URL will look something like this:
 			//     jar:file:/C:/jdk/1.4.2_04/jre/lib/rt.jar!/java/lang/String.class
 			return path.substring(0, path.indexOf('!'));
-		} else if (protocol.equals("file")) {
+		} else if (protocol.equals("file")) { //$NON-NLS-1$
 			// if the class is in a directory, the URL will look something like this:
 			//     file:/C:/dev/main/mwdev/class/org/eclipse/dali/utility/Classpath.class
 			return path.substring(0, path.length() - convertToClassFileName(javaClass).length() - 1);
-		} else if (protocol.equals("bundleresource")) {
+		} else if (protocol.equals("bundleresource")) { //$NON-NLS-1$
 			// if the class is in a bundle resource (Eclipse?), the URL will look something like this:
 			//     bundleresource://43/org/eclipse/dali/utility/Classpath.class
 			return path.substring(0, path.length() - convertToClassFileName(javaClass).length() - 1);
@@ -370,14 +374,14 @@
 	}
 
 	/**
-	 * Returns the directories used by the Java Extension Mechanism.
+	 * Return the directories used by the Java Extension Mechanism.
 	 */
 	public static File[] javaExtensionDirectories() {
 		return convertToFiles(javaExtensionDirectoryNames());
 	}
 
 	/**
-	 * Returns the directory names used by the Java Extension Mechanism.
+	 * Return the directory names used by the Java Extension Mechanism.
 	 */
 	public static String[] javaExtensionDirectoryNames() {
 		return System.getProperty("java.ext.dirs").split(File.pathSeparator);
@@ -485,19 +489,19 @@
 	// ********** public API **********
 
 	/**
-	 * Returns the classpath's entries.
+	 * Return the classpath's entries.
 	 */
 	public Iterable<Entry> getEntries() {
 		return new ArrayIterable<Entry>(this.entries);
 	}
 
 	/**
-	 * Returns the classpath's path.
+	 * Return the classpath's path.
 	 */
 	public String getPath() {
 		int max = this.entries.length - 1;
 		if (max == -1) {
-			return StringTools.EMPTY_STRING;
+			return "";
 		}
 		StringBuilder sb = new StringBuilder(2000);
 		// stop one short of the end of the array
@@ -511,7 +515,7 @@
 
 	/**
 	 * Search the classpath for the specified (unqualified) file
-	 * Returns null if an entry is not found.
+	 * and return its entry. Return null if an entry is not found.
 	 * For example, you could use this method to find the entry
 	 * for <code>"rt.jar"</code> or <code>"toplink.jar"</code>.
 	 */
@@ -525,9 +529,9 @@
 	}
 
 	/**
-	 * Returns the first entry file in the classpath
+	 * Return the first entry file in the classpath
 	 * that contains the specified class.
-	 * Returns null if an entry is not found.
+	 * Return null if an entry is not found.
 	 */
 	public Entry getEntryForClassNamed(String className) {
 		String relativeClassFileName = convertToClassFileName(className);
@@ -541,7 +545,7 @@
 	}
 
 	/**
-	 * Returns the names of all the classes discovered on the classpath,
+	 * Return the names of all the classes discovered on the classpath,
 	 * with duplicates removed.
 	 * @see #classNames()
 	 */
@@ -550,7 +554,7 @@
 	}
 
 	/**
-	 * Returns the names of all the classes discovered on the classpath
+	 * Return the names of all the classes discovered on the classpath
 	 * and accepted by the specified filter, with duplicates removed.
 	 * @see #classNames(Filter)
 	 */
@@ -579,7 +583,7 @@
 	}
 
 	/**
-	 * Returns the names of all the classes discovered on the classpath.
+	 * Return the names of all the classes discovered on the classpath.
 	 * Just a bit more performant than {@link #getClassNames()}.
 	 */
 	public Iterator<String> classNames() {
@@ -587,7 +591,7 @@
 	}
 
 	/**
-	 * Returns the names of all the classes discovered on the classpath
+	 * Return the names of all the classes discovered on the classpath
 	 * that are accepted by the specified filter.
 	 * Just a bit more performant than {@link #getClassNames(Filter)}.
 	 */
@@ -596,7 +600,7 @@
 	}
 
 	private Iterator<Iterator<String>> entryClassNamesIterators(final Filter<String> filter) {
-		return new TransformationIterator<Iterator<String>, Entry>(new ArrayIterator<Entry>(this.entries)) {
+		return new TransformationIterator<Entry, Iterator<String>>(new ArrayIterator<Entry>(this.entries)) {
 			@Override
 			protected Iterator<String> transform(Entry entry) {
 				return entry.classNames(filter);
@@ -605,7 +609,7 @@
 	}
 
 	/**
-	 * Returns a "compressed" version of the classpath with its
+	 * Return a "compressed" version of the classpath with its
 	 * duplicate entries eliminated.
 	 */
 	public Classpath compressed() {
@@ -627,7 +631,7 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.getPath());
+		return ObjectTools.toString(this, this.getPath());
 	}
 
 
@@ -636,7 +640,7 @@
 	/**
 	 * <code>Entry</code> models a Java classpath entry, which can be either a
 	 * directory containing <code>.class</code> files or a JAR file (or,
-	 * Returns the names of
+	 * similarly, a <code>.zip</code> file). The entry can return the names of
 	 * classes found in it etc.
 	 */
 	public static class Entry
@@ -688,7 +692,7 @@
 		}
 
 		/**
-		 * Returns the entry's "canonical" URL.
+		 * Return the entry's "canonical" URL.
 		 */
 		public URL getURL() {
 			try {
@@ -699,21 +703,21 @@
 		}
 
 		/**
-		 * Returns whether the entry contains the specified class.
+		 * Return whether the entry contains the specified class.
 		 */
 		public boolean contains(Class<?> javaClass) {
 			return this.contains(javaClass.getName());
 		}
 
 		/**
-		 * Returns whether the entry contains the specified class.
+		 * Return whether the entry contains the specified class.
 		 */
 		public boolean contains(String className) {
 			return this.contains(convertToClassFileName(className), convertToArchiveClassFileEntryName(className));
 		}
 
 		/**
-		 * Returns whether the entry contains either the specified relative
+		 * Return whether the entry contains either the specified relative
 		 * class file or the specified archive entry.
 		 * Not the prettiest signature, but it's internal....
 		 */
@@ -728,7 +732,7 @@
 		}
 
 		/**
-		 * Returns whether the entry's archive contains the specified entry.
+		 * Return whether the entry's archive contains the specified entry.
 		 */
 		private boolean archiveContainsEntry(String zipEntryName) {
 			ZipFile zipFile = null;
@@ -751,7 +755,7 @@
 		}
 
 		/**
-		 * Returns the names of all the classes discovered in the entry.
+		 * Return the names of all the classes discovered in the entry.
 		 * @see #classNames()
 		 */
 		public Iterable<String> getClassNames() {
@@ -759,7 +763,7 @@
 		}
 
 		/**
-		 * Returns the names of all the classes discovered in the entry
+		 * Return the names of all the classes discovered in the entry
 		 * and accepted by the specified filter.
 		 * @see #classNames(Filter)
 		 */
@@ -807,11 +811,11 @@
 		}
 
 		/**
-		 * Returns an iterator on all the class files discovered
+		 * Return an iterator on all the class files discovered
 		 * under the entry's directory.
 		 */
 		private Iterator<File> classFilesForDirectory() {
-			return new FilteringIterator<File>(FileTools.filesInTree(this.canonicalFile)) {
+			return new FilteringIterator<File>(FileTools.allFiles(this.canonicalFile)) {
 				@Override
 				protected boolean accept(File next) {
 					return Entry.this.fileNameMightBeForClassFile(next.getName());
@@ -849,19 +853,19 @@
 		}
 
 		/**
-		 * Returns whether the specified file might be a Java class file.
+		 * Return whether the specified file might be a Java class file.
 		 * The file name must at least end with <code>".class"</code> and contain no spaces.
 		 * (Neither class names nor package names may contain spaces.)
 		 * Whether it actually is a class file will need to be determined by
 		 * a class loader.
 		 */
 		boolean fileNameMightBeForClassFile(String name) {
-			return FileTools.extension(name).toLowerCase().equals(".class")
+			return FileTools.extension(name).toLowerCase().equals(".class") //$NON-NLS-1$
 					&& (name.indexOf(' ') == -1);
 		}
 
 		/**
-		 * Returns the names of all the classes discovered on the classpath.
+		 * Return the names of all the classes discovered on the classpath.
 		 * Just a bit more performant than {@link #getClassNames()}.
 		 */
 		public Iterator<String> classNames() {
@@ -869,7 +873,7 @@
 		}
 
 		/**
-		 * Returns the names of all the classes discovered on the classpath
+		 * Return the names of all the classes discovered on the classpath
 		 * that are accepted by the specified filter.
 		 * Just a bit more performant than {@link #getClassNames(Filter)}.
 		 */
@@ -886,7 +890,7 @@
 		}
 
 		/**
-		 * Returns the names of all the classes discovered
+		 * Return the names of all the classes discovered
 		 * under the entry's directory and accepted by
 		 * the specified filter.
 		 */
@@ -899,7 +903,7 @@
 		 */
 		private Iterator<String> classNamesForDirectory() {
 			final int start = this.canonicalFile.getAbsolutePath().length() + 1;
-			return new TransformationIterator<String, File>(this.classFilesForDirectory()) {
+			return new TransformationIterator<File, String>(this.classFilesForDirectory()) {
 				@Override
 				protected String transform(File f) {
 					return convertToClassName(f.getAbsolutePath().substring(start));
@@ -908,7 +912,7 @@
 		}
 
 		/**
-		 * Returns the names of all the classes discovered
+		 * Return the names of all the classes discovered
 		 * in the entry's archive file and accepted by the
 		 * specified filter.
 		 */
@@ -939,4 +943,4 @@
 			return classNames.iterator();
 		}
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CollectingExceptionHandler.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CollectingExceptionHandler.java
index 25579c0..980de7a 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CollectingExceptionHandler.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CollectingExceptionHandler.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -14,11 +14,10 @@
 package org.eclipse.persistence.tools.utility;
 
 import java.util.Vector;
-import org.eclipse.persistence.tools.utility.iterables.LiveCloneIterable;
-import org.eclipse.persistence.tools.utility.iterables.SnapshotCloneIterable;
+import org.eclipse.persistence.tools.utility.iterable.SnapshotCloneIterable;
 
 /**
- * An exception handler that collects and hold the exceptions handed to it.
+ * An exception handler that collects and holds the exceptions handed to it.
  * They can be retrieved at a later time via calls to {@link #getExceptions()}
  * and {{@link #clearExceptions()}.
  */
@@ -27,20 +26,25 @@
 {
 	private final Vector<Throwable> exceptions = new Vector<Throwable>();
 
+
+	public CollectingExceptionHandler() {
+		super();
+	}
+
 	@Override
 	public void handleException(Throwable t) {
 		this.exceptions.add(t);
 	}
 
 	/**
-	 * Returns the current list of exceptions handled by the handler so far.
+	 * Return the current list of exceptions handled by the handler so far.
 	 */
 	public Iterable<Throwable> getExceptions() {
-		return new LiveCloneIterable<Throwable>(this.exceptions);
+		return new SnapshotCloneIterable<Throwable>(this.exceptions);
 	}
 
 	/**
-	 * Returns the current list of exceptions handled by the handler
+	 * Clear and return the current list of exceptions handled by the handler
 	 * so far.
 	 */
 	public Iterable<Throwable> clearExceptions() {
@@ -53,6 +57,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.exceptions);
+		return ObjectTools.toString(this, this.exceptions);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CollectionTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CollectionTools.java
deleted file mode 100644
index 3549086..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CollectionTools.java
+++ /dev/null
@@ -1,1982 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Random;
-import java.util.RandomAccess;
-import java.util.TreeSet;
-import java.util.Vector;
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
-import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
-import org.eclipse.persistence.tools.utility.iterators.ArrayListIterator;
-import org.eclipse.persistence.tools.utility.iterators.SingleElementIterator;
-import org.eclipse.persistence.tools.utility.iterators.SingleElementListIterator;
-import org.eclipse.persistence.tools.utility.iterators.SuperIteratorWrapper;
-
-/**
- * {@link Collection}-related utility methods.
- */
-@SuppressWarnings("nls")
-public final class CollectionTools {
-
-	// ********** add all **********
-
-	/**
-	 * Add all the elements returned by the specified iterable
-	 * to the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * <p>
-	 * <code>Collection.addAll(Iterable iterable)</code>
-	 */
-	public static <E> boolean addAll(Collection<? super E> collection, Iterable<? extends E> iterable) {
-		return addAll(collection, iterable.iterator());
-	}
-
-	/**
-	 * Add all the elements returned by the specified iterable
-	 * to the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * <p>
-	 * <code>Collection.addAll(Iterable iterable)</code>
-	 */
-	public static <E> boolean addAll(Collection<? super E> collection, Iterable<? extends E> iterable, int size) {
-		return addAll(collection, iterable.iterator(), size);
-	}
-
-	/**
-	 * Add all the elements returned by the specified iterator
-	 * to the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * <p>
-	 * <code>Collection.addAll(Iterator iterator)</code>
-	 */
-	public static <E> boolean addAll(Collection<? super E> collection, Iterator<? extends E> iterator) {
-		return iterator.hasNext() ? addAll_(collection, iterator) : false;
-	}
-
-	/**
-	 * assume the iterator is not empty
-	 */
-	private static <E> boolean addAll_(Collection<? super E> collection, Iterator<? extends E> iterator) {
-		boolean modified = false;
-		while (iterator.hasNext()) {
-			modified |= collection.add(iterator.next());
-		}
-		return modified;
-	}
-
-	/**
-	 * Add all the elements returned by the specified iterator
-	 * to the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * <p>
-	 * <code>Collection.addAll(Iterator iterator)</code>
-	 */
-	public static <E> boolean addAll(Collection<? super E> collection, Iterator<? extends E> iterator, int size) {
-		return iterator.hasNext() ? collection.addAll(list(iterator, size)) : false;
-	}
-
-	/**
-	 * Add all the elements in the specified array
-	 * to the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * <p>
-	 * <code>Collection.addAll(Object[] array)</code>
-	 */
-	public static <E> boolean addAll(Collection<? super E> collection, E... array) {
-		return (array.length == 0) ? false : addAll_(collection, array);
-	}
-
-	/**
-	 * assume the array is not empty
-	 */
-	private static <E> boolean addAll_(Collection<? super E> collection, E... array) {
-		boolean modified = false;
-		for (E element : array) {
-			modified |= collection.add(element);
-		}
-		return modified;
-	}
-
-	/**
-	 * Add all the elements returned by the specified iterable
-	 * to the specified list at the specified index.
-	 * Returns whether the list changed as a result.
-	 * <p>
-	 * <code>List.addAll(Iterable iterable)</code>
-	 */
-	public static <E> boolean addAll(List<? super E> list, int index, Iterable<E> iterable) {
-		return addAll(list, index, iterable.iterator());
-	}
-
-	/**
-	 * Add all the elements returned by the specified iterable
-	 * to the specified list at the specified index.
-	 * Returns whether the list changed as a result.
-	 * <p>
-	 * <code>List.addAll(Iterable iterable)</code>
-	 */
-	public static <E> boolean addAll(List<? super E> list, int index, Iterable<E> iterable, int size) {
-		return addAll(list, index, iterable.iterator(), size);
-	}
-
-	/**
-	 * Add all the elements returned by the specified iterator
-	 * to the specified list at the specified index.
-	 * Returns whether the list changed as a result.
-	 * <p>
-	 * <code>List.addAll(Iterator iterator)</code>
-	 */
-	public static <E> boolean addAll(List<? super E> list, int index, Iterator<? extends E> iterator) {
-		return iterator.hasNext() ? list.addAll(index, list(iterator)) : false;
-	}
-
-	/**
-	 * Add all the elements returned by the specified iterator
-	 * to the specified list at the specified index.
-	 * Returns whether the list changed as a result.
-	 * <p>
-	 * <code>List.addAll(Iterator iterator)</code>
-	 */
-	public static <E> boolean addAll(List<? super E> list, int index, Iterator<? extends E> iterator, int size) {
-		return iterator.hasNext() ? list.addAll(index, list(iterator, size)) : false;
-	}
-
-	/**
-	 * Add all the elements in the specified array
-	 * to the specified list at the specified index.
-	 * Returns whether the list changed as a result.
-	 * <p>
-	 * <code>List.addAll(Object[] array)</code>
-	 */
-	public static <E> boolean addAll(List<? super E> list, int index, E... array) {
-		return (array.length == 0) ? false : list.addAll(index, Arrays.asList(array));
-	}
-
-
-	// ********** bag **********
-
-	/**
-	 * Returns a bag corresponding to the specified enumeration.
-	 * <p>
-	 * <code>HashBag(Enumeration enumeration)</code>
-	 */
-	public static <E> HashBag<E> bag(Enumeration<? extends E> enumeration) {
-		return bag(enumeration, new HashBag<E>());
-	}
-
-	/**
-	 * Returns a bag corresponding to the specified enumeration.
-	 * The specified enumeration size is a performance hint.
-	 * <p>
-	 * <code>HashBag(Enumeration enumeration)</code>
-	 */
-	public static <E> HashBag<E> bag(Enumeration<? extends E> enumeration, int enumerationSize) {
-		return bag(enumeration, new HashBag<E>(enumerationSize));
-	}
-
-	private static <E> HashBag<E> bag(Enumeration<? extends E> enumeration, HashBag<E> bag) {
-		while (enumeration.hasMoreElements()) {
-			bag.add(enumeration.nextElement());
-		}
-		return bag;
-	}
-
-	/**
-	 * Returns a bag corresponding to the specified iterable.
-	 * <p>
-	 * <code>HashBag(Iterable iterable)</code>
-	 */
-	public static <E> HashBag<E> bag(Iterable<? extends E> iterable) {
-		return bag(iterable.iterator());
-	}
-
-	/**
-	 * Returns a bag corresponding to the specified iterable.
-	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>HashBag(Iterable iterable)</code>
-	 */
-	public static <E> HashBag<E> bag(Iterable<? extends E> iterable, int iterableSize) {
-		return bag(iterable.iterator(), iterableSize);
-	}
-
-	/**
-	 * Returns a bag corresponding to the specified iterator.
-	 * <p>
-	 * <code>HashBag(Iterator iterator)</code>
-	 */
-	public static <E> HashBag<E> bag(Iterator<? extends E> iterator) {
-		return bag(iterator, new HashBag<E>());
-	}
-
-	/**
-	 * Returns a bag corresponding to the specified iterator.
-	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>HashBag(Iterator iterator)</code>
-	 */
-	public static <E> HashBag<E> bag(Iterator<? extends E> iterator, int iteratorSize) {
-		return bag(iterator, new HashBag<E>(iteratorSize));
-	}
-
-	private static <E> HashBag<E> bag(Iterator<? extends E> iterator, HashBag<E> bag) {
-		while (iterator.hasNext()) {
-			bag.add(iterator.next());
-		}
-		return bag;
-	}
-
-	/**
-	 * Returns a bag corresponding to the specified array.
-	 * <p>
-	 * <code>HashBag(Object[] array)</code>
-	 */
-	public static <E> HashBag<E> bag(E... array) {
-		int len = array.length;
-		HashBag<E> bag = new HashBag<E>(len);
-		for (E item : array) {
-			bag.add(item);
-		}
-		return bag;
-	}
-
-
-	// ********** collection **********
-
-	/**
-	 * Returns a collection corresponding to the specified enumeration.
-	 */
-	public static <E> HashBag<E> collection(Enumeration<? extends E> enumeration) {
-		return bag(enumeration);
-	}
-
-	/**
-	 * Returns a collection corresponding to the specified enumeration.
-	 * The specified enumeration size is a performance hint.
-	 */
-	public static <E> HashBag<E> collection(Enumeration<? extends E> enumeration, int enumerationSize) {
-		return bag(enumeration, enumerationSize);
-	}
-
-	/**
-	 * Returns a collection corresponding to the specified iterable.
-	 */
-	public static <E> HashBag<E> collection(Iterable<? extends E> iterable) {
-		return collection(iterable.iterator());
-	}
-
-	/**
-	 * Returns a collection corresponding to the specified iterable.
-	 * The specified iterable size is a performance hint.
-	 */
-	public static <E> HashBag<E> collection(Iterable<? extends E> iterable, int iterableSize) {
-		return collection(iterable.iterator(), iterableSize);
-	}
-
-	/**
-	 * Returns a collection corresponding to the specified iterator.
-	 */
-	public static <E> HashBag<E> collection(Iterator<? extends E> iterator) {
-		return bag(iterator);
-	}
-
-	/**
-	 * Returns a collection corresponding to the specified iterator.
-	 * The specified iterator size is a performance hint.
-	 */
-	public static <E> HashBag<E> collection(Iterator<? extends E> iterator, int iteratorSize) {
-		return bag(iterator, iteratorSize);
-	}
-
-	/**
-	 * Returns a collection corresponding to the specified array.
-	 */
-	public static <E> HashBag<E> collection(E... array) {
-		return bag(array);
-	}
-
-
-	// ********** contains **********
-
-	/**
-	 * Returns whether the specified enumeration contains the
-	 * specified element.
-	 * <p>
-	 * <code>Enumeration.contains(Object o)</code>
-	 */
-	public static boolean contains(Enumeration<?> enumeration, Object value) {
-		if (value == null) {
-			while (enumeration.hasMoreElements()) {
-				if (enumeration.nextElement() == null) {
-					return true;
-				}
-			}
-		} else {
-			while (enumeration.hasMoreElements()) {
-				if (value.equals(enumeration.nextElement())) {
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Returns whether the specified iterable contains the
-	 * specified element.
-	 * <p>
-	 * <code>Iterable.contains(Object o)</code>
-	 */
-	public static boolean contains(Iterable<?> iterable, Object value) {
-		return contains(iterable.iterator(), value);
-	}
-
-	/**
-	 * Returns whether the specified iterator contains the
-	 * specified element.
-	 * <p>
-	 * <code>Iterator.contains(Object o)</code>
-	 */
-	public static boolean contains(Iterator<?> iterator, Object value) {
-		if (value == null) {
-			while (iterator.hasNext()) {
-				if (iterator.next() == null) {
-					return true;
-				}
-			}
-		} else {
-			while (iterator.hasNext()) {
-				if (value.equals(iterator.next())) {
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-
-
-	// ********** contains all **********
-
-	/**
-	 * Returns whether the specified collection contains all of the
-	 * elements in the specified iterable.
-	 * <p>
-	 * <code>Collection.containsAll(Iterable iterable)</code>
-	 */
-	public static boolean containsAll(Collection<?> collection, Iterable<?> iterable) {
-		return containsAll(collection, iterable.iterator());
-	}
-
-	/**
-	 * Returns whether the specified collection contains all of the
-	 * elements in the specified iterator.
-	 * <p>
-	 * <code>Collection.containsAll(Iterator iterator)</code>
-	 */
-	public static boolean containsAll(Collection<?> collection, Iterator<?> iterator) {
-		while (iterator.hasNext()) {
-			if ( ! collection.contains(iterator.next())) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	/**
-	 * Returns whether the specified collection contains all of the
-	 * elements in the specified array.
-	 * <p>
-	 * <code>Collection.containsAll(Object[] array)</code>
-	 */
-	public static boolean containsAll(Collection<?> collection, Object... array) {
-		for (int i = array.length; i-- > 0; ) {
-			if ( ! collection.contains(array[i])) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	/**
-	 * Returns whether the specified iterable contains all of the
-	 * elements in the specified collection.
-	 * <p>
-	 * <code>Iterable.containsAll(Collection collection)</code>
-	 */
-	public static boolean containsAll(Iterable<?> iterable, Collection<?> collection) {
-		return containsAll(iterable.iterator(), collection);
-	}
-
-	/**
-	 * Returns whether the specified iterable contains all of the
-	 * elements in the specified collection.
-	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Iterable.containsAll(Collection collection)</code>
-	 */
-	public static boolean containsAll(Iterable<?> iterable, int iterableSize, Collection<?> collection) {
-		return containsAll(iterable.iterator(), iterableSize, collection);
-	}
-
-	/**
-	 * Returns whether the specified iterable 1 contains all of the
-	 * elements in the specified iterable 2.
-	 * <p>
-	 * <code>Iterable.containsAll(Iterable iterable)</code>
-	 */
-	public static boolean containsAll(Iterable<?> iterable1, Iterable<?> iterable2) {
-		return containsAll(iterable1.iterator(), iterable2.iterator());
-	}
-
-	/**
-	 * Returns whether the specified iterable 1 contains all of the
-	 * elements in the specified iterable 2.
-	 * The specified iterable 1 size is a performance hint.
-	 * <p>
-	 * <code>Iterable.containsAll(Iterable iterable)</code>
-	 */
-	public static boolean containsAll(Iterable<?> iterable1, int iterable1Size, Iterable<?> iterable2) {
-		return containsAll(iterable1.iterator(), iterable1Size, iterable2.iterator());
-	}
-
-	/**
-	 * Returns whether the specified iterable contains all of the
-	 * elements in the specified iterator.
-	 * <p>
-	 * <code>Iterable.containsAll(Iterator iterator)</code>
-	 */
-	public static boolean containsAll(Iterable<?> iterable, Iterator<?> iterator) {
-		return containsAll(iterable.iterator(), iterator);
-	}
-
-	/**
-	 * Returns whether the specified iterable contains all of the
-	 * elements in the specified iterator.
-	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Iterable.containsAll(Iterator iterator)</code>
-	 */
-	public static boolean containsAll(Iterable<?> iterable, int iterableSize, Iterator<?> iterator) {
-		return containsAll(iterable.iterator(), iterableSize, iterator);
-	}
-
-	/**
-	 * Returns whether the specified iterable contains all of the
-	 * elements in the specified array.
-	 * <p>
-	 * <code>Iterable.containsAll(Object[] array)</code>
-	 */
-	public static boolean containsAll(Iterable<?> iterable, Object... array) {
-		return containsAll(iterable.iterator(), array);
-	}
-
-	/**
-	 * Returns whether the specified iterable contains all of the
-	 * elements in the specified array.
-	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Iterable.containsAll(Object[] array)</code>
-	 */
-	public static boolean containsAll(Iterable<?> iterable, int iterableSize, Object... array) {
-		return containsAll(iterable.iterator(), iterableSize, array);
-	}
-
-	/**
-	 * Returns whether the specified iterator contains all of the
-	 * elements in the specified collection.
-	 * <p>
-	 * <code>Iterator.containsAll(Collection collection)</code>
-	 */
-	public static boolean containsAll(Iterator<?> iterator, Collection<?> collection) {
-		return set(iterator).containsAll(collection);
-	}
-
-	/**
-	 * Returns whether the specified iterator contains all of the
-	 * elements in the specified collection.
-	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Iterator.containsAll(Collection collection)</code>
-	 */
-	public static boolean containsAll(Iterator<?> iterator, int iteratorSize, Collection<?> collection) {
-		return set(iterator, iteratorSize).containsAll(collection);
-	}
-
-	/**
-	 * Returns whether the specified iterator contains all of the
-	 * elements in the specified iterable.
-	 * <p>
-	 * <code>Iterator.containsAll(Iterable iterable)</code>
-	 */
-	public static boolean containsAll(Iterator<?> iterator, Iterable<?> iterable) {
-		return containsAll(set(iterator), iterable);
-	}
-
-	/**
-	 * Returns whether the specified iterator contains all of the
-	 * elements in the specified iterable.
-	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Iterator.containsAll(Iterable iterable)</code>
-	 */
-	public static boolean containsAll(Iterator<?> iterator, int iteratorSize, Iterable<?> iterable) {
-		return containsAll(set(iterator, iteratorSize), iterable);
-	}
-
-	/**
-	 * Returns whether the specified iterator 1 contains all of the
-	 * elements in the specified iterator 2.
-	 * <p>
-	 * <code>Iterator.containsAll(Iterator iterator)</code>
-	 */
-	public static boolean containsAll(Iterator<?> iterator1, Iterator<?> iterator2) {
-		return containsAll(set(iterator1), iterator2);
-	}
-
-	/**
-	 * Returns whether the specified iterator 1 contains all of the
-	 * elements in the specified iterator 2.
-	 * The specified iterator 1 size is a performance hint.
-	 * <p>
-	 * <code>Iterator.containsAll(Iterator iterator)</code>
-	 */
-	public static boolean containsAll(Iterator<?> iterator1, int iterator1Size, Iterator<?> iterator2) {
-		return containsAll(set(iterator1, iterator1Size), iterator2);
-	}
-
-	/**
-	 * Returns whether the specified iterator contains all of the
-	 * elements in the specified array.
-	 * <p>
-	 * <code>Iterator.containsAll(Object[] array)</code>
-	 */
-	public static boolean containsAll(Iterator<?> iterator, Object... array) {
-		return containsAll(set(iterator), array);
-	}
-
-	/**
-	 * Returns whether the specified iterator contains all of the
-	 * elements in the specified array.
-	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Iterator.containsAll(Object[] array)</code>
-	 */
-	public static boolean containsAll(Iterator<?> iterator, int iteratorSize, Object... array) {
-		return containsAll(set(iterator, iteratorSize), array);
-	}
-
-
-	// ********** diff **********
-
-	/**
-	 * Returns the index of the first elements in the specified
-	 * lists that are different, beginning at the end.
-	 * Returns -1.
-	 * Returns the index of the
-	 * last element in the longer list.
-	 * Use the elements' {@link Object#equals(Object)} method to compare the
-	 * elements.
-	 * <p>
-	 * <code>Collections.diffEnd(List list1, List list2)</code>
-	 */
-	public static int diffEnd(List<?> list1, List<?> list2) {
-		return ArrayTools.diffEnd(list1.toArray(), list2.toArray());
-	}
-
-	/**
-	 * Returns the range of elements in the specified
-	 * arrays that are different.
-	 * Returns [size, -1].
-	 * Use the elements' {@link Object#equals(Object)} method to compare the
-	 * elements.
-	 * <p>
-	 * <code>Collections.diffRange(List list1, List list2)</code>
-	 * @see #diffStart(List, List)
-	 * @see #diffEnd(List, List)
-	 */
-	public static Range diffRange(List<?> list1, List<?> list2) {
-		return ArrayTools.diffRange(list1.toArray(), list2.toArray());
-	}
-
-	/**
-	 * Returns the index of the first elements in the specified
-	 * lists that are different. If the lists are identical, return
-	 * the size of the two lists (i.e. one past the last index).
-	 * If the lists are different sizes and all the elements in
-	 * the shorter list match their corresponding elements in
-	 * Returns the size of the shorter list
-	 * (i.e. one past the last index of the shorter list).
-	 * Use the elements' {@link Object#equals(Object)} method to compare the
-	 * elements.
-	 * <p>
-	 * <code>Collections.diffStart(List list1, List list2)</code>
-	 */
-	public static int diffStart(List<?> list1, List<?> list2) {
-		return ArrayTools.diffStart(list1.toArray(), list2.toArray());
-	}
-
-
-	// ********** identity diff **********
-
-	/**
-	 * Returns the index of the first elements in the specified
-	 * lists that are different, beginning at the end.
-	 * Returns -1.
-	 * Returns the index of the
-	 * last element in the longer list.
-	 * Use object identity to compare the elements.
-	 * <p>
-	 * <code>Collections.identityDiffEnd(List list1, List list2)</code>
-	 */
-	public static int identityDiffEnd(List<?> list1, List<?> list2) {
-		return ArrayTools.identityDiffEnd(list1.toArray(), list2.toArray());
-	}
-
-	/**
-	 * Returns the range of elements in the specified
-	 * arrays that are different.
-	 * Returns [size, -1].
-	 * Use object identity to compare the elements.
-	 * <p>
-	 * <code>Collections.identityDiffStart(List list1, List list2)</code>
-	 * @see #identityDiffStart(List, List)
-	 * @see #identityDiffEnd(List, List)
-	 */
-	public static Range identityDiffRange(List<?> list1, List<?> list2) {
-		return ArrayTools.identityDiffRange(list1.toArray(), list2.toArray());
-	}
-
-	/**
-	 * Returns the index of the first elements in the specified
-	 * lists that are different. If the lists are identical, return
-	 * the size of the two lists (i.e. one past the last index).
-	 * If the lists are different sizes and all the elements in
-	 * the shorter list match their corresponding elements in
-	 * Returns the size of the shorter list
-	 * (i.e. one past the last index of the shorter list).
-	 * Use object identity to compare the elements.
-	 * <p>
-	 * <code>Collections.identityDiffStart(List list1, List list2)</code>
-	 */
-	public static int identityDiffStart(List<?> list1, List<?> list2) {
-		return ArrayTools.identityDiffStart(list1.toArray(), list2.toArray());
-	}
-
-
-	// ********** elements are equal **********
-
-	/**
-	 * Returns the same elements
-	 * in the same order.
-	 */
-	public static boolean elementsAreDifferent(Iterable<?> iterable1, Iterable<?> iterable2) {
-		return elementsAreDifferent(iterable1.iterator(), iterable2.iterator());
-	}
-
-	/**
-	 * Returns the same elements
-	 * in the same order.
-	 */
-	public static boolean elementsAreDifferent(Iterator<?> iterator1, Iterator<?> iterator2) {
-		return ! elementsAreEqual(iterator1, iterator2);
-	}
-
-	/**
-	 * Returns equal elements
-	 * in the same order.
-	 * <p>
-	 * <code>Iterable.elementsAreEqual(Iterable iterable)</code>
-	 */
-	public static boolean elementsAreEqual(Iterable<?> iterable1, Iterable<?> iterable2) {
-		return elementsAreEqual(iterable1.iterator(), iterable2.iterator());
-	}
-
-	/**
-	 * Returns equal elements
-	 * in the same order.
-	 * <p>
-	 * <code>Iterator.elementsAreEqual(Iterator iterator)</code>
-	 */
-	public static boolean elementsAreEqual(Iterator<?> iterator1, Iterator<?> iterator2) {
-		while (iterator1.hasNext() && iterator2.hasNext()) {
-			if (Tools.valuesAreDifferent(iterator1.next(), iterator2.next())) {
-				return false;
-			}
-		}
-		return ! (iterator1.hasNext() || iterator2.hasNext());
-	}
-
-
-	// ********** elements are identical **********
-
-	/**
-	 * Returns the same elements.
-	 * <p>
-	 * <code>Iterable.identical(Iterable iterable)</code>
-	 */
-	public static boolean elementsAreIdentical(Iterable<?> iterable1, Iterable<?> iterable2) {
-		return elementsAreIdentical(iterable1.iterator(), iterable2.iterator());
-	}
-
-	/**
-	 * Returns the same elements.
-	 * <p>
-	 * <code>Iterator.identical(Iterator iterator)</code>
-	 */
-	public static boolean elementsAreIdentical(Iterator<?> iterator1, Iterator<?> iterator2) {
-		while (iterator1.hasNext() && iterator2.hasNext()) {
-			if (iterator1.next() != iterator2.next()) {
-				return false;
-			}
-		}
-		return ! (iterator1.hasNext() || iterator2.hasNext());
-	}
-
-	/**
-	 * Returns the same
-	 * elements.
-	 * <p>
-	 * <code>Iterable.notIdentical(Iterable iterable)</code>
-	 */
-	public static boolean elementsAreNotIdentical(Iterable<?> iterable1, Iterable<?> iterable2) {
-		return elementsAreNotIdentical(iterable1.iterator(), iterable2.iterator());
-	}
-
-	/**
-	 * Returns the same
-	 * elements.
-	 * <p>
-	 * <code>Iterator.notIdentical(Iterator iterator)</code>
-	 */
-	public static boolean elementsAreNotIdentical(Iterator<?> iterator1, Iterator<?> iterator2) {
-		return ! elementsAreIdentical(iterator1, iterator2);
-	}
-
-
-	// ********** get **********
-
-	/**
-	 * Returns the element corresponding to the specified index
-	 * in the specified iterable.
-	 * <p>
-	 * <code>Iterable.get(int index)</code>
-	 */
-	public static <E> E get(Iterable<? extends E> iterable, int index) {
-		return get(iterable.iterator(), index);
-	}
-
-	/**
-	 * Returns the element corresponding to the specified index
-	 * in the specified iterator.
-	 * <p>
-	 * <code>Iterator.get(int index)</code>
-	 */
-	public static <E> E get(Iterator<? extends E> iterator, int index) {
-		int i = 0;
-		while (iterator.hasNext()) {
-			E next = iterator.next();
-			if (i++ == index) {
-				return next;
-			}
-		}
-		throw new IndexOutOfBoundsException(String.valueOf(index) + ':' + String.valueOf(i));
-	}
-
-
-	// ********** hash code **********
-
-	public static int hashCode(Iterable<?> iterable) {
-		if (iterable == null) {
-			return 0;
-		}
-		int hash = 1;
-		for (Object element : iterable) {
-			hash = 31 * hash + (element == null ? 0 : element.hashCode());
-		}
-		return hash;
-	}
-
-
-	// ********** index of **********
-
-	/**
-	 * Returns the index of the first occurrence of the
-	 * specified element in the specified iterable;
-	 * Returns -1 if there is no such index.
-	 * <p>
-	 * <code>Iterable.indexOf(Object o)</code>
-	 */
-	public static int indexOf(Iterable<?> iterable, Object value) {
-		return indexOf(iterable.iterator(), value);
-	}
-
-	/**
-	 * Returns the index of the first occurrence of the
-	 * specified element in the specified iterator;
-	 * Returns -1 if there is no such index.
-	 * <p>
-	 * <code>Iterator.indexOf(Object o)</code>
-	 */
-	public static int indexOf(Iterator<?> iterator, Object value) {
-		if (value == null) {
-			for (int i = 0; iterator.hasNext(); i++) {
-				if (iterator.next() == null) {
-					return i;
-				}
-			}
-		} else {
-			for (int i = 0; iterator.hasNext(); i++) {
-				if (value.equals(iterator.next())) {
-					return i;
-				}
-			}
-		}
-		return -1;
-	}
-
-
-	// ********** insertion index of **********
-
-	/**
-	 * Returns an index of where the specified comparable object
-	 * can be inserted into the specified sorted list and still keep
-	 * the list sorted. If the specified sorted list is an instance of
-	 * Returns the <em>maximum</em> insertion index;
-	 * Returns the <em>minimum</em> insertion index.
-	 */
-	public static <E extends Comparable<? super E>> int insertionIndexOf(List<E> sortedList, Comparable<E> value) {
-		if (sortedList instanceof RandomAccess) {
-			for (int i = sortedList.size(); i-- > 0; ) {
-				if (value.compareTo(sortedList.get(i)) >= 0) {
-					return i + 1;
-				}
-			}
-			return 0;
-		}
-		int i = 0;
-		for (E element : sortedList) {
-			if (value.compareTo(element) <= 0) {
-				return i;
-			}
-			i++;
-		}
-		return i;
-	}
-
-	/**
-	 * Returns an index of where the specified comparable object
-	 * can be inserted into the specified sorted list and still keep
-	 * the list sorted. If the specified sorted list is an instance of
-	 * Returns the <em>maximum</em> insertion index;
-	 * Returns the <em>minimum</em> insertion index.
-	 */
-	public static <E> int insertionIndexOf(List<E> sortedList, E value, Comparator<? super E> comparator) {
-		if (sortedList instanceof RandomAccess) {
-			for (int i = sortedList.size(); i-- > 0; ) {
-				if (comparator.compare(value, sortedList.get(i)) >= 0) {
-					return i + 1;
-				}
-			}
-			return 0;
-		}
-		int i = 0;
-		for (E element : sortedList) {
-			if (comparator.compare(value, element) <= 0) {
-				return i;
-			}
-			i++;
-		}
-		return i;
-	}
-
-
-	// ********** iterable/iterator **********
-
-	/**
-	 * Returns an iterable on the elements in the specified array.
-	 * <p>
-	 * <code>Arrays.iterable(Object[] array)</code>
-	 */
-	public static <E> Iterable<E> iterable(E... array) {
-		return new ArrayIterable<E>(array);
-	}
-
-	/**
-	 * Returns an iterator on the elements in the specified array.
-	 * <p>
-	 * <code>Arrays.iterator(Object[] array)</code>
-	 */
-	public static <E> Iterator<E> iterator(E... array) {
-		return new ArrayIterator<E>(array);
-	}
-
-
-	// ********** last **********
-
-	/**
-	 * Returns the specified iterable's last element.
-	 * <p>
-	 * <code>Iterable.last()</code>
-	 *
-     * @exception java.util.NoSuchElementException iterable is empty.
-	 */
-	public static <E> E last(Iterable<E> iterable) {
-		return last(iterable.iterator());
-	}
-
-	/**
-	 * Returns the specified iterator's last element.
-	 * <p>
-	 * <code>Iterator.last()</code>
-	 *
-     * @exception java.util.NoSuchElementException iterator is empty.
-	 */
-	public static <E> E last(Iterator<E> iterator) {
-		E last;
-		do {
-			last = iterator.next();
-		} while (iterator.hasNext());
-		return last;
-	}
-
-
-	// ********** last index of **********
-
-	/**
-	 * Returns the index of the last occurrence of the
-	 * specified element in the specified iterable;
-	 * Returns -1 if there is no such index.
-	 * <p>
-	 * <code>Iterable.lastIndexOf(Object o)
-	 */
-	public static int lastIndexOf(Iterable<?> iterable, Object value) {
-		return lastIndexOf(iterable.iterator(), value);
-	}
-
-	/**
-	 * Returns the index of the last occurrence of the
-	 * specified element in the specified iterable;
-	 * Returns -1 if there is no such index.
-	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Iterable.lastIndexOf(Object o)
-	 */
-	public static int lastIndexOf(Iterable<?> iterable, int iterableSize, Object value) {
-		return lastIndexOf(iterable.iterator(), iterableSize, value);
-	}
-
-	/**
-	 * Returns the index of the last occurrence of the
-	 * specified element in the specified iterator;
-	 * Returns -1 if there is no such index.
-	 * <p>
-	 * <code>Iterator.lastIndexOf(Object o)
-	 */
-	public static int lastIndexOf(Iterator<?> iterator, Object value) {
-		return iterator.hasNext() ? list(iterator).lastIndexOf(value) : -1;
-	}
-
-	/**
-	 * Returns the index of the last occurrence of the
-	 * specified element in the specified iterator;
-	 * Returns -1 if there is no such index.
-	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Iterator.lastIndexOf(Object o)
-	 */
-	public static int lastIndexOf(Iterator<?> iterator, int iteratorSize, Object value) {
-		return iterator.hasNext() ? list(iterator, iteratorSize).lastIndexOf(value) : -1;
-	}
-
-
-	// ********** list **********
-
-	/**
-	 * Returns a list corresponding to the specified iterable.
-	 * <p>
-	 * <code>Iterable.toList()</code>
-	 */
-	public static <E> ArrayList<E> list(Iterable<? extends E> iterable) {
-		return list(iterable.iterator());
-	}
-
-	/**
-	 * Returns a list corresponding to the specified iterable.
-	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Iterable.toList()</code>
-	 */
-	public static <E> ArrayList<E> list(Iterable<? extends E> iterable, int iterableSize) {
-		return list(iterable.iterator(), iterableSize);
-	}
-
-	/**
-	 * Returns a list corresponding to the specified iterator.
-	 * <p>
-	 * <code>Iterator.toList()</code>
-	 */
-	public static <E> ArrayList<E> list(Iterator<? extends E> iterator) {
-		return list(iterator, new ArrayList<E>());
-	}
-
-	/**
-	 * Returns a list corresponding to the specified iterator.
-	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Iterator.toList()</code>
-	 */
-	public static <E> ArrayList<E> list(Iterator<? extends E> iterator, int iteratorSize) {
-		return list(iterator, new ArrayList<E>(iteratorSize));
-	}
-
-	private static <E> ArrayList<E> list(Iterator<? extends E> iterator, ArrayList<E> list) {
-		while (iterator.hasNext()) {
-			list.add(iterator.next());
-		}
-		return list;
-	}
-
-	/**
-	 * Returns a list corresponding to the specified array.
-	 * Unlike {@link Arrays#asList(Object[])}, the list
-	 * is modifiable and is not backed by the array.
-	 */
-	public static <E> ArrayList<E> list(E... array) {
-		return new ArrayList<E>(Arrays.asList(array));
-	}
-
-	/**
-	 * Returns a list iterator for the specified array.
-	 * <p>
-	 * <code>Arrays.listIterator(Object[] array)</code>
-	 */
-	public static <E> ListIterator<E> listIterator(E... array) {
-		return listIterator(array, 0);
-	}
-
-	/**
-	 * Returns a list iterator for the specified array
-	 * starting at the specified position in the array.
-	 * <p>
-	 * <code>Arrays.listIterator(Object[] array, int index)</code>
-	 */
-	public static <E> ListIterator<E> listIterator(E[] array, int start) {
-		return listIterator(array, start, array.length - start);
-	}
-
-	/**
-	 * Returns a list iterator for the specified array
-	 * starting at the specified position in the array.
-	 * <p>
-	 * <code>Arrays.listIterator(Object[] array, int index, int length)</code>
-	 */
-	public static <E> ListIterator<E> listIterator(E[] array, int start, int length) {
-		return new ArrayListIterator<E>(array, start, length);
-	}
-
-
-	// ********** move **********
-
-	/**
-	 * Move an element from the specified source index to the specified target
-	 * Returns the altered list.
-	 * <p>
-	 * <code>List.move(int targetIndex, int sourceIndex)</code>
-	 */
-	public static <E> List<E> move(List<E> list, int targetIndex, int sourceIndex) {
-		return (targetIndex == sourceIndex) ? list : move_(list, targetIndex, sourceIndex);
-	}
-
-	/**
-	 * assume targetIndex != sourceIndex
-	 */
-	private static <E> List<E> move_(List<E> list, int targetIndex, int sourceIndex) {
-		if (list instanceof RandomAccess) {
-			// move elements, leaving the list in place
-			E temp = list.get(sourceIndex);
-			if (targetIndex < sourceIndex) {
-				for (int i = sourceIndex; i-- > targetIndex; ) {
-					list.set(i + 1, list.get(i));
-				}
-			} else {
-				for (int i = sourceIndex; i < targetIndex; i++) {
-					list.set(i, list.get(i + 1));
-				}
-			}
-			list.set(targetIndex, temp);
-		} else {
-			// remove the element and re-add it at the target index
-			list.add(targetIndex, list.remove(sourceIndex));
-		}
-		return list;
-	}
-
-	/**
-	 * Move elements from the specified source index to the specified target
-	 * Returns the altered list.
-	 * <p>
-	 * <code>List.move(int targetIndex, int sourceIndex, int length)</code>
-	 */
-	public static <E> List<E> move(List<E> list, int targetIndex, int sourceIndex, int length) {
-		if ((targetIndex == sourceIndex) || (length == 0)) {
-			return list;
-		}
-		if (length == 1) {
-			return move_(list, targetIndex, sourceIndex);
-		}
-		if (list instanceof RandomAccess) {
-			// move elements, leaving the list in place
-			ArrayList<E> temp = new ArrayList<E>(list.subList(sourceIndex, sourceIndex + length));
-			if (targetIndex < sourceIndex) {
-				for (int i = sourceIndex; i-- > targetIndex; ) {
-					list.set(i + length, list.get(i));
-				}
-			} else {
-				for (int i = sourceIndex; i < targetIndex; i++) {
-					list.set(i, list.get(i + length));
-				}
-			}
-			for (int i = 0; i < length; i++) {
-				list.set(targetIndex + i, temp.get(i));
-			}
-		} else {
-			// remove the elements and re-add them at the target index
-			list.addAll(targetIndex, removeElementsAtIndex(list, sourceIndex, length));
-		}
-		return list;
-	}
-
-
-	// ********** remove all **********
-
-	/**
-	 * Remove all the elements returned by the specified iterable
-	 * from the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * <p>
-	 * <code>Collection.removeAll(Iterable iterable)</code>
-	 */
-	public static boolean removeAll(Collection<?> collection, Iterable<?> iterable) {
-		return removeAll(collection, iterable.iterator());
-	}
-
-	/**
-	 * Remove all the elements returned by the specified iterable
-	 * from the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Collection.removeAll(Iterable iterable)</code>
-	 */
-	public static boolean removeAll(Collection<?> collection, Iterable<?> iterable, int iterableSize) {
-		return removeAll(collection, iterable.iterator(), iterableSize);
-	}
-
-	/**
-	 * Remove all the elements returned by the specified iterator
-	 * from the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * <p>
-	 * <code>Collection.removeAll(Iterator iterator)</code>
-	 */
-	public static boolean removeAll(Collection<?> collection, Iterator<?> iterator) {
-		return iterator.hasNext() ? collection.removeAll(set(iterator)) : false;
-	}
-
-	/**
-	 * Remove all the elements returned by the specified iterator
-	 * from the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Collection.removeAll(Iterator iterator)</code>
-	 */
-	public static boolean removeAll(Collection<?> collection, Iterator<?> iterator, int iteratorSize) {
-		return iterator.hasNext() ? collection.removeAll(set(iterator, iteratorSize)) : false;
-	}
-
-	/**
-	 * Remove all the elements in the specified array
-	 * from the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * <p>
-	 * <code>Collection.removeAll(Object[] array)</code>
-	 */
-	public static boolean removeAll(Collection<?> collection, Object... array) {
-		return (array.length == 0) ? false : collection.removeAll(set(array));
-	}
-
-
-	// ********** remove all occurrences **********
-
-	/**
-	 * Remove all occurrences of the specified element
-	 * from the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * <p>
-	 * <code>Collection.removeAllOccurrences(Object value)</code>
-	 */
-	public static boolean removeAllOccurrences(Collection<?> collection, Object value) {
-		boolean modified = false;
-		Iterator<?> stream = collection.iterator();
-		if (value == null) {
-			while (stream.hasNext()) {
-				if (stream.next() == null) {
-					stream.remove();
-					modified = true;
-				}
-			}
-		} else {
-			while (stream.hasNext()) {
-				if (value.equals(stream.next())) {
-					stream.remove();
-					modified = true;
-				}
-			}
-		}
-		return modified;
-	}
-
-
-	// ********** remove elements at index **********
-
-	/**
-	 * Remove the elements at the specified index.
-	 * Returns the removed elements.
-	 * <p>
-	 * <code>List.remove(int index, int length)</code>
-	 */
-	public static <E> ArrayList<E> removeElementsAtIndex(List<E> list, int index, int length) {
-		List<E> subList = list.subList(index, index + length);
-		ArrayList<E> result = new ArrayList<E>(subList);
-		subList.clear();
-		return result;
-	}
-
-
-	// ********** remove duplicate elements **********
-
-	/**
-	 * Remove any duplicate elements from the specified list,
-	 * while maintaining the order.
-	 * Returns whether the list changed as a result.
-	 */
-	public static <E> boolean removeDuplicateElements(List<E> list) {
-		int size = list.size();
-		if ((size == 0) || (size == 1)) {
-			return false;
-		}
-		return removeDuplicateElements(list, size);
-	}
-
-	/**
-	 * assume list is non-empty
-	 */
-	static <E> boolean removeDuplicateElements(List<E> list, int size) {
-		LinkedHashSet<E> temp = new LinkedHashSet<E>(size);		// take advantage of hashed look-up
-		boolean modified = false;
-		for (E item : list) {
-			if ( ! temp.add(item)) {
-				modified = true;  // duplicate item
-			}
-		}
-		if (modified) {
-			int i = 0;
-			for (E e : temp) {
-				list.set(i, e);
-				i++;
-			}
-			int tempSize = temp.size();
-			for (i = list.size(); i-- > tempSize; ) {
-				list.remove(i);  // pull off the end
-			}
-		}
-		return modified;
-	}
-
-
-	// ********** retain all **********
-
-	/**
-	 * Retain only the elements in the specified iterable
-	 * in the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * <p>
-	 * <code>Collection.retainAll(Iterable iterable)</code>
-	 */
-	public static boolean retainAll(Collection<?> collection, Iterable<?> iterable) {
-		return retainAll(collection, iterable.iterator());
-	}
-
-	/**
-	 * Retain only the elements in the specified iterable
-	 * in the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Collection.retainAll(Iterable iterable)</code>
-	 */
-	public static boolean retainAll(Collection<?> collection, Iterable<?> iterable, int iterableSize) {
-		return retainAll(collection, iterable.iterator(), iterableSize);
-	}
-
-	/**
-	 * Retain only the elements in the specified iterator
-	 * in the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * <p>
-	 * <code>Collection.retainAll(Iterator iterator)</code>
-	 */
-	public static boolean retainAll(Collection<?> collection, Iterator<?> iterator) {
-		if (iterator.hasNext()) {
-			return collection.retainAll(set(iterator));
-		}
-		if (collection.isEmpty()) {
-			return false;
-		}
-		collection.clear();
-		return true;
-	}
-
-	/**
-	 * Retain only the elements in the specified iterator
-	 * in the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Collection.retainAll(Iterator iterator)</code>
-	 */
-	public static boolean retainAll(Collection<?> collection, Iterator<?> iterator, int iteratorSize) {
-		if (iterator.hasNext()) {
-			return collection.retainAll(set(iterator, iteratorSize));
-		}
-		if (collection.isEmpty()) {
-			return false;
-		}
-		collection.clear();
-		return true;
-	}
-
-	/**
-	 * Retain only the elements in the specified array
-	 * in the specified collection.
-	 * Returns whether the collection changed as a result.
-	 * <p>
-	 * <code>Collection.retainAll(Object[] array)</code>
-	 */
-	public static boolean retainAll(Collection<?> collection, Object... array) {
-		if (array.length > 0) {
-			return collection.retainAll(set(array));
-		}
-		if (collection.isEmpty()) {
-			return false;
-		}
-		collection.clear();
-		return true;
-	}
-
-
-	// ********** reverse list **********
-
-	/**
-	 * Returns a list with entries in reverse order from those
-	 * returned by the specified iterable.
-	 * <p>
-	 * <code>Iterable.reverseList()</code>
-	 */
-	public static <E> ArrayList<E> reverseList(Iterable<? extends E> iterable) {
-		return reverseList(iterable.iterator());
-	}
-
-	/**
-	 * Returns a list with entries in reverse order from those
-	 * returned by the specified iterable.
-	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Iterable.reverseList()</code>
-	 */
-	public static <E> ArrayList<E> reverseList(Iterable<? extends E> iterable, int iterableSize) {
-		return reverseList(iterable.iterator(), iterableSize);
-	}
-
-	/**
-	 * Returns a list with entries in reverse order from those
-	 * returned by the specified iterator.
-	 * <p>
-	 * <code>Iterator.reverseList()</code>
-	 */
-	public static <E> ArrayList<E> reverseList(Iterator<? extends E> iterator) {
-		return (ArrayList<E>) reverse(list(iterator));
-	}
-
-	/**
-	 * Returns a list with entries in reverse order from those
-	 * returned by the specified iterator.
-	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Iterator.reverseList()</code>
-	 */
-	public static <E> ArrayList<E> reverseList(Iterator<? extends E> iterator, int size) {
-		return (ArrayList<E>) reverse(list(iterator, size));
-	}
-
-
-	// ********** rotate **********
-
-	/**
-	 * Returns the list after it has been "rotated" by one position.
-	 * <p>
-	 * <code>List.rotate()</code>
-	 */
-	public static <E> List<E> rotate(List<E> list) {
-		return rotate(list, 1);
-	}
-
-
-	// ********** set **********
-
-	/**
-	 * Returns a set corresponding to the specified iterable.
-	 * <p>
-	 * <code>HashSet(Iterable iterable)</code>
-	 */
-	public static <E> HashSet<E> set(Iterable<? extends E> iterable) {
-		return set(iterable.iterator());
-	}
-
-	/**
-	 * Returns a set corresponding to the specified iterable.
-	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>HashSet(Iterable iterable)</code>
-	 */
-	public static <E> HashSet<E> set(Iterable<? extends E> iterable, int iterableSize) {
-		return set(iterable.iterator(), iterableSize);
-	}
-
-	/**
-	 * Returns a set corresponding to the specified iterator.
-	 * <p>
-	 * <code>HashSet(Iterator iterator)</code>
-	 */
-	public static <E> HashSet<E> set(Iterator<? extends E> iterator) {
-		return set(iterator, new HashSet<E>());
-	}
-
-	/**
-	 * Returns a set corresponding to the specified iterator.
-	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>HashSet(Iterator iterator)</code>
-	 */
-	public static <E> HashSet<E> set(Iterator<? extends E> iterator, int iteratorSize) {
-		return set(iterator, new HashSet<E>(iteratorSize));
-	}
-
-	private static <E> HashSet<E> set(Iterator<? extends E> iterator, HashSet<E> set) {
-		while (iterator.hasNext()) {
-			set.add(iterator.next());
-		}
-		return set;
-	}
-
-	/**
-	 * Returns a set corresponding to the specified array.
-	 * <p>
-	 * <code>HashSet(Object[] array)</code>
-	 */
-	public static <E> HashSet<E> set(E... array) {
-		HashSet<E> set = new HashSet<E>(array.length);
-		for (int i = array.length; i-- > 0;) {
-			set.add(array[i]);
-		}
-		return set;
-	}
-
-
-	// ********** singleton iterator **********
-
-	/**
-	 * Returns an iterator that returns only the single,
-	 * specified object.
-	 * <p>
-	 * <code>Object.toIterator()</code>
-	 */
-	public static <E> Iterator<E> singletonIterator(E value) {
-		return new SingleElementIterator<E>(value);
-	}
-
-	/**
-	 * Returns a list iterator that returns only the single,
-	 * specified object.
-	 * <p>
-	 * <code>Object.toListIterator()</code>
-	 */
-	public static <E> ListIterator<E> singletonListIterator(E value) {
-		return new SingleElementListIterator<E>(value);
-	}
-
-
-	// ********** size **********
-
-	/**
-	 * Returns the number of elements returned by the specified iterable.
-	 * <p>
-	 * <code>Iterable.size()</code>
-	 */
-	public static int size(Iterable<?> iterable) {
-		return size(iterable.iterator());
-	}
-
-	/**
-	 * Returns the number of elements returned by the specified iterator.
-	 * <p>
-	 * <code>Iterator.size()</code>
-	 */
-	public static int size(Iterator<?> iterator) {
-		int size = 0;
-		while (iterator.hasNext()) {
-			iterator.next();
-			size++;
-		}
-		return size;
-	}
-
-	/**
-	 * Returns whether the specified iterable is empty
-	 * (Shortcuts the iterator rather than calculating the entire size)
-	 */
-	public static boolean isEmpty(Iterable<?> iterable) {
-		return isEmpty(iterable.iterator());
-	}
-
-	/**
-	 * Returns whether the specified iterator is empty
-	 * (Shortcuts the iterator rather than calculating the entire size)
-	 */
-	public static boolean isEmpty(Iterator<?> iterator) {
-		return ! iterator.hasNext();
-	}
-
-
-	// ********** sort **********
-
-	/**
-	 * Returns an iterable containing the sorted elements of the specified iterable.
-	 * <p>
-	 * <code>Iterable.sort()</code>
-	 */
-	public static <E extends Comparable<? super E>> Iterable<E> sort(Iterable<E> iterable) {
-		return sort(iterable, null);
-	}
-
-	/**
-	 * Returns an iterable containing the sorted elements of the specified iterable.
-	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Iterable.sort()</code>
-	 */
-	public static <E extends Comparable<? super E>> Iterable<E> sort(Iterable<E> iterable, int iterableSize) {
-		return sort(iterable, null, iterableSize);
-	}
-
-	/**
-	 * Returns an iterable containing the sorted elements of the specified iterable.
-	 * <p>
-	 * <code>Iterable.sort(Comparator comparator)</code>
-	 */
-	public static <E> Iterable<E> sort(Iterable<E> iterable, Comparator<? super E> comparator) {
-		return sort(list(iterable), comparator);
-	}
-
-	/**
-	 * Returns an iterable containing the sorted elements of the specified iterable.
-	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>Iterable.sort(Comparator comparator)</code>
-	 */
-	public static <E> Iterable<E> sort(Iterable<E> iterable, Comparator<? super E> comparator, int iterableSize) {
-		return sort(list(iterable, iterableSize), comparator);
-	}
-
-	/**
-	 * Returns the iterator after it has been "sorted".
-	 * <p>
-	 * <code>Iterator.sort()</code>
-	 */
-	public static <E extends Comparable<? super E>> ListIterator<E> sort(Iterator<? extends E> iterator) {
-		return sort(iterator, null);
-	}
-
-	/**
-	 * Returns the iterator after it has been "sorted".
-	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Iterator.sort()</code>
-	 */
-	public static <E extends Comparable<? super E>> ListIterator<E> sort(Iterator<? extends E> iterator, int iteratorSize) {
-		return sort(iterator, null, iteratorSize);
-	}
-
-	/**
-	 * Returns the iterator after it has been "sorted".
-	 * <p>
-	 * <code>Iterator.sort(Comparator comparator)</code>
-	 */
-	public static <E> ListIterator<E> sort(Iterator<? extends E> iterator, Comparator<? super E> comparator) {
-		return sort(list(iterator), comparator).listIterator();
-	}
-
-	/**
-	 * Returns the iterator after it has been "sorted".
-	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>Iterator.sort(Comparator comparator)</code>
-	 */
-	public static <E> ListIterator<E> sort(Iterator<? extends E> iterator, Comparator<? super E> comparator, int iteratorSize) {
-		return sort(list(iterator, iteratorSize), comparator).listIterator();
-	}
-
-
-	// ********** sorted set **********
-
-	/**
-	 * Returns a sorted set corresponding to the specified iterable.
-	 * <p>
-	 * <code>TreeSet(Iterable iterable)</code>
-	 */
-	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterable<? extends E> iterable) {
-		return sortedSet(iterable.iterator());
-	}
-
-	/**
-	 * Returns a sorted set corresponding to the specified iterable.
-	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>TreeSet(Iterable iterable)</code>
-	 */
-	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterable<? extends E> iterable, int iterableSize) {
-		return sortedSet(iterable.iterator(), iterableSize);
-	}
-
-	/**
-	 * Returns a sorted set corresponding to the specified iterable
-	 * and comparator.
-	 * <p>
-	 * <code>TreeSet(Iterable iterable, Comparator c)</code>
-	 */
-	public static <E> TreeSet<E> sortedSet(Iterable<? extends E> iterable, Comparator<? super E> comparator) {
-		return sortedSet(iterable.iterator(), comparator);
-	}
-
-	/**
-	 * Returns a sorted set corresponding to the specified iterable
-	 * and comparator.
-	 * The specified iterable size is a performance hint.
-	 * <p>
-	 * <code>TreeSet(Iterable iterable, Comparator c)</code>
-	 */
-	public static <E> TreeSet<E> sortedSet(Iterable<? extends E> iterable, Comparator<? super E> comparator, int iterableSize) {
-		return sortedSet(iterable.iterator(), comparator, iterableSize);
-	}
-
-	/**
-	 * Returns a sorted set corresponding to the specified iterator.
-	 * <p>
-	 * <code>TreeSet(Iterator iterator)</code>
-	 */
-	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterator<? extends E> iterator) {
-		return sortedSet(iterator, null);
-	}
-
-	/**
-	 * Returns a sorted set corresponding to the specified iterator.
-	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>TreeSet(Iterator iterator)</code>
-	 */
-	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterator<? extends E> iterator, int iteratorSize) {
-		return sortedSet(iterator, null, iteratorSize);
-	}
-
-	/**
-	 * Returns a sorted set corresponding to the specified iterator
-	 * and comparator.
-	 * <p>
-	 * <code>TreeSet(Iterator iterator, Comparator c)</code>
-	 */
-	public static <E> TreeSet<E> sortedSet(Iterator<? extends E> iterator, Comparator<? super E> comparator) {
-		return sortedSet(list(iterator), comparator);
-	}
-
-	/**
-	 * Returns a sorted set corresponding to the specified iterator
-	 * and comparator.
-	 * The specified iterator size is a performance hint.
-	 * <p>
-	 * <code>TreeSet(Iterator iterator, Comparator c)</code>
-	 */
-	public static <E> TreeSet<E> sortedSet(Iterator<? extends E> iterator, Comparator<? super E> comparator, int iteratorSize) {
-		return sortedSet(list(iterator, iteratorSize), comparator);
-	}
-
-	private static <E> TreeSet<E> sortedSet(List<E> list, Comparator<? super E> comparator) {
-		TreeSet<E> sortedSet = new TreeSet<E>(comparator);
-		sortedSet.addAll(list);
-		return sortedSet;
-	}
-
-	/**
-	 * Returns a sorted set corresponding to the specified array.
-	 * <p>
-	 * <code>TreeSet(Object[] array)</code>
-	 */
-	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(E... array) {
-		return sortedSet(array, null);
-	}
-
-	/**
-	 * Returns a sorted set corresponding to the specified array
-	 * and comparator.
-	 * <p>
-	 * <code>TreeSet(Object[] array, Comparator c)</code>
-	 */
-	public static <E> TreeSet<E> sortedSet(E[] array, Comparator<? super E> comparator) {
-		TreeSet<E> sortedSet = new TreeSet<E>(comparator);
-		sortedSet.addAll(Arrays.asList(array));
-		return sortedSet;
-	}
-
-
-	// ********** Old School Vector **********
-
-	/**
-	 * Returns a vector corresponding to the specified iterable.
-	 * This is useful for legacy code that requires a {@link Vector}.
-	 * <p>
-	 * <code>Vector(Iterable iterable)</code>
-	 */
-	public static <E> Vector<E> vector(Iterable<? extends E> iterable) {
-		return vector(iterable.iterator());
-	}
-
-	/**
-	 * Returns a vector corresponding to the specified iterable.
-	 * This is useful for legacy code that requires a {@link Vector}.
-	 * <p>
-	 * <code>Vector(Iterable iterable, int size)</code>
-	 */
-	public static <E> Vector<E> vector(Iterable<? extends E> iterable, int size) {
-		return vector(iterable.iterator(), size);
-	}
-
-	/**
-	 * Returns a vector corresponding to the specified iterator.
-	 * This is useful for legacy code that requires a {@link Vector}.
-	 * <p>
-	 * <code>Vector(Iterator iterator)</code>
-	 */
-	public static <E> Vector<E> vector(Iterator<? extends E> iterator) {
-		return vector(iterator, new Vector<E>());
-	}
-
-	/**
-	 * Returns a vector corresponding to the specified iterator.
-	 * This is useful for legacy code that requires a {@link Vector}.
-	 * <p>
-	 * <code>Vector(Iterator iterator, int size)</code>
-	 */
-	public static <E> Vector<E> vector(Iterator<? extends E> iterator, int size) {
-		return vector(iterator, new Vector<E>(size));
-	}
-
-	private static <E> Vector<E> vector(Iterator<? extends E> iterator, Vector<E> v) {
-		while (iterator.hasNext()) {
-			v.addElement(iterator.next());
-		}
-		return v;
-	}
-
-	/**
-	 * Returns a vector corresponding to the specified array.
-	 * This is useful for legacy code that requires a {@link Vector}.
-	 * <p>
-	 * <code>Vector(Object... array)</code>
-	 */
-	public static <E> Vector<E> vector(E... array) {
-		Vector<E> v = new Vector<E>(array.length);
-		for (E item : array) {
-			v.addElement(item);
-		}
-		return v;
-	}
-
-
-	// ********** single-use Iterable **********
-
-	/**
-	 * Returns a one-use {@link Iterable} for the specified {@link Iterator}.
-	 * Throw an {@link IllegalStateException} if {@link Iterable#iterator()}
-	 * is called more than once.
-	 * As such, this utility should only be used in one-use situations, such as
-	 * a foreach loop.
-	 */
-	public static <E> Iterable<E> iterable(Iterator<? extends E> iterator) {
-		return new SingleUseIterable<E>(iterator);
-	}
-
-	/**
-	 * Returns a single iterator.
-	 * Once the iterator is returned the iterable is no longer valid.
-	 * As such, this utility should only be used in one-time use situations,
-	 * such as a 'for-each' loop.
-	 */
-	public static class SingleUseIterable<E> implements Iterable<E> {
-		private Iterator<E> iterator;
-
-		public SingleUseIterable(Iterator<? extends E> iterator) {
-			super();
-			if (iterator == null) {
-				throw new NullPointerException();
-			}
-			this.iterator = new SuperIteratorWrapper<E>(iterator);
-		}
-
-		@Override
-		public Iterator<E> iterator() {
-			if (this.iterator == null) {
-				throw new IllegalStateException("This method has already been called.");
-			}
-			Iterator<E> result = this.iterator;
-			this.iterator = null;
-			return result;
-		}
-
-		@Override
-		public String toString() {
-			return StringTools.buildToStringFor(this, this.iterator);
-		}
-
-	}
-
-
-	// ********** java.util.Collections enhancements **********
-
-	/**
-	 * Returns the destination list after the source list has been copied into it.
-	 * @see Collections#copy(List, List)
-	 */
-	public static <E> List<E> copy(List<E> dest, List<? extends E> src) {
-		Collections.copy(dest, src);
-		return dest;
-	}
-
-	/**
-	 * Returns the list after it has been "filled".
-	 * @see Collections#fill(List, Object)
-	 */
-	public static <E> List<E> fill(List<E> list, E value) {
-		Collections.fill(list, value);
-		return list;
-	}
-
-	/**
-	 * Returns the list after it has been "reversed".
-	 * @see Collections#reverse(List)
-	 */
-	public static <E> List<E> reverse(List<E> list) {
-		Collections.reverse(list);
-		return list;
-	}
-
-	/**
-	 * Returns the list after it has been "rotated".
-	 * @see Collections#rotate(List, int)
-	 */
-	public static <E> List<E> rotate(List<E> list, int distance) {
-		Collections.rotate(list, distance);
-		return list;
-	}
-
-	/**
-	 * Returns the list after it has been "shuffled".
-	 * @see Collections#shuffle(List)
-	 */
-	public static <E> List<E> shuffle(List<E> list) {
-		Collections.shuffle(list);
-		return list;
-	}
-
-	/**
-	 * Returns the list after it has been "shuffled".
-	 * @see Collections#shuffle(List, Random)
-	 */
-	public static <E> List<E> shuffle(List<E> list, Random random) {
-		Collections.shuffle(list, random);
-		return list;
-	}
-
-	/**
-	 * Returns the list after it has been "sorted".
-	 * NB: The list is sorted in place as a side-effect.
-	 * @see Collections#sort(List)
-	 */
-	public static <E extends Comparable<? super E>> List<E> sort(List<E> list) {
-		Collections.sort(list);
-		return list;
-	}
-
-	/**
-	 * Returns the list after it has been "sorted".
-	 * NB: The list is sorted in place as a side-effect.
-	 * @see Collections#sort(List, Comparator)
-	 */
-	public static <E> List<E> sort(List<E> list, Comparator<? super E> comparator) {
-		Collections.sort(list, comparator);
-		return list;
-	}
-
-	/**
-	 * Returns the list after the specified elements have been "swapped".
-	 * @see Collections#swap(List, int, int)
-	 */
-	public static <E> List<E> swap(List<E> list, int i, int j) {
-		Collections.swap(list, i, j);
-		return list;
-	}
-
-
-	// ********** constructor **********
-
-	/**
-	 * Suppress default constructor, ensuring non-instantiability.
-	 */
-	private CollectionTools() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ComparatorAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ComparatorAdapter.java
new file mode 100644
index 0000000..d2c12b7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ComparatorAdapter.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+import java.util.Comparator;
+
+/**
+ * Convenience comparator that always returns 0;
+ *
+ * @param <T> the type of objects to be compared
+ */
+public class ComparatorAdapter<T>
+	implements Comparator<T>
+{
+	@Override
+	public int compare(T o1, T o2) {
+		return 0;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CompositeException.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CompositeException.java
index 3fd3620..b7e9eb0 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CompositeException.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CompositeException.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -16,6 +16,7 @@
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.util.Collection;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
 
 /**
  * Provide a way for multiple exceptions to be packaged and reported.
@@ -27,6 +28,7 @@
 	private final Throwable[] exceptions;
 	private static final long serialVersionUID = 1L;
 
+
 	/**
 	 * The specified exceptions list must not be empty.
 	 */
@@ -37,15 +39,15 @@
 	/**
 	 * The specified exceptions list must not be empty.
 	 */
-	public CompositeException(Throwable[] exceptions) {
+	public CompositeException(Throwable... exceptions) {
 		// provide a list of the nested exceptions and
 		// grab the first exception and make it the "cause"
 		super(buildMessage(exceptions));
 		this.exceptions = exceptions;
 	}
 
-	public Throwable[] getExceptions() {
-		return this.exceptions;
+	public Iterable<Throwable> getExceptions() {
+		return IterableTools.iterable(this.exceptions);
 	}
 
 	private static String buildMessage(Throwable[] exceptions) {
@@ -97,4 +99,4 @@
 			}
 		}
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CompositeExceptionHandler.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CompositeExceptionHandler.java
new file mode 100644
index 0000000..fdce661
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CompositeExceptionHandler.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+/**
+ * An exception handler that forwards exceptions to a collection of other
+ * exception handlers.
+ */
+public class CompositeExceptionHandler
+	extends AbstractCompositeExceptionHandler<ExceptionHandler>
+{
+	public CompositeExceptionHandler() {
+		super();
+	}
+
+	public CompositeExceptionHandler(ExceptionHandler... exceptionHandlers) {
+		super(exceptionHandlers);
+	}
+
+	public CompositeExceptionHandler(Iterable<? extends ExceptionHandler> exceptionHandlers) {
+		super(exceptionHandlers);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CompositeMultiThreadedExceptionHandler.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CompositeMultiThreadedExceptionHandler.java
new file mode 100644
index 0000000..0cff693
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/CompositeMultiThreadedExceptionHandler.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+/**
+ * An exception handler that forwards exceptions to a collection of other
+ * exception handlers.
+ */
+public class CompositeMultiThreadedExceptionHandler
+	extends AbstractCompositeExceptionHandler<MultiThreadedExceptionHandler>
+	implements MultiThreadedExceptionHandler
+{
+	public CompositeMultiThreadedExceptionHandler() {
+		super();
+	}
+
+	public CompositeMultiThreadedExceptionHandler(MultiThreadedExceptionHandler... exceptionHandlers) {
+		super(exceptionHandlers);
+	}
+
+	public CompositeMultiThreadedExceptionHandler(Iterable<? extends MultiThreadedExceptionHandler> exceptionHandlers) {
+		super(exceptionHandlers);
+	}
+
+	@Override
+	public void handleException(Thread thread, Throwable t) {
+		for (MultiThreadedExceptionHandler handler : this.getExceptionHandlers()) {
+			handler.handleException(thread, t);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ConsumerThreadCoordinator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ConsumerThreadCoordinator.java
index f4b100f..cedfe7c 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ConsumerThreadCoordinator.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ConsumerThreadCoordinator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -53,6 +53,7 @@
 	 */
 	/* CU private */ final ExceptionHandler exceptionHandler;
 
+
 	// ********** construction **********
 
 	/**
@@ -146,7 +147,7 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.thread);
+		return ObjectTools.toString(this, this.thread);
 	}
 
 
@@ -200,7 +201,7 @@
 					// we were interrupted while waiting, must be Quittin' Time
 					Thread.currentThread().interrupt();  // set the Thread's interrupt status
 					return;
-				} catch (RuntimeException ex) {
+				} catch (Throwable ex) {
 					ConsumerThreadCoordinator.this.exceptionHandler.handleException(ex);
 					return;  // hmmm... kill the thread?
 				}
@@ -217,7 +218,7 @@
 		private void consume() {
 			try {
 				this.consumer.consume();
-			} catch (RuntimeException ex) {
+			} catch (Throwable ex) {
 				ConsumerThreadCoordinator.this.exceptionHandler.handleException(ex);
 			}
 		}
@@ -244,4 +245,4 @@
 		 */
 		void consume();
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ExceptionHandler.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ExceptionHandler.java
index f108799..30d87d8 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ExceptionHandler.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ExceptionHandler.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -16,16 +16,15 @@
 import java.io.Serializable;
 
 /**
- * Simple interface for allowing clients to pass an exception handler to a service (e.g. to log the
- * exception). This is particularly helpful if the service executes on another, possibly
- * inaccessible, thread.
+ * Simple interface for allowing clients to pass an exception handler to a
+ * service (e.g. to log the exception). This is particularly helpful if the
+ * service executes on another, possibly inaccessible, thread.
  * <p>
- * 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.
- *
- * @version 2.5
+ * 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 ExceptionHandler {
 
@@ -35,46 +34,51 @@
 	void handleException(Throwable t);
 
 	/**
-	 * Singleton implementation of the exception handler interface that does nothing with the exception.
+	 * Singleton implementation of the exception handler interface that does
+	 * nothing with the exception.
 	 */
-	final class Null implements ExceptionHandler, Serializable {
+	final class Null
+		implements ExceptionHandler, Serializable
+	{
 		public static final ExceptionHandler INSTANCE = new Null();
-		private static final long serialVersionUID = 1L;
+		public static ExceptionHandler instance() {
+			return INSTANCE;
+		}
 		// ensure single instance
 		private Null() {
 			super();
 		}
-		public static ExceptionHandler instance() {
-			return INSTANCE;
-		}
 		@Override
 		public void handleException(Throwable t) {
 			// do nothing
 		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
 		private Object readResolve() {
 			// replace this object with the singleton
 			return INSTANCE;
 		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
 	}
 
 	/**
-	 * Singleton implementation of the exception handler interface that wraps the exception in a
-	 * runtime exception and throws it.
+	 * Singleton implementation of the exception handler interface that
+	 * wraps the exception in a runtime exception and throws the runtime
+	 * exception.
 	 */
-	final class Runtime implements ExceptionHandler, Serializable {
+	final class Runtime
+		implements ExceptionHandler, Serializable
+	{
 		public static final ExceptionHandler INSTANCE = new Runtime();
-		private static final long serialVersionUID = 1L;
+		public static ExceptionHandler instance() {
+			return INSTANCE;
+		}
 		// ensure single instance
 		private Runtime() {
 			super();
 		}
-		public static ExceptionHandler instance() {
-			return INSTANCE;
-		}
 		@Override
 		public void handleException(Throwable t) {
 			// re-throw the exception unchecked
@@ -83,13 +87,47 @@
 			}
 			throw new RuntimeException(t);
 		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
 		private Object readResolve() {
 			// replace this object with the singleton
 			return INSTANCE;
 		}
+	}
+
+	/**
+	 * Singleton implementation of the exception handler interface that,
+	 * like what happens with an unhandled exception
+	 * (see {@link ThreadGroup#uncaughtException(Thread, Throwable)}),
+	 * prints the exception's stack trace to {@link System#err the
+	 * "standard" error output stream}.
+	 */
+	final class Default
+		implements ExceptionHandler, Serializable
+	{
+		public static final ExceptionHandler INSTANCE = new Default();
+		public static ExceptionHandler instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Default() {
+			super();
+		}
+		@Override
+		public void handleException(Throwable t) {
+			t.printStackTrace();
+		}
 		@Override
 		public String toString() {
-			return StringTools.buildSingletonToString(this);
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
 		}
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ExceptionHandlerAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ExceptionHandlerAdapter.java
new file mode 100644
index 0000000..1ad1847
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ExceptionHandlerAdapter.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+/**
+ * Convenience exception handler that does nothing.
+ */
+public class ExceptionHandlerAdapter
+	implements ExceptionHandler
+{
+	@Override
+	public void handleException(Throwable t) {
+		// NOP
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ExceptionHandlerThreadGroup.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ExceptionHandlerThreadGroup.java
new file mode 100644
index 0000000..b71915e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ExceptionHandlerThreadGroup.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+/**
+ * This thread group overrides {@link #uncaughtException(Thread, Throwable)}
+ * and notifies the configured exception handler.
+ */
+public class ExceptionHandlerThreadGroup
+	extends ThreadGroup
+{
+	/**
+	 * Broadcasting delegate.
+	 */
+	private final MultiThreadedExceptionHandler exceptionHandler;
+
+
+	// ********** constructors/initialization **********
+
+	/**
+	 * @see ThreadGroup#ThreadGroup(String)
+	 */
+	public ExceptionHandlerThreadGroup(String name, MultiThreadedExceptionHandler exceptionHandler) {
+		super(name);
+		if (exceptionHandler == null) {
+			throw new NullPointerException();
+		}
+		this.exceptionHandler = exceptionHandler;
+	}
+
+	/**
+	 * @see ThreadGroup#ThreadGroup(ThreadGroup, String)
+	 */
+	public ExceptionHandlerThreadGroup(ThreadGroup parent, String name, MultiThreadedExceptionHandler exceptionHandler) {
+		super(parent, name);
+		if (exceptionHandler == null) {
+			throw new NullPointerException();
+		}
+		this.exceptionHandler = exceptionHandler;
+	}
+
+
+	/**
+	 * Any uncaught exceptions are forwarded to the exception handler.
+	 * @see ThreadGroup#uncaughtException(Thread, Throwable)
+	 */
+	@Override
+	public synchronized void uncaughtException(Thread t, Throwable e) {
+		this.exceptionHandler.handleException(t, e);
+	}
+
+	/**
+	 * Return the exception handler the thread group uses to forward any
+	 * uncaught exceptions.
+	 */
+	public MultiThreadedExceptionHandler getExceptionHandler() {
+		return this.exceptionHandler;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/FileTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/FileTools.java
deleted file mode 100644
index 610d11d..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/FileTools.java
+++ /dev/null
@@ -1,1005 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.channels.FileChannel;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
-import org.eclipse.persistence.tools.utility.iterators.CompositeIterator;
-import org.eclipse.persistence.tools.utility.iterators.FilteringIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
-
-/**
- * Assorted file tools:
- * - delete entire trees of directories and files
- * - build iterators on entire trees of directories and files
- * - build a temporary directory
- * - "canonize" files
- */
-@SuppressWarnings("nls")
-public final class FileTools {
-
-	public static final String USER_HOME_DIRECTORY_NAME = System.getProperty("user.home");
-	public static final String USER_TEMPORARY_DIRECTORY_NAME = System.getProperty("java.io.tmpdir");
-	public static String DEFAULT_TEMPORARY_DIRECTORY_NAME = "tmpdir";
-	public static final String CURRENT_WORKING_DIRECTORY_NAME = System.getProperty("user.dir");
-
-    /** A list of some invalid file name characters.
-				: is the filename separator in MacOS and the drive indicator in DOS
-				* is a DOS wildcard character
-				| is a DOS redirection character
-				& is our own escape character
-				/ is the filename separator in Unix and the command option tag in DOS
-				\ is the filename separator in DOS/Windows and the escape character in Unix
-				; is ???
-				? is a DOS wildcard character
-				[ is ???
-				] is ???
-				= is ???
-				+ is ???
-				< is a DOS redirection character
-				> is a DOS redirection character
-				" is used by DOS to delimit file names with spaces
-				, is ???
-     */
-	public static final char[] INVALID_FILENAME_CHARACTERS = { ':', '*', '|', '&', '/', '\\', ';', '?', '[', ']', '=', '+', '<', '>', '"', ',' };
-
-	/** This encoder will convert strings into valid file names. */
-	public static final XMLStringEncoder FILE_NAME_ENCODER = new XMLStringEncoder(INVALID_FILENAME_CHARACTERS);
-
-	/** Windows files that are redirected to devices etc. */
-	private static final String[] WINDOWS_RESERVED_FILE_NAMES = {
-		"con",
-		"aux",
-		"com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9",
-		"lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9",
-		"prn",
-		"nul"
-	};
-
-	/** The default length of a shortened file name. */
-	public static final int MAXIMUM_SHORTENED_FILE_NAME_LENGTH = 60;
-
-	// ********** deleting directories **********
-
-	/**
-	 * Delete the specified directory and all of its contents.
-	 * <em>USE WITH CARE.</em>
-	 * File#deleteAll()?
-	 */
-	public static void deleteDirectory(String directoryName) {
-		deleteDirectory(new File(directoryName));
-	}
-
-	/**
-	 * Delete the specified directory and all of its contents.
-	 * <em>USE WITH CARE.</em>
-	 * File#deleteAll()?
-	 */
-	public static void deleteDirectory(File directory) {
-		deleteDirectoryContents(directory);
-		if ( ! directory.delete()) {
-			throw new RuntimeException("unable to delete directory: " + directory.getAbsolutePath());
-		}
-	}
-
-	/**
-	 * Delete the contents of the specified directory
-	 * (but not the directory itself).
-	 * <em>USE WITH CARE.</em>
-	 * File#deleteFiles()
-	 */
-	public static void deleteDirectoryContents(String directoryName) {
-		deleteDirectoryContents(new File(directoryName));
-	}
-
-	/**
-	 * Delete the contents of the specified directory
-	 * (but not the directory itself).
-	 * <em>USE WITH CARE.</em>
-	 * File#deleteFiles()
-	 */
-	public static void deleteDirectoryContents(File directory) {
-		for (File file : directory.listFiles()) {
-			if (file.isDirectory()) {
-				deleteDirectory(file);	// recurse through subdirectories
-			} else {
-				if ( ! file.delete()) {
-					throw new RuntimeException("unable to delete file: " + file.getAbsolutePath());
-				}
-			}
-		}
-	}
-
-
-	// ********** copying files **********
-
-	/**
-	 * Copies the content of the source file to the destination file.
-	 * File#copy(File destinationFile)
-	 */
-	public static void copyToFile(File sourceFile, File destinationFile)
-		throws IOException
-	{
-		FileChannel sourceChannel = new FileInputStream(sourceFile).getChannel();
-		FileChannel destinationChannel = new FileOutputStream(destinationFile).getChannel();
-		try {
-			destinationChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
-		} finally {
-			sourceChannel.close();
-			destinationChannel.close();
-		}
-	}
-
-	/**
-	 * Copies the content of the source file to a file by
-	 * the same name in the destination directory.
-	 * File#copyToDirectory(File destinationDirectory)
-	 */
-	public static void copyToDirectory(File sourceFile, File destinationDirectory)
-		throws IOException
-	{
-		File destinationFile = new File(destinationDirectory, sourceFile.getName());
-		if ( ! destinationFile.exists() && ! destinationFile.createNewFile()) {
-			throw new RuntimeException("createNewFile() failed: " + destinationFile);
-		}
-		copyToFile(sourceFile, destinationFile);
-	}
-
-
-	// ********** iteratoring over files and directories **********
-
-	/**
-	 * Returns an iterator on all the files in the specified directory.
-	 * The iterator will skip over subdirectories.
-	 * File#files()
-	 */
-	public static Iterator<File> filesIn(String directoryName) {
-		return filesIn(new File(directoryName));
-	}
-
-	/**
-	 * Returns an iterator on all the files in the specified directory.
-	 * The iterator will skip over subdirectories.
-	 * File#files()
-	 */
-	public static Iterator<File> filesIn(File directory) {
-		return filesIn(directory.listFiles());
-	}
-
-	private static Iterator<File> filesIn(File[] files) {
-		return new FilteringIterator<File>(new ArrayIterator<File>(files)) {
-			@Override
-			protected boolean accept(File next) {
-				return next.isFile();
-			}
-		};
-	}
-
-	/**
-	 * Returns an iterator on all the subdirectories
-	 * in the specified directory.
-	 * File#subDirectories()
-	 */
-	public static Iterator<File> directoriesIn(String directoryName) {
-		return directoriesIn(new File(directoryName));
-	}
-
-	/**
-	 * Returns an iterator on all the subdirectories
-	 * in the specified directory.
-	 * File#subDirectories()
-	 */
-	public static Iterator<File> directoriesIn(File directory) {
-		return directoriesIn(directory.listFiles());
-	}
-
-	private static Iterator<File> directoriesIn(File[] files) {
-		return new FilteringIterator<File>(new ArrayIterator<File>(files)) {
-			@Override
-			protected boolean accept(File next) {
-				return next.isDirectory();
-			}
-		};
-	}
-
-	/**
-	 * Returns an iterator on all the files under the specified
-	 * directory, recursing into subdirectories.
-	 * The iterator will skip over the subdirectories themselves.
-	 * File#filesRecurse()
-	 */
-	public static Iterator<File> filesInTree(String directoryName) {
-		return filesInTree(new File(directoryName));
-	}
-
-	/**
-	 * Returns an iterator on all the files under the specified
-	 * directory, recursing into subdirectories.
-	 * The iterator will skip over the subdirectories themselves.
-	 * File#filesRecurse()
-	 */
-	public static Iterator<File> filesInTree(File directory) {
-		return filesInTreeAsSet(directory).iterator();
-	}
-
-	private static Set<File> filesInTreeAsSet(File directory) {
-		Set<File> files = new HashSet<File>(10000);
-		addFilesInTreeTo(directory, files);
-		return files;
-	}
-
-	private static void addFilesInTreeTo(File directory, Collection<File> allFiles) {
-		for (File file : directory.listFiles()) {
-			if (file.isFile()) {
-				allFiles.add(file);
-			} else if (file.isDirectory()) {
-				addFilesInTreeTo(file, allFiles);
-			}
-		}
-	}
-
-	/**
-	 * Returns an iterator on all the directories under the specified
-	 * directory, recursing into subdirectories.
-	 * File#subDirectoriesRecurse()
-	 */
-	public static Iterator<File> directoriesInTree(String directoryName) {
-		return directoriesInTree(new File(directoryName));
-	}
-
-	/**
-	 * Returns an iterator on all the directories under the specified
-	 * directory, recursing into subdirectories.
-	 * File#subDirectoriesRecurse()
-	 */
-	@SuppressWarnings("unchecked")
-	public static Iterator<File> directoriesInTree(File directory) {
-		File[] files = directory.listFiles();
-		return new CompositeIterator<File>(directoriesIn(files), directoriesInTrees(directoriesIn(files)));
-	}
-
-	private static Iterator<File> directoriesInTrees(Iterator<File> directories) {
-		return new CompositeIterator<File>(
-			new TransformationIterator<Iterator<File>, File>(directories) {
-				@Override
-				protected Iterator<File> transform(File next) {
-					return FileTools.directoriesInTree(next);
-				}
-			}
-		);
-	}
-
-
-	// ********** short file name manipulation **********
-
-	/**
-	 * Strip the extension from the specified file name
-	 * Returns the result. If the file name has no
-	 * extension, it is returned unchanged
-	 * File#basePath()
-	 */
-	public static String stripExtension(String fileName) {
-		int index = fileName.lastIndexOf('.');
-		if (index == -1) {
-			return fileName;
-		}
-		return fileName.substring(0, index);
-	}
-
-	/**
-	 * Strip the extension from the specified file's name
-	 * Returns the result. If the file's name has no
-	 * extension, it is returned unchanged
-	 * File#basePath()
-	 */
-	public static String stripExtension(File file) {
-		return stripExtension(file.getPath());
-	}
-
-	/**
-	 * Returns the extension, including the dot, of the specified file name.
-	 * Returns an empty string.
-	 * File#extension()
-	 */
-	public static String extension(String fileName) {
-		int index = fileName.lastIndexOf('.');
-		if (index == -1) {
-			return StringTools.EMPTY_STRING;
-		}
-		return fileName.substring(index);
-	}
-
-	/**
-	 * Returns the extension, including the dot, of the specified file's name.
-	 * Returns an empty string.
-	 * File#extension()
-	 */
-	public static String extension(File file) {
-		return extension(file.getPath());
-	}
-
-
-	// ********** temporary directories **********
-
-	/**
-	 * Returns an empty temporary directory with the specified
-	 * name. If the directory already exists, it will be cleared out.
-	 * This directory will be a subdirectory of the Java temporary directory,
-	 * as indicated by the System property "java.io.tmpdir".
-	 */
-	public static File emptyTemporaryDirectory(String name) {
-		File dir = new File(userTemporaryDirectory(), name);
-		if (dir.exists()) {
-			deleteDirectoryContents(dir);
-		} else {
-			mkdirs(dir);
-		}
-		return dir;
-	}
-
-	private static void mkdirs(File dir) {
-		if ( ! dir.mkdirs()) {
-			throw new RuntimeException("mkdirs() failed: " + dir);
-		}
-	}
-
-	/**
-	 * Returns an empty temporary directory with a
-	 * name of "tmpdir". If the directory already exists, it will be cleared out.
-	 * This directory will be a subdirectory of the Java temporary directory,
-	 * as indicated by the System property "java.io.tmpdir".
-	 */
-	public static File emptyTemporaryDirectory() {
-		return emptyTemporaryDirectory(DEFAULT_TEMPORARY_DIRECTORY_NAME);
-	}
-
-	/**
-	 * Returns a temporary directory with the specified
-	 * name. If the directory already exists, it will be left unchanged;
-	 * if it does not already exist, it will be created.
-	 * This directory will be a subdirectory of the Java temporary directory,
-	 * as indicated by the System property "java.io.tmpdir".
-	 */
-	public static File temporaryDirectory(String name) {
-		File dir = new File(userTemporaryDirectory(), name);
-		if ( ! dir.exists()) {
-			mkdirs(dir);
-		}
-		return dir;
-	}
-
-	/**
-	 * Returns a temporary directory with a name of
-	 * "tmpdir". If the directory already exists, it will be left unchanged;
-	 * if it does not already exist, it will be created.
-	 * This directory will be a subdirectory of the Java temporary directory,
-	 * as indicated by the System property "java.io.tmpdir".
-	 */
-	public static File temporaryDirectory() {
-		return temporaryDirectory(DEFAULT_TEMPORARY_DIRECTORY_NAME);
-	}
-
-	/**
-	 * Returns a *new* temporary directory with the specified
-	 * prefix. The prefix will be appended with a number that
-	 * is incremented, starting with 1, until a non-pre-existing directory
-	 * is found and successfully created. This directory will be a
-	 * subdirectory of the Java temporary directory, as indicated by
-	 * the System property "java.io.tmpdir".
-	 */
-	public static File newTemporaryDirectory(String prefix) {
-		if ( ! prefix.endsWith(".")) {
-			prefix = prefix + '.';
-		}
-		File dir;
-		int i = 0;
-		do {
-			i++;
-			dir = new File(userTemporaryDirectory(), prefix + i);
-		} while ( ! dir.mkdirs());
-		return dir;
-	}
-
-	/**
-	 * Returns a *new* temporary directory with a
-	 * prefix of "tmpdir". This prefix will be appended with a number that
-	 * is incremented, starting with 1, until a non-pre-existing directory
-	 * is found and successfully created. This directory will be a
-	 * subdirectory of the Java temporary directory, as indicated by
-	 * the System property "java.io.tmpdir".
-	 */
-	public static File newTemporaryDirectory() {
-		return newTemporaryDirectory(DEFAULT_TEMPORARY_DIRECTORY_NAME);
-	}
-
-
-	// ********** resource files **********
-
-	/**
-	 * Returns a file for the specified resource.
-	 * The resource name must be fully-qualified, i.e. it cannot be relative
-	 * to the package name/directory.
-	 * NB: There is a bug in jdk1.4.x the prevents us from getting
-	 * a resource that has spaces (or other special characters) in
-	 * its name.... (see Sun's Java bug 4466485)
-	 */
-	public static File resourceFile(String resourceName) throws URISyntaxException {
-		if ( ! resourceName.startsWith("/")) {
-			throw new IllegalArgumentException(resourceName);
-		}
-		return resourceFile(resourceName, FileTools.class);
-	}
-
-	/**
-	 * Returns a file for the specified resource.
-	 * NB: There is a bug in jdk1.4.x the prevents us from getting
-	 * a resource that has spaces (or other special characters) in
-	 * its name.... (see Sun's Java bug 4466485)
-	 */
-	public static File resourceFile(String resourceName, Class<?> javaClass) throws URISyntaxException {
-		URL url = javaClass.getResource(resourceName);
-		return buildFile(url);
-	}
-
-	/**
-	 * Returns a file for the specified URL.
-	 * NB: There is a bug in jdk1.4.x the prevents us from getting
-	 * a resource that has spaces (or other special characters) in
-	 * its name.... (see Sun's Java bug 4466485)
-	 */
-	public static File buildFile(URL url) throws URISyntaxException {
-		return buildFile(url.getFile());
-	}
-
-	/**
-	 * Returns a file for the specified file name.
-	 * NB: There is a bug in jdk1.4.x the prevents us from getting
-	 * a resource that has spaces (or other special characters) in
-	 * its name.... (see Sun's Java bug 4466485)
-	 */
-	public static File buildFile(String fileName) throws URISyntaxException {
-		URI uri = new URI(fileName);
-		File file = new File(uri.getPath());
-		return file;
-	}
-
-
-	// ********** "canonical" files **********
-
-	/**
-	 * Convert the specified file into a "canonical" file.
-	 */
-	public static File canonicalFile(File file) {
-		try {
-			return file.getCanonicalFile();
-		} catch (IOException ioexception) {
-			// settle for the absolute file
-			return file.getAbsoluteFile();
-		}
-	}
-
-	/**
-	 * Build an iterator that will convert the specified files
-	 * into "canonical" files.
-	 */
-	public static Iterator<File> canonicalFiles(Iterator<File> files) {
-		return new TransformationIterator<File, File>(files) {
-			@Override
-			protected File transform(File next) {
-				return canonicalFile(next);
-			}
-		};
-	}
-
-	/**
-	 * Build an iterator that will convert the specified files
-	 * into "canonical" files.
-	 */
-	public static Iterator<File> canonicalFiles(Collection<File> files) {
-		return canonicalFiles(files.iterator());
-	}
-
-	/**
-	 * Convert the specified file name into a "canonical" file name.
-	 */
-	public static String canonicalFileName(String fileName) {
-		return canonicalFile(new File(fileName)).getAbsolutePath();
-	}
-
-	/**
-	 * Build an iterator that will convert the specified file names
-	 * into "canonical" file names.
-	 */
-	public static Iterator<String> canonicalFileNames(Iterator<String> fileNames) {
-		return new TransformationIterator<String, String>(fileNames) {
-			@Override
-			protected String transform(String next) {
-				return canonicalFileName(next);
-			}
-		};
-	}
-
-	/**
-	 * Build an iterator that will convert the specified file names
-	 * into "canonical" file names.
-	 */
-	public static Iterator<String> canonicalFileNames(Collection<String> fileNames) {
-		return canonicalFileNames(fileNames.iterator());
-	}
-
-
-	// ********** file name validation **********
-
-	/**
-	 * Returns whether the specified file name is invalid.
-	 */
-	public static boolean fileNameIsInvalid(String filename) {
-		return ! fileNameIsValid(filename);
-	}
-
-	/**
-	 * Returns whether the specified file name is valid.
-	 */
-	public static boolean fileNameIsValid(String filename) {
-		int len = filename.length();
-		for (int i = 0; i < len; i++) {
-			char filenameChar = filename.charAt(i);
-			if (ArrayTools.contains(INVALID_FILENAME_CHARACTERS, filenameChar)) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	/**
-	 * Convert the illegal characters in the specified file name to
-	 * Returns the result.
-	 */
-	public static String convertToValidFileName(String filename, char replacementChar) {
-		int len = filename.length();
-		StringBuilder sb = new StringBuilder(len);
-		for (int i = 0; i < len; i++) {
-			char filenameChar = filename.charAt(i);
-			if (ArrayTools.contains(INVALID_FILENAME_CHARACTERS, filenameChar)) {
-				sb.append(replacementChar);
-			} else {
-				sb.append(filenameChar);
-			}
-		}
-		return sb.toString();
-	}
-
-	/**
-	 * Convert the illegal characters in the specified file name to
-	 * Returns the result.
-	 */
-	public static String convertToValidFileName(String filename) {
-		return convertToValidFileName(filename, '.');
-	}
-
-	/**
-	 * Returns whether the specified file name is "reserved"
-	 * (i.e. it cannot be used for "user" files). Windows reserves
-	 * a number of file names (e.g. CON, AUX, PRN).
-	 */
-	public static boolean fileNameIsReserved(String fileName) {
-		// Unix/Linux does not have any "reserved" file names (I think...)
-		return Tools.osIsWindows() && ArrayTools.contains(WINDOWS_RESERVED_FILE_NAMES, fileName.toLowerCase());
-	}
-
-	/**
-	 * Returns whether the specified file contains any "reserved"
-	 * components.
-	 * Windows reserves a number of file names (e.g. CON, AUX, PRN);
-	 * and these file names cannot be used for either the names of
-	 * files or directories.
-	 */
-	public static boolean fileHasAnyReservedComponents(File file) {
-		File temp = file;
-		while (temp != null) {
-			if (fileNameIsReserved(temp.getName())) {
-				return true;
-			}
-			temp = temp.getParentFile();
-		}
-		return false;
-	}
-
-
-	// ********** shortened file names **********
-
-	/**
-	 * Returns a shorter version of the absolute file name for the specified file.
-	 * The shorter version will not be longer than the maximum length.
-	 * The first directory (usually the drive letter) and the file name or the
-	 * last directory will always be added to the generated string regardless of
-	 * the maximum length allowed.
-	 */
-	public static String shortenFileName(URL url) {
-		return shortenFileName(url, MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
-	}
-
-	/**
-	 * Returns a shorter version of the absolute file name for the specified file.
-	 * The shorter version will not be longer than the maximum length.
-	 * The first directory (usually the drive letter) and the file name or the
-	 * last directory will always be added to the generated string regardless of
-	 * the maximum length allowed.
-	 */
-	public static String shortenFileName(URL url, int maxLength) {
-		File file;
-		try {
-			file = buildFile(url);
-		} catch (URISyntaxException e) {
-			file = new File(url.getFile());
-		}
-		return shortenFileName(file, maxLength);
-	}
-
-	/**
-	 * Returns a shorter version of the absolute file name for the specified file.
-	 * The shorter version will not be longer than the maximum length.
-	 * The first directory (usually the drive letter) and the file name or the
-	 * last directory will always be added to the generated string regardless of
-	 * the maximum length allowed.
-	 */
-	public static String shortenFileName(File file) {
-		return shortenFileName(file, MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
-	}
-
-	/**
-	 * Returns a shorter version of the absolute file name for the specified file.
-	 * The shorter version will not be longer than the maximum length.
-	 * The first directory (usually the drive letter) and the file name or the
-	 * last directory will always be added to the generated string regardless of
-	 * the maximum length allowed.
-	 */
-	public static String shortenFileName(File file, int maxLength) {
-		String absoluteFileName = canonicalFile(file).getAbsolutePath();
-		if (absoluteFileName.length() <= maxLength) {
-			// no need to shorten
-			return absoluteFileName;
-		}
-
-		// break down the path into its components
-		String fs = File.separator;
-		String[] paths = absoluteFileName.split('\\' + fs);
-
-		if (paths.length <= 1) {
-			// e.g. "C:\"
-			return paths[0];
-		}
-
-		if (paths.length == 2) {
-			// e.g. "C:\MyReallyLongFileName.ext" or "C:\MyReallyLongDirectoryName"
-			// return the complete file name since this is a minimum requirement,
-			// regardless of the maximum length allowed
-			return absoluteFileName;
-		}
-
-		StringBuilder sb = new StringBuilder();
-		sb.append(paths[0]);		// always add the first directory, which is usually the drive letter
-
-		// Keep the index of insertion into the string buffer
-		int insertIndex = sb.length();
-
-		sb.append(fs);
-		sb.append(paths[paths.length - 1]);		// append the file name or the last directory
-
-		maxLength -= 4;                      // -4 for "/..."
-
-		int currentLength = sb.length() - 4; // -4 for "/..."
-		int leftIndex = 1;                   //  1 to skip the root directory
-		int rightIndex = paths.length - 2;   // -1 for the file name or the last directory
-
-		boolean canAddFromLeft = true;
-		boolean canAddFromRight = true;
-
-		// Add each directory, the insertion is going in both direction: left and
-		// right, once a side can't be added, the other side is still continuing
-		// until both can't add anymore
-		while (true) {
-			if (!canAddFromLeft && !canAddFromRight)
-				break;
-
-			if (canAddFromRight) {
-				String rightDirectory = paths[rightIndex];
-				int rightLength = rightDirectory.length();
-
-				// Add the directory on the right side of the loop
-				if (currentLength + rightLength + 1 <= maxLength) {
-					sb.insert(insertIndex,     fs);
-					sb.insert(insertIndex + 1, rightDirectory);
-
-					currentLength += rightLength + 1;
-					rightIndex--;
-
-					// The right side is now overlapping the left side, that means
-					// we can't add from the right side anymore
-					if (leftIndex >= rightIndex) {
-						canAddFromRight = false;
-					}
-				} else {
-					canAddFromRight = false;
-				}
-			}
-
-			if (canAddFromLeft) {
-				String leftDirectory = paths[leftIndex];
-				int leftLength = leftDirectory.length();
-
-				// Add the directory on the left side of the loop
-				if (currentLength + leftLength + 1 <= maxLength) {
-					sb.insert(insertIndex,     fs);
-					sb.insert(insertIndex + 1, leftDirectory);
-
-					insertIndex += leftLength + 1;
-					currentLength += leftLength + 1;
-					leftIndex++;
-
-					// The left side is now overlapping the right side, that means
-					// we can't add from the left side anymore
-					if (leftIndex >= rightIndex) {
-						canAddFromLeft = false;
-					}
-				} else {
-					canAddFromLeft = false;
-				}
-			}
-		}
-
-		if (leftIndex <= rightIndex) {
-			sb.insert(insertIndex, fs);
-			sb.insert(insertIndex + 1, "...");
-		}
-
-		return sb.toString();
-	}
-
-
-	// ********** system properties **********
-
-	/**
-	 * Returns a file representing the user's home directory.
-	 */
-	public static File userHomeDirectory() {
-		return new File(USER_HOME_DIRECTORY_NAME);
-	}
-
-	/**
-	 * Returns a file representing the user's temporary directory.
-	 */
-	public static File userTemporaryDirectory() {
-		return new File(USER_TEMPORARY_DIRECTORY_NAME);
-	}
-
-	/**
-	 * Returns a file representing the current working directory.
-	 */
-	public static File currentWorkingDirectory() {
-		return new File(CURRENT_WORKING_DIRECTORY_NAME);
-	}
-
-
-	// ********** miscellaneous **********
-
-	/**
-	 * Returns only the files that fit the filter.
-	 * File#files(FileFilter fileFilter)
-	 */
-	public static Iterator<File> filter(Iterator<File> files, final FileFilter fileFilter) {
-		return new FilteringIterator<File>(files) {
-			@Override
-			protected boolean accept(File next) {
-				return fileFilter.accept(next);
-			}
-		};
-	}
-
-	/**
-	 * Returns a file that is a re-specification of the specified
-	 * file, relative to the specified directory.
-	 *     Linux/Unix/Mac:
-	 *         convertToRelativeFile(/foo/bar/baz.java, /foo)
-	 *             => bar/baz.java
-	 *     Windows:
-	 *         convertToRelativeFile(C:\foo\bar\baz.java, C:\foo)
-	 *             => bar/baz.java
-	 * The file can be either a file or a directory; the directory
-	 * *should* be a directory.
-	 * If the file is already relative or it cannot be made relative
-	 * to the directory, it will be returned unchanged.
-	 *
-	 * NB: This method has been tested on Windows and Linux,
-	 * but not Mac (but the Mac is Unix-based these days, so
-	 * it shouldn't be a problem...).
-	 */
-	public static File convertToRelativeFile(final File file, final File dir) {
-		// check whether the file is already relative
-		if ( ! file.isAbsolute()) {
-			return file;		// return unchanged
-		}
-
-		File cFile = canonicalFile(file);
-		File cDir = canonicalFile(dir);
-
-		// the two are the same directory
-		if (cFile.equals(cDir)) {
-			return new File(".");
-		}
-
-		File[] filePathFiles = pathFiles(cFile);
-		File[] dirPathFiles = pathFiles(cDir);
-
-		// Windows only (?): the roots are different - e.g. D:\ vs. C:\
-		if ( ! dirPathFiles[0].equals(filePathFiles[0])) {
-			return file;		// return unchanged
-		}
-
-		// at this point we know the root is the same, now find how much is in common
-		int i = 0;		// this will point at the first miscompare
-		while ((i < dirPathFiles.length) && (i < filePathFiles.length)) {
-			if (dirPathFiles[i].equals(filePathFiles[i])) {
-				i++;
-			} else {
-				break;
-			}
-		}
-		// save our current position
-		int firstMismatch = i;
-
-		// check whether the file is ABOVE the directory: ../..
-		if (firstMismatch == filePathFiles.length) {
-			return relativeParentFile(dirPathFiles.length - firstMismatch);
-		}
-
-		// build a new file from the path beyond the matching portions
-		File diff = new File(filePathFiles[i].getName());
-		while (++i < filePathFiles.length) {
-			diff = new File(diff, filePathFiles[i].getName());
-		}
-
-		// check whether the file is BELOW the directory: subdir1/subdir2/file.ext
-		if (firstMismatch == dirPathFiles.length) {
-			return diff;
-		}
-
-		// the file must be a PEER of the directory: ../../subdir1/subdir2/file.ext
-		return new File(relativeParentFile(dirPathFiles.length - firstMismatch), diff.getPath());
-	}
-
-	/**
-	 * Returns a file that is a re-specification of the specified
-	 * file, relative to the current working directory.
-	 *     Linux/Unix/Mac (CWD = /foo):
-	 *         convertToRelativeFile(/foo/bar/baz.java)
-	 *             => bar/baz.java
-	 *     Windows (CWD = C:\foo):
-	 *         convertToRelativeFile(C:\foo\bar\baz.java)
-	 *             => bar/baz.java
-	 * The file can be either a file or a directory.
-	 * If the file is already relative or it cannot be made relative
-	 * to the directory, it will be returned unchanged.
-	 *
-	 * NB: This method has been tested on Windows and Linux,
-	 * but not Mac (but the Mac is Unix-based these days, so
-	 * it shouldn't be a problem...).
-	 */
-	public static File convertToRelativeFile(final File file) {
-		return convertToRelativeFile(file, currentWorkingDirectory());
-	}
-
-	/**
-	 * Returns an array of files representing the path to the specified
-	 * file. For example:
-	 *     C:/foo/bar/baz.txt =>
-	 *     { C:/, C:/foo, C:/foo/bar, C:/foo/bar/baz.txt }
-	 */
-	private static File[] pathFiles(File file) {
-		List<File> path = new ArrayList<File>();
-		for (File f = file; f != null; f = f.getParentFile()) {
-			path.add(f);
-		}
-		Collections.reverse(path);
-		return path.toArray(new File[path.size()]);
-	}
-
-	/**
-	 * Returns a file with the specified (non-zero) number of relative
-	 * file names, e.g. xxx(3) => ../../..
-	 */
-	private static File relativeParentFile(int len) {
-		if (len <= 0) {
-			throw new IllegalArgumentException("length must be greater than zero: " + len);
-		}
-		File result = new File("..");
-		for (int i = len - 1; i-- > 0; ) {
-			result = new File(result, "..");
-		}
-		return result;
-	}
-
-	/**
-	 * Returns a file that is a re-specification of the specified
-	 * file, absolute to the specified directory.
-	 *     Linux/Unix/Mac:
-	 *         convertToAbsoluteFile(bar/baz.java, /foo)
-	 *             => /foo/bar/baz.java
-	 *     Windows:
-	 *         convertToAbsoluteFile(bar/baz.java, C:\foo)
-	 *             => C:\foo\bar\baz.java
-	 * The file can be either a file or a directory; the directory
-	 * *should* be a directory.
-	 * If the file is already absolute, it will be returned unchanged.
-	 *
-	 * NB: This method has been tested on Windows and Linux,
-	 * but not Mac (but the Mac is Unix-based these days, so
-	 * it shouldn't be a problem...).
-	 */
-	public static File convertToAbsoluteFile(final File file, final File dir) {
-		// check whether the file is already absolute
-		if (file.isAbsolute()) {
-			return file;		// return unchanged
-		}
-		return canonicalFile(new File(dir, file.getPath()));
-	}
-
-	/**
-	 * Returns a file that is a re-specification of the specified
-	 * file, absolute to the current working directory.
-	 *     Linux/Unix/Mac (CWD = /foo):
-	 *         convertToAbsoluteFile(bar/baz.java)
-	 *             => /foo/bar/baz.java
-	 *     Windows (CWD = C:\foo):
-	 *         convertToAbsoluteFile(bar/baz.java)
-	 *             => C:\foo\bar\baz.java
-	 * The file can be either a file or a directory.
-	 * If the file is already absolute, it will be returned unchanged.
-	 *
-	 * NB: This method has been tested on Windows and Linux,
-	 * but not Mac (but the Mac is Unix-based these days, so
-	 * it shouldn't be a problem...).
-	 */
-	public static File convertToAbsoluteFile(final File file) {
-		return convertToAbsoluteFile(file, currentWorkingDirectory());
-	}
-
-
-	// ********** constructor **********
-
-	/**
-	 * Suppress default constructor, ensuring non-instantiability.
-	 */
-	private FileTools() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Filter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Filter.java
deleted file mode 100644
index 00d9939..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Filter.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * Used by various "pluggable" classes to filter objects.
- * <p>
- * 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.
- *
- * @param <T> the type of objects to be filtered
- * @version 2.5
- */
-public interface Filter<T> {
-
-	/**
-	 * Returns whether the specified object is "accepted" by the filter. The semantics of "accept"
-	 * is determined by the contract between the client and the server.
-	 */
-	boolean accept(T object);
-
-	/**
-	 * Singleton implementation of the filter interface that throws an exception if called.
-	 */
-	final class Disabled<S> implements Filter<S>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final Filter INSTANCE = new Disabled();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Disabled() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <R> Filter<R> instance() {
-			return INSTANCE;
-		}
-		// throw an exception
-		@Override
-		public boolean accept(S o) {
-			throw new UnsupportedOperationException();
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-
-	/**
-	 * Singleton implementation of the filter interface that accepts none of the objects (i.e. it
-	 * filters out all the objects).
-	 */
-	final class Opaque<S> implements Filter<S>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final Filter INSTANCE = new Opaque();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Opaque() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <R> Filter<R> instance() {
-			return INSTANCE;
-		}
-		// everything is filtered - nothing is accepted
-		@Override
-		public boolean accept(S o) {
-			return false;
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-
-	/**
-	 * Singleton implementation of the filter interface that accepts all the objects (i.e. it does
-	 * no filtering).
-	 */
-	final class Transparent<S> implements Filter<S>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final Filter INSTANCE = new Transparent();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Transparent() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <R> Filter<R> instance() {
-			return INSTANCE;
-		}
-		// nothing is filtered - everything is accepted
-		@Override
-		public boolean accept(S o) {
-			return true;
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/FilterAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/FilterAdapter.java
deleted file mode 100644
index c56c1d7..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/FilterAdapter.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-
-/**
- * Convenience filter implementation that accepts everything.
- * 
- * @see org.eclipse.persistence.tools.utility.Filter.Transparent
- */
-public class FilterAdapter<T>
-	implements Filter<T>
-{
-	@Override
-	public boolean accept(T o) {
-		return true;
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this);
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/FlaggedObjectReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/FlaggedObjectReference.java
deleted file mode 100644
index 3b8f262..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/FlaggedObjectReference.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-/**
- * Provide a container for passing an object that can be changed by the
- * recipient. If the value is set at any time after construction of the
- * reference, the reference is marked "set". This allows the client to
- * detect whether the server/recipient ever set the value, even if it remains
- * unchanged. This is particularly useful when the value can be set to
- * <code>null</code>.
- * <p>
- * The reference can be set multiple times, but it can
- * never be "unset" once it is "set".
- */
-public class FlaggedObjectReference<V>
-	extends SimpleObjectReference<V>
-{
-	private volatile boolean set = false;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Create an object reference with the specified initial value.
-	 */
-	public FlaggedObjectReference(V value) {
-		super(value);
-	}
-
-	/**
-	 * Create an object reference with an initial value of
-	 * <code>null</code>.
-	 */
-	public FlaggedObjectReference() {
-		super();
-	}
-
-
-	// ********** set **********
-
-	public boolean isSet() {
-		return this.set;
-	}
-
-
-	// ********** overrides **********
-
-	@Override
-	public V setValue(V value) {
-		this.set = true;
-		return super.setValue(value);
-	}
-
-	@Override
-	public String toString() {
-		String s = super.toString();
-		return (this.set) ? '*' + s : s;
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/HashBag.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/HashBag.java
deleted file mode 100644
index 10b03c2..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/HashBag.java
+++ /dev/null
@@ -1,908 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-import java.util.AbstractCollection;
-import java.util.Collection;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * This class implements the {@link Bag} interface, backed by a
- * hash table. It makes no guarantees as to the iteration order of
- * the bag's elements; in particular, it does not guarantee the order
- * will remain constant over time. This class permits the <code>null</code>
- * element.
- * <p>
- * This class offers constant time performance for the basic operations
- * (<code>add</code>, <code>remove</code>, <code>contains</code> and
- * <code>size</code>), assuming the hash function disperses the elements
- * properly among the buckets. Iterating over this bag requires time
- * proportional to the sum of the bag's size (the number of elements) plus the
- * "capacity" of the backing hash table (the number of buckets). Thus, it is
- * important not to set the initial capacity too high (or the load factor too
- * low) if iteration performance is important.
- * <p>
- * <strong>Note that this implementation is not synchronized.</strong> If multiple
- * threads access a bag concurrently, and at least one of the threads modifies
- * the bag, it <em>must</em> be synchronized externally. This is typically
- * accomplished by synchronizing on some object that naturally encapsulates
- * the bag. If no such object exists, the bag should be "wrapped" using the
- * <code>Collections.synchronizedCollection</code> method. This is
- * best done at creation time, to prevent accidental unsynchronized access
- * to the bag:
- * <pre>
- * Collection c = Collections.synchronizedCollection(new HashBag(...));
- * </pre>
- * <p>
- * The iterators returned by this class's <code>iterator</code> method are
- * <em>fail-fast</em>: if the bag is modified at any time after the iterator is
- * created, in any way except through the iterator's own <code>remove</code>
- * method, the iterator throws a {@link ConcurrentModificationException}.
- * Thus, in the face of concurrent modification, the iterator fails quickly
- * and cleanly, rather than risking arbitrary, non-deterministic behavior at
- * an undetermined time in the future.
- * <p>
- * Note that the fail-fast behavior of an iterator cannot be guaranteed
- * as it is, generally speaking, impossible to make any hard guarantees in the
- * presence of unsynchronized concurrent modification. Fail-fast iterators
- * throw <code>ConcurrentModificationException</code> on a best-effort basis.
- * Therefore, it would be wrong to write a program that depended on this
- * exception for its correctness: <em>the fail-fast behavior of iterators
- * should be used only to detect bugs.</em>
- *
- * @param <E> the type of elements maintained by the bag
- *
- * @see Collection
- * @see Bag
- * @see SynchronizedBag
- * @see	java.util.Collections#synchronizedCollection(Collection)
- * @see IdentityHashBag
- */
-@SuppressWarnings("nls")
-public class HashBag<E>
-	extends AbstractCollection<E>
-	implements Bag<E>, Cloneable, Serializable
-{
-	/** The hash table. Resized as necessary. Length MUST Always be a power of two. */
-	transient Entry<E>[] table;
-
-	/** The total number of entries in the bag. */
-	transient int size = 0;
-
-	/** The number of UNIQUE entries in the bag. */
-	transient int uniqueCount = 0;
-
-	/**
-	 * The hash table is rehashed when its size exceeds this threshold. (The
-	 * value of this field is <code>(int) (capacity * loadFactor)</code>.)
-	 *
-	 * @serial size threshold
-	 */
-	private int threshold;
-
-	/**
-	 * The load factor for the hash table.
-	 *
-	 * @serial load factor
-	 */
-	private final float loadFactor;
-
-	/**
-	 * The number of times this bag has been structurally modified.
-	 * Structural modifications are those that change the number of entries in
-	 * the bag or otherwise modify its internal structure (e.g. rehash).
-	 * This field is used to make iterators on this bag fail-fast.
-	 *
-	 * @see java.util.ConcurrentModificationException
-	 */
-	transient int modCount = 0;
-
-	/**
-	 * The default initial capacity - MUST be a power of two.
-	 */
-	private static final int DEFAULT_INITIAL_CAPACITY = 16;
-
-	/**
-	 * The maximum capacity, used if a higher value is implicitly specified
-	 * by either of the constructors with arguments.
-	 * MUST be a power of two <= (1 << 30).
-	 */
-	private static final int MAXIMUM_CAPACITY = 1 << 30;
-
-	/**
-	 * The load factor used when none specified in constructor.
-	 */
-	private static final float DEFAULT_LOAD_FACTOR = 0.75f;
-
-	/**
-	 * Construct a new, empty bag with the
-	 * default capacity, which is 16, and load factor, which is 0.75.
-	 */
-	public HashBag() {
-		this(DEFAULT_INITIAL_CAPACITY);
-	}
-
-	/**
-	 * Construct a new, empty bag with the specified initial capacity
-	 * and the default load factor, which is 0.75.
-	 *
-	 * @param initialCapacity the initial capacity
-	 * @exception IllegalArgumentException if the initial capacity is less
-	 *     than zero
-	 */
-	public HashBag(int initialCapacity) {
-		this(initialCapacity, DEFAULT_LOAD_FACTOR, false);  // false = do not validate parms
-	}
-
-	/**
-	 * Construct a new, empty bag with
-	 * the specified initial capacity and load factor.
-	 *
-	 * @param initialCapacity the initial capacity
-	 * @param loadFactor the load factor
-	 * @exception IllegalArgumentException if the initial capacity is less
-	 *     than zero or if the load factor is non-positive
-	 */
-	public HashBag(int initialCapacity, float loadFactor) {
-		this(initialCapacity, loadFactor, true);  // true = validate parms
-	}
-
-	private HashBag(int initialCapacity, float loadFactor, boolean validateParms) {
-		super();
-		int capacity = initialCapacity;
-		if (validateParms) {
-			if (capacity < 0) {
-				throw new IllegalArgumentException("Illegal Initial Capacity: " + capacity);
-			}
-			if (capacity > MAXIMUM_CAPACITY) {
-				capacity = MAXIMUM_CAPACITY;
-			}
-			if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
-				throw new IllegalArgumentException("Illegal Load factor: " + loadFactor);
-			}
-
-			// find a power of 2 >= 'initialCapacity'
-			capacity = 1;
-			while (capacity < initialCapacity) {
-				capacity <<= 1;
-			}
-		}
-
-		this.loadFactor = loadFactor;
-		this.table = this.buildTable(capacity);
-		this.threshold = (int) (capacity * loadFactor);
-	}
-
-	/**
-	 * Construct a new bag containing the elements in the specified
-	 * collection. The bag's load factor will be the default, which is 0.75,
-	 * and its initial capacity will be sufficient to hold all the elements in
-	 * the specified collection.
-	 *
-	 * @param c the collection whose elements are to be placed into this bag.
-	 */
-	public HashBag(Collection<? extends E> c) {
-		this(Math.max((int) (c.size() / DEFAULT_LOAD_FACTOR) + 1, DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
-		this.addAll_(c);
-	}
-
-	/**
-	 * Returns a hash for the specified object.
-	 */
-	private int hash(Object o) {
-		return (o == null) ? 0 : this.tweakHash(o.hashCode());
-	}
-
-	/**
-	 * Tweak the specified hash, to defend against poor implementations
-	 * of {@link Object#hashCode()}.
-	 */
-	private int tweakHash(int h) {
-		h ^= (h >>> 20) ^ (h >>> 12);
-		return h ^ (h >>> 7) ^ (h >>> 4);
-	}
-
-	/**
-	 * Returns the index for the specified hash.
-	 */
-	private int index(int hash) {
-		return this.index(hash, this.table.length);
-	}
-
-	/**
-	 * Returns the index for the specified hash
-	 * within a table with the specified length.
-	 */
-	int index(int hash, int length) {
-		return hash & (length - 1);
-	}
-
-	/**
-	 * Internal {@link #addAll(Collection)} for construction and cloning.
-	 * Returns value.)
-	 */
-	private void addAll_(Iterable<? extends E> c) {
-		for (E e : c) {
-			this.add_(e);
-		}
-	}
-
-	/**
-	 * Internal {@link #add(Object)} for construction and cloning.
-	 * Returns value.)
-	 */
-	private void add_(E o) {
-		this.add_(o, 1);
-	}
-
-	/**
-	 * Internal {@link #add(Object, int)} for construction, cloning, and serialization.
-	 * Returns value.)
-	 */
-	private void add_(E o, int cnt) {
-		int hash = this.hash(o);
-		int index = this.index(hash);
-		for (Entry<E> e = this.table[index]; e != null; e = e.next) {
-			Object eo;
-			if ((e.hash == hash) && (((eo = e.object) == o) || ((o != null) && o.equals(eo)))) {
-				e.count += cnt;
-				this.size += cnt;
-				return;
-			}
-		}
-
-		// create the new entry and put it in the table
-		Entry<E> e = this.buildEntry(hash, o, cnt, this.table[index]);
-		this.table[index] = e;
-		this.size += cnt;
-		this.uniqueCount++;
-	}
-
-	/**
-	 * This implementation simply returns the maintained size.
-	 */
-	@Override
-	public int size() {
-		return this.size;
-	}
-
-	/**
-	 * This implementation simply compares the maintained size to zero.
-	 */
-	@Override
-	public boolean isEmpty() {
-		return this.size == 0;
-	}
-
-	/**
-	 * Search for the object's entry in the hash table by calculating
-	 * the object's hash code and examining the entries in the corresponding hash
-	 * table bucket.
-	 */
-	private Entry<E> getEntry(Object o) {
-		int hash = this.hash(o);
-		for (Entry<E> e = this.table[this.index(hash)]; e != null; e = e.next) {
-			Object eo;
-			if ((e.hash == hash) && (((eo = e.object) == o) || ((o != null) && o.equals(eo)))) {
-				return e;
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public boolean contains(Object o) {
-		return this.getEntry(o) != null;
-	}
-
-	@Override
-	public int count(Object o) {
-		Entry<E> e = this.getEntry(o);
-		return (e == null) ? 0 : e.count;
-	}
-
-	/**
-	 * Rehash the contents of the bag into a new hash table
-	 * with a larger capacity. This method is called when the
-	 * number of different elements in the bag exceeds its
-	 * capacity and load factor.
-	 */
-	private void rehash() {
-		Entry<E>[] oldTable = this.table;
-		int oldCapacity = oldTable.length;
-
-		if (oldCapacity == MAXIMUM_CAPACITY) {
-			this.threshold = Integer.MAX_VALUE;
-			return;
-		}
-
-		int newCapacity = 2 * oldCapacity;
-		Entry<E>[] newTable = this.buildTable(newCapacity);
-
-		for (int i = oldCapacity; i-- > 0; ) {
-			for (Entry<E> old = oldTable[i]; old != null; ) {
-				Entry<E> e = old;
-				old = old.next;
-
-				int index = this.index(e.hash, newCapacity);
-				e.next = newTable[index];
-				newTable[index] = e;
-			}
-		}
-
-		this.table = newTable;
-		this.threshold = (int) (newCapacity * this.loadFactor);
-	}
-
-	// minimize scope of suppressed warnings
-	@SuppressWarnings("unchecked")
-	private Entry<E>[] buildTable(int capacity) {
-		return new Entry[capacity];
-	}
-
-	/**
-	 * This implementation searches for the object in the hash table by calculating
-	 * the object's hash code and examining the entries in the corresponding hash
-	 * table bucket.
-	 */
-	@Override
-	public boolean add(E o) {
-		return this.add(o, 1);
-	}
-
-	/**
-	 * This implementation searches for the object in the hash table by calculating
-	 * the object's hash code and examining the entries in the corresponding hash
-	 * table bucket.
-	 */
-	@Override
-	public boolean add(E o, int cnt) {
-		if (cnt <= 0) {
-			return false;
-		}
-		this.modCount++;
-		int hash = this.hash(o);
-		int index = this.index(hash);
-
-		// if the object is already in the bag, simply bump its count
-		for (Entry<E> e = this.table[index]; e != null; e = e.next) {
-			Object eo;
-			if ((e.hash == hash) && (((eo = e.object) == o) || ((o != null) && o.equals(eo)))) {
-				e.count += cnt;
-				this.size += cnt;
-				return true;
-			}
-		}
-
-		// rehash the table if we are going to exceed the threshold
-		if (this.uniqueCount >= this.threshold) {
-			this.rehash();
-			index = this.index(hash);  // need to re-calculate the index
-		}
-
-		// create the new entry and put it in the table
-		Entry<E> e = this.buildEntry(hash, o, cnt, this.table[index]);
-		this.table[index] = e;
-		this.size += cnt;
-		this.uniqueCount++;
-		return true;
-	}
-
-	// minimize scope of suppressed warnings
-	@SuppressWarnings({ "rawtypes", "unchecked" } )
-	private Entry<E> buildEntry(int hash, Object o, int cnt, Entry next) {
-		return new Entry<E>(hash, (E) o, cnt, (Entry<E>) next);
-	}
-
-	/**
-	 * This implementation searches for the object in the hash table by calculating
-	 * the object's hash code and examining the entries in the corresponding hash
-	 * table bucket.
-	 */
-	@Override
-	public boolean remove(Object o) {
-		return this.remove(o, 1);
-	}
-
-	/**
-	 * This implementation searches for the object in the hash table by calculating
-	 * the object's hash code and examining the entries in the corresponding hash
-	 * table bucket.
-	 */
-	@Override
-	public boolean remove(Object o, int cnt) {
-		if (cnt <= 0) {
-			return false;
-		}
-		int hash = this.hash(o);
-		int index = this.index(hash);
-
-		for (Entry<E> e = this.table[index], prev = null; e != null; prev = e, e = e.next) {
-			Object eo;
-			if ((e.hash == hash) && (((eo = e.object) == o) || ((o != null) && o.equals(eo)))) {
-				this.modCount++;
-				cnt = (cnt < e.count) ? cnt : e.count;
-				e.count -= cnt;
-				// if we are removing the last element(s), remove the entry from the table
-				if (e.count == 0) {
-					if (prev == null) {
-						this.table[index] = e.next;
-					} else {
-						prev.next = e.next;
-					}
-					this.uniqueCount--;
-				}
-				this.size -= cnt;
-				return true;
-			}
-		}
-
-		return false;
-	}
-
-	/**
-	 * This implementation simply clears out all of the hash table buckets.
-	 */
-	@Override
-	public void clear() {
-		Entry<E>[] tab = this.table;
-		this.modCount++;
-		for (int i = tab.length; i-- > 0; ) {
-			tab[i] = null;
-		}
-		this.size = 0;
-		this.uniqueCount = 0;
-	}
-
-	/**
-	 * Returns a shallow copy of this bag: the elements
-	 * themselves are not cloned.
-	 *
-	 * @return a shallow copy of this bag.
-	 */
-	@Override
-	public HashBag<E> clone() {
-		try {
-			@SuppressWarnings("unchecked")
-			HashBag<E> clone = (HashBag<E>) super.clone();
-			clone.table = this.buildTable(this.table.length);
-			clone.size = 0;
-			clone.uniqueCount = 0;
-			clone.modCount = 0;
-			clone.addAll_(this);
-			return clone;
-		} catch (CloneNotSupportedException e) {
-			throw new InternalError();
-		}
-	}
-
-
-	/**
-	 * Hash table collision list entry.
-	 */
-	private static class Entry<E>
-		implements Bag.Entry<E>
-	{
-		final int hash;
-		final E object;
-		int count;
-		Entry<E> next;
-
-		Entry(int hash, E object, int count, Entry<E> next) {
-			this.hash = hash;
-			this.object = object;
-			this.count = count;
-			this.next = next;
-		}
-
-		// ***** Bag.Entry implementation
-		@Override
-		public E getElement() {
-			return this.object;
-		}
-
-		@Override
-		public int getCount() {
-			return this.count;
-		}
-
-		@Override
-		public int setCount(int count) {
-			if (count <= 0) {
-				throw new IllegalArgumentException("count must be greater than zero: " + count);
-			}
-			int old = this.count;
-			this.count = count;
-			return old;
-		}
-
-		@Override
-		public boolean equals(Object o) {
-			if ( ! (o instanceof Bag.Entry<?>)) {
-				return false;
-			}
-			@SuppressWarnings("rawtypes")
-			Bag.Entry e = (Bag.Entry) o;
-			return (this.count == e.getCount()) &&
-					Tools.valuesAreEqual(this.object, e.getElement());
-		}
-
-		@Override
-		public int hashCode() {
-			E o = this.object;
-			return (o == null) ? 0 : (this.count * o.hashCode());
-		}
-
-		@Override
-		public String toString() {
-			return this.object + "=>" + this.count;
-		}
-	}
-
-
-	@Override
-	@SuppressWarnings("unchecked")
-	public Iterator<E> iterator() {
-		return (this.size == 0) ? EMPTY_ITERATOR : new HashIterator();
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	public Iterator<E> uniqueIterator() {
-		return (this.size == 0) ? EMPTY_ITERATOR : new UniqueIterator();
-	}
-
-	@Override
-	public int uniqueCount() {
-		return this.uniqueCount;
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	public Iterator<Bag.Entry<E>> entries() {
-		return (this.size == 0) ? EMPTY_ITERATOR : new EntryIterator();
-	}
-
-
-	/**
-	 * Empty iterator that does just about nothing.
-	 */
-	@SuppressWarnings("rawtypes")
-	private static final Iterator EMPTY_ITERATOR = new EmptyIterator();
-
-	@SuppressWarnings("rawtypes")
-	private static class EmptyIterator
-		implements Iterator
-	{
-		EmptyIterator() {
-			super();
-		}
-
-		@Override
-		public boolean hasNext() {
-			return false;
-		}
-
-		@Override
-		public Object next() {
-			throw new NoSuchElementException();
-		}
-
-		@Override
-		public void remove() {
-			throw new IllegalStateException();
-		}
-	}
-
-
-	private class HashIterator
-		implements Iterator<E>
-	{
-		private int index = HashBag.this.table.length;	// start at the end of the table
-		private Entry<E> nextEntry = null;
-		private int nextEntryCount = 0;
-		private Entry<E> lastReturnedEntry = null;
-
-		/**
-		 * The modCount value that the iterator believes that the backing
-		 * bag should have. If this expectation is violated, the iterator
-		 * has detected a concurrent modification.
-		 */
-		private int expectedModCount = HashBag.this.modCount;
-
-		HashIterator() {
-			super();
-		}
-
-		@Override
-		public boolean hasNext() {
-			Entry<E> e = this.nextEntry;
-			int i = this.index;
-			Entry<E>[] tab = HashBag.this.table;
-			// Use locals for faster loop iteration
-			while ((e == null) && (i > 0)) {
-				e = tab[--i];		// move backwards through the table
-			}
-			this.nextEntry = e;
-			this.index = i;
-			return e != null;
-		}
-
-		@Override
-		public E next() {
-			if (HashBag.this.modCount != this.expectedModCount) {
-				throw new ConcurrentModificationException();
-			}
-			Entry<E> et = this.nextEntry;
-			int i = this.index;
-			Entry<E>[] tab = HashBag.this.table;
-			// Use locals for faster loop iteration
-			while ((et == null) && (i > 0)) {
-				et = tab[--i];		// move backwards through the table
-			}
-			this.nextEntry = et;
-			this.index = i;
-			if (et == null) {
-				throw new NoSuchElementException();
-			}
-			Entry<E> e = this.lastReturnedEntry = this.nextEntry;
-			this.nextEntryCount++;
-			if (this.nextEntryCount == e.count) {
-				this.nextEntry = e.next;
-				this.nextEntryCount = 0;
-			}
-			return e.object;
-		}
-
-		@Override
-		public void remove() {
-			if (this.lastReturnedEntry == null) {
-				throw new IllegalStateException();
-			}
-			if (HashBag.this.modCount != this.expectedModCount) {
-				throw new ConcurrentModificationException();
-			}
-			int slot = HashBag.this.index(this.lastReturnedEntry.hash, HashBag.this.table.length);
-			for (Entry<E> e = HashBag.this.table[slot], prev = null; e != null; prev = e, e = e.next) {
-				if (e == this.lastReturnedEntry) {
-					HashBag.this.modCount++;
-					this.expectedModCount++;
-					e.count--;
-					if (e.count == 0) {
-						// if we are removing the last one, remove the entry from the table
-						if (prev == null) {
-							HashBag.this.table[slot] = e.next;
-						} else {
-							prev.next = e.next;
-						}
-						HashBag.this.uniqueCount--;
-					} else {
-						// slide back the count to account for the just-removed element
-						this.nextEntryCount--;
-					}
-					HashBag.this.size--;
-					this.lastReturnedEntry = null;	// it cannot be removed again
-					return;
-				}
-			}
-			throw new ConcurrentModificationException();
-		}
-	}
-
-
-	private class EntryIterator
-		implements Iterator<Entry<E>>
-	{
-		private int index = HashBag.this.table.length;	// start at the end of the table
-		private Entry<E> nextEntry = null;
-		private Entry<E> lastReturnedEntry = null;
-
-		/**
-		 * The modCount value that the iterator believes that the backing
-		 * bag should have. If this expectation is violated, the iterator
-		 * has detected a concurrent modification.
-		 */
-		private int expectedModCount = HashBag.this.modCount;
-
-		EntryIterator() {
-			super();
-		}
-
-		@Override
-		public boolean hasNext() {
-			Entry<E> e = this.nextEntry;
-			int i = this.index;
-			Entry<E>[] tab = HashBag.this.table;
-			// Use locals for faster loop iteration
-			while ((e == null) && (i > 0)) {
-				e = tab[--i];		// move backwards through the table
-			}
-			this.nextEntry = e;
-			this.index = i;
-			return e != null;
-		}
-
-		@Override
-		public Entry<E> next() {
-			if (HashBag.this.modCount != this.expectedModCount) {
-				throw new ConcurrentModificationException();
-			}
-			Entry<E> et = this.nextEntry;
-			int i = this.index;
-			Entry<E>[] tab = HashBag.this.table;
-			// Use locals for faster loop iteration
-			while ((et == null) && (i > 0)) {
-				et = tab[--i];		// move backwards through the table
-			}
-			this.nextEntry = et;
-			this.index = i;
-			if (et == null) {
-				throw new NoSuchElementException();
-			}
-			Entry<E> e = this.lastReturnedEntry = this.nextEntry;
-			this.nextEntry = e.next;
-			return e;
-		}
-
-		@Override
-		public void remove() {
-			if (this.lastReturnedEntry == null) {
-				throw new IllegalStateException();
-			}
-			if (HashBag.this.modCount != this.expectedModCount) {
-				throw new ConcurrentModificationException();
-			}
-			int slot = HashBag.this.index(this.lastReturnedEntry.hash, HashBag.this.table.length);
-			for (Entry<E> e = HashBag.this.table[slot], prev = null; e != null; prev = e, e = e.next) {
-				if (e == this.lastReturnedEntry) {
-					HashBag.this.modCount++;
-					this.expectedModCount++;
-					// remove the entry from the table
-					if (prev == null) {
-						HashBag.this.table[slot] = e.next;
-					} else {
-						prev.next = e.next;
-					}
-					HashBag.this.uniqueCount--;
-					HashBag.this.size -= this.lastReturnedEntry.count;
-					this.lastReturnedEntry = null;	// it cannot be removed again
-					return;
-				}
-			}
-			throw new ConcurrentModificationException();
-		}
-	}
-
-
-	private class UniqueIterator
-		implements Iterator<E>
-	{
-		private EntryIterator entryIterator = new EntryIterator();
-
-		UniqueIterator() {
-			super();
-		}
-
-		@Override
-		public boolean hasNext() {
-			return this.entryIterator.hasNext();
-		}
-
-		@Override
-		public E next() {
-			return this.entryIterator.next().object;
-		}
-
-		@Override
-		public void remove() {
-			this.entryIterator.remove();
-		}
-	}
-
-
-	@Override
-	public boolean equals(Object o) {
-		if (o == this) {
-			return true;
-		}
-		if ( ! (o instanceof Bag<?>)) {
-			return false;
-		}
-		@SuppressWarnings("unchecked")
-		Bag<E> b = (Bag<E>) o;
-		if (b.size() != this.size()) {
-			return false;
-		}
-		if (b.uniqueCount() != this.uniqueCount()) {
-			return false;
-		}
-		for (Iterator<Bag.Entry<E>> stream = b.entries(); stream.hasNext(); ) {
-			Bag.Entry<E> entry = stream.next();
-			if (entry.getCount() != this.count(entry.getElement())) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	@Override
-	public int hashCode() {
-		int h = 0;
-		for (E o : this) {
-			if (o != null) {
-				h += o.hashCode();
-			}
-		}
-		return h;
-	}
-
-	/**
-	 * Save the state of this bag to a stream (i.e. serialize it).
-	 *
-	 * @serialData Emit the capacity of the bag (int),
-	 *     followed by the number of unique elements in the bag (int),
-	 *     followed by all of the bag's elements (each an Object) and
-	 *     their counts (each an int), in no particular order.
-	 */
-	private void writeObject(java.io.ObjectOutputStream s)
-				throws java.io.IOException {
-		// write out the threshold, load factor, and any hidden stuff
-		s.defaultWriteObject();
-
-		// write out number of buckets
-		s.writeInt(this.table.length);
-
-		// write out number of unique elements
-		s.writeInt(this.uniqueCount);
-
-		// write out elements and counts (alternating)
-		if (this.uniqueCount > 0) {
-			for (Entry<E> entry : this.table) {
-				while (entry != null) {
-					s.writeObject(entry.object);
-					s.writeInt(entry.count);
-					entry = entry.next;
-				}
-			}
-		}
-	}
-
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Reconstitute the bag from a stream (i.e. deserialize it).
-	 */
-	private void readObject(java.io.ObjectInputStream s)
-				throws java.io.IOException, ClassNotFoundException {
-		// read in the threshold, loadfactor, and any hidden stuff
-		s.defaultReadObject();
-
-		// read in number of buckets and allocate the bucket array
-		this.table = this.buildTable(s.readInt());
-
-		// read in number of unique elements
-		int unique = s.readInt();
-
-		// read the elements and counts, and put the elements in the bag
-		for (int i = 0; i < unique; i++) {
-			@SuppressWarnings("unchecked")
-			E element = (E) s.readObject();
-			int elementCount = s.readInt();
-			this.add_(element, elementCount);
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/IdentityHashBag.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/IdentityHashBag.java
deleted file mode 100644
index a68c8a2..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/IdentityHashBag.java
+++ /dev/null
@@ -1,950 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-import java.util.AbstractCollection;
-import java.util.Collection;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * This class implements the {@link Bag} interface with a
- * hash table, using object-identity in place of object-equality when
- * comparing elements. In other words, in an <code>IdentityHashBag</code>,
- * two objects <code>o1</code> and <code>o2</code> are considered
- * equal if and only if <code>(o1 == o2)</code>. (In normal {@link Bag}
- * implementations (like {@link HashBag}) two objects <code>o1</code>
- * and <code>o2</code> are considered equal if and only if
- * <code>(o1 == null ? o2 == null : o1.equals(o2))</code>.)
- * <p>
- * <strong>
- * This class is <em>not</em> a general-purpose {@link Bag}
- * implementation! While this class implements the {@link Bag} interface, it
- * intentionally violates {@link Bag}'s general contract, which mandates the
- * use of the <code>equals</code> method when comparing objects. This class is
- * designed for use only in the rare cases wherein object-identity
- * semantics are required.
- * </strong>
- * <p>
- * This class makes no guarantees as to the iteration order of
- * the bag's elements; in particular, it does not guarantee that the order
- * will remain constant over time. This class permits the <code>null</code>
- * element.
- * <p>
- * This class offers constant time performance for the basic operations
- * (<code>add</code>, <code>remove</code>, <code>contains</code> and
- * <code>size</code>), assuming the system identity hash function
- * ({@link System#identityHashCode(Object)}) disperses elements properly
- * among the buckets. Iterating over this bag requires time
- * proportional to the sum of the bag's size (the number of elements) plus the
- * "capacity" of the backing hash table (the number of buckets). Thus, it is
- * important not to set the initial capacity too high (or the load factor too
- * low) if iteration performance is important.
- * <p>
- * <strong>Note that this implementation is not synchronized.</strong> If multiple
- * threads access a bag concurrently, and at least one of the threads modifies
- * the bag, it <em>must</em> be synchronized externally. This is typically
- * accomplished by synchronizing on some object that naturally encapsulates
- * the bag. If no such object exists, the bag should be "wrapped" using the
- * <code>Collections.synchronizedCollection</code> method. This is
- * best done at creation time, to prevent accidental unsynchronized access
- * to the bag:
- * <pre>
- * Collection c = Collections.synchronizedCollection(new IdentityHashBag(...));
- * </pre>
- * <p>
- * The iterators returned by this class's <code>iterator</code> method are
- * <em>fail-fast</em>: if the bag is modified at any time after the iterator is
- * created, in any way except through the iterator's own <code>remove</code>
- * method, the iterator throws a {@link ConcurrentModificationException}.
- * Thus, in the face of concurrent modification, the iterator fails quickly
- * and cleanly, rather than risking arbitrary, non-deterministic behavior at
- * an undetermined time in the future.
- * <p>
- * Note that the fail-fast behavior of an iterator cannot be guaranteed
- * as it is, generally speaking, impossible to make any hard guarantees in the
- * presence of unsynchronized concurrent modification. Fail-fast iterators
- * throw <code>ConcurrentModificationException</code> on a best-effort basis.
- * Therefore, it would be wrong to write a program that depended on this
- * exception for its correctness: <em>the fail-fast behavior of iterators
- * should be used only to detect bugs.</em>
- *
- * @param <E> the type of elements maintained by the bag
- *
- * @see Collection
- * @see Bag
- * @see SynchronizedBag
- * @see	java.util.Collections#synchronizedCollection(Collection)
- * @see HashBag
- */
-@SuppressWarnings("nls")
-public class IdentityHashBag<E>
-	extends AbstractCollection<E>
-	implements Bag<E>, Cloneable, Serializable
-{
-	/** The hash table. Resized as necessary. Length MUST Always be a power of two. */
-	transient Entry<E>[] table;
-
-	/** The total number of entries in the bag. */
-	transient int size = 0;
-
-	/** The number of UNIQUE entries in the bag. */
-	transient int uniqueCount = 0;
-
-	/**
-	 * The hash table is rehashed when its size exceeds this threshold. (The
-	 * value of this field is <code>(int) (capacity * loadFactor)</code>.)
-	 *
-	 * @serial size threshold
-	 */
-	private int threshold;
-
-	/**
-	 * The load factor for the hash table.
-	 *
-	 * @serial load factor
-	 */
-	private final float loadFactor;
-
-	/**
-	 * The number of times this bag has been structurally modified.
-	 * Structural modifications are those that change the number of entries in
-	 * the bag or otherwise modify its internal structure (e.g. rehash).
-	 * This field is used to make iterators on this bag fail-fast.
-	 *
-	 * @see java.util.ConcurrentModificationException
-	 */
-	transient int modCount = 0;
-
-	/**
-	 * The default initial capacity - MUST be a power of two.
-	 */
-	private static final int DEFAULT_INITIAL_CAPACITY = 16;
-
-	/**
-	 * The maximum capacity, used if a higher value is implicitly specified
-	 * by either of the constructors with arguments.
-	 * MUST be a power of two <= (1 << 30).
-		 */
-	private static final int MAXIMUM_CAPACITY = 1 << 30;
-
-	/**
-	 * The load factor used when none specified in constructor.
-	 */
-	private static final float DEFAULT_LOAD_FACTOR = 0.75f;
-
-	/**
-	 * Construct a new, empty bag with the
-	 * default capacity, which is 16, and load factor, which is 0.75.
-	 */
-	public IdentityHashBag() {
-		this(DEFAULT_INITIAL_CAPACITY);
-	}
-
-	/**
-	 * Construct a new, empty bag with the specified initial capacity
-	 * and the default load factor, which is 0.75.
-	 *
-	 * @param initialCapacity the initial capacity
-	 * @throws IllegalArgumentException if the initial capacity is less
-	 *     than zero
-	 */
-	public IdentityHashBag(int initialCapacity) {
-		this(initialCapacity, DEFAULT_LOAD_FACTOR, false);  // false = do not validate parms
-	}
-
-	/**
-	 * Construct a new, empty bag with
-	 * the specified initial capacity and load factor.
-	 *
-	 * @param initialCapacity the initial capacity
-	 * @param loadFactor the load factor
-	 * @throws IllegalArgumentException if the initial capacity is less
-	 *     than zero or if the load factor is non-positive
-	 */
-	public IdentityHashBag(int initialCapacity, float loadFactor) {
-		this(initialCapacity, loadFactor, true);  // true = validate parms
-	}
-
-	private IdentityHashBag(int initialCapacity, float loadFactor, boolean validateParms) {
-		super();
-		int capacity = initialCapacity;
-		if (validateParms) {
-			if (capacity < 0) {
-				throw new IllegalArgumentException("Illegal Initial Capacity: " + capacity);
-			}
-			if (capacity > MAXIMUM_CAPACITY) {
-				capacity = MAXIMUM_CAPACITY;
-			}
-			if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
-				throw new IllegalArgumentException("Illegal Load factor: " + loadFactor);
-			}
-
-			// find a power of 2 >= 'initialCapacity'
-			capacity = 1;
-			while (capacity < initialCapacity) {
-				capacity <<= 1;
-			}
-		}
-
-		this.loadFactor = loadFactor;
-		this.table = this.buildTable(capacity);
-		this.threshold = (int) (capacity * loadFactor);
-	}
-
-	/**
-	 * Construct a new bag containing the elements in the specified
-	 * collection. The bag's load factor will be the default, which is 0.75,
-	 * and its initial capacity will be sufficient to hold all the elements in
-	 * the specified collection.
-	 *
-	 * @param c the collection whose elements are to be placed into this bag.
-	 */
-	public IdentityHashBag(Collection<? extends E> c) {
-		this(Math.max((int) (c.size() / DEFAULT_LOAD_FACTOR) + 1, DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
-		this.addAll_(c);
-	}
-
-	/**
-	 * Returns a index for the specified object.
-	 */
-	private int index(Object o) {
-		return this.index(this.hash(o));
-	}
-
-	/**
-	 * Returns a hash for the specified object.
-	 */
-	private int hash(Object o) {
-		return (o == null) ? 0 : this.tweakHash(System.identityHashCode(o));
-	}
-
-	/**
-	 * Tweak the specified hash.
-	 */
-	private int tweakHash(int h) {
-		return h;
-//		h ^= (h >>> 20) ^ (h >>> 12);
-//		return h ^ (h >>> 7) ^ (h >>> 4);
-	}
-
-	/**
-	 * Returns the index for the specified hash.
-	 */
-	private int index(int hash) {
-		return this.index(hash, this.table.length);
-	}
-
-	/**
-	 * Returns the index for the specified hash
-	 * within a table with the specified length.
-	 */
-	int index(int hash, int length) {
-		return hash & (length - 1);
-	}
-
-	/**
-	 * Internal {@link #addAll(Collection)} for construction and cloning.
-	 * Returns value.)
-	 */
-	private void addAll_(Iterable<? extends E> c) {
-		for (E e : c) {
-			this.add_(e);
-		}
-	}
-
-	/**
-	 * Internal {@link #add(Object)} for construction and cloning.
-	 * Returns value.)
-	 */
-	private void add_(E o) {
-		this.add_(o, 1);
-	}
-
-	/**
-	 * Internal {@link #add(Object, int)} for construction, cloning, and serialization.
-	 * Returns value.)
-	 */
-	private void add_(E o, int cnt) {
-		int hash = this.hash(o);
-		int index = this.index(hash);
-		for (Entry<E> e = this.table[index]; e != null; e = e.next) {
-			if (e.object == o) {
-				e.count += cnt;
-				this.size += cnt;
-				return;
-			}
-		}
-
-		// create the new entry and put it in the table
-		Entry<E> e = this.buildEntry(hash, o, cnt, this.table[index]);
-		this.table[index] = e;
-		this.size += cnt;
-		this.uniqueCount++;
-	}
-
-	/**
-	 * This implementation simply returns the maintained size.
-	 */
-	@Override
-	public int size() {
-		return this.size;
-	}
-
-	/**
-	 * This implementation simply compares the maintained size to zero.
-	 */
-	@Override
-	public boolean isEmpty() {
-		return this.size == 0;
-	}
-
-	/**
-	 * Search for the object's entry in the hash table by calculating
-	 * the object's identity hash code and examining the entries in the corresponding hash
-	 * table bucket.
-	 */
-	private Entry<E> getEntry(Object o) {
-		for (Entry<E> e = this.table[this.index(o)]; e != null; e = e.next) {
-			if (e.object == o) {
-				return e;
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public boolean contains(Object o) {
-		return this.getEntry(o) != null;
-	}
-
-	@Override
-	public int count(Object o) {
-		Entry<E> e = this.getEntry(o);
-		return (e == null) ? 0 : e.count;
-	}
-
-	/**
-	 * Rehash the contents of the bag into a new hash table
-	 * with a larger capacity. This method is called when the
-	 * number of different elements in the bag exceeds its
-	 * capacity and load factor.
-	 */
-	private void rehash() {
-		Entry<E>[] oldTable = this.table;
-		int oldCapacity = oldTable.length;
-
-		if (oldCapacity == MAXIMUM_CAPACITY) {
-			this.threshold = Integer.MAX_VALUE;
-			return;
-		}
-
-		int newCapacity = 2 * oldCapacity;
-		Entry<E>[] newTable = this.buildTable(newCapacity);
-
-		for (int i = oldCapacity; i-- > 0; ) {
-			for (Entry<E> old = oldTable[i]; old != null; ) {
-				Entry<E> e = old;
-				old = old.next;
-
-				int index = this.index(e.hash, newCapacity);
-				e.next = newTable[index];
-				newTable[index] = e;
-			}
-		}
-
-		this.table = newTable;
-		this.threshold = (int) (newCapacity * this.loadFactor);
-	}
-
-	// minimize scope of suppressed warnings
-	@SuppressWarnings("unchecked")
-	private Entry<E>[] buildTable(int capacity) {
-		return new Entry[capacity];
-	}
-
-	/**
-	 * This implementation searches for the object in the hash table by calculating
-	 * the object's identity hash code and examining the entries in the corresponding hash
-	 * table bucket.
-	 */
-	@Override
-	public boolean add(E o) {
-		return this.add(o, 1);
-	}
-
-	/**
-	 * This implementation searches for the object in the hash table by calculating
-	 * the object's identity hash code and examining the entries in the corresponding hash
-	 * table bucket.
-	 */
-	@Override
-	public boolean add(E o, int cnt) {
-		if (cnt <= 0) {
-			return false;
-		}
-		this.modCount++;
-		int hash = this.hash(o);
-		int index = this.index(hash);
-
-		// if the object is already in the bag, simply bump its count
-		for (Entry<E> e = this.table[index]; e != null; e = e.next) {
-			if (e.object == o) {
-				e.count += cnt;
-				this.size += cnt;
-				return true;
-			}
-		}
-
-		// rehash the table if we are going to exceed the threshold
-		if (this.uniqueCount >= this.threshold) {
-			this.rehash();
-			index = this.index(hash);  // need to re-calculate the index
-		}
-
-		// create the new entry and put it in the table
-		Entry<E> e = this.buildEntry(hash, o, cnt, this.table[index]);
-		this.table[index] = e;
-		this.size += cnt;
-		this.uniqueCount++;
-		return true;
-	}
-
-	// minimize scope of suppressed warnings
-	@SuppressWarnings({ "unchecked", "rawtypes" })
-	private Entry<E> buildEntry(int hash, Object o, int cnt, Entry next) {
-		return new Entry<E>(hash, (E) o, cnt, (Entry<E>) next);
-	}
-
-	/**
-	 * This implementation searches for the object in the hash table by calculating
-	 * the object's identity hash code and examining the entries in the corresponding hash
-	 * table bucket.
-	 */
-	@Override
-	public boolean remove(Object o) {
-		return this.remove(o, 1);
-	}
-
-	/**
-	 * This implementation searches for the object in the hash table by calculating
-	 * the object's identity hash code and examining the entries in the corresponding hash
-	 * table bucket.
-	 */
-	@Override
-	public boolean remove(Object o, int cnt) {
-		if (cnt <= 0) {
-			return false;
-		}
-		int index = this.index(o);
-
-		for (Entry<E> e = this.table[index], prev = null; e != null; prev = e, e = e.next) {
-			if (e.object == o) {
-				this.modCount++;
-				cnt = (cnt < e.count) ? cnt : e.count;
-				e.count -= cnt;
-				// if we are removing the last element(s), remove the entry from the table
-				if (e.count == 0) {
-					if (prev == null) {
-						this.table[index] = e.next;
-					} else {
-						prev.next = e.next;
-					}
-					this.uniqueCount--;
-				}
-				this.size -= cnt;
-				return true;
-			}
-		}
-
-		return false;
-	}
-
-	/**
-	 * This implementation uses object-identity to determine whether the
-	 * specified collection contains a particular element.
-	 */
-	@Override
-	public boolean removeAll(Collection<?> c) {
-		return super.removeAll(new IdentityHashBag<Object>(c));
-	}
-
-	/**
-	 * This implementation uses object-identity to determine whether the
-	 * specified collection contains a particular element.
-	 */
-	@Override
-	public boolean retainAll(Collection<?> c) {
-		return super.retainAll(new IdentityHashBag<Object>(c));
-	}
-
-	/**
-	 * This implementation simply clears out all of the hash table buckets.
-	 */
-	@Override
-	public void clear() {
-		Entry<E>[] tab = this.table;
-		this.modCount++;
-		for (int i = tab.length; i-- > 0; ) {
-			tab[i] = null;
-		}
-		this.size = 0;
-		this.uniqueCount = 0;
-	}
-
-	/**
-	 * Returns a shallow copy of this bag: the elements
-	 * themselves are not cloned.
-	 *
-	 * @return a shallow copy of this bag.
-	 */
-	@Override
-	public IdentityHashBag<E> clone() {
-		try {
-			@SuppressWarnings("unchecked")
-			IdentityHashBag<E> clone = (IdentityHashBag<E>) super.clone();
-			clone.table = this.buildTable(this.table.length);
-			clone.size = 0;
-			clone.uniqueCount = 0;
-			clone.modCount = 0;
-			clone.addAll_(this);
-			return clone;
-		} catch (CloneNotSupportedException e) {
-			throw new InternalError();
-		}
-	}
-
-
-	/**
-	 * Hash table collision list entry.
-	 */
-	private static class Entry<E> implements Bag.Entry<E> {
-		final int hash;  // cache the hash for re-hashes
-		final E object;
-		int count;
-		Entry<E> next;
-
-		Entry(int hash, E object, int count, Entry<E> next) {
-			this.hash = hash;
-			this.object = object;
-			this.count = count;
-			this.next = next;
-		}
-
-		// ***** Bag.Entry implementation
-		@Override
-		public E getElement() {
-			return this.object;
-		}
-
-		@Override
-		public int getCount() {
-			return this.count;
-		}
-
-		@Override
-		public int setCount(int count) {
-			if (count <= 0) {
-				throw new IllegalArgumentException("count must be greater than zero: " + count);
-			}
-			int old = this.count;
-			this.count = count;
-			return old;
-		}
-
-		@Override
-		public boolean equals(Object o) {
-			if ( ! (o instanceof Bag.Entry<?>)) {
-				return false;
-			}
-			@SuppressWarnings("rawtypes")
-			Bag.Entry e = (Bag.Entry) o;
-			return (this.object == e.getElement())
-					&& (this.count == e.getCount());
-		}
-
-		@Override
-		public int hashCode() {
-			E o = this.object;
-			return (o == null) ? 0 : (this.count * o.hashCode());
-		}
-
-		@Override
-		public String toString() {
-			return this.object + "=>" + this.count;
-		}
-	}
-
-
-	@Override
-	@SuppressWarnings("unchecked")
-	public Iterator<E> iterator() {
-		return (this.size == 0) ? EMPTY_ITERATOR : new HashIterator();
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	public Iterator<E> uniqueIterator() {
-		return (this.size == 0) ? EMPTY_ITERATOR : new UniqueIterator();
-	}
-
-	@Override
-	public int uniqueCount() {
-		return this.uniqueCount;
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	public Iterator<Bag.Entry<E>> entries() {
-		return (this.size == 0) ? EMPTY_ITERATOR : new EntryIterator();
-	}
-
-
-	/**
-	 * Empty iterator that does just about nothing.
-	 */
-	@SuppressWarnings("rawtypes")
-	private static final Iterator EMPTY_ITERATOR = new EmptyIterator();
-
-	@SuppressWarnings("rawtypes")
-	private static class EmptyIterator implements Iterator {
-
-		EmptyIterator() {
-			super();
-		}
-
-		@Override
-		public boolean hasNext() {
-			return false;
-		}
-
-		@Override
-		public Object next() {
-			throw new NoSuchElementException();
-		}
-
-		@Override
-		public void remove() {
-			throw new IllegalStateException();
-		}
-	}
-
-
-	private class HashIterator implements Iterator<E> {
-		private int index = IdentityHashBag.this.table.length;	// start at the end of the table
-		private Entry<E> nextEntry = null;
-		private int nextEntryCount = 0;
-		private Entry<E> lastReturnedEntry = null;
-
-		/**
-		 * The modCount value that the iterator believes that the backing
-		 * bag should have. If this expectation is violated, the iterator
-		 * has detected a concurrent modification.
-		 */
-		private int expectedModCount = IdentityHashBag.this.modCount;
-
-		HashIterator() {
-			super();
-		}
-
-		@Override
-		public boolean hasNext() {
-			Entry<E> e = this.nextEntry;
-			int i = this.index;
-			Entry<E>[] tab = IdentityHashBag.this.table;
-			// Use locals for faster loop iteration
-			while ((e == null) && (i > 0)) {
-				e = tab[--i];		// move backwards through the table
-			}
-			this.nextEntry = e;
-			this.index = i;
-			return e != null;
-		}
-
-		@Override
-		public E next() {
-			if (IdentityHashBag.this.modCount != this.expectedModCount) {
-				throw new ConcurrentModificationException();
-			}
-			Entry<E> et = this.nextEntry;
-			int i = this.index;
-			Entry<E>[] tab = IdentityHashBag.this.table;
-			// Use locals for faster loop iteration
-			while ((et == null) && (i > 0)) {
-				et = tab[--i];		// move backwards through the table
-			}
-			this.nextEntry = et;
-			this.index = i;
-			if (et == null) {
-				throw new NoSuchElementException();
-			}
-			Entry<E> e = this.lastReturnedEntry = this.nextEntry;
-			this.nextEntryCount++;
-			if (this.nextEntryCount == e.count) {
-				this.nextEntry = e.next;
-				this.nextEntryCount = 0;
-			}
-			return e.object;
-		}
-
-		@Override
-		public void remove() {
-			if (this.lastReturnedEntry == null) {
-				throw new IllegalStateException();
-			}
-			if (IdentityHashBag.this.modCount != this.expectedModCount) {
-				throw new ConcurrentModificationException();
-			}
-			int slot = IdentityHashBag.this.index(this.lastReturnedEntry.hash, IdentityHashBag.this.table.length);
-			for (Entry<E> e = IdentityHashBag.this.table[slot], prev = null; e != null; prev = e, e = e.next) {
-				if (e == this.lastReturnedEntry) {
-					IdentityHashBag.this.modCount++;
-					this.expectedModCount++;
-					e.count--;
-					if (e.count == 0) {
-						// if we are removing the last one, remove the entry from the table
-						if (prev == null) {
-							IdentityHashBag.this.table[slot] = e.next;
-						} else {
-							prev.next = e.next;
-						}
-						IdentityHashBag.this.uniqueCount--;
-					} else {
-						// slide back the count to account for the just-removed element
-						this.nextEntryCount--;
-					}
-					IdentityHashBag.this.size--;
-					this.lastReturnedEntry = null;	// it cannot be removed again
-					return;
-				}
-			}
-			throw new ConcurrentModificationException();
-		}
-
-	}
-
-
-	private class EntryIterator implements Iterator<Entry<E>> {
-		private int index = IdentityHashBag.this.table.length;	// start at the end of the table
-		private Entry<E> nextEntry = null;
-		private Entry<E> lastReturnedEntry = null;
-
-		/**
-		 * The modCount value that the iterator believes that the backing
-		 * bag should have. If this expectation is violated, the iterator
-		 * has detected a concurrent modification.
-		 */
-		private int expectedModCount = IdentityHashBag.this.modCount;
-
-		EntryIterator() {
-			super();
-		}
-
-		@Override
-		public boolean hasNext() {
-			Entry<E> e = this.nextEntry;
-			int i = this.index;
-			Entry<E>[] tab = IdentityHashBag.this.table;
-			// Use locals for faster loop iteration
-			while ((e == null) && (i > 0)) {
-				e = tab[--i];		// move backwards through the table
-			}
-			this.nextEntry = e;
-			this.index = i;
-			return e != null;
-		}
-
-		@Override
-		public Entry<E> next() {
-			if (IdentityHashBag.this.modCount != this.expectedModCount) {
-				throw new ConcurrentModificationException();
-			}
-			Entry<E> et = this.nextEntry;
-			int i = this.index;
-			Entry<E>[] tab = IdentityHashBag.this.table;
-			// Use locals for faster loop iteration
-			while ((et == null) && (i > 0)) {
-				et = tab[--i];		// move backwards through the table
-			}
-			this.nextEntry = et;
-			this.index = i;
-			if (et == null) {
-				throw new NoSuchElementException();
-			}
-			Entry<E> e = this.lastReturnedEntry = this.nextEntry;
-			this.nextEntry = e.next;
-			return e;
-		}
-
-		@Override
-		public void remove() {
-			if (this.lastReturnedEntry == null) {
-				throw new IllegalStateException();
-			}
-			if (IdentityHashBag.this.modCount != this.expectedModCount) {
-				throw new ConcurrentModificationException();
-			}
-			int slot = IdentityHashBag.this.index(this.lastReturnedEntry.hash, IdentityHashBag.this.table.length);
-			for (Entry<E> e = IdentityHashBag.this.table[slot], prev = null; e != null; prev = e, e = e.next) {
-				if (e == this.lastReturnedEntry) {
-					IdentityHashBag.this.modCount++;
-					this.expectedModCount++;
-					// remove the entry from the table
-					if (prev == null) {
-						IdentityHashBag.this.table[slot] = e.next;
-					} else {
-						prev.next = e.next;
-					}
-					IdentityHashBag.this.uniqueCount--;
-					IdentityHashBag.this.size -= this.lastReturnedEntry.count;
-					this.lastReturnedEntry = null;	// it cannot be removed again
-					return;
-				}
-			}
-			throw new ConcurrentModificationException();
-		}
-
-	}
-
-
-	private class UniqueIterator implements Iterator<E> {
-		private EntryIterator entryIterator = new EntryIterator();
-
-		UniqueIterator() {
-			super();
-		}
-
-		@Override
-		public boolean hasNext() {
-			return this.entryIterator.hasNext();
-		}
-
-		@Override
-		public E next() {
-			return this.entryIterator.next().object;
-		}
-
-		@Override
-		public void remove() {
-			this.entryIterator.remove();
-		}
-
-	}
-
-
-	@Override
-	public boolean equals(Object o) {
-		if (o == this) {
-			return true;
-		} else if (o instanceof IdentityHashBag<?>) {
-			@SuppressWarnings("unchecked")
-			IdentityHashBag<E> b = (IdentityHashBag<E>) o;
-			if (b.size() != this.size()) {
-				return false;
-			}
-			if (b.uniqueCount() != this.uniqueCount()) {
-				return false;
-			}
-			for (Iterator<Bag.Entry<E>> stream = b.entries(); stream.hasNext(); ) {
-				Bag.Entry<E> entry = stream.next();
-				if (entry.getCount() != this.count(entry.getElement())) {
-					return false;
-				}
-			}
-			return true;
-		} else {
-			return this.equals_(o);
-		}
-//		} else if (o instanceof Bag<?>) {
-//			// hmmm...
-//			return new HashBag<Object>(this).equals(o);
-//		} else {
-//			return false;
-//		}
-	}
-
-	private boolean equals_(Object o) {
-		// hmmm...
-		return (o instanceof Bag<?>) &&
-				new HashBag<Object>(this).equals(o);
-	}
-
-	@Override
-	public int hashCode() {
-		int h = 0;
-		for (E o : this) {
-			h += System.identityHashCode(o);
-		}
-		return h;
-	}
-
-	/**
-	 * Save the state of this bag to a stream (i.e. serialize it).
-	 *
-	 * @serialData Emit the capacity of the bag (int),
-	 *     followed by the number of unique elements in the bag (int),
-	 *     followed by all of the bag's elements (each an Object) and
-	 *     their counts (each an int), in no particular order.
-	 */
-	private void writeObject(java.io.ObjectOutputStream s)
-				throws java.io.IOException {
-		// write out the threshold, load factor, and any hidden stuff
-		s.defaultWriteObject();
-
-		// write out number of buckets
-		s.writeInt(this.table.length);
-
-		// write out number of unique elements
-		s.writeInt(this.uniqueCount);
-
-		// write out elements and counts (alternating)
-		if (this.uniqueCount > 0) {
-			for (Entry<E> entry : this.table) {
-				while (entry != null) {
-					s.writeObject(entry.object);
-					s.writeInt(entry.count);
-					entry = entry.next;
-				}
-			}
-		}
-	}
-
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Reconstitute the bag from a stream (i.e. deserialize it).
-	 */
-	private void readObject(java.io.ObjectInputStream s)
-				throws java.io.IOException, ClassNotFoundException {
-		// read in the threshold, loadfactor, and any hidden stuff
-		s.defaultReadObject();
-
-		// read in number of buckets and allocate the bucket array
-		this.table = this.buildTable(s.readInt());
-
-		// read in number of unique elements
-		int unique = s.readInt();
-
-		// read the elements and counts, and put the elements in the bag
-		for (int i = 0; i < unique; i++) {
-			@SuppressWarnings("unchecked")
-			E element = (E) s.readObject();
-			int elementCount = s.readInt();
-			this.add_(element, elementCount);
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/IndentingPrintWriter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/IndentingPrintWriter.java
deleted file mode 100644
index 8c75ae8..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/IndentingPrintWriter.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.PrintWriter;
-import java.io.Writer;
-
-/**
- * Extend {@link PrintWriter} to automatically indent new lines.
- *
- * @version 2.5
- */
-@SuppressWarnings("nls")
-public class IndentingPrintWriter extends PrintWriter {
-
-	private final String indent;
-	private int indentLevel;
-	private boolean needsIndent;
-
-	public static String DEFAULT_INDENT = "\t";
-
-	/**
-	 * Construct a writer that indents with tabs.
-	 */
-	public IndentingPrintWriter(Writer out) {
-		this(out, DEFAULT_INDENT);
-	}
-
-	/**
-	 * Construct a writer that indents with the specified string.
-	 */
-	public IndentingPrintWriter(Writer out, String indent) {
-		super(out);
-		this.indent = indent;
-		this.indentLevel = 0;
-		this.needsIndent = true;
-	}
-
-	/**
-	 * Decrement the indent level.
-	 */
-	public void decrementIndentLevel() {
-		synchronized (this.lock) {
-			this.indentLevel--;
-		}
-	}
-
-	/**
-	 * Returns the current indent level.
-	 */
-	public int getIndentLevel() {
-		synchronized (this.lock) {
-			return this.indentLevel;
-		}
-	}
-
-	/**
-	 * Bump the indent level.
-	 */
-	public void incrementIndentLevel() {
-		synchronized (this.lock) {
-			this.indentLevel++;
-		}
-	}
-
-	/**
-	 * Bump the indent level.
-	 */
-	public void indent() {
-		this.incrementIndentLevel();
-	}
-
-	/**
-	 * Print the appropriate indent.
-	 * Pre-condition: synchronized
-	 */
-	private void printIndent() {
-		if (this.needsIndent) {
-			this.needsIndent = false;
-			for (int i = this.indentLevel; i-- > 0; ) {
-				this.print(this.indent);
-			}
-		}
-	}
-
-	/**
-	 * Set flag so following line is indented.
-	 */
-	@Override
-	public void println() {
-		synchronized (this.lock) {
-			super.println();
-			this.needsIndent = true;
-		}
-	}
-
-	/**
-	 * Allow the indent level to be set directly.
-	 * Returns the previous indent level.
-	 */
-	public int setIndentLevel(int indentLevel) {
-		synchronized (this.lock) {
-			int old = this.indentLevel;
-			this.indentLevel = indentLevel;
-			return old;
-		}
-	}
-
-	/**
-	 * Decrement the indent level.
-	 */
-	public void undent() {
-		this.decrementIndentLevel();
-	}
-
-	/**
-	 * Write a portion of an array of characters.
-	 */
-	@Override
-	public void write(char buf[], int off, int len) {
-		synchronized (this.lock) {
-			this.printIndent();
-			super.write(buf, off, len);
-		}
-	}
-
-	/**
-	 * Write a single character.
-	 */
-	@Override
-	public void write(int c) {
-		synchronized (this.lock) {
-			this.printIndent();
-			super.write(c);
-		}
-	}
-
-	/**
-	 * Write a portion of a string.
-	 */
-	@Override
-	public void write(String s, int off, int len) {
-		synchronized (this.lock) {
-			this.printIndent();
-			super.write(s, off, len);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/IntReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/IntReference.java
deleted file mode 100644
index db7ba91..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/IntReference.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-/**
- * Interface for a container for holding an <code>int</code> that cannot be changed by clients.
- */
-public interface IntReference extends Comparable<IntReference> {
-
-	/**
-	 * Returns the absolute value of the current <code>int</code> value.
-	 */
-	int abs();
-
-	/**
-	 * Returns the current <code>int</code> value plus the specified value.
-	 */
-	int add(int v);
-
-	/**
-	 * Returns current <code>int</code> value divided by the specified value.
-	 */
-	int divide(int v);
-
-	/**
-	 * Returns whether the current <code>int</code> value is equal to the
-	 * specified value.
-	 */
-	boolean equals(int v);
-
-	/**
-	 * Returns the current <code>int</code> value.
-	 */
-	int getValue();
-
-	/**
-	 * Returns whether the current <code>int</code> value is greater than
-	 * the specified value.
-	 */
-	boolean isGreaterThan(int v);
-
-	/**
-	 * Returns whether the current <code>int</code> value is greater than
-	 * or equal to the specified value.
-	 */
-	boolean isGreaterThanOrEqual(int v);
-
-	/**
-	 * Returns whether the current <code>int</code> value is less than
-	 * the specified value.
-	 */
-	boolean isLessThan(int v);
-
-	/**
-	 * Returns whether the current <code>int</code> value is less than
-	 * or equal to the specified value.
-	 */
-	boolean isLessThanOrEqual(int v);
-
-	/**
-	 * Returns whether the current <code>int</code> value is negative.
-	 */
-	boolean isNegative();
-
-	/**
-	 * Returns whether the current <code>int</code> value is not negative
-	 * (i.e. zero or positive).
-	 */
-	boolean isNotNegative();
-
-	/**
-	 * Returns whether the current <code>int</code> value is not positive
-	 * (i.e. negative or zero).
-	 */
-	boolean isNotPositive();
-
-	/**
-	 * Returns whether the current <code>int</code> value is not zero.
-	 */
-	boolean isNotZero();
-
-	/**
-	 * Returns whether the current <code>int</code> value is positive.
-	 */
-	boolean isPositive();
-
-	/**
-	 * Returns whether the current <code>int</code> value is zero.
-	 */
-	boolean isZero();
-
-	/**
-	 * Returns the maximum of the current <code>int</code> value and
-	 * the specified value.
-	 */
-	int max(int v);
-
-	/**
-	 * Returns the minimum of the current <code>int</code> value and
-	 * the specified value.
-	 */
-	int min(int v);
-
-	/**
-	 * Returns current <code>int</code> value multiplied by the specified value.
-	 */
-	int multiply(int v);
-
-	/**
-	 * Returns the negative value of the current <code>int</code> value.
-	 */
-	int neg();
-
-	/**
-	 * Returns whether the current <code>int</code> value is not equal to
-	 * the specified value.
-	 */
-	boolean notEqual(int v);
-
-	/**
-	 * Returns the current <code>int</code> value raised to the power
-	 * of the specified value.
-	 */
-	double pow(int v);
-
-	/**
-	 * Returns the remainder of the current <code>int</code> value divided by
-	 * the specified value.
-	 */
-	int remainder(int v);
-
-	/**
-	 * Returns current <code>int</code> value minus the specified value.
-	 */
-	int subtract(int v);
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/JDBCTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/JDBCTools.java
deleted file mode 100644
index 12201f8..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/JDBCTools.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.sql.Types;
-import java.util.HashMap;
-
-/**
- * Helper methods for dealing with the JDBC API.
- */
-@SuppressWarnings("nls")
-public final class JDBCTools {
-
-	/**
-	 * Returns the JDBC type corresponding to the specified class.
-	 * @see java.sql.Types
-	 */
-	public static JDBCType jdbcTypeForClassNamed(String className) {
-		JavaToJDBCTypeMapping mapping = javaToJDBCTypeMapping(className);
-		return (mapping == null) ? DEFAULT_JDBC_TYPE : mapping.getJDBCType();
-	}
-
-	/**
-	 * Returns the JDBC type corresponding to the specified class.
-	 * @see java.sql.Types
-	 */
-	public static JDBCType jdbcTypeFor(Class<?> javaClass) {
-		return jdbcTypeForClassNamed(javaClass.getName());
-	}
-
-	/**
-	 * Returns the JDBC type corresponding to the specified class.
-	 * @see java.sql.Types
-	 */
-	public static JDBCType jdbcTypeFor(JavaType javaType) {
-		return jdbcTypeForClassNamed(javaType.getJavaClassName());
-	}
-
-	/**
-	 * Returns the Java type corresponding to the specified JDBC type.
-	 * @see java.sql.Types
-	 */
-	public static JavaType javaTypeForJDBCTypeNamed(String jdbcTypeName) {
-		JDBCToJavaTypeMapping mapping = jdbcToJavaTypeMapping(jdbcTypeName);
-		return (mapping == null) ? DEFAULT_JAVA_TYPE : mapping.getJavaType();
-	}
-
-	/**
-	 * Returns the Java type corresponding to the specified JDBC type.
-	 * @see java.sql.Types
-	 */
-	public static JavaType javaTypeFor(JDBCType jdbcType) {
-		return javaTypeForJDBCTypeNamed(jdbcType.name());
-	}
-
-	/**
-	 * Returns the Java type corresponding to the specified JDBC type.
-	 * @see java.sql.Types
-	 */
-	public static JavaType javaTypeForJDBCTypeCode(int jdbcTypeCode) {
-		return javaTypeFor(JDBCType.type(jdbcTypeCode));
-	}
-
-
-	// ********** internal stuff **********
-
-
-	// ********** JDBC => Java **********
-
-	/**
-	 * JDBC => Java type mappings, keyed by JDBC type name (e.g. "VARCHAR")
-	 */
-	private static HashMap<String, JDBCToJavaTypeMapping> JDBC_TO_JAVA_TYPE_MAPPINGS;  // pseudo 'final' - lazy-initialized
-	private static final JavaType DEFAULT_JAVA_TYPE = new SimpleJavaType(java.lang.Object.class);  // TODO Object is the default?
-
-
-	private static JDBCToJavaTypeMapping jdbcToJavaTypeMapping(String jdbcTypeName) {
-		return jdbcToJavaTypeMappings().get(jdbcTypeName);
-	}
-
-	private static synchronized HashMap<String, JDBCToJavaTypeMapping> jdbcToJavaTypeMappings() {
-		if (JDBC_TO_JAVA_TYPE_MAPPINGS == null) {
-			JDBC_TO_JAVA_TYPE_MAPPINGS = buildJDBCToJavaTypeMappings();
-		}
-		return JDBC_TO_JAVA_TYPE_MAPPINGS;
-	}
-
-	private static HashMap<String, JDBCToJavaTypeMapping> buildJDBCToJavaTypeMappings() {
-		HashMap<String, JDBCToJavaTypeMapping> mappings = new HashMap<String, JDBCToJavaTypeMapping>();
-		addJDBCToJavaTypeMappingsTo(mappings);
-		return mappings;
-	}
-
-	/**
-	 * hard code the default mappings from the JDBC types to the
-	 * appropriate Java types
-	 * @see java.sql.Types
-	 * see "JDBC 3.0 Specification" Appendix B
-	 */
-	private static void addJDBCToJavaTypeMappingsTo(HashMap<String, JDBCToJavaTypeMapping> mappings) {
-		addJDBCToJavaTypeMappingTo(Types.ARRAY, java.sql.Array.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.BIGINT, long.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.BINARY, byte[].class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.BIT, boolean.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.BLOB, java.sql.Blob.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.BOOLEAN, boolean.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.CHAR, java.lang.String.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.CLOB, java.sql.Clob.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.DATALINK, java.net.URL.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.DATE, java.sql.Date.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.DECIMAL, java.math.BigDecimal.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.DISTINCT, java.lang.Object.class, mappings);  // ???
-		addJDBCToJavaTypeMappingTo(Types.DOUBLE, double.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.FLOAT, double.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.INTEGER, int.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.JAVA_OBJECT, java.lang.Object.class, mappings);  // ???
-		addJDBCToJavaTypeMappingTo(Types.LONGVARBINARY, byte[].class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.LONGVARCHAR, java.lang.String.class, mappings);
-		// not sure why this is defined in java.sql.Types
-//		addJDBCToJavaTypeMappingTo(Types.NULL, java.lang.Object.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.NUMERIC, java.math.BigDecimal.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.OTHER, java.lang.Object.class, mappings);	// ???
-		addJDBCToJavaTypeMappingTo(Types.REAL, float.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.REF, java.sql.Ref.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.SMALLINT, short.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.STRUCT, java.sql.Struct.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.TIME, java.sql.Time.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.TIMESTAMP, java.sql.Timestamp.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.TINYINT, byte.class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.VARBINARY, byte[].class, mappings);
-		addJDBCToJavaTypeMappingTo(Types.VARCHAR, java.lang.String.class, mappings);
-	}
-
-	private static void addJDBCToJavaTypeMappingTo(int jdbcTypeCode, Class<?> javaClass, HashMap<String, JDBCToJavaTypeMapping> mappings) {
-		// check for duplicates
-		JDBCType jdbcType = JDBCType.type(jdbcTypeCode);
-		Object prev = mappings.put(jdbcType.name(), buildJDBCToJavaTypeMapping(jdbcType, javaClass));
-		if (prev != null) {
-			throw new IllegalArgumentException("duplicate JDBC type: " + jdbcType.name());
-		}
-	}
-
-	private static JDBCToJavaTypeMapping buildJDBCToJavaTypeMapping(JDBCType jdbcType, Class<?> javaClass) {
-		return new JDBCToJavaTypeMapping(jdbcType, new SimpleJavaType(javaClass));
-	}
-
-
-	// ********** Java => JDBC **********
-
-	/**
-	 * Java => JDBC type mappings, keyed by Java class name (e.g. "java.lang.Object")
-	 */
-	private static HashMap<String, JavaToJDBCTypeMapping> JAVA_TO_JDBC_TYPE_MAPPINGS;  // pseudo 'final' - lazy-initialized
-	private static final JDBCType DEFAULT_JDBC_TYPE = JDBCType.type(Types.VARCHAR);  // TODO VARCHAR is the default?
-
-
-	private static JavaToJDBCTypeMapping javaToJDBCTypeMapping(String className) {
-		return javaToJDBCTypeMappings().get(className);
-	}
-
-	private static synchronized HashMap<String, JavaToJDBCTypeMapping> javaToJDBCTypeMappings() {
-		if (JAVA_TO_JDBC_TYPE_MAPPINGS == null) {
-			JAVA_TO_JDBC_TYPE_MAPPINGS = buildJavaToJDBCTypeMappings();
-		}
-		return JAVA_TO_JDBC_TYPE_MAPPINGS;
-	}
-
-	private static HashMap<String, JavaToJDBCTypeMapping> buildJavaToJDBCTypeMappings() {
-		HashMap<String, JavaToJDBCTypeMapping> mappings = new HashMap<String, JavaToJDBCTypeMapping>();
-		addJavaToJDBCTypeMappingsTo(mappings);
-		return mappings;
-	}
-
-	/**
-	 * hard code the default mappings from the Java types to the
-	 * appropriate JDBC types
-	 * @see java.sql.Types
-	 * see "JDBC 3.0 Specification" Appendix B
-	 */
-	private static void addJavaToJDBCTypeMappingsTo(HashMap<String, JavaToJDBCTypeMapping> mappings) {
-		// primitives
-		addJavaToJDBCTypeMappingTo(boolean.class, Types.BIT, mappings);
-		addJavaToJDBCTypeMappingTo(byte.class, Types.TINYINT, mappings);
-		addJavaToJDBCTypeMappingTo(double.class, Types.DOUBLE, mappings);
-		addJavaToJDBCTypeMappingTo(float.class, Types.REAL, mappings);
-		addJavaToJDBCTypeMappingTo(int.class, Types.INTEGER, mappings);
-		addJavaToJDBCTypeMappingTo(long.class, Types.BIGINT, mappings);
-		addJavaToJDBCTypeMappingTo(short.class, Types.SMALLINT, mappings);
-
-		// reference classes
-		addJavaToJDBCTypeMappingTo(java.lang.Boolean.class, Types.BIT, mappings);
-		addJavaToJDBCTypeMappingTo(java.lang.Byte.class, Types.TINYINT, mappings);
-		addJavaToJDBCTypeMappingTo(java.lang.Double.class, Types.DOUBLE, mappings);
-		addJavaToJDBCTypeMappingTo(java.lang.Float.class, Types.REAL, mappings);
-		addJavaToJDBCTypeMappingTo(java.lang.Integer.class, Types.INTEGER, mappings);
-		addJavaToJDBCTypeMappingTo(java.lang.Long.class, Types.BIGINT, mappings);
-		addJavaToJDBCTypeMappingTo(java.lang.Short.class, Types.SMALLINT, mappings);
-		addJavaToJDBCTypeMappingTo(java.lang.String.class, Types.VARCHAR, mappings);
-		addJavaToJDBCTypeMappingTo(java.math.BigDecimal.class, Types.NUMERIC, mappings);
-		addJavaToJDBCTypeMappingTo(java.net.URL.class, Types.DATALINK, mappings);
-		addJavaToJDBCTypeMappingTo(java.sql.Array.class, Types.ARRAY, mappings);
-		addJavaToJDBCTypeMappingTo(java.sql.Blob.class, Types.BLOB, mappings);
-		addJavaToJDBCTypeMappingTo(java.sql.Clob.class, Types.CLOB, mappings);
-		addJavaToJDBCTypeMappingTo(java.sql.Date.class, Types.DATE, mappings);
-		addJavaToJDBCTypeMappingTo(java.sql.Ref.class, Types.REF, mappings);
-		addJavaToJDBCTypeMappingTo(java.sql.Struct.class, Types.STRUCT, mappings);
-		addJavaToJDBCTypeMappingTo(java.sql.Time.class, Types.TIME, mappings);
-		addJavaToJDBCTypeMappingTo(java.sql.Timestamp.class, Types.TIMESTAMP, mappings);
-
-		// arrays
-		addJavaToJDBCTypeMappingTo(byte[].class, Types.VARBINARY, mappings);
-		addJavaToJDBCTypeMappingTo(java.lang.Byte[].class, Types.VARBINARY, mappings);
-	}
-
-	private static void addJavaToJDBCTypeMappingTo(Class<?> javaClass, int jdbcTypeCode, HashMap<String, JavaToJDBCTypeMapping> mappings) {
-		// check for duplicates
-		Object prev = mappings.put(javaClass.getName(), buildJavaToJDBCTypeMapping(javaClass, jdbcTypeCode));
-		if (prev != null) {
-			throw new IllegalArgumentException("duplicate Java class: " + ((JavaToJDBCTypeMapping) prev).getJavaType().declaration());
-		}
-	}
-
-	private static JavaToJDBCTypeMapping buildJavaToJDBCTypeMapping(Class<?> javaClass, int jdbcTypeCode) {
-		return new JavaToJDBCTypeMapping(new SimpleJavaType(javaClass), JDBCType.type(jdbcTypeCode));
-	}
-
-
-	// ********** constructor **********
-
-	/**
-	 * Suppress default constructor, ensuring non-instantiability.
-	 */
-	private JDBCTools() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-
-
-	// ********** member classes **********
-
-	/**
-	 * JDBC => Java
-	 */
-	static class JDBCToJavaTypeMapping {
-		private final JDBCType jdbcType;
-		private final JavaType javaType;
-
-		JDBCToJavaTypeMapping(JDBCType jdbcType, JavaType javaType) {
-			super();
-			this.jdbcType = jdbcType;
-			this.javaType = javaType;
-		}
-
-		public JDBCType getJDBCType() {
-			return this.jdbcType;
-		}
-
-		public JavaType getJavaType() {
-			return this.javaType;
-		}
-
-		public boolean maps(int jdbcTypeCode) {
-			return this.jdbcType.code() == jdbcTypeCode;
-		}
-
-		public boolean maps(String jdbcTypeName) {
-			return this.jdbcType.name().equals(jdbcTypeName);
-		}
-
-		public boolean maps(JDBCType type) {
-			return this.jdbcType == type;
-		}
-
-		@Override
-		public String toString() {
-			StringBuilder sb = new StringBuilder();
-			this.appendTo(sb);
-			return sb.toString();
-		}
-
-		public void appendTo(StringBuilder sb) {
-			this.jdbcType.appendTo(sb);
-			sb.append(" => ");
-			this.javaType.appendDeclarationTo(sb);
-		}
-
-	}
-
-	/**
-	 * Java => JDBC
-	 */
-	static class JavaToJDBCTypeMapping {
-		private final JavaType javaType;
-		private final JDBCType jdbcType;
-
-		JavaToJDBCTypeMapping(JavaType javaType, JDBCType jdbcType) {
-			super();
-			this.javaType = javaType;
-			this.jdbcType = jdbcType;
-		}
-
-		public JavaType getJavaType() {
-			return this.javaType;
-		}
-
-		public JDBCType getJDBCType() {
-			return this.jdbcType;
-		}
-
-		public boolean maps(JavaType jt) {
-			return this.javaType.equals(jt);
-		}
-
-		public boolean maps(String elementTypeName, int arrayDepth) {
-			return this.javaType.equals(elementTypeName, arrayDepth);
-		}
-
-		public boolean maps(String javaClassName) {
-			return this.javaType.describes(javaClassName);
-		}
-
-		public boolean maps(Class<?> javaClass) {
-			return this.javaType.describes(javaClass);
-		}
-
-		@Override
-		public String toString() {
-			StringBuilder sb = new StringBuilder();
-			this.appendTo(sb);
-			return sb.toString();
-		}
-
-		public void appendTo(StringBuilder sb) {
-			this.javaType.appendDeclarationTo(sb);
-			sb.append(" => ");
-			this.jdbcType.appendTo(sb);
-		}
-
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/JDBCType.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/JDBCType.java
deleted file mode 100644
index bf0f99e..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/JDBCType.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-import java.lang.reflect.Field;
-import java.sql.Types;
-
-/**
- * Associate the Java constant and the JDBC type name.
- * These are derived from java.sql.Types.
- *
- * @see java.sql.Types
- */
-@SuppressWarnings("nls")
-public final class JDBCType
-	implements Cloneable, Serializable
-{
-
-	/**
-	 * the constant name (e.g. VARCHAR)
-	 */
-	private final String name;
-
-	/**
-	 * the JDBC code used by JDBC drivers
-	 */
-	private final int code;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct a JDBC type with the specified name and type code.
-	 * This is private because all the possible JDBC types are built and
-	 * stored in the static array TYPES.
-	 * @see #types()
-	 */
-	private JDBCType(String name, int code) {
-		super();
-		this.name = name;
-		this.code = code;
-	}
-
-
-	// ********** accessors **********
-
-	/**
-	 * Returns the name of the type, as defined in java.sql.Types.
-	 */
-	public String name() {
-		return this.name;
-	}
-
-
-	/**
-	 * Returns the type code, as defined in java.sql.Types.
-	 */
-	public int code() {
-		return this.code;
-	}
-
-
-	// ********** printing and displaying **********
-
-	public void appendTo(StringBuilder sb) {
-		sb.append(this.name);
-	}
-
-	@Override
-	public String toString() {
-		StringBuilder sb = new StringBuilder();
-		sb.append(this.getClass().getSimpleName());
-		sb.append('(');
-		this.appendTo(sb);
-		sb.append(')');
-		return sb.toString();
-	}
-
-	@Override
-	public JDBCType clone() {
-		try {
-			return (JDBCType) super.clone();
-		} catch (CloneNotSupportedException ex) {
-			throw new InternalError();
-		}
-	}
-
-
-	// ********** static stuff **********
-
-	/**
-	 * all the JDBC type defined in java.sql.Types
-	 */
-	private static JDBCType[] TYPES;		// pseudo 'final' - lazy-initialized
-
-
-	public synchronized static JDBCType[] types() {
-		if (TYPES == null) {
-			TYPES = buildTypes();
-		}
-		return TYPES;
-	}
-
-	/**
-	 * Returns the JDBC type for the specified type code (e.g. Types.VARCHAR).
-	 * @see java.sql.Types
-	 */
-	public static JDBCType type(int code) {
-		JDBCType[] types = types();
-		for (int i = types.length; i-- > 0; ) {
-			if (types[i].code() == code) {
-				return types[i];
-			}
-		}
-		throw new IllegalArgumentException("invalid JDBC type code: " + code);
-	}
-
-	/**
-	 * Returns the JDBC type for the specified type name (e.g. "VARCHAR").
-	 * @see java.sql.Types
-	 */
-	public static JDBCType type(String name) {
-		JDBCType[] types = types();
-		for (int i = types.length; i-- > 0; ) {
-			if (types[i].name().equals(name)) {
-				return types[i];
-			}
-		}
-		throw new IllegalArgumentException("invalid JDBC type name: " + name);
-	}
-
-	/**
-	 * build up the JDBC types via reflection
-	 * @see java.sql.Types
-	 */
-	private static JDBCType[] buildTypes() {
-		Field[] fields = Types.class.getDeclaredFields();
-		int len = fields.length;
-		JDBCType[] types = new JDBCType[len];
-		for (int i = len; i-- > 0; ) {
-			String name = fields[i].getName();
-			int code;
-			try {
-				code = ((Integer) fields[i].get(null)).intValue();
-			} catch (IllegalAccessException ex) {
-				throw new RuntimeException(ex);	// shouldn't happen...
-			}
-			types[i] = new JDBCType(name, code);
-		}
-		return types;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/JarManifestInterrogator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/JarManifestInterrogator.java
new file mode 100644
index 0000000..aec45e5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/JarManifestInterrogator.java
@@ -0,0 +1,255 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import org.eclipse.persistence.tools.utility.io.FileTools;
+
+/**
+ * This class parses most of the necessary information from a specified
+ * class's manifest.
+ * The manifest is built and stored in a file (<code>META_INF/MANIFEST.MF</code>)
+ * in the class's JAR during the build process.
+ * <p>
+ * Users of this class must provide a Java class from which
+ * the JAR file is determined. They also must provide an implementation of
+ * {@link Defaults} for when the JAR and/or the manifest cannot be resolved.
+ */
+@SuppressWarnings("nls")
+public class JarManifestInterrogator {
+	/**
+	 * Defaults for when the Java class is not found
+	 * within a JAR or the JAR has no manifest.
+	 */
+	private final Defaults defaults;
+
+	/**
+	 * This is determined from the specified Java class.
+	 * It will be <code>null</code> if the class is <em>not</em> in a JAR.
+	 */
+	private final String jarFileName;
+
+	/** Hold the manifest so we can get stuff from it as needed. */
+	private final Manifest manifest;
+
+
+	/** Names of attributes stored in the JAR file manifest. */
+	private static final Attributes.Name RELEASE_DESIGNATION = new Attributes.Name("Release-Designation");
+	private static final Attributes.Name LIBRARY_DESIGNATION = new Attributes.Name("Library-Designation");
+
+
+	/**
+	 * Construct a manifest interrogator for the specified class.
+	 * If the manifest is unavailable, use the specified defaults.
+	 */
+	public JarManifestInterrogator(Class<?> javaClass, Defaults defaults) {
+		super();
+		if (defaults == null) {
+			throw new NullPointerException();
+		}
+		this.defaults = defaults;
+		this.jarFileName = this.buildJarFileName(javaClass);
+		this.manifest = this.buildManifest();
+	}
+
+	/**
+	 * Return the "full" name of the specified Java class's JAR file,
+	 * either fully-qualified or with a path relative to the current
+	 * working directory; e.g. <code>"C:/orahome/toplink/jlib/toplinkmw.jar"</code>
+	 * or <code>"jlib/toplinkmw.jar"</code>.
+	 * Return <code>null</code> if the JAR cannot be determined.
+	 */
+	protected String buildJarFileName(Class<?> javaClass) {
+		URL url = Classpath.convertToResource(javaClass);
+		if (url.getProtocol().equalsIgnoreCase("file")) { //$NON-NLS-1$
+			return null; // the class is NOT in a JAR
+		}
+
+		// if the class is in a JAR, the URL will look something like this:
+		// jar:file:/C:/jdk/1.4.2_04/jre/lib/rt.jar!/java/lang/String.class
+		File file;
+		try {
+			file = FileTools.buildFile(url);
+		} catch (URISyntaxException ex) {
+			throw new RuntimeException(ex);
+		}
+		return file.getAbsolutePath().substring(0, file.getAbsolutePath().indexOf('!'));
+	}
+
+	/**
+	 * Build and return the application's manifest.
+	 */
+	private Manifest buildManifest() {
+		JarFile jarFile = this.buildJarFile();
+		if (jarFile == null) {
+			// if there is no JAR file, use an empty manifest
+			return new Manifest();
+		}
+		try {
+			Manifest result = jarFile.getManifest();
+			if (result == null) {
+				// if there is no manifest in the JAR, use an empty manifest
+				return new Manifest();
+			}
+			return result;
+		} catch (IOException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+	/**
+	 * Build and return the application's JAR file. If the JAR file cannot
+	 * be determined, return <code>null</code>.
+	 */
+	private JarFile buildJarFile() {
+		if (this.jarFileName == null) {
+			return null;
+		}
+		try {
+			return new JarFile(this.jarFileName);
+		} catch (IOException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+	/**
+	 * Return the value of the specified attribute.
+	 * Return <code>null</code> if the attribute is not found or empty.
+	 */
+	public String getMainAttributeValue(Attributes.Name name) {
+		return this.getMainAttributeValue(name, null);
+	}
+
+	/**
+	 * Return the value of the specified attribute.
+	 * Return the specified default value if the attribute
+	 * is not found or empty.
+	 */
+	public String getMainAttributeValue(Attributes.Name name, String defaultValue) {
+		String result = this.manifest.getMainAttributes().getValue(name);
+		return (StringTools.isNotBlank(result)) ? result : defaultValue;
+	}
+
+	/**
+	 * Return <code>false</code> if the application is being executed from a
+	 * JAR file.
+	 */
+	public boolean isDevelopmentMode() {
+		return this.jarFileName == null;
+	}
+
+	/**
+	 * Concatenate the Specification Title and
+	 * the Library Designation, as derived from the JAR file manifest.
+	 */
+	public String getFullProductName() {
+		return this.getSpecificationVendor() + ' ' + this.getProductName() + ' ' + this.getShortProductName();
+	}
+
+	/**
+	 * Return the Specification Title, as derived from the JAR file manifest.
+	 */
+	public String getProductName() {
+		return this.getMainAttributeValue(Attributes.Name.SPECIFICATION_TITLE, this.defaults.defaultSpecificationTitle());
+	}
+
+	/**
+	 * Return the Specification Vendor, as derived from the JAR file manifest.
+	 */
+	public String getSpecificationVendor() {
+		return this.getMainAttributeValue(Attributes.Name.SPECIFICATION_VENDOR, this.defaults.defaultSpecificationVendor());
+	}
+
+	/**
+	 * Return the Library Designation, as derived from the JAR file manifest.
+	 */
+	public String getShortProductName() {
+		return this.getMainAttributeValue(LIBRARY_DESIGNATION, this.defaults.defaultLibraryDesignation());
+	}
+
+	/**
+	 * Return the Specification Version, as derived from the JAR file manifest.
+	 */
+	public String getVersionNumber() {
+		return this.getMainAttributeValue(Attributes.Name.SPECIFICATION_VERSION, this.defaults.defaultSpecificationVersion());
+	}
+
+	/**
+	 * Strip the build number off the end of the Implementation Version.
+	 */
+	public String getBuildNumber() {
+		if (this.isDevelopmentMode()) {
+			return "<dev>";
+		}
+		String specVersion = this.getVersionNumber();
+		String impVersion = this.getMainAttributeValue(Attributes.Name.IMPLEMENTATION_VERSION, this.defaults.defaultImplementationVersion());
+		return impVersion.substring(specVersion.length() + 1);
+	}
+
+	/**
+	 * Return the Release Designation, as derived from the JAR file manifest.
+	 */
+	public String getReleaseDesignation() {
+		return this.getMainAttributeValue(RELEASE_DESIGNATION, this.defaults.defaultReleaseDesignation());
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.jarFileName);
+	}
+
+	// ********** Defaults interface **********
+
+	/**
+	 * Clients of {@link JarManifestInterrogator} must provide an implementation of this
+	 * interface.
+	 */
+	public interface Defaults {
+		/**
+		 * Return the default to be used when a manifest is unavailable.
+		 */
+		String defaultSpecificationTitle();
+
+		/**
+		 * Return the default to be used when a manifest is unavailable.
+		 */
+		String defaultSpecificationVendor();
+
+		/**
+		 * Return the default to be used when a manifest is unavailable.
+		 */
+		String defaultReleaseDesignation();
+
+		/**
+		 * Return the default to be used when a manifest is unavailable.
+		 */
+		String defaultLibraryDesignation();
+
+		/**
+		 * Return the default to be used when a manifest is unavailable.
+		 */
+		String defaultSpecificationVersion();
+
+		/**
+		 * Return the default to be used when a manifest is unavailable.
+		 */
+		String defaultImplementationVersion();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/JavaType.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/JavaType.java
index 3ad551a..1baaf5c 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/JavaType.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/JavaType.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -16,95 +16,46 @@
 import java.io.PrintWriter;
 
 /**
- * This interface describes a Java type; i.e. its "element type" and its "array depth". The element
- * type is referenced by name, allowing us to reference classes that are not (or cannot be) loaded.
+ * This interface describes a Java type; i.e. its "element type"
+ * and its "array depth". The element type is referenced by name,
+ * allowing us to reference classes that are not (or cannot be) loaded.
  * <p>
- * 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.
+ * 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.
  * <p>
  * This interface is not intended to be implemented by clients.
- *
- * @version 2.5
  */
 public interface JavaType {
 
 	/**
-	 * Appends the version of the type's name that can be used in source code:<ul>
-	 * <li><code>"[[J"</code> => <code>"long[][]"</code>
-	 * <li><code>"java.util.Map$Entry"</code> => <code>"java.util.Map.Entry"</code>
-	 * </ul>
-	 */
-	void appendDeclarationTo(StringBuilder sb);
-
-	/**
-	 * Returns the version of the type's name that can be used in source code:<ul>
-	 * <li><code>"[[J"</code> => <code>"long[][]"</code>
-	 * <li><code>"java.util.Map$Entry"</code> => <code>"java.util.Map.Entry"</code>
-	 * </ul>
-	 */
-	String declaration();
-
-	/**
-	 * Returns whether the type describes to the specified type.
-	 */
-	boolean describes(Class<?> javaClass);
-
-	/**
-	 * Returns whether the type describes to the specified type.
-	 */
-	boolean describes(String className);
-
-	/**
-	 * Returns whether the type is equal to the specified type.
-	 */
-	boolean equals(JavaType other);
-
-	/**
-	 * Returns whether the type is equal to the specified type.
-	 */
-	boolean equals(String otherElementTypeName, int otherArrayDepth);
-
-	/**
-	 * Returns the type's "array depth".
-	 */
-	int getArrayDepth();
-
-	/**
-	 * Returns the name of the type's "element type".
+	 * Return the name of the type's "element type".
 	 * A member type will have one or more <code>'$'</code> characters in its name.
 	 */
 	String getElementTypeName();
 
 	/**
-	 * Returns the class corresponding to the type's element type and array depth.
+	 * Return the type's "array depth".
 	 */
-	Class<?> getJavaClass() throws ClassNotFoundException;
+	int getArrayDepth();
 
 	/**
-	 * Returns the version of the type's name that matches that
-	 * returned by {@link java.lang.Class#getName()}
-	 * (e.g. <code>"[[J"</code>, <code>"[Ljava.lang.Object;"</code>,
-	 * <code>"java.util.Map$Entry"</code>).
-	 */
-	String getJavaClassName();
-
-	/**
-	 * Returns whether the type is an array (i.e. its "array depth" is greater
-	 * than zero).
+	 * Return whether the type is an array (i.e. its {@link #getArrayDepth()
+	 * "array depth"} is greater than zero).
 	 */
 	boolean isArray();
 
 	/**
-	 * Returns whether the type is a "primitive" (e.g. <code>int</code>, <code>float</code>).
+	 * Return whether the type is a "primitive" (e.g. <code>int</code>, <code>float</code>).
 	 * <p>
 	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
 	 */
 	boolean isPrimitive();
 
 	/**
-	 * Returns whether the type is a "primitive wrapper" (e.g. {@link java.lang.Integer},
+	 * Return whether the type is a "primitive wrapper" (e.g. {@link java.lang.Integer},
 	 * {@link java.lang.Float}).
 	 * <p>
 	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
@@ -112,7 +63,7 @@
 	boolean isPrimitiveWrapper();
 
 	/**
-	 * Returns whether the type is a "variable primitive" (e.g. <code>int</code>, <code>float</code>,
+	 * Return whether the type is a "variable primitive" (e.g. <code>int</code>, <code>float</code>,
 	 * but not <code>void</code>).
 	 * <p>
 	 * <strong>NB:</strong> variables cannot be declared <code>void</code>
@@ -120,7 +71,7 @@
 	boolean isVariablePrimitive();
 
 	/**
-	 * Returns whether the type is a "variable primitive wrapper" (e.g.
+	 * Return whether the type is a "variable primitive wrapper" (e.g.
 	 * {@link java.lang.Integer}, {@link java.lang.Float},
 	 * but not {@link java.lang.Void}).
 	 * <p>
@@ -129,6 +80,55 @@
 	boolean isVariablePrimitiveWrapper();
 
 	/**
+	 * Return the class corresponding to the type's element type and array depth.
+	 */
+	Class<?> getJavaClass() throws ClassNotFoundException;
+
+	/**
+	 * Return the version of the type's name that matches that
+	 * returned by {@link java.lang.Class#getName()}
+	 * (e.g. <code>"[[J"</code>, <code>"[Ljava.lang.Object;"</code>,
+	 * <code>"java.util.Map$Entry"</code>).
+	 */
+	String getJavaClassName();
+
+	/**
+	 * Return whether the type is equal to the specified type.
+	 */
+	boolean equals(String otherElementTypeName, int otherArrayDepth);
+
+	/**
+	 * Return whether the type describes to the specified type.
+	 */
+	boolean describes(String className);
+
+	/**
+	 * Return whether the type describes to the specified type.
+	 */
+	boolean describes(Class<?> javaClass);
+
+	/**
+	 * Return whether the type is equal to the specified type.
+	 */
+	boolean equals(JavaType other);
+
+	/**
+	 * Return the version of the type's name that can be used in source code:<ul>
+	 * <li><code>"[[J"</code> => <code>"long[][]"</code>
+	 * <li><code>"java.util.Map$Entry"</code> => <code>"java.util.Map.Entry"</code>
+	 * </ul>
+	 */
+	String declaration();
+
+	/**
+	 * Append the version of the type's name that can be used in source code:<ul>
+	 * <li><code>"[[J"</code> => <code>"long[][]"</code>
+	 * <li><code>"java.util.Map$Entry"</code> => <code>"java.util.Map.Entry"</code>
+	 * </ul>
+	 */
+	void appendDeclarationTo(StringBuilder sb);
+
+	/**
 	 * Print the version of the type's name that can be used in source code:<ul>
 	 * <li><code>"[[J"</code> => <code>"long[][]"</code>
 	 * <li><code>"java.util.Map$Entry"</code> => <code>"java.util.Map.Entry"</code>
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/KeyedSet.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/KeyedSet.java
deleted file mode 100644
index ddd6111..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/KeyedSet.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*******************************************************************************
- *  Copyright (c) 2010  Oracle and/or its affiliates. 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.persistence.tools.utility;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * This class maintains a {@link Set} of items, and a {@link Map} of keys to those items.
- * An item may have multiple keys, but an item may have no keys and remain in the set.  Once an 
- * item's last key is removed, the item is also removed.
- */
-public class KeyedSet<K, V> {
-	
-	private final Set<V> itemSet;
-	private final Set<V> unmodifiableItemSet;
-	private final Map<K,V> map;
-	
-	
-	public KeyedSet() {
-		this.itemSet = new HashSet<V>();
-		this.unmodifiableItemSet = Collections.unmodifiableSet(this.itemSet);
-		this.map = new HashMap<K,V>();
-	}
-	
-	/**
-	 * Returns an unmodifiable representation of the set of items.
-	 */
-	public Set<V> getItemSet() {
-		return this.unmodifiableItemSet;
-	}
-	
-	/**
-	 * Returns the item stored under the given key.
-	 */
-	public V getItem(K key) {
-		return this.map.get(key);
-	}
-	
-	/**
-	 * Returns whether an item is stored under the given key.
-	 */
-	public boolean containsKey(K key) {
-		return this.map.containsKey(key);
-	}
-	
-	/**
-	 * Returns whether the item is stored under *any* key.
-	 */
-	public boolean containsItem(V item) {
-		return this.itemSet.contains(item);
-	}
-	
-	/**
-	 * Add an item to be stored under the given key.  
-	 * The item must not already be stored.
-	 */
-	public void addItem(K key, V item) {
-		addItem(item);
-		addKey(key, item);
-	}
-	
-	private void addItem(V item) {
-		if (item == null) {
-			throw new IllegalArgumentException();
-		}
-		this.itemSet.add(item);
-	}
-	
-	/** 
-	 * Add an additional key to an item already stored under an alternate key.
-	 */
-	public void addKey(K key, V item) {
-		if (key == null || item == null) {
-			throw new IllegalArgumentException();
-		}
-		if (! this.itemSet.contains(item)) {
-			throw new IllegalArgumentException();
-		}
-		this.map.put(key, item);
-	}
-	
-	/**
-	 * Remove the given item and remove any key-to-item mapping it may have.
-	 */
-	public boolean removeItem(V item) {
-		if (this.itemSet.remove(item)) {
-			for (Map.Entry<K,V> entry : CollectionTools.collection(this.map.entrySet())) {
-				if (entry.getValue() == item) {
-					map.remove(entry.getKey());
-				}
-			}
-			return true;
-		}
-		return false;
-	}
-	
-	/**
-	 * Remove the key-to-item mapping for the given key.
-	 * If it is the last key to the item, also remove the item.
-	 */
-	public boolean removeKey(K key) {
-		final V item = this.map.get(key);
-		if (item != null) {
-			this.map.remove(key);
-			boolean otherKey = false;
-			for (Map.Entry<K,V> entry : CollectionTools.collection(this.map.entrySet())) {
-				if (otherKey | entry.getValue() == item) {
-					otherKey = true;
-				}
-			}
-			if (! otherKey) {
-				removeItem(item);
-			}
-			return true;
-		}
-		return false;
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/LazyObjectReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/LazyObjectReference.java
deleted file mode 100644
index 6c7623c..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/LazyObjectReference.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * Provide a thread-safe, reasonably performing container for holding an
- * object that will be "lazy-initialized" upon its first reference. This is
- * also useful for preventing direct references (accidental or otherwise) to
- * lazy-initialized state.
- * <p>
- * There are some penalties:<ul>
- * <li>The reference's use of generics will require casting (and the requisite
- *     VM testing) with every access
- * <li>If the value calculated during lazy initialization is <code>null</code>,
- *     access will be <code>synchronized</code> <em>every</em> time.
- * </ul>
- * @see SimpleObjectReference
- * @see SynchronizedObject
- */
-public abstract class LazyObjectReference<V>
-	implements ObjectReference<V>, Cloneable, Serializable
-{
-	/** Backing value. */
-	private volatile V value = null;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Create a lazy object reference.
-	 */
-	protected LazyObjectReference() {
-		super();
-	}
-
-
-	// ********** value **********
-
-	/**
-	 * In JDK 5 and later, this "double-checked locking" idiom works as long
-	 * as the instance variable is marked <code>volatile</code>.
-	 */
-	@Override
-	public V getValue() {
-		V result = this.value;
-		if (result == null) {
-			synchronized (this) {
-				result = this.value;
-				if (result == null) {
-					this.value = result = this.buildValue();
-				}
-			}
-		}
-		return result;
-	}
-
-	protected abstract V buildValue();
-
-	@Override
-	public boolean valueEquals(Object object) {
-		return Tools.valuesAreEqual(this.getValue(), object);
-	}
-
-	@Override
-	public boolean valueNotEqual(Object object) {
-		return Tools.valuesAreDifferent(this.getValue(), object);
-	}
-
-	@Override
-	public boolean isNull() {
-		return this.getValue() == null;
-	}
-
-	@Override
-	public boolean isNotNull() {
-		return this.getValue() != null;
-	}
-
-
-	// ********** standard methods **********
-
-	@Override
-	public LazyObjectReference<V> clone() {
-		try {
-			@SuppressWarnings("unchecked")
-			LazyObjectReference<V> clone = (LazyObjectReference<V>) super.clone();
-			return clone;
-		} catch (CloneNotSupportedException ex) {
-			throw new InternalError();
-		}
-	}
-
-	/**
-	 * This method will <em>not</em> trigger the "lazy-initialization".
-	 */
-	@Override
-	public String toString() {
-		return '[' + String.valueOf(this.value) + ']';
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ListenerList.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ListenerList.java
index a56fbac..4d8175d 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ListenerList.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ListenerList.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -19,8 +19,7 @@
 import java.io.Serializable;
 import java.lang.reflect.Array;
 import java.util.Arrays;
-
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
 
 /**
  * Maintain a thread-safe list of listeners that does not allow adding
@@ -40,6 +39,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	/**
 	 * Construct a listener list for listeners of the specified type.
 	 */
@@ -67,21 +67,21 @@
 	}
 
 	/**
-	 * Returns the listeners.
+	 * Return the listeners.
 	 */
 	public Iterable<L> getListeners() {
 		return new ArrayIterable<L>(this.listeners);
 	}
 
 	/**
-	 * Returns the number of listeners.
+	 * Return the number of listeners.
 	 */
 	public int size() {
 		return this.listeners.length;
 	}
 
 	/**
-	 * Returns whether the listener list has no listeners.
+	 * Return whether the listener list has no listeners.
 	 */
 	public boolean isEmpty() {
 		return this.listeners.length == 0;
@@ -124,7 +124,7 @@
 	}
 
 	/**
-	 * Returns the type of listeners held by the listener list.
+	 * Return the type of listeners held by the listener list.
 	 */
 	@SuppressWarnings("unchecked")
 	public Class<L> getListenerType() {
@@ -172,4 +172,4 @@
 			this.listeners = ArrayTools.add(this.listeners, (L) o);
 		}
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/MethodSignature.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/MethodSignature.java
index 4dd8a7c..c00c6b8 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/MethodSignature.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/MethodSignature.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -17,60 +17,59 @@
 import java.lang.reflect.Method;
 
 /**
- * This interface describes a Java method signature; i.e. its "name" and its "parameter types". The
- * parameter types are referenced by name, allowing us to reference classes that are not (or cannot
- * be) loaded.
+ * This interface describes a Java method signature; i.e. its "name"
+ * and its "parameter types". The parameter types are referenced by name,
+ * allowing us to reference classes that are not (or cannot be) loaded.
  * <p>
- * 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.
+ * 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.
  * <p>
  * This interface is not intended to be implemented by clients.
- *
- * @version 2.5
  */
 public interface MethodSignature {
 
 	/**
-	 * Appends a string representation of the method's signature:<p>
-	 * <code>"foo(int, java.lang.String)"</code>
-	 */
-	void appendSignatureTo(StringBuilder sb);
-
-	/**
-	 * Returns whether the method signature describes the specified method.
-	 */
-	boolean describes(Method method);
-
-	/**
-	 * Returns whether the method signature equals the specified signature.
-	 */
-	boolean equals(MethodSignature other);
-
-	/**
-	 * Returns whether the method signature equals the specified signature.
-	 */
-	boolean equals(String otherName, JavaType[] otherParameterTypes);
-
-	/**
-	 * Returns the method's name.
+	 * Return the method's name.
 	 */
 	String getName();
 
 	/**
-	 * Returns the method's parameter types.
+	 * Return the method's parameter types.
 	 */
 	JavaType[] getParameterTypes();
 
 	/**
-	 * Returns a string representation of the method's signature:<p>
+	 * Return whether the method signature describes the specified method.
+	 */
+	boolean describes(Method method);
+
+	/**
+	 * Return whether the method signature equals the specified signature.
+	 */
+	boolean equals(String otherName, JavaType[] otherParameterTypes);
+
+	/**
+	 * Return whether the method signature equals the specified signature.
+	 */
+	boolean equals(MethodSignature other);
+
+	/**
+	 * Return a string representation of the method's signature:<p>
 	 * <code>"foo(int, java.lang.String)"</code>
 	 */
 	String getSignature();
 
 	/**
-	 * Prints a string representation of the method's signature:<p>
+	 * Append a string representation of the method's signature:<p>
+	 * <code>"foo(int, java.lang.String)"</code>
+	 */
+	void appendSignatureTo(StringBuilder sb);
+
+	/**
+	 * Print a string representation of the method's signature:<p>
 	 * <code>"foo(int, java.lang.String)"</code>
 	 */
 	void printSignatureOn(PrintWriter pw);
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ModifiableBooleanReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ModifiableBooleanReference.java
deleted file mode 100644
index d1bf883..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ModifiableBooleanReference.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-
-/**
- * Interface for a container for passing a flag that can be changed by the recipient.
- */
-public interface ModifiableBooleanReference extends BooleanReference {
-
-	/**
-	 * Set the <code>boolean</code> value to the NOT of its current value.
-	 * Returns the new value.
-	 */
-	boolean flip();
-
-	/**
-	 * Set the <code>boolean</code> value to <code>false</code>.
-	 * Returns the previous value.
-	 */
-	boolean setFalse();
-
-	/**
-	 * Set the <code>boolean</code> value to the NOT of the specified value.
-	 * Returns the previous value.
-	 */
-	boolean setNot(boolean v);
-
-	/**
-	 * Set the <code>boolean</code> value to <code>true</code>.
-	 * Returns the previous value.
-	 */
-	boolean setTrue();
-
-	/**
-	 * Set the <code>boolean</code> value.
-	 * Returns the previous value.
-	 */
-	boolean setValue(boolean value);
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ModifiableIntReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ModifiableIntReference.java
deleted file mode 100644
index 5975ee7..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ModifiableIntReference.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-/**
- * Interface for a container for passing an integer that can be changed by
- * the recipient.
- */
-public interface ModifiableIntReference extends IntReference {
-
-	/**
-	 * Returns the <code>int</code> value.
-	 */
-	int decrement();
-
-	/**
-	 * Returns the <code>int</code> value.
-	 */
-	int increment();
-
-	/**
-	 * Set the <code>int</code> value.
-	 * Returns the previous value.
-	 */
-	int setValue(int value);
-
-	/**
-	 * Set the <code>int</code> value to zero.
-	 * Returns the previous value.
-	 */
-	int setZero();
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ModifiableObjectReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ModifiableObjectReference.java
deleted file mode 100644
index c5da678..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ModifiableObjectReference.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-/**
- * Provide a container for passing an object that can be changed by the recipient.
- *
- * @version 2.5
- */
-public interface ModifiableObjectReference<V> extends ObjectReference<V> {
-
-	/**
-	 * Sets the value to <code>null</code>.
-	 * Returns the previous value.
-	 */
-	V setNull();
-
-	/**
-	 * Sets the value.
-	 * Returns the previous value.
-	 */
-	V setValue(V value);
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/MultiThreadedExceptionHandler.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/MultiThreadedExceptionHandler.java
new file mode 100644
index 0000000..9e47748
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/MultiThreadedExceptionHandler.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+import java.io.Serializable;
+
+/**
+ * Simple interface for allowing clients to pass an exception handler to a
+ * service (e.g. to log the exception). This is particularly helpful if the
+ * service executes on another, possibly inaccessible, thread.
+ * <p>
+ * 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 MultiThreadedExceptionHandler
+	extends ExceptionHandler
+{
+	/**
+	 * The specified exception was thrown while the specified thread was
+	 * executing. Handle it appropriately.
+	 */
+	void handleException(Thread thread, Throwable t);
+
+	/**
+	 * Singleton implementation of the multi-threaded exception handler
+	 * interface that does nothing with the exception.
+	 */
+	final class Null
+		implements MultiThreadedExceptionHandler, Serializable
+	{
+		public static final ExceptionHandler INSTANCE = new Null();
+		public static ExceptionHandler instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Null() {
+			super();
+		}
+		@Override
+		public void handleException(Thread thread, Throwable t) {
+			// do nothing
+		}
+		@Override
+		public void handleException(Throwable t) {
+			// do nothing
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+
+	/**
+	 * Singleton implementation of the multi-threaded exception handler
+	 * interface that wraps the exception in a runtime exception and
+	 * throws the runtime exception.
+	 */
+	final class Runtime
+		implements MultiThreadedExceptionHandler, Serializable
+	{
+		public static final ExceptionHandler INSTANCE = new Runtime();
+		public static ExceptionHandler instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Runtime() {
+			super();
+		}
+		@Override
+		public void handleException(Thread thread, Throwable t) {
+			this.handleException(t);
+		}
+		@Override
+		public void handleException(Throwable t) {
+			t.printStackTrace();
+			// re-throw the exception unchecked
+			if (t instanceof RuntimeException) {
+				throw (RuntimeException) t;
+			}
+			throw new RuntimeException(t);
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+
+	/**
+	 * Singleton implementation of the multi-threaded exception handler
+	 * interface that, like what happens with an unhandled exception
+	 * (see {@link ThreadGroup#uncaughtException(Thread, Throwable)}),
+	 * prints the exception's stack trace to {@link System#err the
+	 * "standard" error output stream}.
+	 */
+	final class Default
+		implements MultiThreadedExceptionHandler, Serializable
+	{
+		public static final ExceptionHandler INSTANCE = new Default();
+		public static ExceptionHandler instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Default() {
+			super();
+		}
+		@Override
+		public void handleException(Thread thread, Throwable t) {
+			this.handleException(t);
+		}
+		@Override
+		public void handleException(Throwable t) {
+			t.printStackTrace();
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/MultiThreadedExceptionHandlerAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/MultiThreadedExceptionHandlerAdapter.java
new file mode 100644
index 0000000..60be1e7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/MultiThreadedExceptionHandlerAdapter.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+/**
+ * Convenience exception handler that does nothing.
+ */
+public class MultiThreadedExceptionHandlerAdapter
+	extends ExceptionHandlerAdapter
+	implements MultiThreadedExceptionHandler
+{
+	@Override
+	public void handleException(Thread thread, Throwable t) {
+		// NOP
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NameTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NameTools.java
index 0257aeb..1463615 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NameTools.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NameTools.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -17,11 +17,8 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.SortedSet;
-import java.util.regex.Pattern;
-
-import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
 
 /**
  * Various helper methods for generating names.
@@ -29,54 +26,52 @@
 @SuppressWarnings("nls")
 public final class NameTools {
 
+	// ********** unique names **********
+
 	/**
-	 * Given a "root" name and a set of existing names, generate a unique
-	 * name that is either the "root" name or some variation on the "root"
-	 * name (e.g. "root2", "root3",...). The names are case-sensitive
-	 * (i.e. "Root" and "root" are both allowed).
+	 * @see #uniqueName(String, Collection)
 	 */
-	public static String uniqueNameFor(String rootName, Iterator<String> existingNames) {
-		return uniqueNameFor(rootName, CollectionTools.set(existingNames));
+	public static String uniqueName(String rootName, Iterable<String> existingNames) {
+		return uniqueName(rootName, CollectionTools.set(existingNames));
 	}
 
 	/**
 	 * Given a "root" name and a set of existing names, generate a unique
 	 * name that is either the "root" name or some variation on the "root"
-	 * name (e.g. "root2", "root3",...). The names are case-sensitive
-	 * (i.e. "Root" and "root" are both allowed).
+	 * name (e.g. <code>"root2"</code>, <code>"root3"</code>,...).
+	 * The names are case-sensitive (i.e. <code>"Root"</code> and
+	 * <code>"root"</code> are allowed to co-exist).
 	 */
-	public static String uniqueNameFor(String rootName, Collection<String> existingNames) {
-		return uniqueNameFor(rootName, existingNames, rootName);
+	public static String uniqueName(String rootName, Collection<String> existingNames) {
+		return uniqueName(rootName, existingNames, rootName);
+	}
+
+	/**
+	 * @see #uniqueNameIgnoreCase(String, Collection)
+	 */
+	public static String uniqueNameIgnoreCase(String rootName, Iterable<String> existingNames) {
+		return uniqueNameIgnoreCase(rootName, CollectionTools.set(existingNames));
 	}
 
 	/**
 	 * Given a "root" name and a set of existing names, generate a unique
 	 * name that is either the "root" name or some variation on the "root"
-	 * name (e.g. "root2", "root3",...). The names are NOT case-sensitive
-	 * (i.e. "Root" and "root" are NOT both allowed).
+	 * name (e.g. <code>"root2"</code>, <code>"root3"</code>,...).
+	 * The names are <em>not</em> case-sensitive (i.e. <code>"Root"</code> and
+	 * <code>"root"</code> are <em>not</em> both allowed).
 	 */
-	public static String uniqueNameForIgnoreCase(String rootName, Iterator<String> existingNames) {
-		return uniqueNameForIgnoreCase(rootName, CollectionTools.set(existingNames));
+	public static String uniqueNameIgnoreCase(String rootName, Collection<String> existingNames) {
+		return uniqueName(rootName, convertToLowerCase(existingNames), rootName.toLowerCase());
 	}
 
 	/**
-	 * Given a "root" name and a set of existing names, generate a unique
-	 * name that is either the "root" name or some variation on the "root"
-	 * name (e.g. "root2", "root3",...). The names are NOT case-sensitive
-	 * (i.e. "Root" and "root" are NOT both allowed).
-	 */
-	public static String uniqueNameForIgnoreCase(String rootName, Collection<String> existingNames) {
-		return uniqueNameFor(rootName, convertToLowerCase(existingNames), rootName.toLowerCase());
-	}
-
-	/**
-	 * use the suffixed "template" name to perform the comparisons, but RETURN
+	 * Use the suffixed "template" name to perform the comparisons, but <em>return</em>
 	 * the suffixed "root" name; this allows case-insensitive comparisons
 	 * (i.e. the "template" name has been morphed to the same case as
 	 * the "existing" names, while the "root" name has not, but the "root" name
-	 * is what the client wants morphed to be unique)
+	 * is what the client wants morphed to be unique).
 	 */
-	private static String uniqueNameFor(String rootName, Collection<String> existingNames, String templateName) {
+	private static String uniqueName(String rootName, Collection<String> existingNames, String templateName) {
 		if ( ! existingNames.contains(templateName)) {
 			return rootName;
 		}
@@ -100,44 +95,44 @@
 		return result;
 	}
 
-	/**
-	 * Build a fully-qualified name for the specified database object.
-	 * Variations:
-	 *     catalog.schema.name
-	 *     catalog..name
-	 *     schema.name
-	 *     name
-	 */
-	public static String buildQualifiedDatabaseObjectName(String catalog, String schema, String name) {
-		if (name == null) {
-			return null;
-		}
-		if ((catalog == null) && (schema == null)) {
-			return name;
-		}
 
+	// ********** qualified name **********
+
+	/**
+	 * Build a fully-qualified name for the specified name segments.
+	 * Typical database variations:<ul>
+	 * <li><code>catalog.schema.name</code>
+	 * <li><code>catalog..name</code>
+	 * <li><code>schema.name</code>
+	 * <li><code>name</code>
+	 * </ul>
+	 */
+	public static String buildQualifiedName(String... segments) {
 		StringBuilder sb = new StringBuilder(100);
-		if (catalog != null) {
-			sb.append(catalog);
-			sb.append('.');
+		boolean next = false;
+		for (String segment : segments) {
+			if (next) {
+				sb.append('.');
+			}
+			if (segment != null) {
+				next = true;
+				sb.append(segment);
+			}
 		}
-		if (schema != null) {
-			sb.append(schema);
-		}
-		sb.append('.');
-		sb.append(name);
 		return sb.toString();
 	}
 
-	/** regex used to replace characters in a database identifier that are invalid in java identifiers */
-	private static final Pattern DB_IDENTIFIER_EXCLUSIONS = Pattern.compile("[@$# .]");
-	
+
+	// ********** Java identifiers **********
+
 	/**
 	 * The set of reserved words in the Java programming language.
 	 * These words cannot be used as identifiers (i.e. names).
-	 * http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
+	 * <p>
+	 * <a href="http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html">
+	 * Java Language Keywords</a>
 	 */
-	public static final String[] JAVA_RESERVED_WORDS = new String[] {
+	private static final String[] JAVA_RESERVED_WORDS_ARRAY = new String[] {
 				"abstract",
 				"assert",  // jdk 1.4
 				"boolean",
@@ -196,157 +191,55 @@
 	/**
 	 * The set of reserved words in the Java programming language.
 	 * These words cannot be used as identifiers (i.e. names).
-	 * http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
+	 * <p>
+	 * <a href="http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html">
+	 * Java Language Keywords</a>
 	 */
-	public static final SortedSet<String> JAVA_RESERVED_WORDS_SET =
-		Collections.unmodifiableSortedSet(CollectionTools.sortedSet(JAVA_RESERVED_WORDS));
-	
-	/**
-	 * Generates a javabean compliant method name based on the provided
-	 * property name.  Does not alter the case of the property name if the
-	 * second character is capitalized, e.g.:
-	 * <ul>
-	 *    <li>javabeanMethodName("get", "URL", "") produces "getURL"
-	 *    <li>javabeanMethodName("get", "fName", "") produces "getfName"
-	 *    <li>javabeanMethodName("get", "fname", "") produces "getFname"
-	 *    <li>javabeanMethodName("get", "firstName", "") produces "getFirstName"
-	 * </ul>
-	 *
-	 * The "fName" example in particular may seem strange, but is required by
-	 * JDev ADF interpretation of the JavaBean naming conventions.
-	 * See bug #4572393.
-	 *
-	 * @param prefix - <code>String</code> representing the prefix for the
-	 *                 method name (for example, "get" to produce a getter
-	 *                 method).
-	 * @param propertyName - <code>String</code> representing the name of the
-	 *                 property for which an accessor name is being generated.
-	 * @param suffix - <code>String</code> representing the suffix for the
-	 *                 accessor being generated (for example, "Holder" for
-	 *                 ValueHolder accessors).
-	 */
-	public static String javabeanAccessorName(String prefix, String propertyName, String suffix) {
-		StringBuilder sb = new StringBuilder(propertyName.length() + 10);
-
-		sb.append(prefix);
-		if (propertyName.length() >=  2
-				&& Character.isUpperCase(propertyName.charAt(1)))
-		{
-			sb.append(propertyName);
-		}
-		else
-		{
-			StringTools.capitalizeOn(propertyName, sb);
-		}
-		sb.append(suffix);
-		return sb.toString();
-	}
-	
-	/**
-	 * Generates a Java identifier name based on the provided database name.
-	 * Camel-cases the Java identifier on _ characters and on characters that
-	 * are valid in DB identifiers but not Java identifiers (the @ symbol, for
-	 * example). Does not capitalize the first letter of the generated
-	 * identifier.
-	 *
-	 * @param databaseName - <code>String</code> representing the database
-	 * identifier that should be used to produce a Java identifier.
-	 */
-	public static String javaNameFromDatabaseName(String databaseName) {
-		return javaNameFromDatabaseName(databaseName, false);
-	}
+	public static final SortedSet<String> JAVA_RESERVED_WORDS =
+		Collections.unmodifiableSortedSet(CollectionTools.sortedSet(JAVA_RESERVED_WORDS_ARRAY));
 
 	/**
-	 * Generates a Java identifier name based on the provided database name.
-	 * Camel-cases the Java identifier on _ characters and on characters that are
-	 * valid in DB identifiers but not Java identifiers (the @ symbol, for
-	 * example).
-	 * @param databaseName - <code>String</code> representing the database
-	 * identifier that should be used to produce a Java identifier.
-	 *
-	 * @param capitalizeFirstLetter - <code>boolean</code> indicating whether
-	 * the first letter of the identifier should be capitalized.
-	 */
-	public static String javaNameFromDatabaseName(String databaseName, boolean capitalizeFirstLetter) {
-		return StringTools.convertAllCapsToCamelBack(normalizeJavaIdentifier(DB_IDENTIFIER_EXCLUSIONS.matcher(databaseName).replaceAll("_")),
-		capitalizeFirstLetter);
-	}
-	
-	/**
-	 * Returns the set of Java programming language reserved words.
-	 * These words cannot be used as identifiers (i.e. names).
-	 * http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
-	 */
-	public static Iterator<String> javaReservedWords() {
-		return new ArrayIterator<String>(JAVA_RESERVED_WORDS);
-	}
-
-	/**
-	 * Normalizes the specified candidate string as a valid Java identifier.
-	 * Defaults the delimitor character for replacement as '_'.
-	 *
-	 * @see StringTools#normalizeJavaIdentifier(String, char)
-	 */
-	public static String normalizeJavaIdentifier(String candidateString)
-	{
-		return normalizeJavaIdentifier(candidateString, '_');
-	}
-
-	/**
-	 * Normalizes the specified candidate string as a valid Java identifier
-	 * by replacing any invalid characters with the specified delimitor
-	 * character.
-	 */
-	public static String normalizeJavaIdentifier(String candidateString, char delimitor)
-	{
-		StringBuffer normalizedString = new StringBuffer();
-		for(int i=0; i<candidateString.length(); i++)
-		{
-			char currentChar = candidateString.charAt(i);
-			if ((i==0 && Character.isJavaIdentifierStart(currentChar)) ||
-			    Character.isJavaIdentifierPart(currentChar))
-			{
-				normalizedString.append(currentChar);
-			}
-			else
-			{
-				normalizedString.append(delimitor);
-			}
-		}
-
-		return normalizedString.toString();
-	}
-	
-	/**
-	 * Returns whether the specified string consists of Java identifier
+	 * Return whether the specified string consists of Java identifier
 	 * characters (but may be a reserved word).
 	 */
-	public static boolean stringConsistsOfJavaIdentifierCharacters(String string) {
-		if (string.length() == 0) {
-			return false;
-		}
-		return stringConsistsOfJavaIdentifierCharacters_(string.toCharArray());
+	public static boolean consistsOfJavaIdentifierCharacters(String string) {
+		int len = string.length();
+		return (len != 0) &&
+				consistsOfJavaIdentifierCharacters(string, len);
 	}
 
 	/**
-	 * Returns whether the specified string consists of Java identifier
-	 * characters (but may be a reserved word).
+	 * Pre-condition: the specified string is not empty.
 	 */
-	public static boolean stringConsistsOfJavaIdentifierCharacters(char[] string) {
-		if (string.length == 0) {
+	private static boolean consistsOfJavaIdentifierCharacters(String string, int len) {
+		if ( ! Character.isJavaIdentifierStart(string.charAt(0))) {
 			return false;
 		}
-		return stringConsistsOfJavaIdentifierCharacters_(string);
+		for (int i = len; i-- > 1; ) {  // NB: end with 1
+			if ( ! Character.isJavaIdentifierPart(string.charAt(i))) {
+				return false;
+			}
+		}
+		return true;
 	}
 
 	/**
-	 * The specified string must not be empty.
+	 * @see #consistsOfJavaIdentifierCharacters(String)
 	 */
-	private static boolean stringConsistsOfJavaIdentifierCharacters_(char[] string) {
+	public static boolean consistsOfJavaIdentifierCharacters(char[] string) {
+		int len = string.length;
+		return (len != 0) &&
+				consistsOfJavaIdentifierCharacters(string, len);
+	}
+
+	/**
+	 * Pre-condition: the specified string is not empty.
+	 */
+	private static boolean consistsOfJavaIdentifierCharacters(char[] string, int len) {
 		if ( ! Character.isJavaIdentifierStart(string[0])) {
 			return false;
 		}
-		for (int i = string.length; i-- > 1; ) {  // NB: end with 1
+		for (int i = len; i-- > 1; ) {  // NB: end with 1
 			if ( ! Character.isJavaIdentifierPart(string[i])) {
 				return false;
 			}
@@ -355,25 +248,25 @@
 	}
 
 	/**
-	 * Returns whether the specified string is a valid Java identifier.
+	 * Return whether the specified string is a valid Java identifier.
 	 */
-	public static boolean stringIsLegalJavaIdentifier(String string) {
-		return stringConsistsOfJavaIdentifierCharacters(string)
-				&& ! JAVA_RESERVED_WORDS_SET.contains(string);
+	public static boolean isLegalJavaIdentifier(String string) {
+		return consistsOfJavaIdentifierCharacters(string)
+				&& ! JAVA_RESERVED_WORDS.contains(string);
 	}
 
 	/**
-	 * Returns whether the specified string is a valid Java identifier.
+	 * @see #isLegalJavaIdentifier(String)
 	 */
-	public static boolean stringIsLegalJavaIdentifier(char[] string) {
-		return stringConsistsOfJavaIdentifierCharacters(string)
-				&& ! JAVA_RESERVED_WORDS_SET.contains(new String(string));
+	public static boolean isLegalJavaIdentifier(char[] string) {
+		return consistsOfJavaIdentifierCharacters(string)
+				&& ! JAVA_RESERVED_WORDS.contains(new String(string));
 	}
 
 	/**
 	 * Convert the specified string to a valid Java identifier
-	 * by substituting an underscore '_' for any invalid characters
-	 * in the string and appending an underscore '_' to the string if
+	 * by substituting an underscore (<code>'_'</code>) for any invalid characters
+	 * in the string and appending an underscore (<code>'_'</code>) to the string if
 	 * it is a Java reserved word.
 	 */
 	public static String convertToJavaIdentifier(String string) {
@@ -390,7 +283,7 @@
 		if (string.length() == 0) {
 			return string;
 		}
-		if (JAVA_RESERVED_WORDS_SET.contains(string)) {
+		if (JAVA_RESERVED_WORDS.contains(string)) {
 			// a reserved word is a valid identifier, we just need to tweak it a bit
 			checkCharIsJavaIdentifierPart(c);
 			return convertToJavaIdentifier(string + c, c);
@@ -400,37 +293,31 @@
 	}
 
 	/**
-	 * Convert the specified string to a valid Java identifier
-	 * by substituting an underscore '_' for any invalid characters
-	 * in the string and appending an underscore '_' to the string if
-	 * it is a Java reserved word.
+	 * @see #convertToJavaIdentifier(String)
 	 */
 	public static char[] convertToJavaIdentifier(char[] string) {
 		return convertToJavaIdentifier(string, '_');
 	}
 
 	/**
-	 * Convert the specified string to a valid Java identifier
-	 * by substituting the specified character for any invalid characters
-	 * in the string and, if necessary, appending the specified character
-	 * to the string until it is not a Java reserved word.
+	 * @see #convertToJavaIdentifier(String, char)
 	 */
 	public static char[] convertToJavaIdentifier(char[] string, char c) {
 		if (string.length == 0) {
 			return string;
 		}
-		if (JAVA_RESERVED_WORDS_SET.contains(new String(string))) {
+		if (JAVA_RESERVED_WORDS.contains(new String(string))) {
 			// a reserved word is a valid identifier, we just need to tweak it a bit
 			checkCharIsJavaIdentifierPart(c);
 			return convertToJavaIdentifier(ArrayTools.add(string, c), c);
 		}
-		convertToJavaIdentifier_(string, c);
-		return string;
+		char[] copy = string.clone();
+		return convertToJavaIdentifier_(copy, c) ? copy : string;
 	}
 
 	/**
-	 * The specified string must not be empty.
-	 * Returns whether the string was modified.
+	 * Pre-condition: The specified string is not empty.
+	 * Return whether the string was modified.
 	 */
 	private static boolean convertToJavaIdentifier_(char[] string, char c) {
 		boolean mod = false;
@@ -465,7 +352,7 @@
 	 * Convert the specified method name to a property name.
 	 * @see Introspector#decapitalize(String)
 	 */
-	public static String convertGetterSetterMethodNameToPropertyName(String methodName) {
+	public static String convertGetterOrSetterMethodNameToPropertyName(String methodName) {
 		int beginIndex = 0;
 		if (methodName.startsWith("get")) {
 			beginIndex = 3;
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NonEmptyStringFilter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NonEmptyStringFilter.java
deleted file mode 100644
index 6ad9181..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NonEmptyStringFilter.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * This filter accepts only non-<code>null</code>, non-empty,
- * non-whitespace-only strings.
- */
-public class NonEmptyStringFilter
-	implements Filter<String>, Serializable
-{
-	public static final Filter<String> INSTANCE = new NonEmptyStringFilter();
-
-	public static Filter<String> instance() {
-		return INSTANCE;
-	}
-
-	// ensure single instance
-	private NonEmptyStringFilter() {
-		super();
-	}
-
-	// accept only non-null objects
-	@Override
-	public boolean accept(String string) {
-		return StringTools.stringIsNotEmpty(string);
-	}
-
-	@Override
-	public String toString() {
-		return this.getClass().getSimpleName();
-	}
-
-	private static final long serialVersionUID = 1L;
-	private Object readResolve() {
-		// replace this object with the singleton
-		return INSTANCE;
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NonNullBooleanTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NonNullBooleanTransformer.java
deleted file mode 100644
index 655e50a..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NonNullBooleanTransformer.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-/**
- * A <code>NonNullBooleanTransformer</code> will transform a possibly-null
- * {@link Boolean} to a non-null {@link Boolean}:<ul>
- * <li>When the original {@link Boolean} is <em>not</em> <code>null</code>,
- * Returns it unchanged.
- * <li>When the original {@link Boolean} is <code>null</code>,
- * Returns its client-specified "null value"
- * ({@link Boolean#TRUE} or {@link Boolean#FALSE}).
- * </ul>
- */
-public final class NonNullBooleanTransformer
-	implements Transformer<Boolean, Boolean>
-{
-	// not null
-	private final Boolean nullValue;
-
-	/**
-	 * Returns the original {@link Boolean} when
-	 * it is non-<code>null</code>; otherwise the {@link Transformer} will return
-	 * {@link Boolean#TRUE}.
-	 */
-	public static final Transformer<Boolean, Boolean> TRUE = new NonNullBooleanTransformer(Boolean.TRUE);
-
-	/**
-	 * Returns the original {@link Boolean} when
-	 * it is non-<code>null</code>; otherwise the {@link Transformer} will return
-	 * {@link Boolean#FALSE}.
-	 */
-	public static final Transformer<Boolean, Boolean> FALSE = new NonNullBooleanTransformer(Boolean.FALSE);
-
-	/**
-	 * Returns the specified value if the original
-	 * value is <code>null</code>. Throw a {@link NullPointerException} if the
-	 * specified value is <code>null</code>.
-	 */
-	public Transformer<Boolean, Boolean> valueOf(Boolean b) {
-		return valueOf(b.booleanValue());
-	}
-
-	/**
-	 * Returns the {@link Boolean} corresponding
-	 * to the specified value if the original value is <code>null</code>.
-	 */
-	public Transformer<Boolean, Boolean> valueOf(boolean b) {
-		return b ? TRUE : FALSE;
-	}
-
-	/**
-	 * Ensure only 2 constant versions.
-	 */
-	private NonNullBooleanTransformer(Boolean nullValue) {
-		super();
-		if (nullValue == null) {
-			throw new NullPointerException();
-		}
-		this.nullValue = nullValue;
-	}
-
-	@Override
-	public Boolean transform(Boolean b) {
-		return (b != null) ? b : this.nullValue;
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.nullValue);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NotBooleanTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NotBooleanTransformer.java
deleted file mode 100644
index 8de7c29..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NotBooleanTransformer.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * A <code>NotBooleanTransformer</code> will transform a
- * {@link Boolean} to its NOT value:<ul>
- * <li>If the original {@link Boolean} is {@link Boolean#TRUE},
- * Returns {@link Boolean#FALSE}.
- * <li>If the original {@link Boolean} is {@link Boolean#FALSE},
- * Returns {@link Boolean#TRUE}.
- * <li>If the original {@link Boolean} is <code>null</code>,
- * Returns <code>null</code>.
- * </ul>
- */
-public class NotBooleanTransformer
-	implements BidiTransformer<Boolean, Boolean>, Serializable
-{
-	public static final BidiTransformer<Boolean, Boolean> INSTANCE = new NotBooleanTransformer();
-
-	public static BidiTransformer<Boolean, Boolean> instance() {
-		return INSTANCE;
-	}
-
-	// ensure single instance
-	private NotBooleanTransformer() {
-		super();
-	}
-
-	@Override
-	public Boolean transform(Boolean b) {
-		return (b == null) ? null : BooleanTools.not(b);
-	}
-
-	@Override
-	public Boolean reverseTransform(Boolean b) {
-		return (b == null) ? null : BooleanTools.not(b);
-	}
-
-	@Override
-	public String toString() {
-		return this.getClass().getSimpleName();
-	}
-
-	private static final long serialVersionUID = 1L;
-	private Object readResolve() {
-		// replace this object with the singleton
-		return INSTANCE;
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NotNullFilter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NotNullFilter.java
deleted file mode 100644
index 899612d..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NotNullFilter.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * This filter accepts only non-null objects.
- */
-public final class NotNullFilter<T>
-	implements Filter<T>, Serializable
-{
-	@SuppressWarnings("rawtypes")
-	public static final Filter INSTANCE = new NotNullFilter();
-
-	@SuppressWarnings("unchecked")
-	public static <R> Filter<R> instance() {
-		return INSTANCE;
-	}
-
-	// ensure single instance
-	private NotNullFilter() {
-		super();
-	}
-
-	// accept only non-null objects
-	@Override
-	public boolean accept(T o) {
-		return o != null;
-	}
-
-	@Override
-	public String toString() {
-		return this.getClass().getSimpleName();
-	}
-
-	private static final long serialVersionUID = 1L;
-	private Object readResolve() {
-		// replace this object with the singleton
-		return INSTANCE;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NullList.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NullList.java
deleted file mode 100644
index 1c0d3b2..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NullList.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.iterators.EmptyIterator;
-import org.eclipse.persistence.tools.utility.iterators.EmptyListIterator;
-
-/**
- * A "null" list is a bit different from an "empty" list: it allows clients to
- * add/remove elements to/from it but never changes. This is useful
- * for passing to methods that require a "collecting parameter" but the
- * client will ignore the resulting "collection".
- */
-@SuppressWarnings("nls")
-public final class NullList<E>
-	implements List<E>, Serializable
-{
-	// singleton
-	@SuppressWarnings("rawtypes")
-	private static final NullList INSTANCE = new NullList();
-
-	/**
-	 * Returns the singleton.
-	 */
-	@SuppressWarnings("unchecked")
-	public static <E> List<E> instance() {
-		return INSTANCE;
-	}
-
-	/**
-	 * Ensure single instance.
-	 */
-	private NullList() {
-		super();
-	}
-
-	@Override
-	public boolean add(E o) {
-		return false;  // the list did not change
-	}
-
-	@Override
-	public void add(int index, E element) {
-		// ignore
-	}
-
-	@Override
-	public boolean addAll(Collection<? extends E> c) {
-		return false;  // the list did not change
-	}
-
-	@Override
-	public boolean addAll(int index, Collection<? extends E> c) {
-		return false;  // the list did not change
-	}
-
-	@Override
-	public void clear() {
-		// ignore
-	}
-
-	@Override
-	public boolean contains(Object o) {
-		return false;
-	}
-
-	@Override
-	public boolean containsAll(Collection<?> c) {
-		return c.isEmpty();
-	}
-
-	@Override
-	public E get(int index) {
-		throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0"); //$NON-NLS-2$
-	}
-
-	@Override
-	public int indexOf(Object o) {
-		return -1;
-	}
-
-	@Override
-	public boolean isEmpty() {
-		return true;
-	}
-
-	@Override
-	public Iterator<E> iterator() {
-		return EmptyIterator.instance();
-	}
-
-	@Override
-	public int lastIndexOf(Object o) {
-		return -1;
-	}
-
-	@Override
-	public ListIterator<E> listIterator() {
-		return EmptyListIterator.instance();
-	}
-
-	@Override
-	public ListIterator<E> listIterator(int index) {
-		return EmptyListIterator.instance();
-	}
-
-	@Override
-	public boolean remove(Object o) {
-		return false;  // the list did not change
-	}
-
-	@Override
-	public E remove(int index) {
-		throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0"); //$NON-NLS-2$
-	}
-
-	@Override
-	public boolean removeAll(Collection<?> c) {
-		return false;  // the list did not change
-	}
-
-	@Override
-	public boolean retainAll(Collection<?> c) {
-		return false;  // the list did not change
-	}
-
-	@Override
-	public E set(int index, E element) {
-		throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0"); //$NON-NLS-2$
-	}
-
-	@Override
-	public int size() {
-		return 0;
-	}
-
-	@Override
-	public List<E> subList(int fromIndex, int toIndex) {
-		return this;
-	}
-
-	private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
-	@Override
-	public Object[] toArray() {
-		return EMPTY_OBJECT_ARRAY;
-	}
-
-	@Override
-	public <T> T[] toArray(T[] a) {
-		return a;
-	}
-
-	@Override
-	public String toString() {
-		return this.getClass().getSimpleName();
-	}
-
-	private static final long serialVersionUID = 1L;
-	private Object readResolve() {
-		// replace this object with the singleton
-		return INSTANCE;
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ObjectReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ObjectReference.java
deleted file mode 100644
index 30c7076..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ObjectReference.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-/**
- * Provide a container for holding an object that cannot be changed.
- *
- * @see ModifiableObjectReference
- * @version 2.5
- */
-public interface ObjectReference<V> {
-
-	/**
-	 * Returns the current value.
-	 */
-	V getValue();
-
-	/**
-	 * Returns whether the current value is not <code>null</code>.
-	 */
-	boolean isNotNull();
-
-	/**
-	 * Returns whether the current value is <code>null</code>.
-	 */
-	boolean isNull();
-
-	/**
-	 * Returns whether the current value is equal to the specified value.
-	 */
-	boolean valueEquals(Object object);
-
-	/**
-	 * Returns whether the current value is not equal to the specified value.
-	 */
-	boolean valueNotEqual(Object object);
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ObjectTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ObjectTools.java
new file mode 100644
index 0000000..80380ba
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ObjectTools.java
@@ -0,0 +1,471 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * {@link Object} utility methods.
+ * <p>
+ * There are a number of convenience reflection methods.
+ * These methods provide shortcuts for manipulating objects via
+ * reflection; particularly when dealing with fields and/or methods that
+ * are not publicly accessible or are inherited.
+ * <p>
+ * In most cases, all exceptions are handled and wrapped in
+ * {@link java.lang.RuntimeException}s; so these methods should
+ * be used when there should be no problems using reflection (i.e.
+ * the referenced members are presumably present etc.).
+ * <p>
+ * There are also a number of methods whose names
+ * end with an underscore. These methods declare the expected checked
+ * exceptions (e.g. {@link NoSuchMethodException}, {@link NoSuchFieldException}).
+ * These methods can be used to probe
+ * for methods, fields, etc. that should be present but might not be.
+ */
+public final class ObjectTools {
+
+	public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
+
+
+	// ********** object comparison **********
+
+	/**
+	 * Return whether the specified objects are equal, with the appropriate
+	 * <code>null</code> checks.
+	 * @see Object#equals(Object)
+	 */
+	public static boolean equals(Object object1, Object object2) {
+		return (object1 == null) ?
+				(object2 == null) :
+				((object2 != null) && object1.equals(object2));
+	}
+
+	/**
+	 * Return whether the specified objects are not equal, with the appropriate
+	 * <code>null</code> checks.
+	 * @see Object#equals(Object)
+	 */
+	public static boolean notEquals(Object object1, Object object2) {
+		return ! equals(object1, object2);
+	}
+
+
+	// ********** hash code **********
+
+	/**
+	 * Return the hash code of the specified object, with the appropriate
+	 * <code>null</code> check (i.e. return <code>0</code> if the specified
+	 * object is <code>null</code>).
+	 * @see Object#hashCode()
+	 */
+	public static int hashCode(Object object) {
+		return hashCode(object, 0);
+	}
+
+	/**
+	 * Return the hash code of the specified object, with the appropriate
+	 * <code>null</code> check (i.e. return the specified <code>null</code>
+	 * hash code if the specified object is <code>null</code>).
+	 * @see Object#hashCode()
+	 */
+	public static int hashCode(Object object, int nullHashCode) {
+		return (object == null) ? nullHashCode : object.hashCode();
+	}
+
+
+	// ********** string representation **********
+
+	/**
+	 * Build a "Dali standard" {@link Object#toString() toString()} result for
+	 * the specified object and additional information:<pre>
+	 *     ClassName[00-F3-EE-42](add'l info)
+	 * </pre>
+	 * @see Object#toString()
+	 */
+	public static String toString(Object object, Object additionalInfo) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.appendHashCodeToString(sb, object);
+		sb.append('(');
+		sb.append(additionalInfo);
+		sb.append(')');
+		return sb.toString();
+	}
+
+	/**
+	 * @see #toString(Object, Object)
+	 */
+	public static String toString(Object object, boolean additionalInfo) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.appendHashCodeToString(sb, object);
+		sb.append('(');
+		sb.append(additionalInfo);
+		sb.append(')');
+		return sb.toString();
+	}
+
+	/**
+	 * @see #toString(Object, Object)
+	 */
+	public static String toString(Object object, char additionalInfo) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.appendHashCodeToString(sb, object);
+		sb.append('(');
+		sb.append(additionalInfo);
+		sb.append(')');
+		return sb.toString();
+	}
+
+	/**
+	 * @see #toString(Object, Object)
+	 */
+	public static String toString(Object object, char[] additionalInfo) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.appendHashCodeToString(sb, object);
+		sb.append('(');
+		sb.append(additionalInfo);
+		sb.append(')');
+		return sb.toString();
+	}
+
+	/**
+	 * @see #toString(Object, Object)
+	 */
+	public static String toString(Object object, CharSequence additionalInfo) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.appendHashCodeToString(sb, object);
+		sb.append('(');
+		sb.append(additionalInfo);
+		sb.append(')');
+		return sb.toString();
+	}
+
+	/**
+	 * @see #toString(Object, Object)
+	 */
+	public static String toString(Object object, double additionalInfo) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.appendHashCodeToString(sb, object);
+		sb.append('(');
+		sb.append(additionalInfo);
+		sb.append(')');
+		return sb.toString();
+	}
+
+	/**
+	 * @see #toString(Object, Object)
+	 */
+	public static String toString(Object object, float additionalInfo) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.appendHashCodeToString(sb, object);
+		sb.append('(');
+		sb.append(additionalInfo);
+		sb.append(')');
+		return sb.toString();
+	}
+
+	/**
+	 * @see #toString(Object, Object)
+	 */
+	public static String toString(Object object, int additionalInfo) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.appendHashCodeToString(sb, object);
+		sb.append('(');
+		sb.append(additionalInfo);
+		sb.append(')');
+		return sb.toString();
+	}
+
+	/**
+	 * @see #toString(Object, Object)
+	 */
+	public static String toString(Object object, long additionalInfo) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.appendHashCodeToString(sb, object);
+		sb.append('(');
+		sb.append(additionalInfo);
+		sb.append(')');
+		return sb.toString();
+	}
+
+	/**
+	 * @see #toString(Object, Object)
+	 */
+	public static String toString(Object object, String additionalInfo) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.appendHashCodeToString(sb, object);
+		sb.append('(');
+		sb.append(additionalInfo);
+		sb.append(')');
+		return sb.toString();
+	}
+
+	/**
+	 * @see #toString(Object, Object)
+	 */
+	public static String toString(Object object, StringBuffer additionalInfo) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.appendHashCodeToString(sb, object);
+		sb.append('(');
+		sb.append(additionalInfo);
+		sb.append(')');
+		return sb.toString();
+	}
+
+	/**
+	 * Build a "Dali standard" {@link Object#toString() toString()} result for
+	 * the specified object:<pre>
+	 *     ClassName[00-F3-EE-42]
+	 * </pre>
+	 * @see Object#toString()
+	 */
+	public static String toString(Object object) {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.appendHashCodeToString(sb, object);
+		return sb.toString();
+	}
+
+	/**
+	 * Return a string suitable for a <em>singleton</em>; which is the simple
+	 * name of the object's class, since there should only be one.
+	 *
+	 * @see ClassTools#toStringName(Class)
+	 * @see Object#toString()
+	 */
+	public static String singletonToString(Object object) {
+		return ClassTools.toStringName(object.getClass());
+	}
+
+
+	// ********** fields **********
+
+	/**
+	 * Return the value of the specified object's field with the specified
+	 * name.
+	 * Useful for accessing private, package, or protected fields.
+	 * @see Field#get(Object)
+	 */
+	public static Object get(Object object, String fieldName) {
+		try {
+			return get_(object, fieldName);
+		} catch (NoSuchFieldException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(object, fieldName), ex);
+		} catch (IllegalAccessException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(object, fieldName), ex);
+		}
+	}
+
+	/**
+	 * @see #get(Object, String)
+	 */
+	public static Object get_(Object object, String fieldName)
+		throws NoSuchFieldException, IllegalAccessException
+	{
+		return field_(object, fieldName).get(object);
+	}
+
+	/**
+	 * Set the value of the specified object's field with the specified
+	 * name to the specified value.
+	 * Useful for accessing private, package, or protected fields.
+	 * @see Field#set(Object, Object)
+	 */
+	public static void set(Object object, String fieldName, Object value) {
+		try {
+			set_(object, fieldName, value);
+		} catch (NoSuchFieldException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(object, fieldName), ex);
+		} catch (IllegalAccessException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(object, fieldName), ex);
+		}
+	}
+
+	/**
+	 * @see #set(Object, String, Object)
+	 */
+	public static void set_(Object object, String fieldName, Object value)
+		throws NoSuchFieldException, IllegalAccessException
+	{
+		field_(object, fieldName).set(object, value);
+	}
+
+	/**
+	 * @see ClassTools#field(Class, String)
+	 */
+	public static Field field(Object object, String fieldName) {
+		try {
+			return field_(object, fieldName);
+		} catch (NoSuchFieldException ex) {
+			throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(object, fieldName), ex);
+		}
+	}
+
+	/**
+	 * @see ClassTools#field_(Class, String)
+	 */
+	public static Field field_(Object object, String fieldName)
+		throws NoSuchFieldException
+	{
+		return ClassTools.field_(object.getClass(), fieldName);
+	}
+
+	/**
+	 * Return a string representation of the specified field.
+	 */
+	private static String buildFullyQualifiedFieldName(Object object, String fieldName) {
+		return ClassTools.buildFullyQualifiedFieldName(object.getClass(), fieldName);
+	}
+
+
+	// ********** methods **********
+
+	/**
+	 * Execute the specified zero-argument method.
+	 * Return its result.
+	 * Useful for invoking private, package, or protected methods.
+	 */
+	public static Object execute(Object object, String methodName) {
+		return execute(object, methodName, ClassTools.EMPTY_ARRAY, EMPTY_OBJECT_ARRAY);
+	}
+
+	/**
+	 * @see #execute(Object, String)
+	 */
+	public static Object execute_(Object object, String methodName)
+		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
+	{
+		return execute_(object, methodName, ClassTools.EMPTY_ARRAY, EMPTY_OBJECT_ARRAY);
+	}
+
+	/**
+	 * Execute the specified one-argument method.
+	 * Return its result.
+	 * Useful for invoking private, package, or protected methods.
+	 */
+	public static Object execute(Object object, String methodName, Class<?> parameterType, Object argument) {
+		return execute(object, methodName, new Class[] {parameterType}, new Object[] {argument});
+	}
+
+	/**
+	 * @see #execute(Object, String, Class, Object)
+	 */
+	public static Object execute_(Object object, String methodName, Class<?> parameterType, Object argument)
+		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
+	{
+		return execute_(object, methodName, new Class[] {parameterType}, new Object[] {argument});
+	}
+
+	/**
+	 * Execute the specified method.
+	 * Return its result.
+	 * Useful for invoking private, package, or protected methods.
+	 */
+	public static Object execute(Object object, String methodName, Class<?>[] parameterTypes, Object[] arguments) {
+		return execute(object, method(object, methodName, parameterTypes), arguments);
+	}
+
+	/**
+	 * Execute the specified method, given the receiver and arguments.
+	 * Return its result.
+	 * Useful for invoking cached methods.
+	 */
+	public static Object execute(Object receiver, Method method, Object[] arguments) {
+		try {
+			return method.invoke(receiver, arguments);
+		} catch (IllegalAccessException ex) {
+			throw new RuntimeException(ex + StringTools.CR + method, ex);
+		} catch (InvocationTargetException ex) {
+			throw new RuntimeException(method + StringTools.CR + ex.getTargetException(), ex);
+		}
+	}
+
+	/**
+	 * @see #execute(Object, String, Class[], Object[])
+	 */
+	public static Object execute_(Object object, String methodName, Class<?>[] parameterTypes, Object[] arguments)
+		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
+	{
+		return method_(object, methodName, parameterTypes).invoke(object, arguments);
+	}
+
+	/**
+	 * Return the zero-argument method for the specified object
+	 * and method name. If the object's class does not directly
+	 * implement the method, look for it in the class's superclasses.
+	 * Make any private/package/protected method accessible.
+	 */
+	public static Method method(Object object, String methodName) {
+		return ClassTools.method(object.getClass(), methodName);
+	}
+
+	/**
+	 * @see #method(Object, String)
+	 */
+	public static Method method_(Object object, String methodName)
+		throws NoSuchMethodException
+	{
+		return ClassTools.method_(object.getClass(), methodName);
+	}
+
+	/**
+	 * Return the one-argument method for the specified object, method name,
+	 * and formal parameter type. If the object's class does not directly
+	 * implement the method, look for it in the class's superclasses.
+	 * Make any private/package/protected method accessible.
+	 */
+	public static Method method(Object object, String methodName, Class<?> parameterType) {
+		return ClassTools.method(object.getClass(), methodName, parameterType);
+	}
+
+	/**
+	 * @see #method(Object, String, Class)
+	 */
+	public static Method method_(Object object, String methodName, Class<?> parameterType)
+		throws NoSuchMethodException
+	{
+		return ClassTools.method_(object.getClass(), methodName, parameterType);
+	}
+
+	/**
+	 * Return the method for the specified object, method name,
+	 * and formal parameter types. If the object's class does not directly
+	 * implement the method, look for it in the class's superclasses.
+	 * Make any private/package/protected method accessible.
+	 */
+	public static Method method(Object object, String methodName, Class<?>[] parameterTypes) {
+		return ClassTools.method(object.getClass(), methodName, parameterTypes);
+	}
+
+	/**
+	 * @see #method(Object, String, Class[])
+	 */
+	public static Method method_(Object object, String methodName, Class<?>[] parameterTypes)
+		throws NoSuchMethodException
+	{
+		return ClassTools.method_(object.getClass(), methodName, parameterTypes);
+	}
+
+
+	// ********** suppressed constructor **********
+
+	/**
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private ObjectTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/PrintStreamExceptionHandler.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/PrintStreamExceptionHandler.java
new file mode 100644
index 0000000..f5135de
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/PrintStreamExceptionHandler.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+import java.io.PrintStream;
+
+/**
+ * An exception handler that prints the exceptions to the configured
+ * {@link PrintStream}.
+ */
+public class PrintStreamExceptionHandler
+	extends ExceptionHandlerAdapter
+{
+	private final PrintStream printStream;
+
+	/**
+	 * Construct an exception handler that prints any exceptions
+	 * to the specified print stream.
+	 */
+	public PrintStreamExceptionHandler(PrintStream printStream) {
+		super();
+		if (printStream == null) {
+			throw new NullPointerException();
+		}
+		this.printStream = printStream;
+	}
+
+	@Override
+	public void handleException(Throwable t) {
+		t.printStackTrace(this.printStream);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/PrintWriterExceptionHandler.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/PrintWriterExceptionHandler.java
new file mode 100644
index 0000000..4c9c917
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/PrintWriterExceptionHandler.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+import java.io.PrintWriter;
+
+/**
+ * An exception handler that prints the exceptions to the configured
+ * {@link PrintWriter}.
+ */
+public class PrintWriterExceptionHandler
+	extends ExceptionHandlerAdapter
+{
+	private final PrintWriter printWriter;
+
+	/**
+	 * Construct an exception handler that prints any exceptions
+	 * to the specified print writer.
+	 */
+	public PrintWriterExceptionHandler(PrintWriter printWriter) {
+		super();
+		if (printWriter == null) {
+			throw new NullPointerException();
+		}
+		this.printWriter = printWriter;
+	}
+
+	@Override
+	public void handleException(Throwable t) {
+		t.printStackTrace(this.printWriter);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Queue.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Queue.java
deleted file mode 100644
index 44cd11d..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Queue.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-import java.util.NoSuchElementException;
-
-/**
- * Interface defining the classic queue behavior, without the backdoors allowed by {@link
- * java.util.Queue Queue}.
- *
- * @param <E> the type of elements contained by the queue
- */
-public interface Queue<E> {
-
-	/**
-	 * "Dequeue" an item from the head of the queue.
-	 */
-	E dequeue();
-
-	/**
-	 * "Enqueue" the specified item to the tail of the queue.
-	 */
-	void enqueue(E object);
-
-	/**
-	 * Returns whether the queue is empty.
-	 */
-	boolean isEmpty();
-
-	/**
-	 * Returns the item on the head of the queue
-	 * without removing it from the queue.
-	 */
-	E peek();
-
-	final class Empty<E> implements Queue<E>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final Queue INSTANCE = new Empty();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Empty() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <T> Queue<T> instance() {
-			return INSTANCE;
-		}
-		@Override
-		public E dequeue() {
-			throw new NoSuchElementException();
-		}
-		@Override
-		public void enqueue(E o) {
-			throw new UnsupportedOperationException();
-		}
-		@Override
-		public boolean isEmpty() {
-			return true;
-		}
-		@Override
-		public E peek() {
-			throw new NoSuchElementException();
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Range.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Range.java
index 3827210..8c1e471 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Range.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Range.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2008 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -16,7 +16,8 @@
 import java.io.Serializable;
 
 /**
- * This simple container class simply puts a bit of semantics around a pair of numbers.
+ * This simple container class simply puts a bit of semantics
+ * around a pair of numbers.
  */
 @SuppressWarnings("nls")
 public class Range
@@ -36,6 +37,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	/**
 	 * Construct with the specified start and end,
 	 * both of which are immutable.
@@ -48,7 +50,7 @@
 	}
 
 	/**
-	 * Returns whether the range includes the specified
+	 * Return whether the range includes the specified
 	 * index.
 	 */
 	public boolean includes(int index) {
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ReflectionTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ReflectionTools.java
deleted file mode 100644
index 3d5278b..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ReflectionTools.java
+++ /dev/null
@@ -1,1548 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
-
-/**
- * Convenience methods related to the <code>java.lang.reflect</code> package.
- * These methods provide shortcuts for manipulating objects via
- * reflection; particularly when dealing with fields and/or methods that
- * are not publicly accessible or are inherited.
- * <p>
- * In most cases, all exceptions are handled and wrapped in
- * {@link java.lang.RuntimeException}s; so these methods should
- * be used when there should be no problems using reflection (i.e.
- * the referenced members are presumably present etc.).
- * <p>
- * There are also a number of methods whose names
- * end with an underscore. These methods declare the expected checked
- * exceptions (e.g. {@link NoSuchMethodException}, {@link NoSuchFieldException}).
- * These methods can be used to probe
- * for methods, fields, etc. that should be present but might not be.
- */
-@SuppressWarnings("nls")
-public final class ReflectionTools {
-
-	public static final Class<?>[] ZERO_PARAMETER_TYPES = new Class[0];
-	public static final Object[] ZERO_ARGUMENTS = new Object[0];
-	private static final String CR = StringTools.CR;
-
-	public static final Class<?> VOID_CLASS = void.class;
-	public static final Class<java.lang.Void> VOID_WRAPPER_CLASS = java.lang.Void.class;
-
-	// ********** fields **********
-
-	/**
-	 * Get a field value, given the containing object and field name.
-	 * Returns its result.
-	 * Useful for accessing private, package, or protected fields.
-	 * <p>
-	 * <code>Object.getFieldValue(String fieldName)</code>
-	 */
-	public static Object getFieldValue(Object object, String fieldName) {
-		try {
-			return getFieldValue_(object, fieldName);
-		} catch (NoSuchFieldException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(object, fieldName), ex);
-		} catch (IllegalAccessException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(object, fieldName), ex);
-		}
-	}
-
-	/**
-	 * Get a field value, given the containing object and field name.
-	 * Returns its result.
-	 * Useful for accessing private, package, or protected fields.
-	 * <p>
-	 * <code>Object.getFieldValue(String fieldName)</code>
-	 */
-	public static Object getFieldValue_(Object object, String fieldName)
-		throws NoSuchFieldException, IllegalAccessException
-	{
-		return getField_(object, fieldName).get(object);
-	}
-
-	/**
-	 * Get a static field value, given the containing class and field name.
-	 * Returns its result.
-	 * Useful for accessing private, package, or protected fields.
-	 * <p>
-	 * <code>Class.getStaticFieldValue(String fieldName)</code>
-	 */
-	public static Object getStaticFieldValue(Class<?> javaClass, String fieldName) {
-		try {
-			return getStaticFieldValue_(javaClass, fieldName);
-		} catch (NoSuchFieldException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
-		} catch (IllegalAccessException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
-		}
-	}
-
-	/**
-	 * Get a static field value, given the containing class and field name.
-	 * Returns its result.
-	 * Useful for accessing private, package, or protected fields.
-	 * <p>
-	 * <code>Class.getStaticFieldValue(String fieldName)</code>
-	 */
-	public static Object getStaticFieldValue_(Class<?> javaClass, String fieldName)
-		throws NoSuchFieldException, IllegalAccessException
-	{
-		return getField_(javaClass, fieldName).get(null);
-	}
-
-	/**
-	 * Set a field value, given the containing object, field name, and new value.
-	 * Useful for accessing private, package, or protected fields.
-	 * <p>
-	 * <code>Object.setFieldValue(String fieldName, Object value)</code>
-	 */
-	public static void setFieldValue(Object object, String fieldName, Object value) {
-		try {
-			setFieldValue_(object, fieldName, value);
-		} catch (NoSuchFieldException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(object, fieldName), ex);
-		} catch (IllegalAccessException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(object, fieldName), ex);
-		}
-	}
-
-	/**
-	 * Set a field value, given the containing object, field name, and new value.
-	 * Useful for accessing private, package, or protected fields.
-	 * <p>
-	 * <code>Object.setFieldValue(String fieldName, Object value)</code>
-	 */
-	public static void setFieldValue_(Object object, String fieldName, Object value)
-		throws NoSuchFieldException, IllegalAccessException
-	{
-		getField_(object, fieldName).set(object, value);
-	}
-
-	/**
-	 * Set a static field value, given the containing class, field name, and new value.
-	 * Useful for accessing private, package, or protected fields.
-	 * <p>
-	 * <code>Class.setStaticFieldValue(String fieldName, Object value)</code>
-	 */
-	public static void setStaticFieldValue(Class<?> javaClass, String fieldName, Object value) {
-		try {
-			setStaticFieldValue_(javaClass, fieldName, value);
-		} catch (NoSuchFieldException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
-		} catch (IllegalAccessException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
-		}
-	}
-
-	/**
-	 * Set a static field value, given the containing class, field name, and new value.
-	 * Useful for accessing private, package, or protected fields.
-	 * <p>
-	 * <code>Class.setStaticFieldValue(String fieldName, Object value)</code>
-	 */
-	public static void setStaticFieldValue_(Class<?> javaClass, String fieldName, Object value)
-		throws NoSuchFieldException, IllegalAccessException
-	{
-		getField_(javaClass, fieldName).set(null, value);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a field for the specified object and field name.
-	 * If the object's class does not directly
-	 * define the field, look for it in the class's superclasses.
-	 * Make any private/package/protected field accessible.
-	 * <p>
-	 * <code>Object.getField(String fieldName)</code>
-	 */
-	public static Field getField(Object object, String fieldName) {
-		try {
-			return getField_(object, fieldName);
-		} catch (NoSuchFieldException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(object, fieldName), ex);
-		}
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a field for the specified object and field name.
-	 * If the object's class does not directly
-	 * define the field, look for it in the class's superclasses.
-	 * Make any private/package/protected field accessible.
-	 * <p>
-	 * <code>Object.getField(String fieldName)</code>
-	 */
-	public static Field getField_(Object object, String fieldName)
-		throws NoSuchFieldException
-	{
-		return getField_(object.getClass(), fieldName);
-	}
-
-	/**
-	 * Returns a field for the specified class and field name.
-	 * If the class does not directly
-	 * define the field, look for it in the class's superclasses.
-	 * Make any private/package/protected field accessible.
-	 */
-	public static Field getField(Class<?> javaClass, String fieldName) {
-		try {
-			return getField_(javaClass, fieldName);
-		} catch (NoSuchFieldException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedFieldName(javaClass, fieldName), ex);
-		}
-	}
-
-	/**
-	 * Returns a field for the specified class and field name.
-	 * If the class does not directly
-	 * define the field, look for it in the class's superclasses.
-	 * Make any private/package/protected field accessible.
-	 */
-	public static Field getField_(Class<?> javaClass, String fieldName)
-		throws NoSuchFieldException
-	{
-		Field field = null;
-		try {
-			field = javaClass.getDeclaredField(fieldName);
-		} catch (NoSuchFieldException ex) {
-			Class<?> superclass = javaClass.getSuperclass();
-			if (superclass == null) {
-				throw ex;
-			}
-			return getField_(superclass, fieldName);  // recurse
-		}
-		field.setAccessible(true);
-		return field;
-	}
-
-	/**
-	 * Returns all the fields for the
-	 * specified class, including inherited fields.
-	 * Make any private/package/protected fields accessible.
-	 * <p>
-	 * <code>Class.getAllFields()</code>
-	 */
-	public static Iterable<Field> getAllFields(Class<?> javaClass) {
-		ArrayList<Field> fields = new ArrayList<Field>();
-		for (Class<?> tempClass = javaClass; tempClass != null; tempClass = tempClass.getSuperclass()) {
-			addDeclaredFieldsTo(tempClass, fields);
-		}
-		return fields;
-	}
-
-	/*
-	 * Add the declared fields for the specified class
-	 * to the specified list.
-	 */
-	private static void addDeclaredFieldsTo(Class<?> javaClass, ArrayList<Field> fields) {
-		for (Field field : getDeclaredFields(javaClass)) {
-			fields.add(field);
-		}
-	}
-
-	/**
-	 * Returns the declared fields for the specified class.
-	 * Make any private/package/protected fields accessible.
-	 * <p>
-	 * <code>Class.getAccessibleDeclaredFields()</code>
-	 */
-	public static Iterable<Field> getDeclaredFields(Class<?> javaClass) {
-		Field[] fields = javaClass.getDeclaredFields();
-		for (Field field : fields) {
-			field.setAccessible(true);
-		}
-		return new ArrayIterable<Field>(fields);
-	}
-
-
-	// ********** methods **********
-
-	/**
-	 * Convenience method.
-	 * Execute a zero-argument method, given the receiver and method name.
-	 * Returns its result.
-	 * Useful for invoking private, package, or protected methods.
-	 * <p>
-	 * <code>Object.execute(String methodName)</code>
-	 */
-	public static Object executeMethod(Object receiver, String methodName) {
-		return executeMethod(receiver, methodName, ZERO_PARAMETER_TYPES, ZERO_ARGUMENTS);
-	}
-
-	/**
-	 * Convenience method.
-	 * Execute a one-argument method, given the receiver,
-	 * method name, parameter type, and argument.
-	 * Returns its result.
-	 * Useful for invoking private, package, or protected methods.
-	 * <p>
-	 * <code>Object.execute(String methodName, Class<?> parameterType, Object argument)</code>
-	 */
-	public static Object executeMethod(Object receiver, String methodName, Class<?> parameterType, Object argument) {
-		return executeMethod(receiver, methodName, new Class[] {parameterType}, new Object[] {argument});
-	}
-
-	/**
-	 * Execute a method, given the receiver,
-	 * method name, parameter types, and arguments.
-	 * Returns its result.
-	 * Useful for invoking private, package, or protected methods.
-	 * <p>
-	 * <code>Object.execute(String methodName, Class<?>[] parameterTypes, Object[] arguments)</code>
-	 */
-	public static Object executeMethod(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] arguments) {
-		return executeMethod(getMethod(receiver, methodName, parameterTypes), receiver, arguments);
-	}
-
-	/**
-	 * Execute the specified method, given the receiver and arguments.
-	 * Returns its result.
-	 * Useful for invoking cached methods.
-	 */
-	public static Object executeMethod(Method method, Object receiver, Object[] arguments) {
-		try {
-			return method.invoke(receiver, arguments);
-		} catch (IllegalAccessException ex) {
-			throw new RuntimeException(ex + CR + method, ex);
-		} catch (InvocationTargetException ex) {
-			throw new RuntimeException(method + CR + ex.getTargetException(), ex);
-		}
-	}
-
-	/**
-	 * Convenience method.
-	 * Execute a zero-argument method,
-	 * given the receiver and method name.
-	 * Returns its result.
-	 * Throw an exception if the method is not defined.
-	 * Useful for invoking private, package, or protected methods.
-	 * <p>
-	 * <code>Object.execute(String methodName)</code>
-	 */
-	public static Object executeMethod_(Object receiver, String methodName)
-		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
-	{
-		return executeMethod_(receiver, methodName, ZERO_PARAMETER_TYPES, ZERO_ARGUMENTS);
-	}
-
-	/**
-	 * Convenience method.
-	 * Execute a method, given the receiver,
-	 * method name, parameter type, and argument.
-	 * Returns its result.
-	 * Throw an exception if the method is not defined.
-	 * Useful for invoking private, package, or protected methods.
-	 * <p>
-	 * <code>Object.execute(String methodName, Class<?> parameterType, Object argument)</code>
-	 */
-	public static Object executeMethod_(Object receiver, String methodName, Class<?> parameterType, Object argument)
-		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
-	{
-		return executeMethod_(receiver, methodName, new Class[] {parameterType}, new Object[] {argument});
-	}
-
-	/**
-	 * Execute a method, given the receiver,
-	 * method name, parameter types, and arguments.
-	 * Returns its result.
-	 * Throw an exception if the method is not defined.
-	 * Useful for invoking private, package, or protected methods.
-	 * <p>
-	 * <code>Object.execute(String methodName, Class<?>[] parameterTypes, Object[] arguments)</code>
-	 */
-	public static Object executeMethod_(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] arguments)
-		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
-	{
-		return getMethod_(receiver, methodName, parameterTypes).invoke(receiver, arguments);
-	}
-
-	/**
-	 * Convenience method.
-	 * Execute a zero-argument static method,
-	 * given the class and method name.
-	 * Returns its result.
-	 * Useful for invoking private, package, or protected methods.
-	 * <p>
-	 * <code>Class.executeStaticMethod(String methodName)</code>
-	 */
-	public static Object executeStaticMethod(Class<?> javaClass, String methodName) {
-		return executeStaticMethod(javaClass, methodName, ZERO_PARAMETER_TYPES, ZERO_ARGUMENTS);
-	}
-
-	/**
-	 * Convenience method.
-	 * Execute a static method, given the class,
-	 * method name, parameter type, and argument.
-	 * Returns its result.
-	 * Useful for invoking private, package, or protected methods.
-	 * <p>
-	 * <code>Class.executeStaticMethod(String methodName, Class<?> parameterType, Object argument)</code>
-	 */
-	public static Object executeStaticMethod(Class<?> javaClass, String methodName, Class<?> parameterType, Object argument) {
-		return executeStaticMethod(javaClass, methodName, new Class[] {parameterType}, new Object[] {argument});
-	}
-
-	/**
-	 * Execute a static method, given the class,
-	 * method name, parameter types, and arguments.
-	 * Returns its result.
-	 * Useful for invoking private, package, or protected methods.
-	 * <p>
-	 * <code>Class.executeStaticMethod(String methodName, Class<?>[] parameterTypes, Object[] arguments)</code>
-	 */
-	public static Object executeStaticMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes, Object[] arguments) {
-		try {
-			return executeStaticMethod_(javaClass, methodName, parameterTypes, arguments);
-		} catch (NoSuchMethodException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), ex);
-		} catch (IllegalAccessException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), ex);
-		} catch (InvocationTargetException ex) {
-			throw new RuntimeException(buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes) + CR + ex.getTargetException(), ex);
-		}
-	}
-
-	/**
-	 * Convenience method.
-	 * Execute a zero-argument static method,
-	 * given the class and method name.
-	 * Returns its result.
-	 * Useful for invoking private, package, or protected methods.
-	 * <p>
-	 * <code>Class.executeStaticMethod(String methodName)</code>
-	 */
-	public static Object executeStaticMethod_(Class<?> javaClass, String methodName)
-		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
-	{
-		return executeStaticMethod_(javaClass, methodName, ZERO_PARAMETER_TYPES, ZERO_ARGUMENTS);
-	}
-
-	/**
-	 * Convenience method.
-	 * Execute a static method, given the class,
-	 * method name, parameter type, and argument.
-	 * Returns its result.
-	 * Useful for invoking private, package, or protected methods.
-	 * <p>
-	 * <code>Class.executeStaticMethod(String methodName, Class<?> parameterType, Object argument)</code>
-	 */
-	public static Object executeStaticMethod_(Class<?> javaClass, String methodName, Class<?> parameterType, Object argument)
-		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
-	{
-		return executeStaticMethod_(javaClass, methodName, new Class[] {parameterType}, new Object[] {argument});
-	}
-
-	/**
-	 * Execute a static method, given the class,
-	 * method name, parameter types, and arguments.
-	 * Returns its result.
-	 * Useful for invoking private, package, or protected methods.
-	 * <p>
-	 * <code>Class.executeStaticMethod(String methodName, Class<?>[] parameterTypes, Object[] arguments)</code>
-	 */
-	public static Object executeStaticMethod_(Class<?> javaClass, String methodName, Class<?>[] parameterTypes, Object[] arguments)
-		throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
-	{
-		return getStaticMethod_(javaClass, methodName, parameterTypes).invoke(null, arguments);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a zero-argument method for the specified class
-	 * and method name. If the class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getMethod(Class<?> javaClass, String methodName) {
-		return getMethod(javaClass, methodName, ZERO_PARAMETER_TYPES);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a zero-argument method for the specified class
-	 * and method name. If the class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getMethod_(Class<?> javaClass, String methodName)
-		throws NoSuchMethodException
-	{
-		return getMethod_(javaClass, methodName, ZERO_PARAMETER_TYPES);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a method for the specified class, method name,
-	 * and formal parameter type. If the class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getMethod(Class<?> javaClass, String methodName, Class<?> parameterType) {
-		return getMethod(javaClass, methodName, new Class[] {parameterType});
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a method for the specified class, method name,
-	 * and formal parameter type. If the class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getMethod_(Class<?> javaClass, String methodName, Class<?> parameterType)
-		throws NoSuchMethodException
-	{
-		return getMethod_(javaClass, methodName, new Class[] {parameterType});
-	}
-
-	/**
-	 * Returns a method for the specified class, method name,
-	 * and formal parameter types. If the class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) {
-		try {
-			return getMethod_(javaClass, methodName, parameterTypes);
-		} catch (NoSuchMethodException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), ex);
-		}
-	}
-
-	/**
-	 * Returns a method for the specified class, method name,
-	 * and formal parameter types. If the class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getMethod_(Class<?> javaClass, String methodName, Class<?>[] parameterTypes)
-		throws NoSuchMethodException
-	{
-		Method method = null;
-		try {
-			method = javaClass.getDeclaredMethod(methodName, parameterTypes);
-		} catch (NoSuchMethodException ex) {
-			Class<?> superclass = javaClass.getSuperclass();
-			if (superclass == null) {
-				throw ex;
-			}
-			// recurse
-			return getMethod_(superclass, methodName, parameterTypes);
-		}
-		method.setAccessible(true);
-		return method;
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a zero-argument method for the specified object
-	 * and method name. If the object's class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getMethod(Object object, String methodName) {
-		return getMethod(object.getClass(), methodName);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a zero-argument method for the specified object
-	 * and method name. If the object's class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getMethod_(Object object, String methodName)
-		throws NoSuchMethodException
-	{
-		return getMethod_(object.getClass(), methodName);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a method for the specified object, method name,
-	 * and formal parameter types. If the object's class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getMethod(Object object, String methodName, Class<?>[] parameterTypes) {
-		return getMethod(object.getClass(), methodName, parameterTypes);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a method for the specified object, method name,
-	 * and formal parameter types. If the object's class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getMethod_(Object object, String methodName, Class<?>[] parameterTypes)
-		throws NoSuchMethodException
-	{
-		return getMethod_(object.getClass(), methodName, parameterTypes);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a method for the specified object, method name,
-	 * and formal parameter type. If the object's class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getMethod(Object object, String methodName, Class<?> parameterType) {
-		return getMethod(object.getClass(), methodName, parameterType);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a method for the specified object, method name,
-	 * and formal parameter type. If the object's class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getMethod_(Object object, String methodName, Class<?> parameterType)
-		throws NoSuchMethodException
-	{
-		return getMethod_(object.getClass(), methodName, parameterType);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a zero-argument static method for the specified class
-	 * and method name. If the class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getStaticMethod(Class<?> javaClass, String methodName) {
-		return getStaticMethod(javaClass, methodName, ZERO_PARAMETER_TYPES);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a static method for the specified class, method name,
-	 * and formal parameter type. If the class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getStaticMethod(Class<?> javaClass, String methodName, Class<?> parameterTypes) {
-		return getStaticMethod(javaClass, methodName, new Class[] {parameterTypes});
-	}
-
-	/**
-	 * Returns a static method for the specified class, method name,
-	 * and formal parameter types. If the class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getStaticMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) {
-		try {
-			return getStaticMethod_(javaClass, methodName, parameterTypes);
-		} catch (NoSuchMethodException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), ex);
-		}
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a zero-argument static method for the specified class
-	 * and method name. If the class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getStaticMethod_(Class<?> javaClass, String methodName)
-		throws NoSuchMethodException
-	{
-		return getStaticMethod_(javaClass, methodName, ZERO_PARAMETER_TYPES);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a static method for the specified class, method name,
-	 * and formal parameter type. If the class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getStaticMethod_(Class<?> javaClass, String methodName, Class<?> parameterTypes)
-		throws NoSuchMethodException
-	{
-		return getStaticMethod_(javaClass, methodName, new Class[] {parameterTypes});
-	}
-
-	/**
-	 * Returns a static method for the specified class, method name,
-	 * and formal parameter types. If the class does not directly
-	 * implement the method, look for it in the class's superclasses.
-	 * Make any private/package/protected method accessible.
-	 */
-	public static Method getStaticMethod_(Class<?> javaClass, String methodName, Class<?>[] parameterTypes)
-		throws NoSuchMethodException
-	{
-		Method method = getMethod_(javaClass, methodName, parameterTypes);
-		if (Modifier.isStatic(method.getModifiers())) {
-			return method;
-		}
-		throw new NoSuchMethodException(buildFullyQualifiedMethodSignature(javaClass, methodName, parameterTypes));
-	}
-
-	/**
-	 * Returns all the methods for the
-	 * specified class, including inherited methods.
-	 * Make any private/package/protected methods accessible.
-	 * <p>
-	 * <code>Class.getAllMethods()</code>
-	 */
-	public static Iterable<Method> getAllMethods(Class<?> javaClass) {
-		ArrayList<Method> methods = new ArrayList<Method>();
-		for (Class<?> tempClass = javaClass; tempClass != null; tempClass = tempClass.getSuperclass()) {
-			addDeclaredMethodsTo(tempClass, methods);
-		}
-		return methods;
-	}
-
-	/*
-	 * Add the declared methods for the specified class
-	 * to the specified list.
-	 */
-	private static void addDeclaredMethodsTo(Class<?> javaClass, ArrayList<Method> methods) {
-		for (Method method : getDeclaredMethods(javaClass)) {
-			methods.add(method);
-		}
-	}
-
-	/**
-	 * Returns the declared methods for the specified class.
-	 * Make any private/package/protected methods accessible.
-	 * <p>
-	 * <code>Class.getAccessibleDeclaredMethods()</code>
-	 */
-	public static Iterable<Method> getDeclaredMethods(Class<?> javaClass) {
-		Method[] methods = javaClass.getDeclaredMethods();
-		for (Method method : methods) {
-			method.setAccessible(true);
-		}
-		return new ArrayIterable<Method>(methods);
-	}
-
-
-	// ********** constructors **********
-
-	/**
-	 * Returns the default (zero-argument) constructor
-	 * for the specified class.
-	 * Make any private/package/protected constructor accessible.
-	 * <p>
-	 * <code>Class.getDefaultConstructor()</code>
-	 */
-	public static <T> Constructor<T> getDefaultConstructor(Class<T> javaClass) {
-		return getConstructor(javaClass);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns the default (zero-argument) constructor
-	 * for the specified class.
-	 * Make any private/package/protected constructor accessible.
-	 * <p>
-	 * <code>Class.getConstructor()</code>
-	 */
-	public static <T> Constructor<T> getConstructor(Class<T> javaClass) {
-		return getConstructor(javaClass, ZERO_PARAMETER_TYPES);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns the constructor for the specified class
-	 * and formal parameter type.
-	 * Make any private/package/protected constructor accessible.
-	 * <p>
-	 * <code>Class.getConstructor(Class<?> parameterType)</code>
-	 */
-	public static <T> Constructor<T> getConstructor(Class<T> javaClass, Class<?> parameterType) {
-		return getConstructor(javaClass, new Class[] {parameterType});
-	}
-
-	/**
-	 * Returns the constructor for the specified class
-	 * and formal parameter types.
-	 * Make any private/package/protected constructor accessible.
-	 * <p>
-	 * <code>Class.getConstructor(Class<?>[] parameterTypes)</code>
-	 */
-	public static <T> Constructor<T> getConstructor(Class<T> javaClass, Class<?>[] parameterTypes) {
-		try {
-			return getConstructor_(javaClass, parameterTypes);
-		} catch (NoSuchMethodException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedConstructorSignature(javaClass, parameterTypes), ex);
-		}
-	}
-
-	/**
-	 * Returns the default (zero-argument) constructor
-	 * for the specified class.
-	 * Make any private/package/protected constructor accessible.
-	 * <p>
-	 * <code>Class.getDefaultConstructor()</code>
-	 */
-	public static <T> Constructor<T> getDefaultConstructor_(Class<T> javaClass)
-		throws NoSuchMethodException
-	{
-		return getConstructor_(javaClass);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns the default (zero-argument) constructor
-	 * for the specified class.
-	 * Make any private/package/protected constructor accessible.
-	 * <p>
-	 * <code>Class.getConstructor()</code>
-	 */
-	public static <T> Constructor<T> getConstructor_(Class<T> javaClass)
-		throws NoSuchMethodException
-	{
-		return getConstructor_(javaClass, ZERO_PARAMETER_TYPES);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns the constructor for the specified class
-	 * and formal parameter type.
-	 * Make any private/package/protected constructor accessible.
-	 * <p>
-	 * <code>Class.getConstructor(Class<?> parameterType)</code>
-	 */
-	public static <T> Constructor<T> getConstructor_(Class<T> javaClass, Class<?> parameterType)
-		throws NoSuchMethodException
-	{
-		return getConstructor_(javaClass, new Class[] {parameterType});
-	}
-
-	/**
-	 * Returns the constructor for the specified class
-	 * and formal parameter types.
-	 * Make any private/package/protected constructor accessible.
-	 * <p>
-	 * <code>Class.getConstructor(Class<?>[] parameterTypes)</code>
-	 */
-	public static <T> Constructor<T> getConstructor_(Class<T> javaClass, Class<?>[] parameterTypes)
-		throws NoSuchMethodException
-	{
-		Constructor<T> constructor = javaClass.getDeclaredConstructor(parameterTypes);
-		constructor.setAccessible(true);
-		return constructor;
-	}
-
-	/**
-	 * Returns the declared constructors for the specified class.
-	 * Make any private/package/protected constructors accessible.
-	 * <p>
-	 * <code>Class.getAccessibleDeclaredConstructors()</code>
-	 */
-	public static <T> Iterable<Constructor<T>> getDeclaredConstructors(Class<T> javaClass) {
-		@SuppressWarnings("unchecked")
-		Constructor<T>[] constructors = (Constructor<T>[])javaClass.getDeclaredConstructors();
-		for (Constructor<T> constructor : constructors) {
-			constructor.setAccessible(true);
-		}
-		return new ArrayIterable<Constructor<T>>(constructors);
-	}
-
-
-	// ********** classes **********
-
-	/**
-	 * Convenience method.
-	 * Returns the specified class (without the checked exception).
-	 */
-	public static Class<?> classForName(String className) {
-		try {
-			return Class.forName(className);
-		} catch (ClassNotFoundException ex) {
-			throw new RuntimeException(className, ex);
-		}
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns the specified class (without the checked exception).
-	 */
-	public static Class<?> classForName(String className, boolean initialize, ClassLoader classLoader) {
-		try {
-			return Class.forName(className, initialize, classLoader);
-		} catch (ClassNotFoundException ex) {
-			throw new RuntimeException(className, ex);
-		}
-	}
-
-	/**
-	 * Returns the "array depth" of the specified class.
-	 * The depth is the number of dimensions for an array type.
-	 * Non-array types have a depth of zero.
-	 * <p>
-	 * <code>Class.getArrayDepth()</code>
-	 */
-	public static int getArrayDepth(Class<?> javaClass) {
-		int depth = 0;
-		while (javaClass.isArray()) {
-			depth++;
-			javaClass = javaClass.getComponentType();
-		}
-		return depth;
-	}
-
-	/**
-	 * Returns the "element type" of the specified class.
-	 * The element type is the base type held by an array type.
-	 * A non-array type simply returns itself.
-	 * <p>
-	 * <code>Class.getElementType()</code>
-	 */
-	public static Class<?> getElementType(Class<?> javaClass) {
-		while (javaClass.isArray()) {
-			javaClass = javaClass.getComponentType();
-		}
-		return javaClass;
-	}
-
-	/**
-	 * Returns the wrapper class corresponding to the specified
-	 * Returns <code>null</code> if the specified class
-	 * is not a primitive class.
-	 * <p>
-	 * <code>Class.getWrapperClass()</code>
-	 */
-	public static Class<?> getWrapperClass(Class<?> primitiveClass) {
-		for (Primitive primitive : PRIMITIVES) {
-			if (primitive.javaClass == primitiveClass) {
-				return primitive.wrapperClass;
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns whether the specified class is a primitive wrapper
-	 * class (i.e. <code>java.lang.Void</code> or one of the primitive
-	 * variable wrapper classes, <code>java.lang.Boolean</code>,
-	 * <code>java.lang.Integer</code>, <code>java.lang.Float</code>, etc.).
-	 * <p>
-	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
-	 * <p>
-	 * <code>Class.isPrimitiveWrapper()</code>
-	 */
-	public static boolean classIsPrimitiveWrapper(Class<?> javaClass) {
-		if (javaClass.isArray() || (javaClass.getName().length() > MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH)) {
-			return false;  // performance tweak
-		}
-		for (Primitive primitive : PRIMITIVES) {
-			if (javaClass == primitive.wrapperClass) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Returns whether the specified class is a "variable" primitive wrapper
-	 * class (i.e. <code>java.lang.Boolean</code>,
-	 * <code>java.lang.Integer</code>, <code>java.lang.Float</code>, etc.,
-	 * but not <code>java.lang.Void</code>).
-	 * <p>
-	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
-	 * <p>
-	 * <code>Class.isVariablePrimitiveWrapper()</code>
-	 */
-	public static boolean classIsVariablePrimitiveWrapper(Class<?> javaClass) {
-		return classIsPrimitiveWrapper(javaClass)
-			&& (javaClass != VOID_WRAPPER_CLASS);
-	}
-
-	/**
-	 * Returns whether the specified class is a "variable" primitive
-	 * class (i.e. <code>boolean</code>, <code>int</code>,
-	 * <code>float</code>, etc., but not <code>void</code>).
-	 * <p>
-	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
-	 * <p>
-	 * <code>Class.isVariablePrimitive()</code>
-	 */
-	public static boolean classIsVariablePrimitive(Class<?> javaClass) {
-		return javaClass.isPrimitive() && (javaClass != VOID_CLASS);
-	}
-
-	/**
-	 * Returns the primitive class for the specified primitive class code.
-	 * Returns <code>null</code> if the specified code
-	 * is not a primitive class code.
-	 * @see java.lang.Class#getName()
-	 */
-	public static Class<?> getClassForCode(int classCode) {
-		return getClassForCode((char) classCode);
-	}
-
-	/**
-	 * Returns the primitive class for the specified primitive class code.
-	 * Returns <code>null</code> if the specified code
-	 * is not a primitive class code.
-	 * @see java.lang.Class#getName()
-	 */
-	public static Class<?> getClassForCode(char classCode) {
-		for (Primitive primitive : PRIMITIVES) {
-			if (primitive.code == classCode) {
-				return primitive.javaClass;
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the class code for the specified primitive class.
-	 * Returns <code>0</code> if the specified class
-	 * is not a primitive class.
-	 * @see java.lang.Class#getName()
-	 */
-	public static char getCodeForClass(Class<?> primitiveClass) {
-		if (( ! primitiveClass.isArray()) && (primitiveClass.getName().length() <= MAX_PRIMITIVE_CLASS_NAME_LENGTH)) {
-			for (Primitive primitive : PRIMITIVES) {
-				if (primitive.javaClass == primitiveClass) {
-					return primitive.code;
-				}
-			}
-		}
-		return 0;
-	}
-
-
-	// ********** instantiation **********
-
-	/**
-	 * Convenience method.
-	 * Returns a new instance of the specified class,
-	 * using the class's default (zero-argument) constructor.
-	 * <p>
-	 * <code>Class.newInstance()</code>
-	 */
-	public static Object newInstance(String className) {
-		return newInstance(className, null);
-	}
-
-	/**
-	 * Returns a new instance of the specified class,
-	 * given the constructor parameter type and argument.
-	 * <p>
-	 * <code>Class.newInstance(Class<?> parameterType, Object argument)</code>
-	 */
-	public static Object newInstance(String className, Class<?> parameterType, Object argument) {
-		return newInstance(className, parameterType, argument, null);
-	}
-
-	/**
-	 * Returns a new instance of the specified class,
-	 * given the constructor parameter types and arguments.
-	 * <p>
-	 * <code>Class.newInstance(Class<?>[] parameterTypes, Object[] arguments)</code>
-	 */
-	public static Object newInstance(String className, Class<?>[] parameterTypes, Object[] arguments) {
-		return newInstance(className, parameterTypes, arguments, null);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a new instance of the specified class,
-	 * using the class's default (zero-argument) constructor.
-	 * Use the specified class loader to load the class.
-	 * <p>
-	 * <code>Class.newInstance()</code>
-	 */
-	public static Object newInstance(String className, ClassLoader classLoader) {
-		return newInstance(classForName(className, false, classLoader));
-	}
-
-	/**
-	 * Returns a new instance of the specified class,
-	 * given the constructor parameter type and argument.
-	 * <p>
-	 * <code>Class.newInstance(Class<?> parameterType, Object argument)</code>
-	 */
-	public static Object newInstance(String className, Class<?> parameterType, Object argument, ClassLoader classLoader) {
-		return newInstance(classForName(className, false, classLoader), parameterType, argument);
-	}
-
-	/**
-	 * Returns a new instance of the specified class,
-	 * given the constructor parameter types and arguments.
-	 * <p>
-	 * <code>Class.newInstance(Class<?>[] parameterTypes, Object[] arguments)</code>
-	 */
-	public static Object newInstance(String className, Class<?>[] parameterTypes, Object[] arguments, ClassLoader classLoader) {
-		return newInstance(classForName(className, false, classLoader), parameterTypes, arguments);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a new instance of the specified class,
-	 * using the class's default (zero-argument) constructor.
-	 * <p>
-	 * <code>Class.newInstance()</code>
-	 */
-	public static <T> T newInstance(Class<T> javaClass) {
-		return newInstance(javaClass, ZERO_PARAMETER_TYPES, ZERO_ARGUMENTS);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a new instance of the specified class,
-	 * given the constructor parameter type and argument.
-	 * <p>
-	 * <code>Class.newInstance(Class<?> parameterType, Object argument)</code>
-	 */
-	public static <T> T newInstance(Class<T> javaClass, Class<?> parameterType, Object argument) {
-		return newInstance(javaClass, new Class[] {parameterType}, new Object[] {argument});
-	}
-
-	/**
-	 * Returns a new instance of the specified class,
-	 * given the constructor parameter types and arguments.
-	 * <p>
-	 * <code>Class.newInstance(Class<?>[] parameterTypes, Object[] arguments)</code>
-	 */
-	public static <T> T newInstance(Class<T> javaClass, Class<?>[] parameterTypes, Object[] arguments) {
-		try {
-			return newInstance_(javaClass, parameterTypes, arguments);
-		} catch (InstantiationException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedConstructorSignature(javaClass, parameterTypes), ex);
-		} catch (IllegalAccessException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedConstructorSignature(javaClass, parameterTypes), ex);
-		} catch (InvocationTargetException ex) {
-			throw new RuntimeException(buildFullyQualifiedConstructorSignature(javaClass, parameterTypes) + CR + ex.getTargetException(), ex);
-		} catch (NoSuchMethodException ex) {
-			throw new RuntimeException(ex + CR + buildFullyQualifiedConstructorSignature(javaClass, parameterTypes), ex);
-		}
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a new instance of the specified class,
-	 * using the class's default (zero-argument) constructor.
-	 * <p>
-	 * <code>Class.newInstance()</code>
-	 */
-	public static <T> T newInstance_(Class<T> javaClass)
-		throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
-	{
-		return newInstance_(javaClass, ZERO_PARAMETER_TYPES, ZERO_ARGUMENTS);
-	}
-
-	/**
-	 * Convenience method.
-	 * Returns a new instance of the specified class,
-	 * given the constructor parameter type and argument.
-	 * <p>
-	 * <code>Class.newInstance(Class<?> parameterType, Object argument)</code>
-	 */
-	public static <T> T newInstance_(Class<T> javaClass, Class<?> parameterType, Object argument)
-		throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
-	{
-		return newInstance_(javaClass, new Class[] {parameterType}, new Object[] {argument});
-	}
-
-	/**
-	 * Returns a new instance of the specified class,
-	 * given the constructor parameter types and arguments.
-	 * <p>
-	 * <code>Class.newInstance(Class<?>[] parameterTypes, Object[] arguments)</code>
-	 */
-	public static <T> T newInstance_(Class<T> javaClass, Class<?>[] parameterTypes, Object[] arguments)
-		throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
-	{
-		return getConstructor_(javaClass, parameterTypes).newInstance(arguments);
-	}
-
-
-	// ********** type declarations **********
-
-	/**
-	 * Returns the class for the specified "type declaration".
-	 */
-	public static Class<?> getClassForTypeDeclaration(String typeDeclaration) {
-		return getClassForTypeDeclaration(typeDeclaration, null);
-	}
-
-	/**
-	 * Returns the class for the specified "type declaration".
-	 */
-	public static Class<?> getClassForTypeDeclaration_(String typeDeclaration)
-		throws ClassNotFoundException
-	{
-		return getClassForTypeDeclaration_(typeDeclaration, null);
-	}
-
-	/**
-	 * Returns the class for the specified "type declaration",
-	 * using the specified class loader.
-	 */
-	public static Class<?> getClassForTypeDeclaration(String typeDeclaration, ClassLoader classLoader) {
-		TypeDeclaration td = buildTypeDeclaration(typeDeclaration);
-		return getClassForTypeDeclaration(td.elementTypeName, td.arrayDepth, classLoader);
-	}
-
-	/**
-	 * Returns the class for the specified "type declaration",
-	 * using the specified class loader.
-	 */
-	public static Class<?> getClassForTypeDeclaration_(String typeDeclaration, ClassLoader classLoader)
-		throws ClassNotFoundException
-	{
-		TypeDeclaration td = buildTypeDeclaration(typeDeclaration);
-		return getClassForTypeDeclaration_(td.elementTypeName, td.arrayDepth, classLoader);
-	}
-
-	private static TypeDeclaration buildTypeDeclaration(String typeDeclaration) {
-		typeDeclaration = StringTools.removeAllWhitespace(typeDeclaration);
-		int arrayDepth = getArrayDepthForTypeDeclaration_(typeDeclaration);
-		String elementTypeName = getElementTypeNameForTypeDeclaration_(typeDeclaration, arrayDepth);
-		return new TypeDeclaration(elementTypeName, arrayDepth);
-	}
-
-	/**
-	 * Returns the array depth for the specified "type declaration"; e.g.<ul>
-	 * <li><code>"int[]"</code> returns <code>1</code>
-	 * <li><code>"java.lang.String[][][]"</code> returns <code>3</code>
-	 * </ul>
-	 */
-	public static int getArrayDepthForTypeDeclaration(String typeDeclaration) {
-		return getArrayDepthForTypeDeclaration_(StringTools.removeAllWhitespace(typeDeclaration));
-	}
-
-	/**
-	 * pre-condition: no whitespace in the type declaration.
-	 */
-	private static int getArrayDepthForTypeDeclaration_(String typeDeclaration) {
-		int last = typeDeclaration.length() - 1;
-		int depth = 0;
-		int close = last;
-		while (typeDeclaration.charAt(close) == ']') {
-			if (typeDeclaration.charAt(close - 1) == '[') {
-				depth++;
-			} else {
-				throw new IllegalArgumentException("invalid type declaration: " + typeDeclaration);
-			}
-			close = last - (depth * 2);
-		}
-		return depth;
-	}
-
-	/**
-	 * Returns the element type name for the specified "type declaration"; e.g.<ul>
-	 * <li><code>"int[]"</code> returns <code>"int"</code>
-	 * <li><code>"java.lang.String[][][]"</code> returns <code>"java.lang.String"</code>
-	 * </ul>
-	 */
-	public static String getElementTypeNameForTypeDeclaration(String typeDeclaration) {
-		typeDeclaration = StringTools.removeAllWhitespace(typeDeclaration);
-		return getElementTypeNameForTypeDeclaration_(typeDeclaration, getArrayDepthForTypeDeclaration_(typeDeclaration));
-	}
-
-	/**
-	 * Returns the element type name for the specified "type declaration"; e.g.<ul>
-	 * <li><code>"int[]"</code> returns <code>"int"</code>
-	 * <li><code>"java.lang.String[][][]"</code> returns <code>"java.lang.String"</code>
-	 * </ul>
-	 * Useful for clients that have already queried the type declaration's array depth.
-	 */
-	public static String getElementTypeNameForTypeDeclaration(String typeDeclaration, int arrayDepth) {
-		return getElementTypeNameForTypeDeclaration_(StringTools.removeAllWhitespace(typeDeclaration), arrayDepth);
-	}
-
-	/**
-	 * pre-condition: no whitespace in the type declaration.
-	 */
-	private static String getElementTypeNameForTypeDeclaration_(String typeDeclaration, int arrayDepth) {
-		return typeDeclaration.substring(0, typeDeclaration.length() - (arrayDepth * 2));
-	}
-
-	/**
-	 * Returns the class for the specified "type declaration".
-	 */
-	public static Class<?> getClassForTypeDeclaration(String elementTypeName, int arrayDepth) {
-		return getClassForTypeDeclaration(elementTypeName, arrayDepth, null);
-	}
-
-	/**
-	 * Returns the class for the specified "type declaration".
-	 */
-	public static Class<?> getClassForTypeDeclaration_(String elementTypeName, int arrayDepth)
-		throws ClassNotFoundException
-	{
-		return getClassForTypeDeclaration_(elementTypeName, arrayDepth, null);
-	}
-
-	/**
-	 * Returns the class for the specified "type declaration",
-	 * using the specified class loader.
-	 */
-	public static Class<?> getClassForTypeDeclaration(String elementTypeName, int arrayDepth, ClassLoader classLoader) {
-		try {
-			return getClassForTypeDeclaration_(elementTypeName, arrayDepth, classLoader);
-		} catch (ClassNotFoundException ex) {
-			throw new RuntimeException(ex);
-		}
-	}
-
-	/**
-	 * Returns the class for the specified "type declaration",
-	 * using the specified class loader.
-	 */
-	// see the "Evaluation" of JDK bug 6446627 for a discussion of loading classes
-	public static Class<?> getClassForTypeDeclaration_(String elementTypeName, int arrayDepth, ClassLoader classLoader)
-		throws ClassNotFoundException
-	{
-		// primitives cannot be loaded via Class.forName(),
-		// so check for a primitive class name first
-		Primitive pcc = null;
-		if (elementTypeName.length() <= MAX_PRIMITIVE_CLASS_NAME_LENGTH) {  // performance tweak
-			for (Primitive primitive : PRIMITIVES) {
-				if (primitive.javaClass.getName().equals(elementTypeName)) {
-					pcc = primitive;
-					break;
-				}
-			}
-		}
-
-		// non-array
-		if (arrayDepth == 0) {
-			return (pcc == null) ? Class.forName(elementTypeName, false, classLoader) : pcc.javaClass;
-		}
-
-		// array
-		StringBuilder sb = new StringBuilder(100);
-		for (int i = arrayDepth; i-- > 0; ) {
-			sb.append('[');
-		}
-		if (pcc == null) {
-			ClassName.append(elementTypeName, sb);
-		} else {
-			sb.append(pcc.code);
-		}
-		return Class.forName(sb.toString(), false, classLoader);
-	}
-
-	/**
-	 * Returns the class name for the specified "type declaration"; e.g.<ul>
-	 * <li><code>"int"</code> returns <code>"int"</code>
-	 * <li><code>"int[]"</code> returns <code>"[I"</code>
-	 * <li><code>"java.lang.String"</code> returns <code>"java.lang.String"</code>
-	 * <li><code>"java.lang.String[][][]"</code> returns <code>"[[[Ljava.lang.String;"</code>
-	 * </ul>
-	 * @see java.lang.Class#getName()
-	 */
-	public static String getClassNameForTypeDeclaration(String typeDeclaration) {
-		TypeDeclaration td = buildTypeDeclaration(typeDeclaration);
-		return getClassNameForTypeDeclaration(td.elementTypeName, td.arrayDepth);
-	}
-
-	/**
-	 * Returns the class name for the specified "type declaration".
-	 * @see java.lang.Class#getName()
-	 */
-	public static String getClassNameForTypeDeclaration(String elementTypeName, int arrayDepth) {
-		// non-array
-		if (arrayDepth == 0) {
-			return elementTypeName;
-		}
-
-		if (elementTypeName.equals(ClassName.VOID_CLASS_NAME)) {
-			throw new IllegalArgumentException('\'' + ClassName.VOID_CLASS_NAME + "' must have an array depth of zero: " + arrayDepth + '.');
-		}
-		// array
-		StringBuilder sb = new StringBuilder(100);
-		for (int i = arrayDepth; i-- > 0; ) {
-			sb.append('[');
-		}
-
-		// look for a primitive first
-		Primitive pcc = null;
-		if (elementTypeName.length() <= MAX_PRIMITIVE_CLASS_NAME_LENGTH) {  // performance tweak
-			for (Primitive primitive : PRIMITIVES) {
-				if (primitive.javaClass.getName().equals(elementTypeName)) {
-					pcc = primitive;
-					break;
-				}
-			}
-		}
-
-		if (pcc == null) {
-			ClassName.append(elementTypeName, sb);
-		} else {
-			sb.append(pcc.code);
-		}
-
-		return sb.toString();
-	}
-
-
-	// ********** exception messages **********
-
-	/**
-	 * Returns a string representation of the specified constructor.
-	 */
-	private static String buildFullyQualifiedConstructorSignature(Class<?> javaClass, Class<?>[] parameterTypes) {
-		return buildFullyQualifiedMethodSignature(javaClass, null, parameterTypes);
-	}
-
-	/**
-	 * Returns a string representation of the specified field.
-	 */
-	private static String buildFullyQualifiedFieldName(Class<?> javaClass, String fieldName) {
-		StringBuilder sb = new StringBuilder(200);
-		sb.append(javaClass.getName());
-		sb.append('.');
-		sb.append(fieldName);
-		return sb.toString();
-	}
-
-	/**
-	 * Returns a string representation of the specified field.
-	 */
-	private static String buildFullyQualifiedFieldName(Object object, String fieldName) {
-		return buildFullyQualifiedFieldName(object.getClass(), fieldName);
-	}
-
-	/**
-	 * Returns a string representation of the specified method.
-	 */
-	private static String buildFullyQualifiedMethodSignature(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) {
-		StringBuilder sb = new StringBuilder(200);
-		sb.append(javaClass.getName());
-		// this check allows us to use this code for constructors, where the methodName is null
-		if (methodName != null) {
-			sb.append('.');
-			sb.append(methodName);
-		}
-		sb.append('(');
-		int max = parameterTypes.length - 1;
-		if (max != -1) {
-			// stop one short of the end of the array
-			for (int i = 0; i < max; i++) {
-				sb.append(parameterTypes[i].getName());
-				sb.append(", ");
-			}
-			sb.append(parameterTypes[max].getName());
-		}
-		sb.append(')');
-		return sb.toString();
-	}
-
-
-	// ********** primitive constants **********
-
-	static final Iterable<Primitive> PRIMITIVES = buildPrimitives();
-
-	public static final char BYTE_CODE = 'B';
-	public static final char CHAR_CODE = 'C';
-	public static final char DOUBLE_CODE = 'D';
-	public static final char FLOAT_CODE = 'F';
-	public static final char INT_CODE = 'I';
-	public static final char LONG_CODE = 'J';
-	public static final char SHORT_CODE = 'S';
-	public static final char BOOLEAN_CODE = 'Z';
-	public static final char VOID_CODE = 'V';
-
-	static final int MAX_PRIMITIVE_CLASS_NAME_LENGTH = calculateMaxPrimitiveClassNameLength();
-	static final int MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH = calculateMaxPrimitiveWrapperClassNameLength();
-
-	private static int calculateMaxPrimitiveClassNameLength() {
-		int max = -1;
-		for (Primitive primitive : PRIMITIVES) {
-			int len = primitive.javaClass.getName().length();
-			if (len > max) {
-				max = len;
-			}
-		}
-		return max;
-	}
-
-	private static int calculateMaxPrimitiveWrapperClassNameLength() {
-		int max = -1;
-		for (Primitive primitive : PRIMITIVES) {
-			int len = primitive.wrapperClass.getName().length();
-			if (len > max) {
-				max = len;
-			}
-		}
-		return max;
-	}
-
-	/**
-	 * <strong>NB:</strong> <code>void.class.isPrimitive() == true</code>
-	 */
-	private static Iterable<Primitive> buildPrimitives() {
-		Primitive[] array = new Primitive[9];
-		array[0] = new Primitive(BYTE_CODE, java.lang.Byte.class);
-		array[1] = new Primitive(CHAR_CODE, java.lang.Character.class);
-		array[2] = new Primitive(DOUBLE_CODE, java.lang.Double.class);
-		array[3] = new Primitive(FLOAT_CODE, java.lang.Float.class);
-		array[4] = new Primitive(INT_CODE, java.lang.Integer.class);
-		array[5] = new Primitive(LONG_CODE, java.lang.Long.class);
-		array[6] = new Primitive(SHORT_CODE, java.lang.Short.class);
-		array[7] = new Primitive(BOOLEAN_CODE, java.lang.Boolean.class);
-		array[8] = new Primitive(VOID_CODE, java.lang.Void.class);
-		return new ArrayIterable<Primitive>(array);
-	}
-
-
-	// ********** member classes **********
-
-	static class Primitive {
-		final char code;
-		final Class<?> javaClass;
-		final Class<?> wrapperClass;
-		private static final String WRAPPER_CLASS_TYPE_FIELD_NAME = "TYPE";
-		// e.g. java.lang.Boolean.TYPE => boolean.class
-		Primitive(char code, Class<?> wrapperClass) {
-			this.code = code;
-			this.wrapperClass = wrapperClass;
-			this.javaClass = (Class<?>) getStaticFieldValue(wrapperClass, WRAPPER_CLASS_TYPE_FIELD_NAME);
-		}
-	}
-
-	private static class TypeDeclaration {
-		final String elementTypeName;
-		final int arrayDepth;
-		TypeDeclaration(String elementTypeName, int arrayDepth) {
-			this.elementTypeName = elementTypeName;
-			this.arrayDepth = arrayDepth;
-		}
-	}
-
-
-	// ********** suppressed constructor **********
-
-	/**
-	 * Suppress default constructor, ensuring non-instantiability.
-	 */
-	private ReflectionTools() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ReverseComparator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ReverseComparator.java
index 0aa7281..36b4a56 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ReverseComparator.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/ReverseComparator.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2008 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -18,28 +18,41 @@
 
 /**
  * This comparator will reverse the order of the specified comparator.
- * If the comparator is null, the natural ordering of the objects will be used.
+ * If the specified comparator is <code>null</code>,
+ * the natural ordering of the objects will be used (i.e. assume the elements
+ * implement the {@link Comparable} interface.
  */
-public class ReverseComparator<E extends Comparable<? super E>>
+public class ReverseComparator<E>
 	implements Comparator<E>, Serializable
 {
 	private final Comparator<E> comparator;
+	private static final long serialVersionUID = 1L;
 
+	/**
+	 * Construct a reverse comparator that will reverse the natural order of
+	 * the compared elements.
+	 */
 	public ReverseComparator() {
 		this(null);
 	}
 
+	/**
+	 * Construct a reverse comparator that will reverse the order of
+	 * the compared elements as calculated by the specified comparator.
+	 */
 	public ReverseComparator(Comparator<E> comparator) {
 		super();
 		this.comparator = comparator;
 	}
 
 	@Override
+	@SuppressWarnings("unchecked")
 	public int compare(E e1, E e2) {
-		return (this.comparator == null) ?
-			e2.compareTo(e1)
-		:
-			this.comparator.compare(e2, e1);
+		return (this.comparator != null) ? this.comparator.compare(e2, e1) : ((Comparable<E>) e2).compareTo(e1);
 	}
 
-}
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.comparator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/RunnableAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/RunnableAdapter.java
index 5e8b539..30a267e 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/RunnableAdapter.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/RunnableAdapter.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -26,6 +26,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this);
+		return ObjectTools.toString(this);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/RunnableSystemExit.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/RunnableSystemExit.java
new file mode 100644
index 0000000..eafc051
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/RunnableSystemExit.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+/**
+ * This runnable will sleep for a specified amount of time
+ * and then kill the JVM with a call to {@link System#exit(int)} with
+ * a client-specified exit status. If the thread is interrupted,
+ * we will stop the thread without killing the JVM.
+ */
+@SuppressWarnings("nls")
+public final class RunnableSystemExit
+	implements Runnable
+{
+	/** The time to wait before killing the JVM, in milliseconds. */
+	private final int wait;
+	/** The exit status code that will passed to the O/S on exit. */
+	private final int exitStatus;
+
+	/**
+	 * Construct a killer that will wait for the specified time and
+	 * exit with the specified exit status.
+	 */
+	public RunnableSystemExit(int wait, int exitStatus) {
+		super();
+		this.wait = wait;
+		this.exitStatus = exitStatus;
+	}
+
+	@Override
+	public void run() {
+		long stop = System.currentTimeMillis() + this.wait;
+		long remaining = this.wait;
+		while (remaining > 0L) {
+			try {
+				Thread.sleep(remaining);
+			} catch (InterruptedException ex) {
+				return;		// commuted death sentence
+			}
+			remaining = stop - System.currentTimeMillis();
+		}
+		System.exit(this.exitStatus);
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, "wait=" + this.wait + "; exit status=" + this.exitStatus);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleAssociation.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleAssociation.java
index 39ce37a..4351adf 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleAssociation.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleAssociation.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -16,7 +16,7 @@
 import java.io.Serializable;
 
 /**
- * Straightforward implementation of {@link Association}.
+ * Straightforward implementation of {@link org.eclipse.jpt.common.utility.Association}.
  */
 public class SimpleAssociation<K, V>
 	extends AbstractAssociation<K, V>
@@ -44,7 +44,6 @@
 		this.value = value;
 	}
 
-
 	@Override
 	public K getKey() {
 		return this.key;
@@ -71,5 +70,4 @@
 			throw new InternalError();
 		}
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleBooleanReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleBooleanReference.java
deleted file mode 100644
index 4531c42..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleBooleanReference.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * Provide a container for passing a flag that can be changed by the recipient.
- * 
- * @see SynchronizedBoolean
- */
-public class SimpleBooleanReference
-	implements ModifiableBooleanReference, Cloneable, Serializable
-{
-	/** Backing <code>boolean</code>. */
-	protected volatile boolean value;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Create a <code>boolean</code> reference with the specified initial value.
-	 */
-	public SimpleBooleanReference(boolean value) {
-		super();
-		this.value = value;
-	}
-
-	/**
-	 * Create a <code>boolean</code> reference with an initial value of
-	 * <code>false</code>.
-	 */
-	public SimpleBooleanReference() {
-		this(false);
-	}
-
-
-	// ********** accessors **********
-
-	@Override
-	public boolean getValue() {
-		return this.value;
-	}
-
-	@Override
-	public boolean is(boolean v) {
-		return this.value == v;
-	}
-
-	@Override
-	public boolean isNot(boolean v) {
-		return this.value != v;
-	}
-
-	@Override
-	public boolean isTrue() {
-		return this.value;
-	}
-
-	@Override
-	public boolean isFalse() {
-		return ! this.value;
-	}
-
-	@Override
-	public boolean setValue(boolean value) {
-		boolean old = this.value;
-		this.value = value;
-		return old;
-	}
-
-	@Override
-	public boolean flip() {
-		return this.value = ! this.value;
-	}
-
-	@Override
-	public boolean setNot(boolean v) {
-		return this.setValue( ! v);
-	}
-
-	@Override
-	public boolean setTrue() {
-		return this.setValue(true);
-	}
-
-	@Override
-	public boolean setFalse() {
-		return this.setValue(false);
-	}
-
-
-	// ********** standard methods **********
-
-	@Override
-	public SimpleBooleanReference clone() {
-		try {
-			return (SimpleBooleanReference) super.clone();
-		} catch (CloneNotSupportedException ex) {
-			throw new InternalError();
-		}
-	}
-
-	/**
-	 * Object identity is critical to boolean references.
-	 * There is no reason for two different boolean references to be
-	 * <em>equal</em>.
-	 * 
-	 * @see #is(boolean)
-	 */
-	@Override
-	public boolean equals(Object obj) {
-		return super.equals(obj);
-	}
-
-	/**
-	 * @see #equals(Object)
-	 */
-	@Override
-	public int hashCode() {
-		return super.hashCode();
-	}
-
-	@Override
-	public String toString() {
-		return '[' + String.valueOf(this.value) + ']';
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleFilter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleFilter.java
deleted file mode 100644
index a48eb37..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleFilter.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * Simple, abstract implementation of <code>Filter</code>
- * that holds on to a criterion object that can be used in the
- * {@link #accept(Object) accept} or {@link #reject(Object) reject}
- * methods. Subclasses can override either of these methods,
- * depending on which is easier to implement. Note that at least
- * one of these methods <em>must</em> be overridden or
- * an infinite loop will occur. If both of them are overridden,
- * only the {@link #accept(Object) accept} method will be used.
- * <p>
- * This class simplifies the implementation of straightforward inner classes.
- * Here is an example of a filter that can be used by a
- * {@link org.eclipse.persistence.tools.utility.iterables.FilteringIterable 
- * Returns only those strings
- * in the nested iterable that start with <code>"prefix"</code>:
- * <pre>
- * Filter<String> filter = new SimpleFilter<String, String>("prefix") {
- *     public boolean accept(String string) {
- * Returns string.startsWith(criterion);
- *     }
- * };
- * </pre>
- */
-public abstract class SimpleFilter<T, C>
-	implements Filter<T>, Cloneable, Serializable
-{
-	protected final C criterion;
-
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Construct a simple filter with a <code>null</code> criterion
-	 */
-	protected SimpleFilter() {
-		this(null);
-	}
-
-	/**
-	 * More useful constructor. The specified criterion can
-	 * be used by a subclass to "accept" or "reject" objects.
-	 */
-	protected SimpleFilter(C criterion) {
-		super();
-		this.criterion = criterion;
-	}
-
-	/**
-	 * Returns whether the the specified object should be "rejected".
-	 * The semantics of "rejected" is determined by the client.
-	 */
-	protected boolean reject(T o) {
-		return ! this.accept(o);
-	}
-
-	/**
-	 * Returns whether the the specified object should be "accepted".
-	 * The semantics of "accepted" is determined by the client.
-	 */
-	@Override
-	public boolean accept(T o) {
-		return ! this.reject(o);
-	}
-
-	/**
-	 * Returns the filter's criterion.
-	 */
-	public C getCriterion() {
-		return this.criterion;
-	}
-
-	@Override
-	public SimpleFilter<T, C> clone() {
-		try {
-			@SuppressWarnings("unchecked")
-			SimpleFilter<T, C> clone = (SimpleFilter<T, C>) super.clone();
-			return clone;
-		} catch (CloneNotSupportedException ex) {
-			throw new InternalError();
-		}
-	}
-
-	@Override
-	public boolean equals(Object o) {
-		if ( ! (o instanceof SimpleFilter<?, ?>)) {
-			return false;
-		}
-		SimpleFilter<?, ?> other = (SimpleFilter<?, ?>) o;
-		return Tools.valuesAreEqual(this.criterion, other.criterion);
-	}
-
-	@Override
-	public int hashCode() {
-		return (this.criterion == null) ? 0 : this.criterion.hashCode();
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.criterion);
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleIntReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleIntReference.java
deleted file mode 100644
index 1f12474..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleIntReference.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * This class can be used wherever a mutable integer object is needed.
- * It is a cross between an <code>int</code> and an {@link Integer}.
- * It can be stored in a standard container (e.g. {@link java.util.Collection})
- * but can be modified. It is also useful passing a value that can be changed
- * by the recipient.
- * 
- * @see SynchronizedInt
- */
-public final class SimpleIntReference
-	implements ModifiableIntReference, Cloneable, Serializable
-{
-	/** Backing <code>int</code>. */
-	private volatile int value = 0;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct a <code>int</code> reference with the specified initial value.
-	 */
-	public SimpleIntReference(int count) {
-		super();
-		this.value = count;
-	}
-
-	/**
-	 * Construct a <code>int</code> reference with an initial value of zero.
-	 */
-	public SimpleIntReference() {
-		this(0);
-	}
-
-
-	// ********** methods **********
-
-	@Override
-	public int getValue() {
-		return this.value;
-	}
-
-	@Override
-	public boolean equals(int v) {
-		return this.value == v;
-	}
-
-	@Override
-	public boolean notEqual(int v) {
-		return this.value != v;
-	}
-
-	@Override
-	public boolean isZero() {
-		return this.value == 0;
-	}
-
-	@Override
-	public boolean isNotZero() {
-		return this.value != 0;
-	}
-
-	@Override
-	public boolean isGreaterThan(int v) {
-		return this.value > v;
-	}
-
-	@Override
-	public boolean isGreaterThanOrEqual(int v) {
-		return this.value >= v;
-	}
-
-	@Override
-	public boolean isLessThan(int v) {
-		return this.value < v;
-	}
-
-	@Override
-	public boolean isLessThanOrEqual(int v) {
-		return this.value <= v;
-	}
-
-	@Override
-	public boolean isPositive() {
-		return this.isGreaterThan(0);
-	}
-
-	@Override
-	public boolean isNotPositive() {
-		return this.isLessThanOrEqual(0);
-	}
-
-	@Override
-	public boolean isNegative() {
-		return this.isLessThan(0);
-	}
-
-	@Override
-	public boolean isNotNegative() {
-		return this.isGreaterThanOrEqual(0);
-	}
-
-	@Override
-	public int abs() {
-		return Math.abs(this.value);
-	}
-
-	@Override
-	public int neg() {
-		return -this.value;
-	}
-
-	@Override
-	public int add(int v) {
-		return this.value + v;
-	}
-
-	@Override
-	public int subtract(int v) {
-		return this.value - v;
-	}
-
-	@Override
-	public int multiply(int v) {
-		return this.value * v;
-	}
-
-	@Override
-	public int divide(int v) {
-		return this.value / v;
-	}
-
-	@Override
-	public int remainder(int v) {
-		return this.value % v;
-	}
-
-	@Override
-	public int min(int v) {
-		return Math.min(this.value, v);
-	}
-
-	@Override
-	public int max(int v) {
-		return Math.max(this.value, v);
-	}
-
-	@Override
-	public double pow(int v) {
-		return Math.pow(this.value, v);
-	}
-
-	@Override
-	public int setValue(int value) {
-		int old = this.value;
-		this.value = value;
-		return old;
-	}
-
-	@Override
-	public int setZero() {
-		return this.setValue(0);
-	}
-
-	@Override
-	public int increment() {
-		return ++this.value;
-	}
-
-	@Override
-	public int decrement() {
-		return --this.value;
-	}
-
-
-	// ********** Comparable implementation **********
-
-	@Override
-	public int compareTo(IntReference ref) {
-		int v = ref.getValue();
-		return (this.value < v) ? -1 : ((this.value == v) ? 0 : 1);
-	}
-
-
-	// ********** standard methods **********
-
-	@Override
-	public SimpleIntReference clone() {
-		try {
-			return (SimpleIntReference) super.clone();
-		} catch (CloneNotSupportedException ex) {
-			throw new InternalError();
-		}
-	}
-
-	@Override
-	public String toString() {
-		return '[' + String.valueOf(this.value) + ']';
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleJavaType.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleJavaType.java
index 7c3a9ff..d8912aa 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleJavaType.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleJavaType.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -15,6 +15,7 @@
 
 import java.io.PrintWriter;
 import java.io.Serializable;
+import java.util.HashMap;
 
 /**
  * Straightforward implementation of the {@link JavaType} interface.
@@ -23,7 +24,6 @@
 public final class SimpleJavaType
 	implements JavaType, Cloneable, Serializable
 {
-
 	/**
 	 * store the type as a name, so we can reference classes
 	 * that are not loaded
@@ -38,9 +38,38 @@
 	private static final String BRACKETS = "[]";
 	private static final long serialVersionUID = 1L;
 
+	/**
+	 * Cache the "standard" java types for performance
+	 * Defining this as java.lang*, java.util*, java.sql.* for array dimensionality of 0
+	 * Make this a HashMap for performance, duplicate creation shouldn't be an issue.
+	 */
+	private static final HashMap<String, JavaType> stardardJavaTypesCache = new HashMap<String, JavaType>();
+
 	// ********** constructors **********
 
 	/**
+	 * Use this factory method for performance. Standard java types will be cached.
+	 */
+	//TODO SimpleJavaType(String, int) used incorrectly when building method parameter types
+	//buildSimpleType(java.lang.String[], 1) - this gets passed in for a method parameter String[]
+	public static JavaType buildSimpleJavaType(String elementTypeName, int arrayDepth) {
+		if (arrayDepth == 0) {
+			JavaType javaType = stardardJavaTypesCache.get(elementTypeName);
+			if (javaType != null) {
+				return javaType;
+			}
+			if (elementTypeName.startsWith("java.lang.") || //$NON-NLS-1$
+					elementTypeName.startsWith("java.util.") || //$NON-NLS-1$
+					elementTypeName.startsWith("java.sql.")) { //$NON-NLS-1$
+				javaType = new SimpleJavaType(elementTypeName, arrayDepth);
+				stardardJavaTypesCache.put(elementTypeName, javaType);
+				return javaType;
+			}
+		}
+		return new SimpleJavaType(elementTypeName, arrayDepth);
+	}
+
+	/**
 	 * Construct a Java type with the specified element type and array depth.
 	 */
 	public SimpleJavaType(String elementTypeName, int arrayDepth) {
@@ -48,7 +77,7 @@
 		if ((elementTypeName == null) || (elementTypeName.length() == 0)) {
 			throw new IllegalArgumentException("The element type name is required.");
 		}
-		if (ClassName.getArrayDepth(elementTypeName) != 0) {		// e.g. "[Ljava.lang.Object;"
+		if (ClassNameTools.arrayDepth(elementTypeName) != 0) {		// e.g. "[Ljava.lang.Object;"
 			throw new IllegalArgumentException("The element type must not be an array: " + elementTypeName + '.');
 		}
 		if (arrayDepth < 0) {
@@ -73,7 +102,7 @@
 	 * </code></ul>
 	 */
 	public SimpleJavaType(String javaClassName) {
-		this(ClassName.getElementTypeName(javaClassName), ClassName.getArrayDepth(javaClassName));
+		this(ClassNameTools.elementTypeName(javaClassName), ClassNameTools.arrayDepth(javaClassName));
 	}
 
 	/**
@@ -106,32 +135,32 @@
 
 	@Override
 	public boolean isPrimitive() {
-		return (this.arrayDepth == 0) && ClassName.isPrimitive(this.elementTypeName);
+		return (this.arrayDepth == 0) && ClassNameTools.isPrimitive(this.elementTypeName);
 	}
 
 	@Override
 	public boolean isPrimitiveWrapper() {
-		return (this.arrayDepth == 0) && ClassName.isPrimitiveWrapper(this.elementTypeName);
+		return (this.arrayDepth == 0) && ClassNameTools.isPrimitiveWrapper(this.elementTypeName);
 	}
 
 	@Override
 	public boolean isVariablePrimitive() {
-		return (this.arrayDepth == 0) && ClassName.isVariablePrimitive(this.elementTypeName);
+		return (this.arrayDepth == 0) && ClassNameTools.isVariablePrimitive(this.elementTypeName);
 	}
 
 	@Override
 	public boolean isVariablePrimitiveWrapper() {
-		return (this.arrayDepth == 0) && ClassName.isVariablePrimitiveWrapper(this.elementTypeName);
+		return (this.arrayDepth == 0) && ClassNameTools.isVariablePrimitiveWrapper(this.elementTypeName);
 	}
 
 	@Override
 	public Class<?> getJavaClass() throws ClassNotFoundException {
-		return ReflectionTools.getClassForTypeDeclaration(this.elementTypeName, this.arrayDepth);
+		return ClassTools.forTypeDeclaration(this.elementTypeName, this.arrayDepth);
 	}
 
 	@Override
 	public String getJavaClassName() {
-		return ReflectionTools.getClassNameForTypeDeclaration(this.elementTypeName, this.arrayDepth);
+		return TypeDeclarationTools.className(this.elementTypeName, this.arrayDepth);
 	}
 
 
@@ -145,7 +174,7 @@
 
 	@Override
 	public boolean describes(String className) {
-		return this.equals(ClassName.getElementTypeName(className), ClassName.getArrayDepth(className));
+		return this.equals(ClassNameTools.elementTypeName(className), ClassNameTools.arrayDepth(className));
 	}
 
 	@Override
@@ -227,5 +256,4 @@
 			throw new InternalError();
 		}
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleMethodSignature.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleMethodSignature.java
index 1424bee..03306a2 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleMethodSignature.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleMethodSignature.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -38,6 +38,7 @@
 	private static final String PARAMETER_SEPARATOR = ", ";
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructors **********
 
 	/**
@@ -160,7 +161,7 @@
 				return false;
 			}
 		}
-		return true;
+        return true;
 	}
 
 	@Override
@@ -245,5 +246,4 @@
 			throw new InternalError();
 		}
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleObjectReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleObjectReference.java
deleted file mode 100644
index a7e2b2b..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleObjectReference.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * Provide a container for passing an object that can be changed by the recipient.
- * 
- * @see SynchronizedObject
- */
-public class SimpleObjectReference<V>
-	implements ModifiableObjectReference<V>, Cloneable, Serializable
-{
-	/** Backing value. */
-	private volatile V value;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Create an object reference with the specified initial value.
-	 */
-	public SimpleObjectReference(V value) {
-		super();
-		this.value = value;
-	}
-
-	/**
-	 * Create an object reference with an initial value of
-	 * <code>null</code>.
-	 */
-	public SimpleObjectReference() {
-		this(null);
-	}
-
-
-	// ********** value **********
-
-	@Override
-	public V getValue() {
-		return this.value;
-	}
-
-	@Override
-	public boolean valueEquals(Object object) {
-		return Tools.valuesAreEqual(this.value, object);
-	}
-
-	@Override
-	public boolean valueNotEqual(Object object) {
-		return Tools.valuesAreDifferent(this.value, object);
-	}
-
-	@Override
-	public boolean isNull() {
-		return this.value == null;
-	}
-
-	@Override
-	public boolean isNotNull() {
-		return this.value != null;
-	}
-
-	@Override
-	public V setValue(V value) {
-		V old = this.value;
-		this.value = value;
-		return old;
-	}
-
-	@Override
-	public V setNull() {
-		return this.setValue(null);
-	}
-
-
-	// ********** standard methods **********
-
-	@Override
-	public SimpleObjectReference<V> clone() {
-		try {
-			@SuppressWarnings("unchecked")
-			SimpleObjectReference<V> clone = (SimpleObjectReference<V>) super.clone();
-			return clone;
-		} catch (CloneNotSupportedException ex) {
-			throw new InternalError();
-		}
-	}
-
-	@Override
-	public String toString() {
-		return '[' + String.valueOf(this.value) + ']';
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleQueue.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleQueue.java
deleted file mode 100644
index 7c09529..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleQueue.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.LinkedList;
-
-/**
- * Straightforward implementation of the {@link Queue} interface.
- */
-public class SimpleQueue<E>
-	implements Queue<E>, Cloneable, Serializable
-{
-	private LinkedList<E> elements;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct an empty queue.
-	 */
-	public SimpleQueue() {
-		super();
-		this.elements = new LinkedList<E>();
-	}
-
-	/**
-	 * Construct a queue containing the elements of the specified
-	 * collection. The queue will dequeue its elements in the same
-	 * order they are returned by the collection's iterator (i.e. the
-	 * first element returned by the collection's iterator will be the
-	 * first element returned by {@link #dequeue()}).
-	 */
-	public SimpleQueue(Collection<? extends E> c) {
-		super();
-		this.elements = new LinkedList<E>(c);
-	}
-
-
-	// ********** Queue implementation **********
-
-	@Override
-	public void enqueue(E o) {
-		this.elements.addLast(o);
-	}
-
-	@Override
-	public E dequeue() {
-		return this.elements.removeFirst();
-	}
-
-	@Override
-	public E peek() {
-		return this.elements.getFirst();
-	}
-
-	@Override
-	public boolean isEmpty() {
-		return this.elements.isEmpty();
-	}
-
-
-	// ********** Cloneable implementation **********
-
-	@Override
-	public SimpleQueue<E> clone() {
-		try {
-			@SuppressWarnings("unchecked")
-			SimpleQueue<E> clone = (SimpleQueue<E>) super.clone();
-			@SuppressWarnings("unchecked")
-			LinkedList<E> ll = (LinkedList<E>) this.elements.clone();
-			clone.elements = ll;
-			return clone;
-		} catch (CloneNotSupportedException ex) {
-			throw new InternalError();
-		}
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.peek());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleStack.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleStack.java
deleted file mode 100644
index 451251e..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleStack.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.EmptyStackException;
-import java.util.LinkedList;
-import java.util.NoSuchElementException;
-
-/**
- * Straightforward implementation of the {@link Stack} interface.
- */
-public class SimpleStack<E>
-	implements Stack<E>, Cloneable, Serializable
-{
-	private LinkedList<E> elements;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct an empty stack.
-	 */
-	public SimpleStack() {
-		super();
-		this.elements = new LinkedList<E>();
-	}
-
-	/**
-	 * Construct a stack containing the elements of the specified
-	 * collection. The stack will pop its elements in reverse of the
-	 * order they are returned by the collection's iterator (i.e. the
-	 * last element returned by the collection's iterator will be the
-	 * first element returned by {@link #pop()}).
-	 */
-	public SimpleStack(Collection<? extends E> collection) {
-		super();
-		this.elements = new LinkedList<E>(collection);
-	}
-
-
-	// ********** Stack implementation **********
-
-	@Override
-	public void push(E element) {
-		this.elements.addLast(element);
-	}
-
-	@Override
-	public E pop() {
-		try {
-			return this.elements.removeLast();
-		} catch (NoSuchElementException ex) {
-			throw new EmptyStackException();
-		}
-	}
-
-	@Override
-	public E peek() {
-		try {
-			return this.elements.getLast();
-		} catch (NoSuchElementException ex) {
-			throw new EmptyStackException();
-		}
-	}
-
-	@Override
-	public boolean isEmpty() {
-		return this.elements.isEmpty();
-	}
-
-
-	// ********** standard methods **********
-
-	@Override
-	public SimpleStack<E> clone() {
-		try {
-			@SuppressWarnings("unchecked")
-			SimpleStack<E> clone = (SimpleStack<E>) super.clone();
-			@SuppressWarnings("unchecked")
-			LinkedList<E> ll = (LinkedList<E>) this.elements.clone();
-			clone.elements = ll;
-			return clone;
-		} catch (CloneNotSupportedException ex) {
-			throw new InternalError();
-		}
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.peek());
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleStringMatcher.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleStringMatcher.java
deleted file mode 100644
index ee6d180..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleStringMatcher.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-import java.util.regex.Pattern;
-
-// TODO the regex code is not very fast - we could probably do better,
-// hand-coding the matching algorithm (eclipse StringMatcher?)
-/**
- * This class implements a simple string-matching algorithm that is a little
- * more user-friendly than standard regular expressions. Instantiate a
- * string matcher with a filter pattern and then you can use the matcher
- * to determine whether another string (or object) matches the pattern.
- * You can also specify whether the matching should be case-sensitive.
- *
- * The pattern can contain two "meta-characters":
- * 	'*' will match any set of zero or more characters
- * 	'?' will match any single character
- *
- * Subclasses can override #prefix() and/or #suffix() to change what
- * strings are prepended or appended to the original pattern string.
- * This can offer a slight performance improvement over concatenating
- * strings before calling #setPatternString(String).
- * By default, a '*' is appended to every string.
- *
- * This class also uses the string-matching algorithm to "filter" objects
- * (and, as a result, also implements the Filter interface).
- * A string converter is used to determine what string aspect of the
- * object is compared to the pattern. By default the string returned
- * by the object's #toString() method is passed to the pattern matcher.
- */
-@SuppressWarnings("nls")
-public class SimpleStringMatcher<T>
-	implements StringMatcher, Filter<T>, Serializable
-{
-
-	/** An adapter that converts the objects into strings to be matched with the pattern. */
-	private StringConverter<T> stringConverter;
-
-	/** The string used to construct the regular expression pattern. */
-	private String patternString;
-
-	/** Whether the matcher ignores case - the default is true. */
-	private boolean ignoresCase;
-
-	/** The regular expression pattern built from the pattern string. */
-	private Pattern pattern;
-
-	/** A list of the meta-characters we need to escape if found in the pattern string. */
-	public static final char[] REG_EX_META_CHARS = { '(', '[', '{', '\\', '^', '$', '|', ')', '?', '*', '+', '.' };
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct a string matcher with an pattern that will match
-	 * any string and ignore case.
-	 */
-	public SimpleStringMatcher() {
-		this("*");
-	}
-
-	/**
-	 * Construct a string matcher with the specified pattern
-	 * that will ignore case.
-	 */
-	public SimpleStringMatcher(String patternString) {
-		this(patternString, true);
-	}
-
-	/**
-	 * Construct a string matcher with the specified pattern that will
-	 * ignore case as specified.
-	 */
-	public SimpleStringMatcher(String patternString, boolean ignoresCase) {
-		super();
-		this.patternString = patternString;
-		this.ignoresCase = ignoresCase;
-		this.initialize();
-	}
-
-
-	// ********** initialization **********
-
-	protected void initialize() {
-		this.stringConverter = StringConverter.Default.instance();
-		this.rebuildPattern();
-	}
-
-	/**
-	 * Given the current pattern string and case-sensitivity setting,
-	 * re-build the regular expression pattern.
-	 */
-	protected synchronized void rebuildPattern() {
-		this.pattern = this.buildPattern();
-	}
-
-	/**
-	 * Given the current pattern string and case-sensitivity setting,
-	 * Returns a regular expression pattern that can be used
-	 * to match strings.
-	 */
-	protected Pattern buildPattern() {
-		int patternFlags = 0x0;
-		if (this.ignoresCase) {
-			patternFlags = Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE;
-		}
-		return Pattern.compile(this.convertToRegEx(this.patternString), patternFlags);
-	}
-
-
-	// ********** StringMatcher implementation **********
-
-	@Override
-	public synchronized void setPatternString(String patternString) {
-		this.patternString = patternString;
-		this.rebuildPattern();
-	}
-
-	/**
-	 * Returns whether the specified string matches the pattern.
-	 */
-	@Override
-	public synchronized boolean matches(String string) {
-		return this.pattern.matcher(string).matches();
-	}
-
-
-	// ********** Filter implementation **********
-
-	@Override
-	public synchronized boolean accept(T o) {
-		return this.matches(this.stringConverter.convertToString(o));
-	}
-
-
-	// ********** accessors **********
-
-	/**
-	 * Returns the string converter used to convert the objects
-	 * passed to the matcher into strings.
-	 */
-	public synchronized StringConverter<T> stringConverter() {
-		return this.stringConverter;
-	}
-
-	/**
-	 * Set the string converter used to convert the objects
-	 * passed to the matcher into strings.
-	 */
-	public synchronized void setStringConverter(StringConverter<T> stringConverter) {
-		this.stringConverter = stringConverter;
-	}
-
-	/**
-	 * Returns the original pattern string.
-	 */
-	public synchronized String patternString() {
-		return this.patternString;
-	}
-
-	/**
-	 * Returns whether the matcher ignores case.
-	 */
-	public synchronized boolean ignoresCase() {
-		return this.ignoresCase;
-	}
-
-	/**
-	 * Set whether the matcher ignores case.
-	 */
-	public synchronized void setIgnoresCase(boolean ignoresCase) {
-		this.ignoresCase = ignoresCase;
-		this.rebuildPattern();
-	}
-
-	/**
-	 * Returns the regular expression pattern.
-	 */
-	public synchronized Pattern pattern() {
-		return this.pattern;
-	}
-
-
-	// ********** other public API **********
-
-	/**
-	 * Returns the regular expression corresponding to
-	 * the original pattern string.
-	 */
-	public synchronized String regularExpression() {
-		return this.convertToRegEx(this.patternString);
-	}
-
-
-	// ********** converting **********
-
-	/**
-	 * Convert the specified string to a regular expression.
-	 */
-	protected String convertToRegEx(String string) {
-		StringBuffer sb = new StringBuffer(string.length() + 10);
-		this.convertToRegExOn(this.prefix(), sb);
-		this.convertToRegExOn(string, sb);
-		this.convertToRegExOn(this.suffix(), sb);
-		return sb.toString();
-	}
-
-	/**
-	 * Returns any prefix that should be prepended to the original
-	 * string. By default, there is no prefix.
-	 */
-	protected String prefix() {
-		return StringTools.EMPTY_STRING;
-	}
-
-	/**
-	 * Returns any suffix that should be appended to the original
-	 * string. Since this class is typically used in UI situation where
-	 * the user is typing in a pattern used to filter a list, the default
-	 * suffix is a wildcard character.
-	 */
-	protected String suffix() {
-		return "*";
-	}
-
-	/**
-	 * Convert the specified string to a regular expression.
-	 */
-	protected void convertToRegExOn(String string, StringBuffer sb) {
-		char[] charArray = string.toCharArray();
-		int length = charArray.length;
-		for (int i = 0; i < length; i++) {
-			char c = charArray[i];
-			// convert user-friendly meta-chars into regex meta-chars
-			if (c == '*') {
-				sb.append(".*");
-				continue;
-			}
-			if (c == '?') {
-				sb.append('.');
-				continue;
-			}
-			// escape regex meta-chars
-			if (ArrayTools.contains(REG_EX_META_CHARS, c)) {
-				sb.append('\\');
-			}
-			sb.append(c);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleThreadFactory.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleThreadFactory.java
index 44f8276..d8d3ee1 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleThreadFactory.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SimpleThreadFactory.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -27,7 +27,7 @@
 	private static final SimpleThreadFactory INSTANCE = new SimpleThreadFactory();
 
 	/**
-	 * Returns the singleton.
+	 * Return the singleton.
 	 */
 	public static ThreadFactory instance() {
 		return INSTANCE;
@@ -55,4 +55,4 @@
 		// replace this object with the singleton
 		return INSTANCE;
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Stack.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Stack.java
deleted file mode 100644
index ad68423..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Stack.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-import java.util.EmptyStackException;
-
-/**
- * Interface defining the classic stack behavior, without the backdoors allowed by {@link
- * java.util.Stack Stack}.
- *
- * @param <E> the type of elements contained by the stack
- */
-public interface Stack<E> {
-
-	/**
-	 * Returns whether the stack is empty.
-	 */
-	boolean isEmpty();
-
-	/**
-	 * Returns the item on the top of the stack
-	 * without removing it from the stack.
-	 */
-	E peek();
-
-	/**
-	 * "Pop" an item from the top of the stack.
-	 */
-	E pop();
-
-	/**
-	 * "Push" the specified item on to the top of the stack.
-	 */
-	void push(E element);
-
-	final class Empty<E> implements Stack<E>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final Stack INSTANCE = new Empty();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Empty() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <T> Stack<T> instance() {
-			return INSTANCE;
-		}
-		@Override
-		public boolean isEmpty() {
-			return true;
-		}
-		@Override
-		public E peek() {
-			throw new EmptyStackException();
-		}
-		@Override
-		public E pop() {
-			throw new EmptyStackException();
-		}
-		@Override
-		public void push(E element) {
-			throw new UnsupportedOperationException();
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StackTrace.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StackTrace.java
index b3a05f5..8992f1d 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StackTrace.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StackTrace.java
@@ -1,18 +1,21 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. 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.
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
  *
  * Contributors:
  *     Oracle - initial API and implementation
+ *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility;
 
 import java.io.IOException;
 import java.io.Serializable;
-
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
 
 /**
  * Container for holding and printing the {@StackTraceElement stack trace
@@ -21,8 +24,9 @@
  * @see Thread#getStackTrace()
  * @see Throwable#getStackTrace()
  */
-public class StackTrace implements Serializable {
-
+public class StackTrace
+	implements Serializable
+{
 	private final Thread thread;
 	private final StackTraceElement[] elements;
 	private volatile String string;
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringBufferTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringBufferTools.java
new file mode 100644
index 0000000..e77d4c4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringBufferTools.java
@@ -0,0 +1,1915 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+/**
+ * {@link StringBuffer} utility methods.
+ * <p>
+ * As of JDK 1.5, it's tempting to convert all of these methods to use
+ * {@link Appendable};
+ * but all the {@link Appendable} methods throw {@link java.io.IOException} (yech) and
+ * we [might?] get a bit better performance invoking methods on classes than
+ * we get on interfaces. :-)
+ *
+ * @see StringTools
+ */
+@SuppressWarnings("nls")
+public final class StringBufferTools {
+
+	// ********** char[] **********
+
+	/**
+	 * Convert the specified string buffer to a charactor array
+	 * (<code>char[]</code>).
+	 */
+	public static char[] convertToCharArray(StringBuffer sb) {
+		int len = sb.length();
+		char[] result = new char[len];
+		sb.getChars(0, len, result, 0);
+		return result;
+	}
+
+
+	// ********** padding/truncating/centering **********
+
+	/**
+	 * Center the specified string in the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with spaces at
+	 * each end.
+	 */
+	public static void center(StringBuffer sb, String string, int length) {
+		center(sb, string, length, ' ');
+	}
+
+	/**
+	 * @see #center(StringBuffer, String, int)
+	 */
+	public static void center(StringBuffer sb, char[] string, int length) {
+		center(sb, string, length, ' ');
+	}
+
+	/**
+	 * Center the specified string in the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at each end.
+	 */
+	public static void center(StringBuffer sb, String string, int length, char c) {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length();
+		if (stringLength == length) {
+			sb.append(string);
+		} else if (stringLength > length) {
+			int begin = (stringLength - length) >> 1; // take fewer characters off the front
+			sb.append(string, begin, begin + length);  // NB: end index is exclusive
+		} else {
+			int begin = (length - stringLength) >> 1; // add fewer characters to the front
+			fill(sb, begin, c);
+			sb.append(string);
+			fill(sb, length - (begin + stringLength), c);
+		}
+	}
+
+	/**
+	 * @see #center(StringBuffer, String, int, char)
+	 */
+	public static void center(StringBuffer sb, char[] string, int length, char c) {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length;
+		if (stringLength == length) {
+			sb.append(string);
+		} else if (stringLength > length) {
+			int begin = (stringLength - length) >> 1; // take fewer characters off the front
+			sb.append(string, begin, length);
+		} else {
+			int begin = (length - stringLength) >> 1; // add fewer characters to the front
+			fill(sb, begin, c);
+			sb.append(string);
+			fill(sb, length - (begin + stringLength), c);
+		}
+	}
+
+	/**
+	 * Pad the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with spaces
+	 * at the end.
+	 */
+	public static void pad(StringBuffer sb, String string, int length) {
+		pad(sb, string, length, ' ');
+	}
+
+	/**
+	 * @see #pad(StringBuffer, String, int)
+	 */
+	public static void pad(StringBuffer sb, char[] string, int length) {
+		pad(sb, string, length, ' ');
+	}
+
+	/**
+	 * Pad the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at the end.
+	 */
+	public static void pad(StringBuffer sb, String string, int length, char c) {
+		int stringLength = string.length();
+		if (stringLength > length) {
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
+		}
+		if (stringLength == length) {
+			sb.append(string);
+		} else {
+			pad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * @see #pad(StringBuffer, String, int, char)
+	 */
+	public static void pad(StringBuffer sb, char[] string, int length, char c) {
+		int stringLength = string.length;
+		if (stringLength > length) {
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
+		}
+		if (stringLength == length) {
+			sb.append(string);
+		} else {
+			pad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * Pad or truncate the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with spaces at
+	 * the end.
+	 */
+	public static void fit(StringBuffer sb, String string, int length) {
+		fit(sb, string, length, ' ');
+	}
+
+	/**
+	 * @see #fit(StringBuffer, String, int)
+	 */
+	public static void fit(StringBuffer sb, char[] string, int length) {
+		fit(sb, string, length, ' ');
+	}
+
+	/**
+	 * Pad or truncate the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at the end.
+	 */
+	public static void fit(StringBuffer sb, String string, int length, char c) {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length();
+		if (stringLength == length) {
+			sb.append(string);
+		} else if (stringLength > length) {
+			sb.append(string, 0, length);  // NB: end index is exclusive
+		} else {
+			pad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * @see #fit(StringBuffer, String, int, char)
+	 */
+	public static void fit(StringBuffer sb, char[] string, int length, char c) {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length;
+		if (stringLength == length) {
+			sb.append(string);
+		} else if (stringLength > length) {
+			sb.append(string, 0, length);
+		} else {
+			pad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * Pad the specified string without validating the parms.
+	 */
+	private static void pad_(StringBuffer sb, String string, int stringLength, int length, char c) {
+		sb.append(string);
+		fill(sb, stringLength, length, c);
+	}
+
+	/**
+	 * Pad the specified string without validating the parms.
+	 */
+	private static void pad_(StringBuffer sb, char[] string, int stringLength, int length, char c) {
+		sb.append(string);
+		fill(sb, stringLength, length, c);
+	}
+
+	/**
+	 * Add enough characters to the specified stream to compensate for
+	 * the difference between the specified string length and specified length.
+	 */
+	private static void fill(StringBuffer sb, int stringLength, int length, char c) {
+		fill(sb, length - stringLength, c);
+	}
+
+	/**
+	 * Add the specified length of characters to the specified stream.
+	 */
+	private static void fill(StringBuffer sb, int length, char c) {
+		sb.append(ArrayTools.fill(new char[length], c));
+	}
+
+	/**
+	 * Pad the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with zeros
+	 * at the front.
+	 */
+	public static void zeroPad(StringBuffer sb, String string, int length) {
+		frontPad(sb, string, length, '0');
+	}
+
+	/**
+	 * @see #zeroPad(StringBuffer, String, int)
+	 */
+	public static void zeroPad(StringBuffer sb, char[] string, int length) {
+		frontPad(sb, string, length, '0');
+	}
+
+	/**
+	 * Pad the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at the front.
+	 */
+	public static void frontPad(StringBuffer sb, String string, int length, char c) {
+		int stringLength = string.length();
+		if (stringLength > length) {
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
+		}
+		if (stringLength == length) {
+			sb.append(string);
+		} else {
+			frontPad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * @see #frontPad(StringBuffer, String, int, char)
+	 */
+	public static void frontPad(StringBuffer sb, char[] string, int length, char c) {
+		int stringLength = string.length;
+		if (stringLength > length) {
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
+		}
+		if (stringLength == length) {
+			sb.append(string);
+		} else {
+			frontPad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * Pad or truncate the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, append only the last
+	 * part of the string.
+	 * If the string is shorter than the specified length, pad it with zeros
+	 * at the front.
+	 */
+	public static void zeroFit(StringBuffer sb, String string, int length) {
+		frontFit(sb, string, length, '0');
+	}
+
+	/**
+	 * @see #zeroFit(StringBuffer, String, int)
+	 */
+	public static void zeroFit(StringBuffer sb, char[] string, int length) {
+		frontFit(sb, string, length, '0');
+	}
+
+	/**
+	 * Pad or truncate the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, append only the last
+	 * part of the string.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at the front.
+	 */
+	public static void frontFit(StringBuffer sb, String string, int length, char c) {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length();
+		if (stringLength == length) {
+			sb.append(string);
+		} else if (stringLength > length) {
+			sb.append(string, stringLength - length, stringLength);  // NB: end index is exclusive
+		} else {
+			frontPad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * @see #frontFit(StringBuffer, String, int, char)
+	 */
+	public static void frontFit(StringBuffer sb, char[] string, int length, char c) {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length;
+		if (stringLength == length) {
+			sb.append(string);
+		} else if (stringLength > length) {
+			sb.append(string, stringLength - length, length);
+		} else {
+			frontPad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * Pad the specified string without validating the parms.
+	 */
+	private static void frontPad_(StringBuffer sb, String string, int stringLength, int length, char c) {
+		fill(sb, stringLength, length, c);
+		sb.append(string);
+	}
+
+	/**
+	 * Pad the specified string without validating the parms.
+	 */
+	private static void frontPad_(StringBuffer sb, char[] string, int stringLength, int length, char c) {
+		fill(sb, stringLength, length, c);
+		sb.append(string);
+	}
+
+
+	// ********** separating **********
+
+	/**
+	 * Separate the segments of the specified string with the specified
+	 * separator:<p>
+	 * <code>
+	 * separate("012345", '-', 2) => "01-23-45"
+	 * </code>
+	 */
+	public static void separate(StringBuffer sb, String string, char separator, int segmentSize) {
+		if (segmentSize <= 0) {
+			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
+		}
+		int stringLength = string.length();
+		if (stringLength <= segmentSize) {
+			sb.append(string);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + (stringLength / segmentSize));
+			separate(sb, string, separator, segmentSize, stringLength);
+		}
+	}
+
+	/**
+	 * Pre-conditions: string is longer than segment size; segment size is positive
+	 */
+	private static void separate(StringBuffer sb, String string, char separator, int segmentSize, int stringLength) {
+		int segCount = 0;
+		for (int i = 0; i < stringLength; i++) {
+			char c = string.charAt(i);
+			if (segCount == segmentSize) {
+				sb.append(separator);
+				segCount = 0;
+			}
+			segCount++;
+			sb.append(c);
+		}
+	}
+
+	/**
+	 * @see #separate(StringBuffer, String, char, int)
+	 */
+	public static void separate(StringBuffer sb, char[] string, char separator, int segmentSize) {
+		if (segmentSize <= 0) {
+			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
+		}
+		int stringLength = string.length;
+		if (stringLength <= segmentSize) {
+			sb.append(string);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + (stringLength / segmentSize));
+			separate(sb, string, separator, segmentSize, stringLength);
+		}
+	}
+
+	/**
+	 * Pre-conditions: string is longer than segment size; segment size is positive
+	 */
+	private static void separate(StringBuffer sb, char[] string, char separator, int segmentSize, int stringLength) {
+		int segCount = 0;
+		for (int i = 0; i < stringLength; i++) {
+			char c = string[i];
+			if (segCount == segmentSize) {
+				sb.append(separator);
+				segCount = 0;
+			}
+			segCount++;
+			sb.append(c);
+		}
+	}
+
+
+	// ********** delimiting/quoting **********
+
+	/**
+	 * Delimit the specified string with double quotes.
+	 * Escape any occurrences of a double quote in the string with another
+	 * double quote.
+	 */
+	public static void quote(StringBuffer sb, String string) {
+		delimit(sb, string, CharacterTools.QUOTE);
+	}
+
+	/**
+	 * @see #quote(StringBuffer, String)
+	 */
+	public static void quote(StringBuffer sb, char[] string) {
+		delimit(sb, string, CharacterTools.QUOTE);
+	}
+
+	/**
+	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
+	 * the delimiter at the front and back of the resulting string.
+	 * Escape any occurrences of the delimiter in the string with another delimiter.
+	 */
+	public static void delimit(StringBuffer sb, String string, char delimiter) {
+		int stringLength = string.length();
+		sb.ensureCapacity(sb.length() + stringLength + 2);
+		delimit(sb, string, delimiter, stringLength);
+	}
+
+	private static void delimit(StringBuffer sb, String string, char delimiter, int stringLength) {
+		sb.append(delimiter);
+		for (int i = 0; i < stringLength; i++) {
+			char c = string.charAt(i);
+			if (c == delimiter) {
+				sb.append(c);
+			}
+			sb.append(c);
+		}
+		sb.append(delimiter);
+	}
+
+	/**
+	 * @see #delimit(StringBuffer, String, char)
+	 */
+	public static void delimit(StringBuffer sb, char[] string, char delimiter) {
+		int stringLength = string.length;
+		sb.ensureCapacity(sb.length() + stringLength + 2);
+		delimit(sb, string, delimiter, stringLength);
+	}
+
+	private static void delimit(StringBuffer sb, char[] string, char delimiter, int stringLength) {
+		sb.append(delimiter);
+		for (int i = 0; i < stringLength; i++) {
+			char c = string[i];
+			if (c == delimiter) {
+				sb.append(c);
+			}
+			sb.append(c);
+		}
+		sb.append(delimiter);
+	}
+
+	/**
+	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
+	 * the delimiter at the front and back of the resulting string.
+	 * Escape any occurrences of a single-character delimiter in the string with
+	 * another delimiter.
+	 */
+	public static void delimit(StringBuffer sb, String string, String delimiter) {
+		int delimiterLength = delimiter.length();
+		switch (delimiterLength) {
+			case 0:
+				sb.append(string);
+				break;
+			case 1:
+				delimit(sb, string, delimiter.charAt(0));
+				break;
+			default:
+				delimit(sb, string, delimiter, delimiterLength);
+				break;
+		}
+	}
+
+	/**
+	 * No parm check
+	 */
+	private static void delimit(StringBuffer sb, String string, String delimiter, int delimiterLength) {
+		sb.append(delimiter, 0, delimiterLength);
+		sb.append(string);
+		sb.append(delimiter, 0, delimiterLength);
+	}
+
+	/**
+	 * @see #delimit(StringBuffer, String, String)
+	 */
+	public static void delimit(StringBuffer sb, char[] string, char[] delimiter) {
+		int delimiterLength = delimiter.length;
+		switch (delimiterLength) {
+			case 0:
+				sb.append(string);
+				break;
+			case 1:
+				delimit(sb, string, delimiter[0]);
+				break;
+			default:
+				delimit(sb, string, delimiter, delimiterLength);
+				break;
+		}
+	}
+
+	/**
+	 * No parm check
+	 */
+	private static void delimit(StringBuffer sb, char[] string, char[] delimiter, int delimiterLength) {
+		sb.append(delimiter, 0, delimiterLength);
+		sb.append(string);
+		sb.append(delimiter, 0, delimiterLength);
+	}
+
+
+	// ********** undelimiting **********
+
+	/**
+	 * Remove the delimiters from the specified string, removing any escape
+	 * characters. Throw an {@link IllegalArgumentException} if the string is
+	 * too short to undelimit (i.e. length < 2).
+	 */
+	public static void undelimit(StringBuffer sb, String string) {
+		int stringLength = string.length();
+		int resultLength = stringLength - 2;
+		if (resultLength < 0) {
+			throw new IllegalArgumentException("invalid string: \"" + string + '"');
+		}
+		if (resultLength == 0) {
+			return;
+		}
+		undelimit_(sb, string, stringLength);
+	}
+
+	/**
+	 * pre-condition: string is at least 3 characters long
+	 */
+	private static void undelimit_(StringBuffer sb, String string, int stringLength) {
+		char delimiter = string.charAt(0);  // the first char is the delimiter
+		char c = delimiter;
+		char next = string.charAt(1);
+		int i = 1;
+		int last = stringLength - 1;
+		do {
+			c = next;
+			sb.append(c);
+			i++;
+			next = string.charAt(i);
+			if (c == delimiter) {
+				if ((next != delimiter) || (i == last)) {
+					// an embedded delimiter must be followed by another delimiter
+					return;
+				}
+				i++;
+				next = string.charAt(i);
+			}
+		} while (i != last);
+	}
+
+	/**
+	 * @see #undelimit(StringBuffer, String)
+	 */
+	public static void undelimit(StringBuffer sb, char[] string) {
+		int stringLength = string.length;
+		int resultLength = stringLength - 2;
+		if (resultLength < 0) {
+			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
+		}
+		if (resultLength == 0) {
+			return;
+		}
+		undelimit_(sb, string, stringLength);
+	}
+
+	/**
+	 * pre-condition: string is at least 3 characters long
+	 */
+	private static void undelimit_(StringBuffer sb, char[] string, int stringLength) {
+		char delimiter = string[0];  // the first char is the delimiter
+		char c = delimiter;
+		char next = string[1];
+		int i = 1;
+		int last = stringLength - 1;
+		do {
+			c = next;
+			sb.append(c);
+			i++;
+			next = string[i];
+			if (c == delimiter) {
+				if ((next != delimiter) || (i == last)) {
+					// an embedded delimiter must be followed by another delimiter
+					return;
+				}
+				i++;
+				next = string[i];
+			}
+		} while (i != last);
+	}
+
+	/**
+	 * Remove the first and last count characters from the specified string.
+	 * If the string is too short to be undelimited, throw an
+	 * {@link IllegalArgumentException}.
+	 * Use this method to undelimit strings that do not escape embedded
+	 * delimiters.
+	 */
+	public static void undelimit(StringBuffer sb, String string, int count) {
+		if (count == 0) {
+			sb.append(string);
+			return;
+		}
+		int resultLength = string.length() - (2 * count);
+		if (resultLength < 0) {
+			throw new IllegalArgumentException("invalid string: \"" + string + '"');
+		}
+		if (resultLength == 0) {
+			return;
+		}
+		sb.append(string, count, count + resultLength);  // NB: end index is exclusive
+	}
+
+	/**
+	 * @see #undelimit(StringBuffer, String, int)
+	 */
+	public static void undelimit(StringBuffer sb, char[] string, int count) {
+		if (count == 0) {
+			sb.append(string);
+			return;
+		}
+		int resultLength = string.length - (2 * count);
+		if (resultLength < 0) {
+			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
+		}
+		if (resultLength == 0) {
+			return;
+		}
+		sb.append(string, count, resultLength);
+	}
+
+
+	// ********** removing characters **********
+
+	/**
+	 * Remove the first occurrence of the specified character
+	 * from the specified string and print the result on the specified stream.
+	 */
+	public static void removeFirstOccurrence(StringBuffer sb, String string, char c) {
+		int index = string.indexOf(c);
+		if (index == -1) {
+			sb.append(string);
+		} else {
+			removeCharAtIndex(sb, string, index);
+		}
+	}
+
+	private static void removeCharAtIndex(StringBuffer sb, String string, int index) {
+		int stringLength = string.length();
+		if (index == 0) {
+			// character found at the front of string
+			sb.append(string, 1, stringLength);  // NB: end index is exclusive
+		} else {
+			sb.append(string, 0, index);  // NB: end index is exclusive
+			if (index != (stringLength - 1)) {
+				// character is not at the end of the string
+				sb.append(string, index + 1, stringLength);  // NB: end index is exclusive
+			}
+		}
+	}
+
+	/**
+	 * @see #removeFirstOccurrence(StringBuffer, String, char)
+	 */
+	public static void removeFirstOccurrence(StringBuffer sb, char[] string, char c) {
+		int index = ArrayTools.indexOf(string, c);
+		if (index == -1) {
+			sb.append(string);
+		} else {
+			removeCharAtIndex(sb, string, index);
+		}
+	}
+
+	private static void removeCharAtIndex(StringBuffer sb, char[] string, int index) {
+		int last = string.length - 1;
+		if (index == 0) {
+			// character found at the front of string
+			sb.append(string, 1, last);
+		} else if (index == last) {
+			// character found at the end of string
+			sb.append(string, 0, last);
+		} else {
+			// character found somewhere in the middle of the string
+			sb.append(string, 0, index);
+			sb.append(string, index + 1, last - index);
+		}
+	}
+
+	/**
+	 * Remove all occurrences of the specified character
+	 * from the specified string and write the result to the specified stream.
+	 */
+	public static void removeAllOccurrences(StringBuffer sb, String string, char c) {
+		int first = string.indexOf(c);
+		if (first == -1) {
+			sb.append(string);
+		} else {
+			int stringLength = string.length();
+			sb.ensureCapacity(sb.length() + stringLength);
+			removeAllOccurrences(sb, string, c, first, stringLength);
+		}
+	}
+
+	/**
+	 * The index of the first matching character is passed in.
+	 */
+	private static void removeAllOccurrences(StringBuffer sb, String string, char c, int first, int stringLength) {
+		sb.append(string, 0, first);  // NB: end index is exclusive
+		for (int i = first; i < stringLength; i++) {
+			char d = string.charAt(i);
+			if (d != c) {
+				sb.append(d);
+			}
+		}
+	}
+
+	/**
+	 * @see #removeAllOccurrences(StringBuffer, String, char)
+	 */
+	public static void removeAllOccurrences(StringBuffer sb, char[] string, char c) {
+		int first = ArrayTools.indexOf(string, c);
+		if (first == -1) {
+			sb.append(string);
+		} else {
+			int stringLength = string.length;
+			sb.ensureCapacity(sb.length() + stringLength);
+			removeAllOccurrences(sb, string, c, first, stringLength);
+		}
+	}
+
+	/**
+	 * The index of the first matching character is passed in.
+	 */
+	private static void removeAllOccurrences(StringBuffer sb, char[] string, char c, int first, int stringLength) {
+		sb.append(string, 0, first);
+		for (int i = first; i < stringLength; i++) {
+			char d = string[i];
+			if (d != c) {
+				sb.append(d);
+			}
+		}
+	}
+
+	/**
+	 * Remove all the spaces
+	 * from the specified string and write the result to the specified stream.
+	 */
+	public static void removeAllSpaces(StringBuffer sb, String string) {
+		removeAllOccurrences(sb, string, ' ');
+	}
+
+	/**
+	 * @see #removeAllSpaces(StringBuffer, String)
+	 */
+	public static void removeAllSpaces(StringBuffer sb, char[] string) {
+		removeAllOccurrences(sb, string, ' ');
+	}
+
+	/**
+	 * Remove all the whitespace
+	 * from the specified string and append the result to the
+	 * specified stream.
+	 */
+	public static void removeAllWhitespace(StringBuffer sb, String string) {
+		int first = StringTools.indexOfWhitespace(string);
+		if (first == -1) {
+			sb.append(string);
+		} else {
+			int stringLength = string.length();
+			sb.ensureCapacity(sb.length() + stringLength);
+			removeAllWhitespace(sb, string, first, stringLength);
+		}
+	}
+
+	/**
+	 * The index of the first whitespace character is passed in.
+	 */
+	private static void removeAllWhitespace(StringBuffer sb, String string, int first, int stringLength) {
+		sb.append(string, 0, first);  // NB: end index is exclusive
+		for (int i = first; i < stringLength; i++) {
+			char c = string.charAt(i);
+			if ( ! Character.isWhitespace(c)) {
+				sb.append(c);
+			}
+		}
+	}
+
+	/**
+	 * @see #removeAllWhitespace(StringBuffer, String)
+	 */
+	public static void removeAllWhitespace(StringBuffer sb, char[] string) {
+		int first = CharArrayTools.indexOfWhitespace(string);
+		if (first == -1) {
+			sb.append(string);
+		} else {
+			int stringLength = string.length;
+			sb.ensureCapacity(sb.length() + stringLength);
+			removeAllWhitespace(sb, string, first, stringLength);
+		}
+	}
+
+	/**
+	 * The index of the first whitespace character is passed in.
+	 */
+	private static void removeAllWhitespace(StringBuffer sb, char[] string, int first, int stringLength) {
+		sb.append(string, 0, first);
+		for (int i = first; i < stringLength; i++) {
+			char c = string[i];
+			if ( ! Character.isWhitespace(c)) {
+				sb.append(c);
+			}
+		}
+	}
+
+	/**
+	 * Compress the whitespace
+	 * in the specified string and append the result to the
+	 * specified stream.
+	 * The whitespace is compressed by replacing any occurrence of one or more
+	 * whitespace characters with a single space.
+	 */
+	public static void compressWhitespace(StringBuffer sb, String string) {
+		int first = StringTools.indexOfWhitespace(string);
+		if (first == -1) {
+			sb.append(string);
+		} else {
+			int stringLength = string.length();
+			sb.ensureCapacity(sb.length() + stringLength);
+			compressWhitespace(sb, string, first, stringLength);
+		}
+	}
+
+	/**
+	 * The index of the first whitespace character is passed in.
+	 */
+	private static void compressWhitespace(StringBuffer sb, String string, int first, int stringLength) {
+		sb.append(string, 0, first);  // NB: end index is exclusive
+		int i = first;
+		char c = string.charAt(i);
+		main: while (true) {
+			// replace first whitespace character with a space...
+			sb.append(' ');
+			// ...and skip subsequent whitespace characters
+			while (true) {
+				i++;
+				if (i >= stringLength) {
+					break main;
+				}
+				c = string.charAt(i);
+				if ( ! Character.isWhitespace(c)) {
+					break;
+				}
+			}
+			while (true) {
+				sb.append(c);
+				i++;
+				if (i >= stringLength) {
+					break main;
+				}
+				c = string.charAt(i);
+				if (Character.isWhitespace(c)) {
+					break;
+				}
+			}
+		}
+	}
+
+	/**
+	 * @see #compressWhitespace(StringBuffer, String)
+	 */
+	public static void compressWhitespace(StringBuffer sb, char[] string) {
+		int first = CharArrayTools.indexOfWhitespace(string);
+		if (first == -1) {
+			sb.append(string);
+		} else {
+			int stringLength = string.length;
+			sb.ensureCapacity(sb.length() + stringLength);
+			compressWhitespace(sb, string, first, stringLength);
+		}
+	}
+
+	/**
+	 * The index of the first whitespace character is passed in.
+	 */
+	private static void compressWhitespace(StringBuffer sb, char[] string, int first, int stringLength) {
+		sb.append(string, 0, first);  // NB: end index is exclusive
+		int i = first;
+		char c = string[i];
+		main: while (true) {
+			// replace first whitespace character with a space...
+			sb.append(' ');
+			// ...and skip subsequent whitespace characters
+			while (true) {
+				i++;
+				if (i >= stringLength) {
+					break main;
+				}
+				c = string[i];
+				if ( ! Character.isWhitespace(c)) {
+					break;
+				}
+			}
+			while (true) {
+				sb.append(c);
+				i++;
+				if (i >= stringLength) {
+					break main;
+				}
+				c = string[i];
+				if (Character.isWhitespace(c)) {
+					break;
+				}
+			}
+		}
+	}
+
+
+	// ********** capitalization **********
+
+	/**
+	 * Append the specified string to the specified stream
+	 * with its first letter capitalized.
+	 */
+	public static void capitalize(StringBuffer sb, String string) {
+		if (string.length() == 0) {
+			return;
+		}
+		if (Character.isUpperCase(string.charAt(0))) {
+			sb.append(string);
+		} else {
+			capitalize_(sb, string);
+		}
+	}
+
+	/**
+	 * no zero-length check or upper case check
+	 */
+	private static void capitalize_(StringBuffer sb, String string) {
+		sb.append(Character.toUpperCase(string.charAt(0)));
+		sb.append(string, 1, string.length());  // NB: end index is exclusive
+	}
+
+	/**
+	 * @see #capitalize(StringBuffer, String)
+	 */
+	public static void capitalize(StringBuffer sb, char[] string) {
+		if (string.length == 0) {
+			return;
+		}
+		if (Character.isUpperCase(string[0])) {
+			sb.append(string);
+		} else {
+			capitalize_(sb, string);
+		}
+	}
+
+	/**
+	 * no zero-length check or upper case check
+	 */
+	private static void capitalize_(StringBuffer sb, char[] string) {
+		sb.append(Character.toUpperCase(string[0]));
+		sb.append(string, 1, string.length - 1);
+	}
+
+	/**
+	 * Append the specified string to the specified stream
+	 * with its first letter converted to lower case.
+	 * (Unless both the first and second letters are upper case,
+	 * in which case the string is returned unchanged.)
+	 */
+	public static void uncapitalize(StringBuffer sb, String string) {
+		int stringLength = string.length();
+		if (StringTools.needNotBeUncapitalized(string, stringLength)) {
+			sb.append(string);
+		} else {
+			uncapitalize(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * no zero-length check or upper case check
+	 */
+	private static void uncapitalize(StringBuffer sb, String string, int stringLength) {
+		sb.append(Character.toLowerCase(string.charAt(0)));
+		sb.append(string, 1, stringLength);  // NB: end index is exclusive
+	}
+
+	/**
+	 * @see #uncapitalize(StringBuffer, String)
+	 */
+	public static void uncapitalize(StringBuffer sb, char[] string) {
+		int stringLength = string.length;
+		if (CharArrayTools.needNotBeUncapitalized(string, stringLength)) {
+			sb.append(string);
+		} else {
+			uncapitalize(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * no zero-length check or upper case check
+	 */
+	private static void uncapitalize(StringBuffer sb, char[] string, int stringLength) {
+		sb.append(Character.toLowerCase(string[0]));
+		sb.append(string, 1, stringLength - 1);
+	}
+
+
+	// ********** convert byte array to hex string **********
+
+	/**
+	 * Convert the specified byte array to the corresponding string of
+	 * hexadecimal characters.
+	 * @see ByteArrayTools#convertToHexString(byte[])
+	 */
+	public static void convertToHexString(StringBuffer sb, byte[] bytes) {
+		int bytesLength = bytes.length;
+		if (bytesLength != 0) {
+			sb.ensureCapacity(sb.length() + (bytesLength << 1));
+			convertToHexString(sb, bytes, bytesLength);
+		}
+	}
+
+	/**
+	 * Pre-condition: the byte array is not empty
+	 */
+	private static void convertToHexString(StringBuffer sb, byte[] bytes, int bytesLength) {
+		char[] digits = CharacterTools.DIGITS;
+		for (int i = 0; i < bytesLength; i++) {
+			int b = bytes[i] & 0xFF; // clear any sign bits
+			sb.append(digits[b >> 4]); // first nibble
+			sb.append(digits[b & 0xF]); // second nibble
+		}
+	}
+
+
+	// ********** convert camel case to all caps **********
+
+	/**
+	 * Convert the specified "camel case" string to an "all caps" string:
+	 * <p>
+	 * <code>
+	 * "largeProject" -> "LARGE_PROJECT"
+	 * </code>
+	 */
+	public static void convertCamelCaseToAllCaps(StringBuffer sb, String camelCaseString) {
+		int stringLength = camelCaseString.length();
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + (stringLength / 4));
+			convertCamelCaseToAllCaps_(sb, camelCaseString, stringLength);
+		}
+	}
+
+	/**
+	 * Pre-condition: the string is not empty
+	 */
+	private static void convertCamelCaseToAllCaps_(StringBuffer sb, String camelCaseString, int stringLength) {
+		char prev = 0;	// assume 0 is not a valid char
+		char c = 0;
+		char next = camelCaseString.charAt(0);
+		for (int i = 1; i <= stringLength; i++) {	// NB: start at 1 and end at stringLength!
+			c = next;
+			next = ((i == stringLength) ? 0 : camelCaseString.charAt(i));
+			if (StringTools.camelCaseWordBreak(prev, c, next)) {
+				sb.append('_');
+			}
+			sb.append(Character.toUpperCase(c));
+			prev = c;
+		}
+	}
+
+	/**
+	 * @see #convertCamelCaseToAllCaps(StringBuffer, String)
+	 */
+	public static void convertCamelCaseToAllCaps(StringBuffer sb, char[] camelCaseString) {
+		int stringLength = camelCaseString.length;
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + (stringLength / 4));
+			convertCamelCaseToAllCaps_(sb, camelCaseString, stringLength);
+		}
+	}
+
+	/**
+	 * Pre-condition: the string is not empty
+	 */
+	private static void convertCamelCaseToAllCaps_(StringBuffer sb, char[] camelCaseString, int stringLength) {
+		char prev = 0;	// assume 0 is not a valid char
+		char c = 0;
+		char next = camelCaseString[0];
+		for (int i = 1; i <= stringLength; i++) {	// NB: start at 1 and end at stringLength!
+			c = next;
+			next = ((i == stringLength) ? 0 : camelCaseString[i]);
+			if (StringTools.camelCaseWordBreak(prev, c, next)) {
+				sb.append('_');
+			}
+			sb.append(Character.toUpperCase(c));
+			prev = c;
+		}
+	}
+
+	/**
+	 * Convert the specified "camel case" string to an "all caps" string:
+	 * <p>
+	 * <code>
+	 * "largeProject" -> "LARGE_PROJECT"
+	 * </code>
+	 * <p>
+	 * Limit the resulting string to the specified maximum length.
+	 */
+	public static void convertCamelCaseToAllCaps(StringBuffer sb, String camelCaseString, int maxLength) {
+		if (maxLength != 0) {
+			int stringLength = camelCaseString.length();
+			if (stringLength != 0) {
+				sb.ensureCapacity(sb.length() + maxLength);
+				convertCamelCaseToAllCaps(sb, camelCaseString, maxLength, stringLength);
+			}
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	private static void convertCamelCaseToAllCaps(StringBuffer sb, String camelCaseString, int maxLength, int stringLength) {
+		char prev = 0;	// assume 0 is not a valid char
+		char c = 0;
+		char next = camelCaseString.charAt(0);
+		for (int i = 1; i <= stringLength; i++) {	// NB: start at 1 and end at stringLength!
+			c = next;
+			next = ((i == stringLength) ? 0 : camelCaseString.charAt(i));
+			if (StringTools.camelCaseWordBreak(prev, c, next)) {
+				sb.append('_');
+				if (sb.length() == maxLength) {
+					return;
+				}
+			}
+			sb.append(Character.toUpperCase(c));
+			if (sb.length() == maxLength) {
+				return;
+			}
+			prev = c;
+		}
+	}
+
+	/**
+	 * @see #convertCamelCaseToAllCaps(StringBuffer, String, int)
+	 */
+	public static void convertCamelCaseToAllCaps(StringBuffer sb, char[] camelCaseString, int maxLength) {
+		if (maxLength != 0) {
+			int stringLength = camelCaseString.length;
+			if (stringLength != 0) {
+				sb.ensureCapacity(sb.length() + maxLength);
+				convertCamelCaseToAllCaps(sb, camelCaseString, maxLength, stringLength);
+			}
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	private static void convertCamelCaseToAllCaps(StringBuffer sb, char[] camelCaseString, int maxLength, int stringLength) {
+		char prev = 0;	// assume 0 is not a valid char
+		char c = 0;
+		char next = camelCaseString[0];
+		for (int i = 1; i <= stringLength; i++) {	// NB: start at 1 and end at stringLength!
+			c = next;
+			next = ((i == stringLength) ? 0 : camelCaseString[i]);
+			if (StringTools.camelCaseWordBreak(prev, c, next)) {
+				sb.append('_');
+				if (sb.length() == maxLength) {
+					return;
+				}
+			}
+			sb.append(Character.toUpperCase(c));
+			if (sb.length() == maxLength) {
+				return;
+			}
+			prev = c;
+		}
+	}
+
+
+	// ********** convert all caps to camel case **********
+
+	/**
+	 * Convert the specified "all caps" string to a "camel case" string:
+	 * <p>
+	 * <code>
+	 * "LARGE_PROJECT" -> "LargeProject"
+	 * </code>
+	 * <p>
+	 * Capitalize the first letter.
+	 */
+	public static void convertAllCapsToCamelCase(StringBuffer sb, String allCapsString) {
+		convertAllCapsToCamelCase(sb, allCapsString, true);
+	}
+
+	/**
+	 * @see #convertAllCapsToCamelCase(StringBuffer, String)
+	 */
+	public static void convertAllCapsToCamelCase(StringBuffer sb, char[] allCapsString) {
+		convertAllCapsToCamelCase(sb, allCapsString, true);
+	}
+
+	/**
+	 * Convert the specified "all caps" string to a "camel case" string:
+	 * <p>
+	 * <code>
+	 * "LARGE_PROJECT" -> "largeProject"
+	 * </code>
+	 * <p>
+	 * Optionally capitalize the first letter.
+	 */
+	public static void convertAllCapsToCamelCase(StringBuffer sb, String allCapsString, boolean capitalizeFirstLetter) {
+		int stringLength = allCapsString.length();
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength);
+			convertAllCapsToCamelCase(sb, allCapsString, capitalizeFirstLetter, stringLength);
+		}
+	}
+
+	private static void convertAllCapsToCamelCase(StringBuffer sb, String allCapsString, boolean capitalizeFirstLetter, int stringLength) {
+		char prev = 0;
+		char c = 0;
+		boolean first = true;
+		for (int i = 0; i < stringLength; i++) {
+			prev = c;
+			c = allCapsString.charAt(i);
+			if (c == '_') {
+				continue;
+			}
+			if (first) {
+				first = false;
+				sb.append(capitalizeFirstLetter ? Character.toUpperCase(c) : Character.toLowerCase(c));
+			} else {
+				sb.append((prev == '_') ? Character.toUpperCase(c) : Character.toLowerCase(c));
+			}
+		}
+	}
+
+	/**
+	 * @see #convertAllCapsToCamelCase(StringBuffer, String, boolean)
+	 */
+	public static void convertAllCapsToCamelCase(StringBuffer sb, char[] allCapsString, boolean capitalizeFirstLetter) {
+		int stringLength = allCapsString.length;
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength);
+			convertAllCapsToCamelCase(sb, allCapsString, capitalizeFirstLetter, stringLength);
+		}
+	}
+
+	private static void convertAllCapsToCamelCase(StringBuffer sb, char[] allCapsString, boolean capitalizeFirstLetter, int stringLength) {
+		char prev = 0;
+		char c = 0;
+		boolean first = true;
+		for (int i = 0; i < stringLength; i++) {
+			prev = c;
+			c = allCapsString[i];
+			if (c == '_') {
+				continue;
+			}
+			if (first) {
+				first = false;
+				sb.append(capitalizeFirstLetter ? Character.toUpperCase(c) : Character.toLowerCase(c));
+			} else {
+				sb.append((prev == '_') ? Character.toUpperCase(c) : Character.toLowerCase(c));
+			}
+		}
+	}
+
+
+	// ********** convert to Java string literal **********
+
+	/**
+	 * Convert the specified string to a Java string literal, with the
+	 * appropriate escaped characters.
+	 */
+	public static void convertToJavaStringLiteral(StringBuffer sb, String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			sb.append(StringTools.EMPTY_JAVA_STRING_LITERAL);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + 6);
+			convertToJavaStringLiteral(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	private static void convertToJavaStringLiteral(StringBuffer sb, String string, int stringLength) {
+		sb.append(CharacterTools.QUOTE);
+		convertToJavaStringLiteralContent(sb, string, stringLength);
+		sb.append(CharacterTools.QUOTE);
+	}
+
+	/**
+	 * Convert the specified string to the contents of a Java string literal,
+	 * with the appropriate escaped characters.
+	 */
+	public static void convertToJavaStringLiteralContent(StringBuffer sb, String string) {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 6);
+			convertToJavaStringLiteralContent(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	private static void convertToJavaStringLiteralContent(StringBuffer sb, String string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToJavaStringLiteral(sb, string.charAt(i));
+		}
+	}
+
+	/**
+	 * @see #convertToJavaStringLiteral(StringBuffer, String)
+	 */
+	public static void convertToJavaStringLiteral(StringBuffer sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			sb.append(StringTools.EMPTY_JAVA_STRING_LITERAL);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + 6);
+			convertToJavaStringLiteral(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	private static void convertToJavaStringLiteral(StringBuffer sb, char[] string, int stringLength) {
+		sb.append(CharacterTools.QUOTE);
+		convertToJavaStringLiteralContent(sb, string, stringLength);
+		sb.append(CharacterTools.QUOTE);
+	}
+
+	/**
+	 * @see #convertToJavaStringLiteralContent(StringBuffer, String)
+	 */
+	public static void convertToJavaStringLiteralContent(StringBuffer sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 6);
+			convertToJavaStringLiteralContent(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	private static void convertToJavaStringLiteralContent(StringBuffer sb, char[] string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToJavaStringLiteral(sb, string[i]);
+		}
+	}
+
+	private static void convertToJavaStringLiteral(StringBuffer sb, char c) {
+		switch (c) {
+			case '\b':  // backspace
+				sb.append("\\b");
+				break;
+			case '\t':  // horizontal tab
+				sb.append("\\t");
+				break;
+			case '\n':  // line-feed LF
+				sb.append("\\n");
+				break;
+			case '\f':  // form-feed FF
+				sb.append("\\f");
+				break;
+			case '\r':  // carriage-return CR
+				sb.append("\\r");
+				break;
+			case '"':  // double-quote
+				sb.append("\\\"");
+				break;
+//			case '\'':  // single-quote
+//				sb.append("\\'");
+//				break;
+			case '\\':  // backslash
+				sb.append("\\\\");
+				break;
+			default:
+				sb.append(c);
+				break;
+		}
+	}
+
+
+	// ********** convert to XML **********
+
+	/**
+	 * Convert the specified string to an XML attribute value, escaping the
+	 * appropriate characters. Delimit with quotes (<code>"</code>) unless
+	 * there are <em>embedded</em> quotes (<em>and</em> no embedded
+	 * apostrophes); in which case, delimit with apostrophes (<code>'</code>).
+	 */
+	public static void convertToXmlAttributeValue(StringBuffer sb, String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			sb.append(StringTools.EMPTY_XML_ATTRIBUTE_VALUE);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + 12);
+			convertToXmlAttributeValue(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToXmlAttributeValue(StringBuffer sb, String string, int stringLength) {
+		int index = string.indexOf(CharacterTools.QUOTE);
+		if (index == -1) {
+			// no embedded quotes - use quote delimiters
+			convertToDoubleQuotedXmlAttributeValue(sb, string, stringLength);
+		} else {
+			index = string.indexOf(CharacterTools.APOSTROPHE);
+			if (index == -1) {
+				// embedded quotes but no embedded apostrophes - use apostrophe delimiters
+				convertToSingleQuotedXmlAttributeValue(sb, string, stringLength);
+			} else {
+				// embedded quotes *and* embedded apostrophes - use quote delimiters
+				convertToDoubleQuotedXmlAttributeValue(sb, string, stringLength);
+			}
+		}
+	}
+
+	private static void convertToDoubleQuotedXmlAttributeValue(StringBuffer sb, String string, int stringLength) {
+		sb.append(CharacterTools.QUOTE);
+		convertToDoubleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		sb.append(CharacterTools.QUOTE);
+	}
+
+	private static void convertToSingleQuotedXmlAttributeValue(StringBuffer sb, String string, int stringLength) {
+		sb.append(CharacterTools.APOSTROPHE);
+		convertToSingleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		sb.append(CharacterTools.APOSTROPHE);
+	}
+
+	/**
+	 * Convert the specified string to a double-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * double quotes).
+	 * @see #convertToXmlAttributeValue(StringBuffer, String)
+	 */
+	public static void convertToDoubleQuotedXmlAttributeValue(StringBuffer sb, String string) {
+		convertToDoubleQuotedXmlAttributeValue(sb, string, string.length());
+	}
+
+	/**
+	 * Convert the specified string to the contents of a double-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * double quotes).
+	 * @see #convertToXmlAttributeValue(StringBuffer, String)
+	 */
+	public static void convertToDoubleQuotedXmlAttributeValueContent(StringBuffer sb, String string) {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 10);
+			convertToDoubleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToDoubleQuotedXmlAttributeValueContent(StringBuffer sb, String string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToDoubleQuotedXmlAttributeValueContent(sb, string.charAt(i));
+		}
+	}
+
+	/**
+	 * Convert the specified string to a single-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * single quotes).
+	 * @see #convertToXmlAttributeValue(StringBuffer, String)
+	 */
+	public static void convertToSingleQuotedXmlAttributeValue(StringBuffer sb, String string) {
+		convertToSingleQuotedXmlAttributeValue(sb, string, string.length());
+	}
+
+	/**
+	 * Convert the specified string to the contents of a single-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * single quotes).
+	 * @see #convertToXmlAttributeValue(StringBuffer, String)
+	 */
+	public static void convertToSingleQuotedXmlAttributeValueContent(StringBuffer sb, String string) {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 10);
+			convertToSingleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToSingleQuotedXmlAttributeValueContent(StringBuffer sb, String string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToSingleQuotedXmlAttributeValueContent(sb, string.charAt(i));
+		}
+	}
+
+	/**
+	 * @see #convertToXmlAttributeValue(StringBuffer, String)
+	 */
+	public static void convertToXmlAttributeValue(StringBuffer sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			sb.append(StringTools.EMPTY_XML_ATTRIBUTE_VALUE);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + 12);
+			convertToXmlAttributeValue(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToXmlAttributeValue(StringBuffer sb, char[] string, int stringLength) {
+		int index = ArrayTools.indexOf(string, CharacterTools.QUOTE);
+		if (index == -1) {
+			// no embedded quotes - use quote delimiters
+			convertToDoubleQuotedXmlAttributeValue(sb, string, stringLength);
+		} else {
+			index = ArrayTools.indexOf(string, CharacterTools.APOSTROPHE);
+			if (index == -1) {
+				// embedded quotes but no embedded apostrophes - use apostrophe delimiters
+				convertToSingleQuotedXmlAttributeValue(sb, string, stringLength);
+			} else {
+				// embedded quotes *and* embedded apostrophes - use quote delimiters
+				convertToDoubleQuotedXmlAttributeValue(sb, string, stringLength);
+			}
+		}
+	}
+
+	private static void convertToDoubleQuotedXmlAttributeValue(StringBuffer sb, char[] string, int stringLength) {
+		sb.append(CharacterTools.QUOTE);
+		convertToDoubleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		sb.append(CharacterTools.QUOTE);
+	}
+
+	private static void convertToSingleQuotedXmlAttributeValue(StringBuffer sb, char[] string, int stringLength) {
+		sb.append(CharacterTools.APOSTROPHE);
+		convertToSingleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		sb.append(CharacterTools.APOSTROPHE);
+	}
+
+	/**
+	 * @see #convertToDoubleQuotedXmlAttributeValue(StringBuffer, String)
+	 * @see #convertToXmlAttributeValue(StringBuffer, char[])
+	 */
+	public static void convertToDoubleQuotedXmlAttributeValue(StringBuffer sb, char[] string) {
+		convertToDoubleQuotedXmlAttributeValue(sb, string, string.length);
+	}
+
+	/**
+	 * @see #convertToDoubleQuotedXmlAttributeValueContent(StringBuffer, String)
+	 * @see #convertToXmlAttributeValue(StringBuffer, char[])
+	 */
+	public static void convertToDoubleQuotedXmlAttributeValueContent(StringBuffer sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 10);
+			convertToDoubleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		}
+	}
+
+	private static void convertToDoubleQuotedXmlAttributeValueContent(StringBuffer sb, char[] string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToDoubleQuotedXmlAttributeValueContent(sb, string[i]);
+		}
+	}
+
+	/**
+	 * @see #convertToSingleQuotedXmlAttributeValue(StringBuffer, String)
+	 * @see #convertToXmlAttributeValue(StringBuffer, char[])
+	 */
+	public static void convertToSingleQuotedXmlAttributeValue(StringBuffer sb, char[] string) {
+		convertToSingleQuotedXmlAttributeValue(sb, string, string.length);
+	}
+
+	/**
+	 * @see #convertToSingleQuotedXmlAttributeValueContent(StringBuffer, String)
+	 * @see #convertToXmlAttributeValue(StringBuffer, char[])
+	 */
+	public static void convertToSingleQuotedXmlAttributeValueContent(StringBuffer sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 10);
+			convertToSingleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		}
+	}
+
+	private static void convertToSingleQuotedXmlAttributeValueContent(StringBuffer sb, char[] string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToSingleQuotedXmlAttributeValueContent(sb, string[i]);
+		}
+	}
+
+	/**
+	 * String is delimited with quotes - escape embedded quotes.
+	 * @see <a href="http://www.w3.org/TR/xml/#syntax">XML Spec</a>
+	 */
+	private static void convertToDoubleQuotedXmlAttributeValueContent(StringBuffer sb, char c) {
+		switch (c) {
+			case '"':  // double-quote
+				sb.append(StringTools.XML_QUOTE);
+				break;
+			case '&':  // ampersand
+				sb.append(StringTools.XML_AMP);
+				break;
+			case '<':  // less than
+				sb.append(StringTools.XML_LT);
+				break;
+			default:
+				sb.append(c);
+				break;
+		}
+	}
+
+	/**
+	 * String is delimited with apostrophes - escape embedded apostrophes.
+	 * @see <a href="http://www.w3.org/TR/xml/#syntax">XML Spec</a>
+	 */
+	private static void convertToSingleQuotedXmlAttributeValueContent(StringBuffer sb, char c) {
+		switch (c) {
+			case '\'':  // apostrophe
+				sb.append(StringTools.XML_APOS);
+				break;
+			case '&':  // ampersand
+				sb.append(StringTools.XML_AMP);
+				break;
+			case '<':  // less than
+				sb.append(StringTools.XML_LT);
+				break;
+			default:
+				sb.append(c);
+				break;
+		}
+	}
+
+	/**
+	 * Convert the specified string to an XML element text, escaping the
+	 * appropriate characters.
+	 * @see #convertToXmlElementCDATA(StringBuffer, String)
+	 */
+	public static void convertToXmlElementText(StringBuffer sb, String string) {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 8);
+			convertToXmlElementText(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToXmlElementText(StringBuffer sb, String string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToXmlElementText(sb, string.charAt(i));
+		}
+	}
+
+	/**
+	 * @see #convertToXmlElementText(StringBuffer, String)
+	 */
+	public static void convertToXmlElementText(StringBuffer sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 8);
+			convertToXmlElementText(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToXmlElementText(StringBuffer sb, char[] string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToXmlElementText(sb, string[i]);
+		}
+	}
+
+	/**
+	 * @see <a href="http://www.w3.org/TR/xml/#syntax">XML Spec</a>
+	 */
+	private static void convertToXmlElementText(StringBuffer sb, char c) {
+		switch (c) {
+			case '&':  // ampersand
+				sb.append(StringTools.XML_AMP);
+				break;
+			case '<':  // less than
+				sb.append(StringTools.XML_LT);
+				break;
+			default:
+				sb.append(c);
+				break;
+		}
+	}
+
+	/**
+	 * Convert the specified string to an XML element CDATA, escaping the
+	 * appropriate characters.
+	 * @see #convertToXmlElementText(StringBuffer, String)
+	 */
+	public static void convertToXmlElementCDATA(StringBuffer sb, String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			sb.append(StringTools.EMPTY_XML_ELEMENT_CDATA);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + StringTools.EMPTY_XML_ELEMENT_CDATA.length() + 6);
+			convertToXmlElementCDATA(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToXmlElementCDATA(StringBuffer sb, String string, int stringLength) {
+		sb.append(StringTools.XML_ELEMENT_CDATA_START);
+		convertToXmlElementCDATAContent(sb, string, stringLength);
+		sb.append(StringTools.XML_ELEMENT_CDATA_END);
+	}
+
+	/**
+	 * Convert the specified string to the contents of an XML element CDATA,
+	 * escaping the appropriate characters.
+	 * @see #convertToXmlElementCDATA(StringBuffer, String)
+	 * @see #convertToXmlElementText(StringBuffer, String)
+	 */
+	public static void convertToXmlElementCDATAContent(StringBuffer sb, String string) {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 6);
+			convertToXmlElementCDATAContent(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 * @see <a href="http://www.w3.org/TR/xml/#sec-cdata-sect">XML Spec</a>
+	 */
+	private static void convertToXmlElementCDATAContent(StringBuffer sb, String string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			char c = string.charAt(i);
+			sb.append(c);
+			// "]]>" -> "]]&gt;"
+			if (c != ']') {
+				continue;
+			}
+			if (++i >= stringLength) {
+				break;
+			}
+			c = string.charAt(i);
+			sb.append(c);
+			if (c != ']') {
+				continue;
+			}
+			if (++i >= stringLength) {
+				break;
+			}
+			c = string.charAt(i);
+			if (c == '>') {
+				sb.append(StringTools.XML_GT);
+			} else {
+				sb.append(c);
+			}
+		}
+	}
+
+	/**
+	 * @see #convertToXmlElementCDATA(StringBuffer, String)
+	 */
+	public static void convertToXmlElementCDATA(StringBuffer sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			sb.append(StringTools.EMPTY_XML_ELEMENT_CDATA);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + StringTools.EMPTY_XML_ELEMENT_CDATA.length() + 6);
+			convertToXmlElementCDATA(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToXmlElementCDATA(StringBuffer sb, char[] string, int stringLength) {
+		sb.append(StringTools.XML_ELEMENT_CDATA_START);
+		convertToXmlElementCDATAContent(sb, string, stringLength);
+		sb.append(StringTools.XML_ELEMENT_CDATA_END);
+	}
+
+	/**
+	 * @see #convertToXmlElementCDATAContent(StringBuffer, String)
+	 * @see #convertToXmlElementCDATA(StringBuffer, char[])
+	 */
+	public static void convertToXmlElementCDATAContent(StringBuffer sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 6);
+			convertToXmlElementCDATAContent(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 * @see <a href="http://www.w3.org/TR/xml/#sec-cdata-sect">XML Spec</a>
+	 */
+	private static void convertToXmlElementCDATAContent(StringBuffer sb, char[] string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			char c = string[i];
+			sb.append(c);
+			// "]]>" -> "]]&gt;"
+			if (c != ']') {
+				continue;
+			}
+			if (++i >= stringLength) {
+				break;
+			}
+			c = string[i];
+			sb.append(c);
+			if (c != ']') {
+				continue;
+			}
+			if (++i >= stringLength) {
+				break;
+			}
+			c = string[i];
+			if (c == '>') {
+				sb.append(StringTools.XML_GT);
+			} else {
+				sb.append(c);
+			}
+		}
+	}
+
+
+	// ********** constructor **********
+
+	/*
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private StringBufferTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringBuilderTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringBuilderTools.java
new file mode 100644
index 0000000..44eb01a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringBuilderTools.java
@@ -0,0 +1,2004 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+import java.util.Iterator;
+
+/**
+ * {@link StringBuilder} utility methods.
+ * <p>
+ * As of JDK 1.5, it's tempting to convert all of these methods to use
+ * {@link Appendable};
+ * but all the {@link Appendable} methods throw {@link java.io.IOException} (yech) and
+ * we [might?] get a bit better performance invoking methods on classes than
+ * we get on interfaces. :-)
+ *
+ * @see StringTools
+ */
+@SuppressWarnings("nls")
+public final class StringBuilderTools {
+
+	// ********** char[] **********
+
+	/**
+	 * Convert the specified string builder to a charactor array
+	 * (<code>char[]</code>).
+	 */
+	public static char[] convertToCharArray(StringBuilder sb) {
+		int len = sb.length();
+		char[] result = new char[len];
+		sb.getChars(0, len, result, 0);
+		return result;
+	}
+
+
+	// ********** padding/truncating/centering **********
+
+	/**
+	 * Center the specified string in the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with spaces at
+	 * each end.
+	 */
+	public static void center(StringBuilder sb, String string, int length) {
+		center(sb, string, length, ' ');
+	}
+
+	/**
+	 * @see #center(StringBuilder, String, int)
+	 */
+	public static void center(StringBuilder sb, char[] string, int length) {
+		center(sb, string, length, ' ');
+	}
+
+	/**
+	 * Center the specified string in the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at each end.
+	 */
+	public static void center(StringBuilder sb, String string, int length, char c) {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length();
+		if (stringLength == length) {
+			sb.append(string);
+		} else if (stringLength > length) {
+			int begin = (stringLength - length) >> 1; // take fewer characters off the front
+			sb.append(string, begin, begin + length);  // NB: end index is exclusive
+		} else {
+			int begin = (length - stringLength) >> 1; // add fewer characters to the front
+			fill(sb, begin, c);
+			sb.append(string);
+			fill(sb, length - (begin + stringLength), c);
+		}
+	}
+
+	/**
+	 * @see #center(StringBuilder, String, int, char)
+	 */
+	public static void center(StringBuilder sb, char[] string, int length, char c) {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length;
+		if (stringLength == length) {
+			sb.append(string);
+		} else if (stringLength > length) {
+			int begin = (stringLength - length) >> 1; // take fewer characters off the front
+			sb.append(string, begin, length);
+		} else {
+			int begin = (length - stringLength) >> 1; // add fewer characters to the front
+			fill(sb, begin, c);
+			sb.append(string);
+			fill(sb, length - (begin + stringLength), c);
+		}
+	}
+
+	/**
+	 * Pad the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with spaces
+	 * at the end.
+	 */
+	public static void pad(StringBuilder sb, String string, int length) {
+		pad(sb, string, length, ' ');
+	}
+
+	/**
+	 * @see #pad(StringBuilder, String, int)
+	 */
+	public static void pad(StringBuilder sb, char[] string, int length) {
+		pad(sb, string, length, ' ');
+	}
+
+	/**
+	 * Pad the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at the end.
+	 */
+	public static void pad(StringBuilder sb, String string, int length, char c) {
+		int stringLength = string.length();
+		if (stringLength > length) {
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
+		}
+		if (stringLength == length) {
+			sb.append(string);
+		} else {
+			pad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * @see #pad(StringBuilder, String, int, char)
+	 */
+	public static void pad(StringBuilder sb, char[] string, int length, char c) {
+		int stringLength = string.length;
+		if (stringLength > length) {
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
+		}
+		if (stringLength == length) {
+			sb.append(string);
+		} else {
+			pad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * Pad or truncate the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with spaces at
+	 * the end.
+	 */
+	public static void fit(StringBuilder sb, String string, int length) {
+		fit(sb, string, length, ' ');
+	}
+
+	/**
+	 * @see #fit(StringBuilder, String, int)
+	 */
+	public static void fit(StringBuilder sb, char[] string, int length) {
+		fit(sb, string, length, ' ');
+	}
+
+	/**
+	 * Pad or truncate the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at the end.
+	 */
+	public static void fit(StringBuilder sb, String string, int length, char c) {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length();
+		if (stringLength == length) {
+			sb.append(string);
+		} else if (stringLength > length) {
+			sb.append(string, 0, length);  // NB: end index is exclusive
+		} else {
+			pad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * @see #fit(StringBuilder, String, int, char)
+	 */
+	public static void fit(StringBuilder sb, char[] string, int length, char c) {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length;
+		if (stringLength == length) {
+			sb.append(string);
+		} else if (stringLength > length) {
+			sb.append(string, 0, length);
+		} else {
+			pad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * Pad the specified string without validating the parms.
+	 */
+	private static void pad_(StringBuilder sb, String string, int stringLength, int length, char c) {
+		sb.append(string);
+		fill(sb, stringLength, length, c);
+	}
+
+	/**
+	 * Pad the specified string without validating the parms.
+	 */
+	private static void pad_(StringBuilder sb, char[] string, int stringLength, int length, char c) {
+		sb.append(string);
+		fill(sb, stringLength, length, c);
+	}
+
+	/**
+	 * Add enough characters to the specified stream to compensate for
+	 * the difference between the specified string length and specified length.
+	 */
+	private static void fill(StringBuilder sb, int stringLength, int length, char c) {
+		fill(sb, length - stringLength, c);
+	}
+
+	/**
+	 * Add the specified length of characters to the specified stream.
+	 */
+	private static void fill(StringBuilder sb, int length, char c) {
+		sb.append(ArrayTools.fill(new char[length], c));
+	}
+
+	/**
+	 * Pad the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with zeros
+	 * at the front.
+	 */
+	public static void zeroPad(StringBuilder sb, String string, int length) {
+		frontPad(sb, string, length, '0');
+	}
+
+	/**
+	 * @see #zeroPad(StringBuilder, String, int)
+	 */
+	public static void zeroPad(StringBuilder sb, char[] string, int length) {
+		frontPad(sb, string, length, '0');
+	}
+
+	/**
+	 * Pad the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at the front.
+	 */
+	public static void frontPad(StringBuilder sb, String string, int length, char c) {
+		int stringLength = string.length();
+		if (stringLength > length) {
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
+		}
+		if (stringLength == length) {
+			sb.append(string);
+		} else {
+			frontPad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * @see #frontPad(StringBuilder, String, int, char)
+	 */
+	public static void frontPad(StringBuilder sb, char[] string, int length, char c) {
+		int stringLength = string.length;
+		if (stringLength > length) {
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
+		}
+		if (stringLength == length) {
+			sb.append(string);
+		} else {
+			frontPad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * Pad or truncate the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, append only the last
+	 * part of the string.
+	 * If the string is shorter than the specified length, pad it with zeros
+	 * at the front.
+	 */
+	public static void zeroFit(StringBuilder sb, String string, int length) {
+		frontFit(sb, string, length, '0');
+	}
+
+	/**
+	 * @see #zeroFit(StringBuilder, String, int)
+	 */
+	public static void zeroFit(StringBuilder sb, char[] string, int length) {
+		frontFit(sb, string, length, '0');
+	}
+
+	/**
+	 * Pad or truncate the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, append only the last
+	 * part of the string.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at the front.
+	 */
+	public static void frontFit(StringBuilder sb, String string, int length, char c) {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length();
+		if (stringLength == length) {
+			sb.append(string);
+		} else if (stringLength > length) {
+			sb.append(string, stringLength - length, stringLength);  // NB: end index is exclusive
+		} else {
+			frontPad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * @see #frontFit(StringBuilder, String, int, char)
+	 */
+	public static void frontFit(StringBuilder sb, char[] string, int length, char c) {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length;
+		if (stringLength == length) {
+			sb.append(string);
+		} else if (stringLength > length) {
+			sb.append(string, stringLength - length, length);
+		} else {
+			frontPad_(sb, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * Pad the specified string without validating the parms.
+	 */
+	private static void frontPad_(StringBuilder sb, String string, int stringLength, int length, char c) {
+		fill(sb, stringLength, length, c);
+		sb.append(string);
+	}
+
+	/**
+	 * Pad the specified string without validating the parms.
+	 */
+	private static void frontPad_(StringBuilder sb, char[] string, int stringLength, int length, char c) {
+		fill(sb, stringLength, length, c);
+		sb.append(string);
+	}
+
+
+	// ********** separating **********
+
+	/**
+	 * Separate the segments of the specified string with the specified
+	 * separator:<p>
+	 * <code>
+	 * separate("012345", '-', 2) => "01-23-45"
+	 * </code>
+	 */
+	public static void separate(StringBuilder sb, String string, char separator, int segmentSize) {
+		if (segmentSize <= 0) {
+			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
+		}
+		int stringLength = string.length();
+		if (stringLength <= segmentSize) {
+			sb.append(string);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + (stringLength / segmentSize));
+			separate(sb, string, separator, segmentSize, stringLength);
+		}
+	}
+
+	/**
+	 * Pre-conditions: string is longer than segment size; segment size is positive
+	 */
+	private static void separate(StringBuilder sb, String string, char separator, int segmentSize, int stringLength) {
+		int segCount = 0;
+		for (int i = 0; i < stringLength; i++) {
+			char c = string.charAt(i);
+			if (segCount == segmentSize) {
+				sb.append(separator);
+				segCount = 0;
+			}
+			segCount++;
+			sb.append(c);
+		}
+	}
+
+	/**
+	 * @see #separate(StringBuilder, String, char, int)
+	 */
+	public static void separate(StringBuilder sb, char[] string, char separator, int segmentSize) {
+		if (segmentSize <= 0) {
+			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
+		}
+		int stringLength = string.length;
+		if (stringLength <= segmentSize) {
+			sb.append(string);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + (stringLength / segmentSize));
+			separate(sb, string, separator, segmentSize, stringLength);
+		}
+	}
+
+	/**
+	 * Pre-conditions: string is longer than segment size; segment size is positive
+	 */
+	private static void separate(StringBuilder sb, char[] string, char separator, int segmentSize, int stringLength) {
+		int segCount = 0;
+		for (int i = 0; i < stringLength; i++) {
+			char c = string[i];
+			if (segCount == segmentSize) {
+				sb.append(separator);
+				segCount = 0;
+			}
+			segCount++;
+			sb.append(c);
+		}
+	}
+
+
+	// ********** delimiting/quoting **********
+
+	/**
+	 * Delimit the specified string with double quotes.
+	 * Escape any occurrences of a double quote in the string with another
+	 * double quote.
+	 */
+	public static void quote(StringBuilder sb, String string) {
+		delimit(sb, string, CharacterTools.QUOTE);
+	}
+
+	/**
+	 * @see #quote(StringBuilder, String)
+	 */
+	public static void quote(StringBuilder sb, char[] string) {
+		delimit(sb, string, CharacterTools.QUOTE);
+	}
+
+	/**
+	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
+	 * the delimiter at the front and back of the resulting string.
+	 * Escape any occurrences of the delimiter in the string with another delimiter.
+	 */
+	public static void delimit(StringBuilder sb, String string, char delimiter) {
+		int stringLength = string.length();
+		sb.ensureCapacity(sb.length() + stringLength + 2);
+		delimit(sb, string, delimiter, stringLength);
+	}
+
+	static void delimit(StringBuilder sb, String string, char delimiter, int stringLength) {
+		sb.append(delimiter);
+		for (int i = 0; i < stringLength; i++) {
+			char c = string.charAt(i);
+			if (c == delimiter) {
+				sb.append(c);
+			}
+			sb.append(c);
+		}
+		sb.append(delimiter);
+	}
+
+	/**
+	 * @see #delimit(StringBuilder, String, char)
+	 */
+	public static void delimit(StringBuilder sb, char[] string, char delimiter) {
+		int stringLength = string.length;
+		sb.ensureCapacity(sb.length() + stringLength + 2);
+		delimit(sb, string, delimiter, stringLength);
+	}
+
+	static void delimit(StringBuilder sb, char[] string, char delimiter, int stringLength) {
+		sb.append(delimiter);
+		for (int i = 0; i < stringLength; i++) {
+			char c = string[i];
+			if (c == delimiter) {
+				sb.append(c);
+			}
+			sb.append(c);
+		}
+		sb.append(delimiter);
+	}
+
+	/**
+	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
+	 * the delimiter at the front and back of the resulting string.
+	 * Escape any occurrences of a single-character delimiter in the string with
+	 * another delimiter.
+	 */
+	public static void delimit(StringBuilder sb, String string, String delimiter) {
+		int delimiterLength = delimiter.length();
+		switch (delimiterLength) {
+			case 0:
+				sb.append(string);
+				break;
+			case 1:
+				delimit(sb, string, delimiter.charAt(0));
+				break;
+			default:
+				delimit(sb, string, delimiter, delimiterLength);
+				break;
+		}
+	}
+
+	/**
+	 * No parm check
+	 */
+	private static void delimit(StringBuilder sb, String string, String delimiter, int delimiterLength) {
+		sb.append(delimiter, 0, delimiterLength);
+		sb.append(string);
+		sb.append(delimiter, 0, delimiterLength);
+	}
+
+	/**
+	 * @see #delimit(StringBuilder, String, String)
+	 */
+	public static void delimit(StringBuilder sb, char[] string, char[] delimiter) {
+		int delimiterLength = delimiter.length;
+		switch (delimiterLength) {
+			case 0:
+				sb.append(string);
+				break;
+			case 1:
+				delimit(sb, string, delimiter[0]);
+				break;
+			default:
+				delimit(sb, string, delimiter, delimiterLength);
+				break;
+		}
+	}
+
+	/**
+	 * No parm check
+	 */
+	private static void delimit(StringBuilder sb, char[] string, char[] delimiter, int delimiterLength) {
+		sb.append(delimiter, 0, delimiterLength);
+		sb.append(string);
+		sb.append(delimiter, 0, delimiterLength);
+	}
+
+
+	// ********** undelimiting **********
+
+	/**
+	 * Remove the delimiters from the specified string, removing any escape
+	 * characters. Throw an {@link IllegalArgumentException} if the string is
+	 * too short to undelimit (i.e. length < 2).
+	 */
+	public static void undelimit(StringBuilder sb, String string) {
+		int stringLength = string.length();
+		int resultLength = stringLength - 2;
+		if (resultLength < 0) {
+			throw new IllegalArgumentException("invalid string: \"" + string + '"');
+		}
+		if (resultLength == 0) {
+			return;
+		}
+		undelimit_(sb, string, stringLength);
+	}
+
+	/**
+	 * pre-condition: string is at least 3 characters long
+	 */
+	static void undelimit_(StringBuilder sb, String string, int stringLength) {
+		char delimiter = string.charAt(0);  // the first char is the delimiter
+		char c = delimiter;
+		char next = string.charAt(1);
+		int i = 1;
+		int last = stringLength - 1;
+		do {
+			c = next;
+			sb.append(c);
+			i++;
+			next = string.charAt(i);
+			if (c == delimiter) {
+				if ((next != delimiter) || (i == last)) {
+					// an embedded delimiter must be followed by another delimiter
+					return;
+				}
+				i++;
+				next = string.charAt(i);
+			}
+		} while (i != last);
+	}
+
+	/**
+	 * @see #undelimit(StringBuilder, String)
+	 */
+	public static void undelimit(StringBuilder sb, char[] string) {
+		int stringLength = string.length;
+		int resultLength = stringLength - 2;
+		if (resultLength < 0) {
+			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
+		}
+		if (resultLength == 0) {
+			return;
+		}
+		undelimit_(sb, string, stringLength);
+	}
+
+	/**
+	 * pre-condition: string is at least 3 characters long
+	 */
+	static void undelimit_(StringBuilder sb, char[] string, int stringLength) {
+		char delimiter = string[0];  // the first char is the delimiter
+		char c = delimiter;
+		char next = string[1];
+		int i = 1;
+		int last = stringLength - 1;
+		do {
+			c = next;
+			sb.append(c);
+			i++;
+			next = string[i];
+			if (c == delimiter) {
+				if ((next != delimiter) || (i == last)) {
+					// an embedded delimiter must be followed by another delimiter
+					return;
+				}
+				i++;
+				next = string[i];
+			}
+		} while (i != last);
+	}
+
+	/**
+	 * Remove the first and last count characters from the specified string.
+	 * If the string is too short to be undelimited, throw an
+	 * {@link IllegalArgumentException}.
+	 * Use this method to undelimit strings that do not escape embedded
+	 * delimiters.
+	 */
+	public static void undelimit(StringBuilder sb, String string, int count) {
+		if (count == 0) {
+			sb.append(string);
+			return;
+		}
+		int resultLength = string.length() - (2 * count);
+		if (resultLength < 0) {
+			throw new IllegalArgumentException("invalid string: \"" + string + '"');
+		}
+		if (resultLength == 0) {
+			return;
+		}
+		sb.append(string, count, count + resultLength);  // NB: end index is exclusive
+	}
+
+	/**
+	 * @see #undelimit(StringBuilder, String, int)
+	 */
+	public static void undelimit(StringBuilder sb, char[] string, int count) {
+		if (count == 0) {
+			sb.append(string);
+			return;
+		}
+		int resultLength = string.length - (2 * count);
+		if (resultLength < 0) {
+			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
+		}
+		if (resultLength == 0) {
+			return;
+		}
+		sb.append(string, count, resultLength);
+	}
+
+
+	// ********** removing characters **********
+
+	/**
+	 * Remove the first occurrence of the specified character
+	 * from the specified string and print the result on the specified stream.
+	 */
+	public static void removeFirstOccurrence(StringBuilder sb, String string, char c) {
+		int index = string.indexOf(c);
+		if (index == -1) {
+			sb.append(string);
+		} else {
+			removeCharAtIndex(sb, string, index);
+		}
+	}
+
+	private static void removeCharAtIndex(StringBuilder sb, String string, int index) {
+		int stringLength = string.length();
+		if (index == 0) {
+			// character found at the front of string
+			sb.append(string, 1, stringLength);  // NB: end index is exclusive
+		} else {
+			sb.append(string, 0, index);  // NB: end index is exclusive
+			if (index != (stringLength - 1)) {
+				// character is not at the end of the string
+				sb.append(string, index + 1, stringLength);  // NB: end index is exclusive
+			}
+		}
+	}
+
+	/**
+	 * @see #removeFirstOccurrence(StringBuilder, String, char)
+	 */
+	public static void removeFirstOccurrence(StringBuilder sb, char[] string, char c) {
+		int index = ArrayTools.indexOf(string, c);
+		if (index == -1) {
+			sb.append(string);
+		} else {
+			removeCharAtIndex(sb, string, index);
+		}
+	}
+
+	private static void removeCharAtIndex(StringBuilder sb, char[] string, int index) {
+		int last = string.length - 1;
+		if (index == 0) {
+			// character found at the front of string
+			sb.append(string, 1, last);
+		} else if (index == last) {
+			// character found at the end of string
+			sb.append(string, 0, last);
+		} else {
+			// character found somewhere in the middle of the string
+			sb.append(string, 0, index);
+			sb.append(string, index + 1, last - index);
+		}
+	}
+
+	/**
+	 * Remove all occurrences of the specified character
+	 * from the specified string and write the result to the specified stream.
+	 */
+	public static void removeAllOccurrences(StringBuilder sb, String string, char c) {
+		int first = string.indexOf(c);
+		if (first == -1) {
+			sb.append(string);
+		} else {
+			int stringLength = string.length();
+			sb.ensureCapacity(sb.length() + stringLength);
+			removeAllOccurrences(sb, string, c, first, stringLength);
+		}
+	}
+
+	/**
+	 * The index of the first matching character is passed in.
+	 */
+	static void removeAllOccurrences(StringBuilder sb, String string, char c, int first, int stringLength) {
+		sb.append(string, 0, first);  // NB: end index is exclusive
+		for (int i = first; i < stringLength; i++) {
+			char d = string.charAt(i);
+			if (d != c) {
+				sb.append(d);
+			}
+		}
+	}
+
+	/**
+	 * @see #removeAllOccurrences(StringBuilder, String, char)
+	 */
+	public static void removeAllOccurrences(StringBuilder sb, char[] string, char c) {
+		int first = ArrayTools.indexOf(string, c);
+		if (first == -1) {
+			sb.append(string);
+		} else {
+			int stringLength = string.length;
+			sb.ensureCapacity(sb.length() + stringLength);
+			removeAllOccurrences(sb, string, c, first, stringLength);
+		}
+	}
+
+	/**
+	 * The index of the first matching character is passed in.
+	 */
+	static void removeAllOccurrences(StringBuilder sb, char[] string, char c, int first, int stringLength) {
+		sb.append(string, 0, first);
+		for (int i = first; i < stringLength; i++) {
+			char d = string[i];
+			if (d != c) {
+				sb.append(d);
+			}
+		}
+	}
+
+	/**
+	 * Remove all the spaces
+	 * from the specified string and write the result to the specified stream.
+	 */
+	public static void removeAllSpaces(StringBuilder sb, String string) {
+		removeAllOccurrences(sb, string, ' ');
+	}
+
+	/**
+	 * @see #removeAllSpaces(StringBuilder, String)
+	 */
+	public static void removeAllSpaces(StringBuilder sb, char[] string) {
+		removeAllOccurrences(sb, string, ' ');
+	}
+
+	/**
+	 * Remove all the whitespace
+	 * from the specified string and append the result to the
+	 * specified stream.
+	 */
+	public static void removeAllWhitespace(StringBuilder sb, String string) {
+		int first = StringTools.indexOfWhitespace(string);
+		if (first == -1) {
+			sb.append(string);
+		} else {
+			int stringLength = string.length();
+			sb.ensureCapacity(sb.length() + stringLength);
+			removeAllWhitespace(sb, string, first, stringLength);
+		}
+	}
+
+	/**
+	 * The index of the first whitespace character is passed in.
+	 */
+	static void removeAllWhitespace(StringBuilder sb, String string, int first, int stringLength) {
+		sb.append(string, 0, first);  // NB: end index is exclusive
+		for (int i = first; i < stringLength; i++) {
+			char c = string.charAt(i);
+			if ( ! Character.isWhitespace(c)) {
+				sb.append(c);
+			}
+		}
+	}
+
+	/**
+	 * @see #removeAllWhitespace(StringBuilder, String)
+	 */
+	public static void removeAllWhitespace(StringBuilder sb, char[] string) {
+		int first = CharArrayTools.indexOfWhitespace(string);
+		if (first == -1) {
+			sb.append(string);
+		} else {
+			int stringLength = string.length;
+			sb.ensureCapacity(sb.length() + stringLength);
+			removeAllWhitespace(sb, string, first, stringLength);
+		}
+	}
+
+	/**
+	 * The index of the first whitespace character is passed in.
+	 */
+	static void removeAllWhitespace(StringBuilder sb, char[] string, int first, int stringLength) {
+		sb.append(string, 0, first);
+		for (int i = first; i < stringLength; i++) {
+			char c = string[i];
+			if ( ! Character.isWhitespace(c)) {
+				sb.append(c);
+			}
+		}
+	}
+
+	/**
+	 * Compress the whitespace
+	 * in the specified string and append the result to the
+	 * specified stream.
+	 * The whitespace is compressed by replacing any occurrence of one or more
+	 * whitespace characters with a single space.
+	 */
+	public static void compressWhitespace(StringBuilder sb, String string) {
+		int first = StringTools.indexOfWhitespace(string);
+		if (first == -1) {
+			sb.append(string);
+		} else {
+			int stringLength = string.length();
+			sb.ensureCapacity(sb.length() + stringLength);
+			compressWhitespace(sb, string, first, stringLength);
+		}
+	}
+
+	/**
+	 * The index of the first whitespace character is passed in.
+	 */
+	static void compressWhitespace(StringBuilder sb, String string, int first, int stringLength) {
+		sb.append(string, 0, first);  // NB: end index is exclusive
+		int i = first;
+		char c = string.charAt(i);
+		main: while (true) {
+			// replace first whitespace character with a space...
+			sb.append(' ');
+			// ...and skip subsequent whitespace characters
+			while (true) {
+				i++;
+				if (i >= stringLength) {
+					break main;
+				}
+				c = string.charAt(i);
+				if ( ! Character.isWhitespace(c)) {
+					break;
+				}
+			}
+			while (true) {
+				sb.append(c);
+				i++;
+				if (i >= stringLength) {
+					break main;
+				}
+				c = string.charAt(i);
+				if (Character.isWhitespace(c)) {
+					break;
+				}
+			}
+		}
+	}
+
+	/**
+	 * @see #compressWhitespace(StringBuilder, String)
+	 */
+	public static void compressWhitespace(StringBuilder sb, char[] string) {
+		int first = CharArrayTools.indexOfWhitespace(string);
+		if (first == -1) {
+			sb.append(string);
+		} else {
+			int stringLength = string.length;
+			sb.ensureCapacity(sb.length() + stringLength);
+			compressWhitespace(sb, string, first, stringLength);
+		}
+	}
+
+	/**
+	 * The index of the first whitespace character is passed in.
+	 */
+	static void compressWhitespace(StringBuilder sb, char[] string, int first, int stringLength) {
+		sb.append(string, 0, first);  // NB: end index is exclusive
+		int i = first;
+		char c = string[i];
+		main: while (true) {
+			// replace first whitespace character with a space...
+			sb.append(' ');
+			// ...and skip subsequent whitespace characters
+			while (true) {
+				i++;
+				if (i >= stringLength) {
+					break main;
+				}
+				c = string[i];
+				if ( ! Character.isWhitespace(c)) {
+					break;
+				}
+			}
+			while (true) {
+				sb.append(c);
+				i++;
+				if (i >= stringLength) {
+					break main;
+				}
+				c = string[i];
+				if (Character.isWhitespace(c)) {
+					break;
+				}
+			}
+		}
+	}
+
+
+	// ********** capitalization **********
+
+	/**
+	 * Append the specified string to the specified stream
+	 * with its first letter capitalized.
+	 */
+	public static void capitalize(StringBuilder sb, String string) {
+		if (string.length() == 0) {
+			return;
+		}
+		if (Character.isUpperCase(string.charAt(0))) {
+			sb.append(string);
+		} else {
+			capitalize_(sb, string);
+		}
+	}
+
+	/**
+	 * no zero-length check or upper case check
+	 */
+	private static void capitalize_(StringBuilder sb, String string) {
+		sb.append(Character.toUpperCase(string.charAt(0)));
+		sb.append(string, 1, string.length());  // NB: end index is exclusive
+	}
+
+	/**
+	 * @see #capitalize(StringBuilder, String)
+	 */
+	public static void capitalize(StringBuilder sb, char[] string) {
+		if (string.length == 0) {
+			return;
+		}
+		if (Character.isUpperCase(string[0])) {
+			sb.append(string);
+		} else {
+			capitalize_(sb, string);
+		}
+	}
+
+	/**
+	 * no zero-length check or upper case check
+	 */
+	private static void capitalize_(StringBuilder sb, char[] string) {
+		sb.append(Character.toUpperCase(string[0]));
+		sb.append(string, 1, string.length - 1);
+	}
+
+	/**
+	 * Append the specified string to the specified stream
+	 * with its first letter converted to lower case.
+	 * (Unless both the first and second letters are upper case,
+	 * in which case the string is returned unchanged.)
+	 */
+	public static void uncapitalize(StringBuilder sb, String string) {
+		int stringLength = string.length();
+		if (StringTools.needNotBeUncapitalized(string, stringLength)) {
+			sb.append(string);
+		} else {
+			uncapitalize(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * no zero-length check or upper case check
+	 */
+	private static void uncapitalize(StringBuilder sb, String string, int stringLength) {
+		sb.append(Character.toLowerCase(string.charAt(0)));
+		sb.append(string, 1, stringLength);  // NB: end index is exclusive
+	}
+
+	/**
+	 * @see #uncapitalize(StringBuilder, String)
+	 */
+	public static void uncapitalize(StringBuilder sb, char[] string) {
+		int stringLength = string.length;
+		if (CharArrayTools.needNotBeUncapitalized(string, stringLength)) {
+			sb.append(string);
+		} else {
+			uncapitalize(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * no zero-length check or upper case check
+	 */
+	private static void uncapitalize(StringBuilder sb, char[] string, int stringLength) {
+		sb.append(Character.toLowerCase(string[0]));
+		sb.append(string, 1, stringLength - 1);
+	}
+
+
+	// ********** convert byte array to hex string **********
+
+	/**
+	 * Convert the specified byte array to the corresponding string of
+	 * hexadecimal characters.
+	 * @see ByteArrayTools#convertToHexString(byte[])
+	 */
+	public static void convertToHexString(StringBuilder sb, byte[] bytes) {
+		int bytesLength = bytes.length;
+		if (bytesLength != 0) {
+			sb.ensureCapacity(sb.length() + (bytesLength << 1));
+			convertToHexString(sb, bytes, bytesLength);
+		}
+	}
+
+	/**
+	 * Pre-condition: the byte array is not empty
+	 */
+	static void convertToHexString(StringBuilder sb, byte[] bytes, int bytesLength) {
+		char[] digits = CharacterTools.DIGITS;
+		for (int i = 0; i < bytesLength; i++) {
+			int b = bytes[i] & 0xFF; // clear any sign bits
+			sb.append(digits[b >> 4]); // first nibble
+			sb.append(digits[b & 0xF]); // second nibble
+		}
+	}
+
+
+	// ********** convert camel case to all caps **********
+
+	/**
+	 * Convert the specified "camel case" string to an "all caps" string:
+	 * <p>
+	 * <code>
+	 * "largeProject" -> "LARGE_PROJECT"
+	 * </code>
+	 */
+	public static void convertCamelCaseToAllCaps(StringBuilder sb, String camelCaseString) {
+		int stringLength = camelCaseString.length();
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + (stringLength / 4));
+			convertCamelCaseToAllCaps_(sb, camelCaseString, stringLength);
+		}
+	}
+
+	/**
+	 * Pre-condition: the string is not empty
+	 */
+	static void convertCamelCaseToAllCaps_(StringBuilder sb, String camelCaseString, int stringLength) {
+		char prev = 0;	// assume 0 is not a valid char
+		char c = 0;
+		char next = camelCaseString.charAt(0);
+		for (int i = 1; i <= stringLength; i++) {	// NB: start at 1 and end at stringLength!
+			c = next;
+			next = ((i == stringLength) ? 0 : camelCaseString.charAt(i));
+			if (StringTools.camelCaseWordBreak(prev, c, next)) {
+				sb.append('_');
+			}
+			sb.append(Character.toUpperCase(c));
+			prev = c;
+		}
+	}
+
+	/**
+	 * @see #convertCamelCaseToAllCaps(StringBuilder, String)
+	 */
+	public static void convertCamelCaseToAllCaps(StringBuilder sb, char[] camelCaseString) {
+		int stringLength = camelCaseString.length;
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + (stringLength / 4));
+			convertCamelCaseToAllCaps_(sb, camelCaseString, stringLength);
+		}
+	}
+
+	/**
+	 * Pre-condition: the string is not empty
+	 */
+	static void convertCamelCaseToAllCaps_(StringBuilder sb, char[] camelCaseString, int stringLength) {
+		char prev = 0;	// assume 0 is not a valid char
+		char c = 0;
+		char next = camelCaseString[0];
+		for (int i = 1; i <= stringLength; i++) {	// NB: start at 1 and end at stringLength!
+			c = next;
+			next = ((i == stringLength) ? 0 : camelCaseString[i]);
+			if (StringTools.camelCaseWordBreak(prev, c, next)) {
+				sb.append('_');
+			}
+			sb.append(Character.toUpperCase(c));
+			prev = c;
+		}
+	}
+
+	/**
+	 * Convert the specified "camel case" string to an "all caps" string:
+	 * <p>
+	 * <code>
+	 * "largeProject" -> "LARGE_PROJECT"
+	 * </code>
+	 * <p>
+	 * Limit the resulting string to the specified maximum length.
+	 */
+	public static void convertCamelCaseToAllCaps(StringBuilder sb, String camelCaseString, int maxLength) {
+		if (maxLength != 0) {
+			int stringLength = camelCaseString.length();
+			if (stringLength != 0) {
+				sb.ensureCapacity(sb.length() + maxLength);
+				convertCamelCaseToAllCaps(sb, camelCaseString, maxLength, stringLength);
+			}
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	static void convertCamelCaseToAllCaps(StringBuilder sb, String camelCaseString, int maxLength, int stringLength) {
+		char prev = 0;	// assume 0 is not a valid char
+		char c = 0;
+		char next = camelCaseString.charAt(0);
+		for (int i = 1; i <= stringLength; i++) {	// NB: start at 1 and end at stringLength!
+			c = next;
+			next = ((i == stringLength) ? 0 : camelCaseString.charAt(i));
+			if (StringTools.camelCaseWordBreak(prev, c, next)) {
+				sb.append('_');
+				if (sb.length() == maxLength) {
+					return;
+				}
+			}
+			sb.append(Character.toUpperCase(c));
+			if (sb.length() == maxLength) {
+				return;
+			}
+			prev = c;
+		}
+	}
+
+	/**
+	 * @see #convertCamelCaseToAllCaps(StringBuilder, String, int)
+	 */
+	public static void convertCamelCaseToAllCaps(StringBuilder sb, char[] camelCaseString, int maxLength) {
+		if (maxLength != 0) {
+			int stringLength = camelCaseString.length;
+			if (stringLength != 0) {
+				sb.ensureCapacity(sb.length() + maxLength);
+				convertCamelCaseToAllCaps(sb, camelCaseString, maxLength, stringLength);
+			}
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	static void convertCamelCaseToAllCaps(StringBuilder sb, char[] camelCaseString, int maxLength, int stringLength) {
+		char prev = 0;	// assume 0 is not a valid char
+		char c = 0;
+		char next = camelCaseString[0];
+		for (int i = 1; i <= stringLength; i++) {	// NB: start at 1 and end at stringLength!
+			c = next;
+			next = ((i == stringLength) ? 0 : camelCaseString[i]);
+			if (StringTools.camelCaseWordBreak(prev, c, next)) {
+				sb.append('_');
+				if (sb.length() == maxLength) {
+					return;
+				}
+			}
+			sb.append(Character.toUpperCase(c));
+			if (sb.length() == maxLength) {
+				return;
+			}
+			prev = c;
+		}
+	}
+
+
+	// ********** convert all caps to camel case **********
+
+	/**
+	 * Convert the specified "all caps" string to a "camel case" string:
+	 * <p>
+	 * <code>
+	 * "LARGE_PROJECT" -> "LargeProject"
+	 * </code>
+	 * <p>
+	 * Capitalize the first letter.
+	 */
+	public static void convertAllCapsToCamelCase(StringBuilder sb, String allCapsString) {
+		convertAllCapsToCamelCase(sb, allCapsString, true);
+	}
+
+	/**
+	 * @see #convertAllCapsToCamelCase(StringBuilder, String)
+	 */
+	public static void convertAllCapsToCamelCase(StringBuilder sb, char[] allCapsString) {
+		convertAllCapsToCamelCase(sb, allCapsString, true);
+	}
+
+	/**
+	 * Convert the specified "all caps" string to a "camel case" string:
+	 * <p>
+	 * <code>
+	 * "LARGE_PROJECT" -> "largeProject"
+	 * </code>
+	 * <p>
+	 * Optionally capitalize the first letter.
+	 */
+	public static void convertAllCapsToCamelCase(StringBuilder sb, String allCapsString, boolean capitalizeFirstLetter) {
+		int stringLength = allCapsString.length();
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength);
+			convertAllCapsToCamelCase(sb, allCapsString, capitalizeFirstLetter, stringLength);
+		}
+	}
+
+	static void convertAllCapsToCamelCase(StringBuilder sb, String allCapsString, boolean capitalizeFirstLetter, int stringLength) {
+		char prev = 0;
+		char c = 0;
+		boolean first = true;
+		for (int i = 0; i < stringLength; i++) {
+			prev = c;
+			c = allCapsString.charAt(i);
+			if (c == '_') {
+				continue;
+			}
+			if (first) {
+				first = false;
+				sb.append(capitalizeFirstLetter ? Character.toUpperCase(c) : Character.toLowerCase(c));
+			} else {
+				sb.append((prev == '_') ? Character.toUpperCase(c) : Character.toLowerCase(c));
+			}
+		}
+	}
+
+	/**
+	 * @see #convertAllCapsToCamelCase(StringBuilder, String, boolean)
+	 */
+	public static void convertAllCapsToCamelCase(StringBuilder sb, char[] allCapsString, boolean capitalizeFirstLetter) {
+		int stringLength = allCapsString.length;
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength);
+			convertAllCapsToCamelCase(sb, allCapsString, capitalizeFirstLetter, stringLength);
+		}
+	}
+
+	static void convertAllCapsToCamelCase(StringBuilder sb, char[] allCapsString, boolean capitalizeFirstLetter, int stringLength) {
+		char prev = 0;
+		char c = 0;
+		boolean first = true;
+		for (int i = 0; i < stringLength; i++) {
+			prev = c;
+			c = allCapsString[i];
+			if (c == '_') {
+				continue;
+			}
+			if (first) {
+				first = false;
+				sb.append(capitalizeFirstLetter ? Character.toUpperCase(c) : Character.toLowerCase(c));
+			} else {
+				sb.append((prev == '_') ? Character.toUpperCase(c) : Character.toLowerCase(c));
+			}
+		}
+	}
+
+
+	// ********** convert to Java string literal **********
+
+	/**
+	 * Convert the specified string to a Java string literal, with the
+	 * appropriate escaped characters.
+	 */
+	public static void convertToJavaStringLiteral(StringBuilder sb, String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			sb.append(StringTools.EMPTY_JAVA_STRING_LITERAL);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + 6);
+			convertToJavaStringLiteral(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	static void convertToJavaStringLiteral(StringBuilder sb, String string, int stringLength) {
+		sb.append(CharacterTools.QUOTE);
+		convertToJavaStringLiteralContent(sb, string, stringLength);
+		sb.append(CharacterTools.QUOTE);
+	}
+
+	/**
+	 * Convert the specified string to the contents of a Java string literal,
+	 * with the appropriate escaped characters.
+	 */
+	public static void convertToJavaStringLiteralContent(StringBuilder sb, String string) {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 6);
+			convertToJavaStringLiteralContent(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	static void convertToJavaStringLiteralContent(StringBuilder sb, String string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToJavaStringLiteral(sb, string.charAt(i));
+		}
+	}
+
+	/**
+	 * @see #convertToJavaStringLiteral(StringBuilder, String)
+	 */
+	public static void convertToJavaStringLiteral(StringBuilder sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			sb.append(StringTools.EMPTY_JAVA_STRING_LITERAL);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + 6);
+			convertToJavaStringLiteral(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	static void convertToJavaStringLiteral(StringBuilder sb, char[] string, int stringLength) {
+		sb.append(CharacterTools.QUOTE);
+		convertToJavaStringLiteralContent(sb, string, stringLength);
+		sb.append(CharacterTools.QUOTE);
+	}
+
+	/**
+	 * @see #convertToJavaStringLiteralContent(StringBuilder, String)
+	 */
+	public static void convertToJavaStringLiteralContent(StringBuilder sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 6);
+			convertToJavaStringLiteralContent(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	static void convertToJavaStringLiteralContent(StringBuilder sb, char[] string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToJavaStringLiteral(sb, string[i]);
+		}
+	}
+
+	private static void convertToJavaStringLiteral(StringBuilder sb, char c) {
+		switch (c) {
+			case '\b':  // backspace
+				sb.append("\\b");
+				break;
+			case '\t':  // horizontal tab
+				sb.append("\\t");
+				break;
+			case '\n':  // line-feed LF
+				sb.append("\\n");
+				break;
+			case '\f':  // form-feed FF
+				sb.append("\\f");
+				break;
+			case '\r':  // carriage-return CR
+				sb.append("\\r");
+				break;
+			case '"':  // double-quote
+				sb.append("\\\"");
+				break;
+//			case '\'':  // single-quote
+//				sb.append("\\'");
+//				break;
+			case '\\':  // backslash
+				sb.append("\\\\");
+				break;
+			default:
+				sb.append(c);
+				break;
+		}
+	}
+
+
+	// ********** convert to XML **********
+
+	/**
+	 * Convert the specified string to an XML attribute value, escaping the
+	 * appropriate characters. Delimit with quotes (<code>"</code>) unless
+	 * there are <em>embedded</em> quotes (<em>and</em> no embedded
+	 * apostrophes); in which case, delimit with apostrophes (<code>'</code>).
+	 */
+	public static void convertToXmlAttributeValue(StringBuilder sb, String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			sb.append(StringTools.EMPTY_XML_ATTRIBUTE_VALUE);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + 12);
+			convertToXmlAttributeValue(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	static void convertToXmlAttributeValue(StringBuilder sb, String string, int stringLength) {
+		int index = string.indexOf(CharacterTools.QUOTE);
+		if (index == -1) {
+			// no embedded quotes - use quote delimiters
+			convertToDoubleQuotedXmlAttributeValue(sb, string, stringLength);
+		} else {
+			index = string.indexOf(CharacterTools.APOSTROPHE);
+			if (index == -1) {
+				// embedded quotes but no embedded apostrophes - use apostrophe delimiters
+				convertToSingleQuotedXmlAttributeValue(sb, string, stringLength);
+			} else {
+				// embedded quotes *and* embedded apostrophes - use quote delimiters
+				convertToDoubleQuotedXmlAttributeValue(sb, string, stringLength);
+			}
+		}
+	}
+
+	static void convertToDoubleQuotedXmlAttributeValue(StringBuilder sb, String string, int stringLength) {
+		sb.append(CharacterTools.QUOTE);
+		convertToDoubleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		sb.append(CharacterTools.QUOTE);
+	}
+
+	static void convertToSingleQuotedXmlAttributeValue(StringBuilder sb, String string, int stringLength) {
+		sb.append(CharacterTools.APOSTROPHE);
+		convertToSingleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		sb.append(CharacterTools.APOSTROPHE);
+	}
+
+	/**
+	 * Convert the specified string to a double-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * double quotes).
+	 * @see #convertToXmlAttributeValue(StringBuilder, String)
+	 */
+	public static void convertToDoubleQuotedXmlAttributeValue(StringBuilder sb, String string) {
+		convertToDoubleQuotedXmlAttributeValue(sb, string, string.length());
+	}
+
+	/**
+	 * Convert the specified string to the contents of a double-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * double quotes).
+	 * @see #convertToXmlAttributeValue(StringBuilder, String)
+	 */
+	public static void convertToDoubleQuotedXmlAttributeValueContent(StringBuilder sb, String string) {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 10);
+			convertToDoubleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	static void convertToDoubleQuotedXmlAttributeValueContent(StringBuilder sb, String string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToDoubleQuotedXmlAttributeValueContent(sb, string.charAt(i));
+		}
+	}
+
+	/**
+	 * Convert the specified string to a single-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * single quotes).
+	 * @see #convertToXmlAttributeValue(StringBuilder, String)
+	 */
+	public static void convertToSingleQuotedXmlAttributeValue(StringBuilder sb, String string) {
+		convertToSingleQuotedXmlAttributeValue(sb, string, string.length());
+	}
+
+	/**
+	 * Convert the specified string to the contents of a single-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * single quotes).
+	 * @see #convertToXmlAttributeValue(StringBuilder, String)
+	 */
+	public static void convertToSingleQuotedXmlAttributeValueContent(StringBuilder sb, String string) {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 10);
+			convertToSingleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	static void convertToSingleQuotedXmlAttributeValueContent(StringBuilder sb, String string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToSingleQuotedXmlAttributeValueContent(sb, string.charAt(i));
+		}
+	}
+
+	/**
+	 * @see #convertToXmlAttributeValue(StringBuilder, String)
+	 */
+	public static void convertToXmlAttributeValue(StringBuilder sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			sb.append(StringTools.EMPTY_XML_ATTRIBUTE_VALUE);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + 12);
+			convertToXmlAttributeValue(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	static void convertToXmlAttributeValue(StringBuilder sb, char[] string, int stringLength) {
+		int index = ArrayTools.indexOf(string, CharacterTools.QUOTE);
+		if (index == -1) {
+			// no embedded quotes - use quote delimiters
+			convertToDoubleQuotedXmlAttributeValue(sb, string, stringLength);
+		} else {
+			index = ArrayTools.indexOf(string, CharacterTools.APOSTROPHE);
+			if (index == -1) {
+				// embedded quotes but no embedded apostrophes - use apostrophe delimiters
+				convertToSingleQuotedXmlAttributeValue(sb, string, stringLength);
+			} else {
+				// embedded quotes *and* embedded apostrophes - use quote delimiters
+				convertToDoubleQuotedXmlAttributeValue(sb, string, stringLength);
+			}
+		}
+	}
+
+	static void convertToDoubleQuotedXmlAttributeValue(StringBuilder sb, char[] string, int stringLength) {
+		sb.append(CharacterTools.QUOTE);
+		convertToDoubleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		sb.append(CharacterTools.QUOTE);
+	}
+
+	static void convertToSingleQuotedXmlAttributeValue(StringBuilder sb, char[] string, int stringLength) {
+		sb.append(CharacterTools.APOSTROPHE);
+		convertToSingleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		sb.append(CharacterTools.APOSTROPHE);
+	}
+
+	/**
+	 * @see #convertToDoubleQuotedXmlAttributeValue(StringBuilder, String)
+	 * @see #convertToXmlAttributeValue(StringBuilder, char[])
+	 */
+	public static void convertToDoubleQuotedXmlAttributeValue(StringBuilder sb, char[] string) {
+		convertToDoubleQuotedXmlAttributeValue(sb, string, string.length);
+	}
+
+	/**
+	 * @see #convertToDoubleQuotedXmlAttributeValueContent(StringBuilder, String)
+	 * @see #convertToXmlAttributeValue(StringBuilder, char[])
+	 */
+	public static void convertToDoubleQuotedXmlAttributeValueContent(StringBuilder sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 10);
+			convertToDoubleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		}
+	}
+
+	static void convertToDoubleQuotedXmlAttributeValueContent(StringBuilder sb, char[] string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToDoubleQuotedXmlAttributeValueContent(sb, string[i]);
+		}
+	}
+
+	/**
+	 * @see #convertToSingleQuotedXmlAttributeValue(StringBuilder, String)
+	 * @see #convertToXmlAttributeValue(StringBuilder, char[])
+	 */
+	public static void convertToSingleQuotedXmlAttributeValue(StringBuilder sb, char[] string) {
+		convertToSingleQuotedXmlAttributeValue(sb, string, string.length);
+	}
+
+	/**
+	 * @see #convertToSingleQuotedXmlAttributeValueContent(StringBuilder, String)
+	 * @see #convertToXmlAttributeValue(StringBuilder, char[])
+	 */
+	public static void convertToSingleQuotedXmlAttributeValueContent(StringBuilder sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 10);
+			convertToSingleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		}
+	}
+
+	static void convertToSingleQuotedXmlAttributeValueContent(StringBuilder sb, char[] string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToSingleQuotedXmlAttributeValueContent(sb, string[i]);
+		}
+	}
+
+	/**
+	 * String is delimited with quotes - escape embedded quotes.
+	 * @see <a href="http://www.w3.org/TR/xml/#syntax">XML Spec</a>
+	 */
+	private static void convertToDoubleQuotedXmlAttributeValueContent(StringBuilder sb, char c) {
+		switch (c) {
+			case '"':  // double-quote
+				sb.append(StringTools.XML_QUOTE);
+				break;
+			case '&':  // ampersand
+				sb.append(StringTools.XML_AMP);
+				break;
+			case '<':  // less than
+				sb.append(StringTools.XML_LT);
+				break;
+			default:
+				sb.append(c);
+				break;
+		}
+	}
+
+	/**
+	 * String is delimited with apostrophes - escape embedded apostrophes.
+	 * @see <a href="http://www.w3.org/TR/xml/#syntax">XML Spec</a>
+	 */
+	private static void convertToSingleQuotedXmlAttributeValueContent(StringBuilder sb, char c) {
+		switch (c) {
+			case '\'':  // apostrophe
+				sb.append(StringTools.XML_APOS);
+				break;
+			case '&':  // ampersand
+				sb.append(StringTools.XML_AMP);
+				break;
+			case '<':  // less than
+				sb.append(StringTools.XML_LT);
+				break;
+			default:
+				sb.append(c);
+				break;
+		}
+	}
+
+	/**
+	 * Convert the specified string to an XML element text, escaping the
+	 * appropriate characters.
+	 * @see #convertToXmlElementCDATA(StringBuilder, String)
+	 */
+	public static void convertToXmlElementText(StringBuilder sb, String string) {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 8);
+			convertToXmlElementText(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	static void convertToXmlElementText(StringBuilder sb, String string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToXmlElementText(sb, string.charAt(i));
+		}
+	}
+
+	/**
+	 * @see #convertToXmlElementText(StringBuilder, String)
+	 */
+	public static void convertToXmlElementText(StringBuilder sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 8);
+			convertToXmlElementText(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	static void convertToXmlElementText(StringBuilder sb, char[] string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			convertToXmlElementText(sb, string[i]);
+		}
+	}
+
+	/**
+	 * @see <a href="http://www.w3.org/TR/xml/#syntax">XML Spec</a>
+	 */
+	private static void convertToXmlElementText(StringBuilder sb, char c) {
+		switch (c) {
+			case '&':  // ampersand
+				sb.append(StringTools.XML_AMP);
+				break;
+			case '<':  // less than
+				sb.append(StringTools.XML_LT);
+				break;
+			default:
+				sb.append(c);
+				break;
+		}
+	}
+
+	/**
+	 * Convert the specified string to an XML element CDATA, escaping the
+	 * appropriate characters.
+	 * @see #convertToXmlElementText(StringBuilder, String)
+	 */
+	public static void convertToXmlElementCDATA(StringBuilder sb, String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			sb.append(StringTools.EMPTY_XML_ELEMENT_CDATA);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + StringTools.EMPTY_XML_ELEMENT_CDATA.length() + 6);
+			convertToXmlElementCDATA(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	static void convertToXmlElementCDATA(StringBuilder sb, String string, int stringLength) {
+		sb.append(StringTools.XML_ELEMENT_CDATA_START);
+		convertToXmlElementCDATAContent(sb, string, stringLength);
+		sb.append(StringTools.XML_ELEMENT_CDATA_END);
+	}
+
+	/**
+	 * Convert the specified string to the contents of an XML element CDATA,
+	 * escaping the appropriate characters.
+	 * @see #convertToXmlElementCDATA(StringBuilder, String)
+	 * @see #convertToXmlElementText(StringBuilder, String)
+	 */
+	public static void convertToXmlElementCDATAContent(StringBuilder sb, String string) {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 6);
+			convertToXmlElementCDATAContent(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 * @see <a href="http://www.w3.org/TR/xml/#sec-cdata-sect">XML Spec</a>
+	 */
+	static void convertToXmlElementCDATAContent(StringBuilder sb, String string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			char c = string.charAt(i);
+			sb.append(c);
+			// "]]>" -> "]]&gt;"
+			if (c != ']') {
+				continue;
+			}
+			if (++i >= stringLength) {
+				break;
+			}
+			c = string.charAt(i);
+			sb.append(c);
+			if (c != ']') {
+				continue;
+			}
+			if (++i >= stringLength) {
+				break;
+			}
+			c = string.charAt(i);
+			if (c == '>') {
+				sb.append(StringTools.XML_GT);
+			} else {
+				sb.append(c);
+			}
+		}
+	}
+
+	/**
+	 * @see #convertToXmlElementCDATA(StringBuilder, String)
+	 */
+	public static void convertToXmlElementCDATA(StringBuilder sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			sb.append(StringTools.EMPTY_XML_ELEMENT_CDATA);
+		} else {
+			sb.ensureCapacity(sb.length() + stringLength + StringTools.EMPTY_XML_ELEMENT_CDATA.length() + 6);
+			convertToXmlElementCDATA(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	static void convertToXmlElementCDATA(StringBuilder sb, char[] string, int stringLength) {
+		sb.append(StringTools.XML_ELEMENT_CDATA_START);
+		convertToXmlElementCDATAContent(sb, string, stringLength);
+		sb.append(StringTools.XML_ELEMENT_CDATA_END);
+	}
+
+	/**
+	 * @see #convertToXmlElementCDATAContent(StringBuilder, String)
+	 * @see #convertToXmlElementCDATA(StringBuilder, char[])
+	 */
+	public static void convertToXmlElementCDATAContent(StringBuilder sb, char[] string) {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			sb.ensureCapacity(sb.length() + stringLength + 6);
+			convertToXmlElementCDATAContent(sb, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 * @see <a href="http://www.w3.org/TR/xml/#sec-cdata-sect">XML Spec</a>
+	 */
+	static void convertToXmlElementCDATAContent(StringBuilder sb, char[] string, int stringLength) {
+		for (int i = 0; i < stringLength; i++) {
+			char c = string[i];
+			sb.append(c);
+			// "]]>" -> "]]&gt;"
+			if (c != ']') {
+				continue;
+			}
+			if (++i >= stringLength) {
+				break;
+			}
+			c = string[i];
+			sb.append(c);
+			if (c != ']') {
+				continue;
+			}
+			if (++i >= stringLength) {
+				break;
+			}
+			c = string[i];
+			if (c == '>') {
+				sb.append(StringTools.XML_GT);
+			} else {
+				sb.append(c);
+			}
+		}
+	}
+
+
+	// ********** toString() helper methods **********
+
+	/**
+	 * Append the string representations of the objects in the specified array
+	 * to the specified string builder:<p>
+	 * <code>
+	 * ["foo", "bar", "baz"]
+	 * </code>
+	 */
+	public static void append(StringBuilder sb, Object[] array) {
+		sb.append('[');
+		int max = array.length - 1;
+		if (max > -1) {
+			// stop one short of the end of the array
+			for (int i = 0; i < max; i++) {
+				sb.append(array[i]);
+				sb.append(", ");
+			}
+			sb.append(array[max]);
+		}
+		sb.append(']');
+	}
+
+	/**
+	 * Append the string representations of the objects in the specified iterable
+	 * to the specified string builder:<p>
+	 * <code>
+	 * ["foo", "bar", "baz"]
+	 * </code>
+	 */
+	public static <T> void append(StringBuilder sb, Iterable<T> iterable) {
+		append(sb, iterable.iterator());
+	}
+
+	/**
+	 * Append the string representations of the objects in the specified iterator
+	 * to the specified string builder:<p>
+	 * <code>
+	 * ["foo", "bar", "baz"]
+	 * </code>
+	 */
+	public static <T> void append(StringBuilder sb, Iterator<T> iterator) {
+		sb.append('[');
+		while (iterator.hasNext()) {
+			sb.append(iterator.next());
+			if (iterator.hasNext()) {
+				sb.append(", ");
+			}
+		}
+		sb.append(']');
+	}
+
+	/**
+	 * Append a "Dali standard" {@link Object#toString() toString()} result for
+	 * the specified object to the specified string builder:<pre>
+	 *     ClassName[00-F3-EE-42]
+	 * </pre>
+	 * @see Object#toString()
+	 */
+	public static void appendHashCodeToString(StringBuilder sb, Object object) {
+		appendToStringName(sb, object.getClass());
+		sb.append('[');
+		separate(sb, buildHashCode(object), '-', 2);
+		sb.append(']');
+	}
+
+	/**
+	 * Use {@link System#identityHashCode(Object)},
+	 * since {@link Object#hashCode()} may be overridden.
+	 */
+	private static String buildHashCode(Object object) {
+		return StringTools.zeroPad(Integer.toHexString(System.identityHashCode(object)).toUpperCase(), 8);
+	}
+
+	/**
+	 * Append a class name suitable for a "Dali standard"
+	 * {@link Object#toString() toString()} implementation to the specified
+	 * string builder.
+	 *
+	 * @see ClassTools#toStringName(Class)
+	 * @see Object#toString()
+	 */
+	public static void appendToStringName(StringBuilder sb, Class<?> javaClass) {
+		ClassTools.appendToStringNameTo(javaClass, sb);
+	}
+
+
+	// ********** constructor **********
+
+	/*
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private StringBuilderTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringCollator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringCollator.java
index a3a5f83..aee0f39 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringCollator.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringCollator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -51,6 +51,9 @@
 	 */
 	public StringCollator(Collator collator) {
 		super();
+		if (collator == null) {
+			throw new NullPointerException();
+		}
 		this.collator = collator;
 	}
 
@@ -61,6 +64,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.collator);
+		return ObjectTools.toString(this, this.collator);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringConverter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringConverter.java
deleted file mode 100644
index 4da556c..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringConverter.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * Used by various "pluggable" classes to transform objects into strings.
- */
-public interface StringConverter<T> {
-
-	/**
-	 * Converts the specified object into a string. The semantics of "convert" is determined by the
-	 * contract between the client and the server.
-	 */
-	String convertToString(T object);
-
-	final class Default<S> implements StringConverter<S>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final StringConverter INSTANCE = new Default();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Default() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <R> StringConverter<R> instance() {
-			return INSTANCE;
-		}
-		// * Returns the object's #toString() result
-		@Override
-		public String convertToString(S o) {
-			return (o == null) ? null : o.toString();
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-
-	final class Disabled<S> implements StringConverter<S>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final StringConverter INSTANCE = new Disabled();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Disabled() {
-			super();
-		}
-		@SuppressWarnings("unchecked")
-		public static <R> StringConverter<R> instance() {
-			return INSTANCE;
-		}
-		// throw an exception
-		@Override
-		public String convertToString(S o) {
-			throw new UnsupportedOperationException();
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringMatcher.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringMatcher.java
index d4e897b..e5c75f1 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringMatcher.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringMatcher.java
@@ -1,64 +1,494 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * This interface defines a simple API for allowing "pluggable" string matchers that can be
- * configured with a pattern string then used to determine what strings match the pattern.
- */
-public interface StringMatcher {
-
-	/**
-	 * Returns whether the specified string matches the established pattern string. The semantics of
-	 * a match is determined by the contract between the client and the server.
-	 */
-	boolean matches(String string);
-
-	/**
-	 * Sets the pattern string used to determine future matches. The format and semantics of the
-	 * pattern string are determined by the contract between the client and the server.
-	 */
-	void setPatternString(String patternString);
-
-	final class Null implements StringMatcher, Serializable {
-		public static final StringMatcher INSTANCE = new Null();
-		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Null() {
-			super();
-		}
-		public static StringMatcher instance() {
-			return INSTANCE;
-		}
-		@Override
-		public boolean matches(String string) {
-			// everything is a match
-			return true;
-		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public void setPatternString(String patternString) {
-			// ignore the pattern string
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-	}
-}
\ No newline at end of file
+/*******************************************************************************

+ * Copyright (c) 2000, 2013 IBM Corporation and others.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ *     IBM Corporation - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.persistence.tools.utility;

+

+import java.util.Vector;

+

+/**

+ * A string pattern matcher, supporting "*" and "?" wildcards.

+ * <p>

+ * Copied from org.eclipse.ui.internal.navigator.StringMatcher

+ */

+@SuppressWarnings({"unqualified-field-access", "rawtypes", "unchecked", "javadoc"})

+public class StringMatcher {

+	protected String fPattern;

+

+	protected int fLength; // pattern length

+

+	protected boolean fIgnoreWildCards;

+

+	protected boolean fIgnoreCase;

+

+	protected boolean fHasLeadingStar;

+

+	protected boolean fHasTrailingStar;

+

+	protected String fSegments[]; // the given pattern is split into *

+

+	// separated segments

+

+	/* boundary value beyond which we don't need to search in the text */

+	protected int fBound = 0;

+

+	protected static final char fSingleWildCard = '\u0000';

+

+	/**

+	 *

+	 */

+	static class Position {

+		int start; // inclusive

+

+		int end; // exclusive

+

+		Position(int start, int end) {

+			this.start = start;

+			this.end = end;

+		}

+

+		int getStart() {

+			return start;

+		}

+

+		int getEnd() {

+			return end;

+		}

+	}

+

+	/**

+	 * StringMatcher constructor takes in a String object that is a simple

+	 * pattern which may contain '*' for 0 and many characters and '?' for

+	 * exactly one character.

+	 *

+	 * Literal '*' and '?' characters must be escaped in the pattern e.g., "\*"

+	 * means literal "*", etc.

+	 *

+	 * Escaping any other character (including the escape character itself),

+	 * just results in that character in the pattern. e.g., "\a" means "a" and

+	 * "\\" means "\"

+	 *

+	 * If invoking the StringMatcher with string literals in Java, don't forget

+	 * escape characters are represented by "\\".

+	 *

+	 * @param pattern

+	 *            the pattern to match text against

+	 * @param ignoreCase

+	 *            if true, case is ignored

+	 * @param ignoreWildCards

+	 *            if true, wild cards and their escape sequences are ignored

+	 *            (everything is taken literally).

+	 */

+	public StringMatcher(String pattern, boolean ignoreCase,

+			boolean ignoreWildCards) {

+		if (pattern == null) {

+			throw new IllegalArgumentException();

+		}

+		fIgnoreCase = ignoreCase;

+		fIgnoreWildCards = ignoreWildCards;

+		fPattern = pattern;

+		fLength = pattern.length();

+

+		if (fIgnoreWildCards) {

+			parseNoWildCards();

+		} else {

+			parseWildCards();

+		}

+	}

+

+	/**

+	 * Find the first occurrence of the pattern between

+	 * <code>start</code)(inclusive)

+	 * and <code>end</code>(exclusive).

+	 * @param  text  the String object to search in

+	 * @param  start  the starting index of the search range, inclusive

+	 * @param  end  the ending index of the search range, exclusive

+	 * @return an <code>StringMatcher.Position</code> object that keeps the starting

+	 * (inclusive) and ending positions (exclusive) of the first occurrence of the

+	 * pattern in the specified range of the text; return null if not found or subtext

+	 * is empty (start==end). A pair of zeros is returned if pattern is empty string

+	 * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc"

+	 * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned

+	 */

+	public StringMatcher.Position find(String text, int start, int end) {

+		if (text == null) {

+			throw new IllegalArgumentException();

+		}

+

+		int tlen = text.length();

+		if (start < 0) {

+			start = 0;

+		}

+		if (end > tlen) {

+			end = tlen;

+		}

+		if (end < 0 || start >= end) {

+			return null;

+		}

+		if (fLength == 0) {

+			return new Position(start, start);

+		}

+		if (fIgnoreWildCards) {

+			int x = posIn(text, start, end);

+			if (x < 0) {

+				return null;

+			}

+			return new Position(x, x + fLength);

+		}

+

+		int segCount = fSegments.length;

+		if (segCount == 0) {

+			return new Position(start, end);

+		}

+

+		int curPos = start;

+		int matchStart = -1;

+		int i;

+		for (i = 0; i < segCount && curPos < end; ++i) {

+			String current = fSegments[i];

+			int nextMatch = regExpPosIn(text, curPos, end, current);

+			if (nextMatch < 0) {

+				return null;

+			}

+			if (i == 0) {

+				matchStart = nextMatch;

+			}

+			curPos = nextMatch + current.length();

+		}

+		if (i < segCount) {

+			return null;

+		}

+		return new Position(matchStart, curPos);

+	}

+

+	/**

+	 * match the given <code>text</code> with the pattern

+	 *

+	 * @return true if matched eitherwise false

+	 * @param text

+	 *            a String object

+	 */

+	public boolean match(String text) {

+		if (text == null) {

+			return false;

+		}

+		return match(text, 0, text.length());

+	}

+

+	/**

+	 * Given the starting (inclusive) and the ending (exclusive) positions in

+	 * the <code>text</code>, determine if the given substring matches with

+	 * aPattern

+	 *

+	 * @return true if the specified portion of the text matches the pattern

+	 * @param text

+	 *            a String object that contains the substring to match

+	 * @param start

+	 *            marks the starting position (inclusive) of the substring

+	 * @param end

+	 *            marks the ending index (exclusive) of the substring

+	 */

+	public boolean match(String text, int start, int end) {

+		if (null == text) {

+			throw new IllegalArgumentException();

+		}

+

+		if (start > end) {

+			return false;

+		}

+

+		if (fIgnoreWildCards) {

+			return (end - start == fLength)

+					&& fPattern.regionMatches(fIgnoreCase, 0, text, start,

+							fLength);

+		}

+		int segCount = fSegments.length;

+		if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) {

+			// contains

+			// only

+			// '*'(s)

+			return true;

+		}

+		if (start == end) {

+			return fLength == 0;

+		}

+		if (fLength == 0) {

+			return start == end;

+		}

+

+		int tlen = text.length();

+		if (start < 0) {

+			start = 0;

+		}

+		if (end > tlen) {

+			end = tlen;

+		}

+

+		int tCurPos = start;

+		int bound = end - fBound;

+		if (bound < 0) {

+			return false;

+		}

+		int i = 0;

+		String current = fSegments[i];

+		int segLength = current.length();

+

+		/* process first segment */

+		if (!fHasLeadingStar) {

+			if (!regExpRegionMatches(text, start, current, 0, segLength)) {

+				return false;

+			}

+			++i;

+			tCurPos = tCurPos + segLength;

+

+		}

+		if ((fSegments.length == 1) && (!fHasLeadingStar)

+				&& (!fHasTrailingStar)) {

+			// only one segment to match, no wildcards specified

+			return tCurPos == end;

+		}

+		/* process middle segments */

+		while (i < segCount) {

+			current = fSegments[i];

+			int currentMatch;

+			int k = current.indexOf(fSingleWildCard);

+			if (k < 0) {

+				currentMatch = textPosIn(text, tCurPos, end, current);

+				if (currentMatch < 0) {

+					return false;

+				}

+			} else {

+				currentMatch = regExpPosIn(text, tCurPos, end, current);

+				if (currentMatch < 0) {

+					return false;

+				}

+			}

+			tCurPos = currentMatch + current.length();

+			i++;

+		}

+

+		/* process final segment */

+		if (!fHasTrailingStar && tCurPos != end) {

+			int clen = current.length();

+			return regExpRegionMatches(text, end - clen, current, 0, clen);

+		}

+		return i == segCount;

+	}

+

+	/**

+	 * This method parses the given pattern into segments seperated by wildcard

+	 * '*' characters. Since wildcards are not being used in this case, the

+	 * pattern consists of a single segment.

+	 */

+	private void parseNoWildCards() {

+		fSegments = new String[1];

+		fSegments[0] = fPattern;

+		fBound = fLength;

+	}

+

+	/**

+	 * Parses the given pattern into segments seperated by wildcard '*'

+	 * characters.

+	 *

+	 */

+	private void parseWildCards() {

+		if (fPattern.startsWith("*")) { //$NON-NLS-1$

+			fHasLeadingStar = true;

+		}

+		if (fPattern.endsWith("*")) {//$NON-NLS-1$

+			/* make sure it's not an escaped wildcard */

+			if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') {

+				fHasTrailingStar = true;

+			}

+		}

+

+		Vector temp = new Vector();

+

+		int pos = 0;

+		StringBuffer buf = new StringBuffer();

+		while (pos < fLength) {

+			char c = fPattern.charAt(pos++);

+			switch (c) {

+			case '\\':

+				if (pos >= fLength) {

+					buf.append(c);

+				} else {

+					char next = fPattern.charAt(pos++);

+					/* if it's an escape sequence */

+					if (next == '*' || next == '?' || next == '\\') {

+						buf.append(next);

+					} else {

+						/* not an escape sequence, just insert literally */

+						buf.append(c);

+						buf.append(next);

+					}

+				}

+				break;

+			case '*':

+				if (buf.length() > 0) {

+					/* new segment */

+					temp.addElement(buf.toString());

+					fBound += buf.length();

+					buf.setLength(0);

+				}

+				break;

+			case '?':

+				/* append special character representing single match wildcard */

+				buf.append(fSingleWildCard);

+				break;

+			default:

+				buf.append(c);

+			}

+		}

+

+		/* add last buffer to segment list */

+		if (buf.length() > 0) {

+			temp.addElement(buf.toString());

+			fBound += buf.length();

+		}

+

+		fSegments = new String[temp.size()];

+		temp.copyInto(fSegments);

+	}

+

+	/**

+	 * @param text

+	 *            a string which contains no wildcard

+	 * @param start

+	 *            the starting index in the text for search, inclusive

+	 * @param end

+	 *            the stopping point of search, exclusive

+	 * @return the starting index in the text of the pattern , or -1 if not

+	 *         found

+	 */

+	protected int posIn(String text, int start, int end) {// no wild card in

+		// pattern

+		int max = end - fLength;

+

+		if (!fIgnoreCase) {

+			int i = text.indexOf(fPattern, start);

+			if (i == -1 || i > max) {

+				return -1;

+			}

+			return i;

+		}

+

+		for (int i = start; i <= max; ++i) {

+			if (text.regionMatches(true, i, fPattern, 0, fLength)) {

+				return i;

+			}

+		}

+

+		return -1;

+	}

+

+	/**

+	 * @param text

+	 *            a simple regular expression that may only contain '?'(s)

+	 * @param start

+	 *            the starting index in the text for search, inclusive

+	 * @param end

+	 *            the stopping point of search, exclusive

+	 * @param p

+	 *            a simple regular expression that may contains '?'

+	 * @return the starting index in the text of the pattern , or -1 if not

+	 *         found

+	 */

+	protected int regExpPosIn(String text, int start, int end, String p) {

+		int plen = p.length();

+

+		int max = end - plen;

+		for (int i = start; i <= max; ++i) {

+			if (regExpRegionMatches(text, i, p, 0, plen)) {

+				return i;

+			}

+		}

+		return -1;

+	}

+

+	/**

+	 *

+	 * @return boolean

+	 * @param text

+	 *            a String to match

+	 * @param tStart

+	 *            indicates the starting index of match, inclusive

+	 * @param p

+	 *            a simple regular expression that may contain '?'

+	 * @param pStart

+	 * @param plen

+	 */

+	protected boolean regExpRegionMatches(String text, int tStart, String p,

+			int pStart, int plen) {

+		while (plen-- > 0) {

+			char tchar = text.charAt(tStart++);

+			char pchar = p.charAt(pStart++);

+

+			/* process wild cards */

+			if (!fIgnoreWildCards) {

+				/* skip single wild cards */

+				if (pchar == fSingleWildCard) {

+					continue;

+				}

+			}

+			if (pchar == tchar) {

+				continue;

+			}

+			if (fIgnoreCase) {

+				if (Character.toUpperCase(tchar) == Character

+						.toUpperCase(pchar)) {

+					continue;

+				}

+				// comparing after converting to upper case doesn't handle all

+				// cases;

+				// also compare after converting to lower case

+				if (Character.toLowerCase(tchar) == Character

+						.toLowerCase(pchar)) {

+					continue;

+				}

+			}

+			return false;

+		}

+		return true;

+	}

+

+	/**

+	 * @param text

+	 *            the string to match

+	 * @param start

+	 *            the starting index in the text for search, inclusive

+	 * @param end

+	 *            the stopping point of search, exclusive

+	 * @param p

+	 *            a string that has no wildcard

+	 * @return the starting index in the text of the pattern , or -1 if not

+	 *         found

+	 */

+	protected int textPosIn(String text, int start, int end, String p) {

+

+		int plen = p.length();

+		int max = end - plen;

+

+		if (!fIgnoreCase) {

+			int i = text.indexOf(p, start);

+			if (i == -1 || i > max) {

+				return -1;

+			}

+			return i;

+		}

+

+		for (int i = start; i <= max; ++i) {

+			if (text.regionMatches(true, i, p, 0, plen)) {

+				return i;

+			}

+		}

+

+		return -1;

+	}

+}

diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringTools.java
index 6462f73..84d9ab2 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringTools.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringTools.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -13,72 +13,128 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility;
 
-import java.io.IOException;
-import java.io.Writer;
+import java.io.Serializable;
 import java.util.Arrays;
 import java.util.Iterator;
-import org.eclipse.persistence.tools.utility.iterables.TransformationIterable;
-import org.eclipse.persistence.tools.utility.iterators.ArrayListIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+import org.eclipse.persistence.tools.utility.transformer.TransformerAdapter;
 
 /**
- * Convenience methods related to the java.lang.String class.
+ * {@link String} utility methods
  *
- * As of jdk 1.5, it's tempting to convert all of these methods to use
- * java.lang.Appendable (instead of StringBuffer, StringBuilder, and Writer);
- * but all the Appendable methods throw java.io.IOException (yech) and we
- * [might?] get a bit better performance invoking methods on classes than
- * we get on interfaces. :-)
+ * @see CharArrayTools
+ * @see org.eclipse.jpt.common.utility.internal.io.WriterTools
+ * @see StringBuilderTools
+ * @see StringBufferTools
  */
 @SuppressWarnings("nls")
 public final class StringTools {
 
-	/** * Returns */
+	/** carriage return */
 	public static final String CR = System.getProperty("line.separator");
 
-	/** double quote */
-	public static final char QUOTE = '"';
-
-	/** XML double quote */
-	public static final String XML_QUOTE = "&quot;";
-
-	/** parenthesis */
-	public static final char OPEN_PARENTHESIS = '(';
-	public static final char CLOSE_PARENTHESIS = ')';
-
-	/** brackets */
-	public static final char OPEN_BRACKET = '[';
-	public static final char CLOSE_BRACKET = ']';
-
-	/** brackets */
-	public static final char OPEN_BRACE = '{';
-	public static final char CLOSE_BRACE = '}';
-
-	/** brackets */
-	public static final char OPEN_CHEVRON = '<';
-	public static final char CLOSE_CHEVRON = '>';
-
 	/** empty string */
 	public static final String EMPTY_STRING = "";
 
-	/** empty char array */
-	public static final char[] EMPTY_CHAR_ARRAY = new char[0];
-
 	/** empty string array */
 	public static final String[] EMPTY_STRING_ARRAY = new String[0];
 
 
-	// ********** padding/truncating **********
+	// ********** last **********
+
+	/**
+	 * Return the last character of the specified string.
+	 */
+	public static char last(String string) {
+		return string.charAt(string.length() - 1);
+	}
+
+
+	// ********** concatenation **********
+
+	/**
+	 * Return a concatenation of the specified strings.
+	 */
+	public static String concatenate(String... strings) {
+		int stringLength = 0;
+		for (String string : strings) {
+			stringLength += string.length();
+		}
+		StringBuilder sb = new StringBuilder(stringLength);
+		for (String string : strings) {
+			sb.append(string);
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Return a concatenation of the specified strings.
+	 */
+	public static String concatenate(Iterable<String> strings) {
+		return concatenate(strings.iterator());
+	}
+
+	/**
+	 * Return a concatenation of the specified strings.
+	 */
+	public static String concatenate(Iterator<String> strings) {
+		StringBuilder sb = new StringBuilder();
+		while (strings.hasNext()) {
+			sb.append(strings.next());
+		}
+		return sb.toString();
+	}
+
+
+	// ********** padding/truncating/centering **********
+
+	/**
+	 * Center the specified string in the specified length.
+	 * If the string is already the specified length, return it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with spaces at
+	 * each end.
+	 */
+	public static String center(String string, int length) {
+		return center(string, length, ' ');
+	}
+
+	/**
+	 * Center the specified string in the specified length.
+	 * If the string is already the specified length, return it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at each end.
+	 */
+	public static String center(String string, int length, char c) {
+		if (length == 0) {
+			return EMPTY_STRING;
+		}
+		int stringLength = string.length();
+		if (stringLength == length) {
+			return string;
+		}
+		if (stringLength > length) {
+			int begin = (stringLength - length) >> 1; // take fewer characters off the front
+			return string.substring(begin, begin + length);
+		}
+		// stringLength < length
+		char[] result = new char[length];
+		int begin = (length - stringLength) >> 1; // add fewer characters to the front
+		Arrays.fill(result, 0, begin, c);
+		string.getChars(0, stringLength, result, begin);
+		Arrays.fill(result, begin + stringLength, length, c);
+		return new String(result);
+	}
 
 	/**
 	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.pad(int)
-	 * </code>
+	 * If the string is already the specified length, return it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with spaces
+	 * at the end.
 	 */
 	public static String pad(String string, int length) {
 		return pad(string, length, ' ');
@@ -86,352 +142,45 @@
 
 	/**
 	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.padOn(int, Writer)
-	 * </code>
-	 */
-	public static void padOn(String string, int length, Writer writer) {
-		padOn(string, length, ' ', writer);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.padOn(int, StringBuffer)
-	 * </code>
-	 */
-	public static void padOn(String string, int length, StringBuffer sb) {
-		padOn(string, length, ' ', sb);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.padOn(int, StringBuilder)
-	 * </code>
-	 */
-	public static void padOn(String string, int length, StringBuilder sb) {
-		padOn(string, length, ' ', sb);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
+	 * If the string is already the specified length, return it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with the
 	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.pad(int, char)
-	 * </code>
 	 */
 	public static String pad(String string, int length, char c) {
 		int stringLength = string.length();
 		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
 		}
 		if (stringLength == length) {
 			return string;
 		}
-		return pad_(string, length, c);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.padOn(int, char, Writer)
-	 * </code>
-	 */
-	public static void padOn(String string, int length, char c, Writer writer) {
-		int stringLength = string.length();
-		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
-		}
-		if (stringLength == length) {
-			writeStringOn(string, writer);
-		} else {
-			padOn_(string, length, c, writer);
-		}
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.padOn(int, char, StringBuffer)
-	 * </code>
-	 */
-	public static void padOn(String string, int length, char c, StringBuffer sb) {
-		int stringLength = string.length();
-		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
-		}
-		if (stringLength == length) {
-			sb.append(string);
-		} else {
-			padOn_(string, length, c, sb);
-		}
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.padOn(int, char, StringBuilder)
-	 * </code>
-	 */
-	public static void padOn(String string, int length, char c, StringBuilder sb) {
-		int stringLength = string.length();
-		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
-		}
-		if (stringLength == length) {
-			sb.append(string);
-		} else {
-			padOn_(string, length, c, sb);
-		}
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.pad(int)
-	 * </code>
-	 */
-	public static char[] pad(char[] string, int length) {
-		return pad(string, length, ' ');
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.padOn(int, writer)
-	 * </code>
-	 */
-	public static void padOn(char[] string, int length, Writer writer) {
-		padOn(string, length, ' ', writer);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.padOn(int, StringBuffer)
-	 * </code>
-	 */
-	public static void padOn(char[] string, int length, StringBuffer sb) {
-		padOn(string, length, ' ', sb);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.padOn(int, StringBuilder)
-	 * </code>
-	 */
-	public static void padOn(char[] string, int length, StringBuilder sb) {
-		padOn(string, length, ' ', sb);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.pad(int, char)
-	 * </code>
-	 */
-	public static char[] pad(char[] string, int length, char c) {
-		int stringLength = string.length;
-		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
-		}
-		if (stringLength == length) {
-			return string;
-		}
-		return pad_(string, length, c);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.padOn(int, char, Writer)
-	 * </code>
-	 */
-	public static void padOn(char[] string, int length, char c, Writer writer) {
-		int stringLength = string.length;
-		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
-		}
-		if (stringLength == length) {
-			writeStringOn(string, writer);
-		} else {
-			padOn_(string, length, c, writer);
-		}
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.padOn(int, char, StringBuffer)
-	 * </code>
-	 */
-	public static void padOn(char[] string, int length, char c, StringBuffer sb) {
-		int stringLength = string.length;
-		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
-		}
-		if (stringLength == length) {
-			sb.append(string);
-		} else {
-			padOn_(string, length, c, sb);
-		}
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.padOn(int, char, StringBuilder)
-	 * </code>
-	 */
-	public static void padOn(char[] string, int length, char c, StringBuilder sb) {
-		int stringLength = string.length;
-		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
-		}
-		if (stringLength == length) {
-			sb.append(string);
-		} else {
-			padOn_(string, length, c, sb);
-		}
+		return pad(string, length, c, stringLength);
 	}
 
 	/**
 	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncate(int)
-	 * </code>
+	 * If the string is already the specified length, returned it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with spaces at
+	 * the end.
 	 */
-	public static String padOrTruncate(String string, int length) {
-		return padOrTruncate(string, length, ' ');
+	public static String fit(String string, int length) {
+		return fit(string, length, ' ');
 	}
 
 	/**
 	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncateOn(int, Writer)
-	 * </code>
-	 */
-	public static void padOrTruncateOn(String string, int length, Writer writer) {
-		padOrTruncateOn(string, length, ' ', writer);
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncateOn(int, StringBuffer)
-	 * </code>
-	 */
-	public static void padOrTruncateOn(String string, int length, StringBuffer sb) {
-		padOrTruncateOn(string, length, ' ', sb);
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncateOn(int, StringBuilder)
-	 * </code>
-	 */
-	public static void padOrTruncateOn(String string, int length, StringBuilder sb) {
-		padOrTruncateOn(string, length, ' ', sb);
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with the
+	 * If the string is already the specified length, return it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with the
 	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncate(int, char)
-	 * </code>
 	 */
-	public static String padOrTruncate(String string, int length, char c) {
+	public static String fit(String string, int length, char c) {
+		if (length == 0) {
+			return EMPTY_STRING;
+		}
 		int stringLength = string.length();
 		if (stringLength == length) {
 			return string;
@@ -439,368 +188,26 @@
 		if (stringLength > length) {
 			return string.substring(0, length);
 		}
-		return pad_(string, length, c);
+		return pad(string, length, c, stringLength);
 	}
 
 	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncateOn(int, char, Writer)
-	 * </code>
+	 * no length checks
 	 */
-	public static void padOrTruncateOn(String string, int length, char c, Writer writer) {
-		int stringLength = string.length();
-		if (stringLength == length) {
-			writeStringOn(string, writer);
-		} else if (stringLength > length) {
-			writeStringOn(string.substring(0, length), writer);
-		} else {
-			padOn_(string, length, c, writer);
-		}
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncateOn(int, char, StringBuffer)
-	 * </code>
-	 */
-	public static void padOrTruncateOn(String string, int length, char c, StringBuffer sb) {
-		int stringLength = string.length();
-		if (stringLength == length) {
-			sb.append(string);
-		} else if (stringLength > length) {
-			sb.append(string.substring(0, length));
-		} else {
-			padOn_(string, length, c, sb);
-		}
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncateOn(int, char, StringBuilder)
-	 * </code>
-	 */
-	public static void padOrTruncateOn(String string, int length, char c, StringBuilder sb) {
-		int stringLength = string.length();
-		if (stringLength == length) {
-			sb.append(string);
-		} else if (stringLength > length) {
-			sb.append(string.substring(0, length));
-		} else {
-			padOn_(string, length, c, sb);
-		}
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncate(int)
-	 * </code>
-	 */
-	public static char[] padOrTruncate(char[] string, int length) {
-		return padOrTruncate(string, length, ' ');
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncateOn(int, Writer)
-	 * </code>
-	 */
-	public static void padOrTruncateOn(char[] string, int length, Writer writer) {
-		padOrTruncateOn(string, length, ' ', writer);
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncateOn(int, StringBuffer)
-	 * </code>
-	 */
-	public static void padOrTruncate(char[] string, int length, StringBuffer sb) {
-		padOrTruncateOn(string, length, ' ', sb);
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with spaces at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncateOn(int, StringBuilder)
-	 * </code>
-	 */
-	public static void padOrTruncate(char[] string, int length, StringBuilder sb) {
-		padOrTruncateOn(string, length, ' ', sb);
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncate(int, char)
-	 * </code>
-	 */
-	public static char[] padOrTruncate(char[] string, int length, char c) {
-		int stringLength = string.length;
-		if (stringLength == length) {
-			return string;
-		}
-		if (stringLength > length) {
-			char[] result = new char[length];
-			System.arraycopy(string, 0, result, 0, length);
-			return result;
-		}
-		return pad_(string, length, c);
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncateOn(int, char, Writer)
-	 * </code>
-	 */
-	public static void padOrTruncateOn(char[] string, int length, char c, Writer writer) {
-		int stringLength = string.length;
-		if (stringLength == length) {
-			writeStringOn(string, writer);
-		} else if (stringLength > length) {
-			writeStringOn(string, 0, length, writer);
-		} else {
-			padOn_(string, length, c, writer);
-		}
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncateOn(int, char, StringBuffer)
-	 * </code>
-	 */
-	public static void padOrTruncateOn(char[] string, int length, char c, StringBuffer sb) {
-		int stringLength = string.length;
-		if (stringLength == length) {
-			sb.append(string);
-		} else if (stringLength > length) {
-			sb.append(string, 0, length);
-		} else {
-			padOn_(string, length, c, sb);
-		}
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, it is truncated.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the end.
-	 * <p>
-	 * <code>
-	 * String.padOrTruncateOn(int, char, StringBuilder)
-	 * </code>
-	 */
-	public static void padOrTruncateOn(char[] string, int length, char c, StringBuilder sb) {
-		int stringLength = string.length;
-		if (stringLength == length) {
-			sb.append(string);
-		} else if (stringLength > length) {
-			sb.append(string, 0, length);
-		} else {
-			padOn_(string, length, c, sb);
-		}
-	}
-
-	/*
-	 * Pad the specified string without validating the parms.
-	 */
-	private static String pad_(String string, int length, char c) {
-		return new String(pad_(string.toCharArray(), length, c));
-	}
-
-	/*
-	 * Pad the specified string without validating the parms.
-	 */
-	private static void padOn_(String string, int length, char c, Writer writer) {
-		writeStringOn(string, writer);
-		fill_(string, length, c, writer);
-	}
-
-	/*
-	 * Add enough characters to the specified writer to compensate for
-	 * the difference between the specified string and specified length.
-	 */
-	private static void fill_(String string, int length, char c, Writer writer) {
-		fill_(string.length(), length, c, writer);
-	}
-
-	/*
-	 * Add enough characters to the specified writer to compensate for
-	 * the difference between the specified string and specified length.
-	 */
-	private static void fill_(char[] string, int length, char c, Writer writer) {
-		fill_(string.length, length, c, writer);
-	}
-
-	/*
-	 * Add enough characters to the specified writer to compensate for
-	 * the difference between the specified string and specified length.
-	 */
-	private static void fill_(int stringLength, int length, char c, Writer writer) {
-		writeStringOn(ArrayTools.fill(new char[length - stringLength], c), writer);
-	}
-
-	/*
-	 * Pad the specified string without validating the parms.
-	 */
-	private static void padOn_(String string, int length, char c, StringBuffer sb) {
-		sb.append(string);
-		fill_(string, length, c, sb);
-	}
-
-	/*
-	 * Add enough characters to the specified string buffer to compensate for
-	 * the difference between the specified string and specified length.
-	 */
-	private static void fill_(String string, int length, char c, StringBuffer sb) {
-		fill_(string.length(), length, c, sb);
-	}
-
-	/*
-	 * Add enough characters to the specified string buffer to compensate for
-	 * the difference between the specified string and specified length.
-	 */
-	private static void fill_(char[] string, int length, char c, StringBuffer sb) {
-		fill_(string.length, length, c, sb);
-	}
-
-	/*
-	 * Add enough characters to the specified string buffer to compensate for
-	 * the difference between the specified string and specified length.
-	 */
-	private static void fill_(int stringLength, int length, char c, StringBuffer sb) {
-		sb.append(ArrayTools.fill(new char[length - stringLength], c));
-	}
-
-	/*
-	 * Pad the specified string without validating the parms.
-	 */
-	private static void padOn_(String string, int length, char c, StringBuilder sb) {
-		sb.append(string);
-		fill_(string, length, c, sb);
-	}
-
-	/*
-	 * Add enough characters to the specified string builder to compensate for
-	 * the difference between the specified string and specified length.
-	 */
-	private static void fill_(String string, int length, char c, StringBuilder sb) {
-		fill_(string.length(), length, c, sb);
-	}
-
-	/*
-	 * Add enough characters to the specified string builder to compensate for
-	 * the difference between the specified string and specified length.
-	 */
-	private static void fill_(char[] string, int length, char c, StringBuilder sb) {
-		fill_(string.length, length, c, sb);
-	}
-
-	/*
-	 * Add enough characters to the specified string builder to compensate for
-	 * the difference between the specified string and specified length.
-	 */
-	private static void fill_(int stringLength, int length, char c, StringBuilder sb) {
-		sb.append(ArrayTools.fill(new char[length - stringLength], c));
-	}
-
-	/*
-	 * Pad the specified string without validating the parms.
-	 */
-	private static char[] pad_(char[] string, int length, char c) {
+	private static String pad(String string, int length, char c, int stringLength) {
 		char[] result = new char[length];
-		int stringLength = string.length;
-		System.arraycopy(string, 0, result, 0, stringLength);
+		string.getChars(0, stringLength, result, 0);
 		Arrays.fill(result, stringLength, length, c);
-		return result;
-	}
-
-	/*
-	 * Pad the specified string without validating the parms.
-	 */
-	private static void padOn_(char[] string, int length, char c, Writer writer) {
-		writeStringOn(string, writer);
-		fill_(string, length, c, writer);
-	}
-
-	/*
-	 * Pad the specified string without validating the parms.
-	 */
-	private static void padOn_(char[] string, int length, char c, StringBuffer sb) {
-		sb.append(string);
-		fill_(string, length, c, sb);
-	}
-
-	/*
-	 * Pad the specified string without validating the parms.
-	 */
-	private static void padOn_(char[] string, int length, char c, StringBuilder sb) {
-		sb.append(string);
-		fill_(string, length, c, sb);
+		return new String(result);
 	}
 
 	/**
 	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPad(int)
-	 * </code>
+	 * If the string is already the specified length, return it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with zeros
+	 * at the front.
 	 */
 	public static String zeroPad(String string, int length) {
 		return frontPad(string, length, '0');
@@ -808,352 +215,47 @@
 
 	/**
 	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPadOn(int, Writer)
-	 * </code>
-	 */
-	public static void zeroPadOn(String string, int length, Writer writer) {
-		frontPadOn(string, length, '0', writer);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPadOn(int, StringBuffer)
-	 * </code>
-	 */
-	public static void zeroPadOn(String string, int length, StringBuffer sb) {
-		frontPadOn(string, length, '0', sb);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPadOn(int, StringBuilder)
-	 * </code>
-	 */
-	public static void zeroPadOn(String string, int length, StringBuilder sb) {
-		frontPadOn(string, length, '0', sb);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
+	 * If the string is already the specified length, return it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with the
 	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPad(int, char)
-	 * </code>
 	 */
 	public static String frontPad(String string, int length, char c) {
 		int stringLength = string.length();
 		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
 		}
 		if (stringLength == length) {
 			return string;
 		}
-		return frontPad_(string, length, c);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPadOn(int, char, Writer)
-	 * </code>
-	 */
-	public static void frontPadOn(String string, int length, char c, Writer writer) {
-		int stringLength = string.length();
-		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
-		}
-		if (stringLength == length) {
-			writeStringOn(string, writer);
-		} else {
-			frontPadOn_(string, length, c, writer);
-		}
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPadOn(int, char, StringBuffer)
-	 * </code>
-	 */
-	public static void frontPadOn(String string, int length, char c, StringBuffer sb) {
-		int stringLength = string.length();
-		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
-		}
-		if (stringLength == length) {
-			sb.append(string);
-		} else {
-			frontPadOn_(string, length, c, sb);
-		}
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPadOn(int, char, StringBuilder)
-	 * </code>
-	 */
-	public static void frontPadOn(String string, int length, char c, StringBuilder sb) {
-		int stringLength = string.length();
-		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
-		}
-		if (stringLength == length) {
-			sb.append(string);
-		} else {
-			frontPadOn_(string, length, c, sb);
-		}
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPad(int)
-	 * </code>
-	 */
-	public static char[] zeroPad(char[] string, int length) {
-		return frontPad(string, length, '0');
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPadOn(int, Writer)
-	 * </code>
-	 */
-	public static void zeroPadOn(char[] string, int length, Writer writer) {
-		frontPadOn(string, length, '0', writer);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPadOn(int, StringBuffer)
-	 * </code>
-	 */
-	public static void zeroPadOn(char[] string, int length, StringBuffer sb) {
-		frontPadOn(string, length, '0', sb);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPadOn(int, StringBuilder)
-	 * </code>
-	 */
-	public static void zeroPadOn(char[] string, int length, StringBuilder sb) {
-		frontPadOn(string, length, '0', sb);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPad(int, char)
-	 * </code>
-	 */
-	public static char[] frontPad(char[] string, int length, char c) {
-		int stringLength = string.length;
-		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
-		}
-		if (stringLength == length) {
-			return string;
-		}
-		return frontPad_(string, length, c);
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPadOn(int, char, Writer)
-	 * </code>
-	 */
-	public static void frontPadOn(char[] string, int length, char c, Writer writer) {
-		int stringLength = string.length;
-		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
-		}
-		if (stringLength == length) {
-			writeStringOn(string, writer);
-		} else {
-			frontPadOn_(string, length, c, writer);
-		}
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPadOn(int, char, StringBuffer)
-	 * </code>
-	 */
-	public static void frontPadOn(char[] string, int length, char c, StringBuffer sb) {
-		int stringLength = string.length;
-		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
-		}
-		if (stringLength == length) {
-			sb.append(string);
-		} else {
-			frontPadOn_(string, length, c, sb);
-		}
-	}
-
-	/**
-	 * Pad the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, an IllegalArgumentException is thrown.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPadOn(int, char, StringBuilder)
-	 * </code>
-	 */
-	public static void frontPadOn(char[] string, int length, char c, StringBuilder sb) {
-		int stringLength = string.length;
-		if (stringLength > length) {
-			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);  //$NON-NLS-2$
-		}
-		if (stringLength == length) {
-			sb.append(string);
-		} else {
-			frontPadOn_(string, length, c, sb);
-		}
+		return frontPad(string, length, c, stringLength);
 	}
 
 	/**
 	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPadOrTruncate(int)
-	 * </code>
+	 * If the string is already the specified length, return it unchanged.
+	 * If the string is longer than the specified length, return only the last
+	 * part of the string.
+	 * If the string is shorter than the specified length, pad it with zeros
+	 * at the front.
 	 */
-	public static String zeroPadOrTruncate(String string, int length) {
-		return frontPadOrTruncate(string, length, '0');
+	public static String zeroFit(String string, int length) {
+		return frontFit(string, length, '0');
 	}
 
 	/**
 	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPadOrTruncateOn(int, Writer)
-	 * </code>
-	 */
-	public static void zeroPadOrTruncateOn(String string, int length, Writer writer) {
-		frontPadOrTruncateOn(string, length, '0', writer);
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPadOrTruncateOn(int, StringBuffer)
-	 * </code>
-	 */
-	public static void zeroPadOrTruncateOn(String string, int length, StringBuffer sb) {
-		frontPadOrTruncateOn(string, length, '0', sb);
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPadOrTruncateOn(int, StringBuilder)
-	 * </code>
-	 */
-	public static void zeroPadOrTruncateOn(String string, int length, StringBuilder sb) {
-		frontPadOrTruncateOn(string, length, '0', sb);
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with the
+	 * If the string is already the specified length, return it unchanged.
+	 * If the string is longer than the specified length, return only the last
+	 * part of the string.
+	 * If the string is shorter than the specified length, pad it with the
 	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPadOrTruncate(int, char)
-	 * </code>
 	 */
-	public static String frontPadOrTruncate(String string, int length, char c) {
+	public static String frontFit(String string, int length, char c) {
+		if (length == 0) {
+			return EMPTY_STRING;
+		}
 		int stringLength = string.length();
 		if (stringLength == length) {
 			return string;
@@ -1161,286 +263,18 @@
 		if (stringLength > length) {
 			return string.substring(stringLength - length);
 		}
-		return frontPad_(string, length, c);
+		return frontPad(string, length, c, stringLength);
 	}
 
 	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPadOrTruncateOn(int, char, Writer)
-	 * </code>
+	 * no length checks
 	 */
-	public static void frontPadOrTruncateOn(String string, int length, char c, Writer writer) {
-		int stringLength = string.length();
-		if (stringLength == length) {
-			writeStringOn(string, writer);
-		} else if (stringLength > length) {
-			writeStringOn(string.substring(stringLength - length), writer);
-		} else {
-			frontPadOn_(string, length, c, writer);
-		}
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPadOrTruncateOn(int, char, StringBuffer)
-	 * </code>
-	 */
-	public static void frontPadOrTruncateOn(String string, int length, char c, StringBuffer sb) {
-		int stringLength = string.length();
-		if (stringLength == length) {
-			sb.append(string);
-		} else if (stringLength > length) {
-			sb.append(string.substring(stringLength - length));
-		} else {
-			frontPadOn_(string, length, c, sb);
-		}
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPadOrTruncateOn(int, char, StringBuilder)
-	 * </code>
-	 */
-	public static void frontPadOrTruncateOn(String string, int length, char c, StringBuilder sb) {
-		int stringLength = string.length();
-		if (stringLength == length) {
-			sb.append(string);
-		} else if (stringLength > length) {
-			sb.append(string.substring(stringLength - length));
-		} else {
-			frontPadOn_(string, length, c, sb);
-		}
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPadOrTruncate(int)
-	 * </code>
-	 */
-	public static char[] zeroPadOrTruncate(char[] string, int length) {
-		return frontPadOrTruncate(string, length, '0');
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPadOrTruncateOn(int, Writer)
-	 * </code>
-	 */
-	public static void zeroPadOrTruncateOn(char[] string, int length, Writer writer) {
-		frontPadOrTruncateOn(string, length, '0', writer);
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPadOrTruncateOn(int, StringBuffer)
-	 * </code>
-	 */
-	public static void zeroPadOrTruncateOn(char[] string, int length, StringBuffer sb) {
-		frontPadOrTruncateOn(string, length, '0', sb);
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with zeros at the front.
-	 * <p>
-	 * <code>
-	 * String.zeroPadOrTruncateOn(int, StringBuilder)
-	 * </code>
-	 */
-	public static void zeroPadOrTruncateOn(char[] string, int length, StringBuilder sb) {
-		frontPadOrTruncateOn(string, length, '0', sb);
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPadOrTruncate(int, char)
-	 * </code>
-	 */
-	public static char[] frontPadOrTruncate(char[] string, int length, char c) {
-		int stringLength = string.length;
-		if (stringLength == length) {
-			return string;
-		}
-		if (stringLength > length) {
-			char[] result = new char[length];
-			System.arraycopy(string, stringLength - length, result, 0, length);
-			return result;
-		}
-		return frontPad_(string, length, c);
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPadOrTruncateOn(int, char, Writer)
-	 * </code>
-	 */
-	public static void frontPadOrTruncateOn(char[] string, int length, char c, Writer writer) {
-		int stringLength = string.length;
-		if (stringLength == length) {
-			writeStringOn(string, writer);
-		} else if (stringLength > length) {
-			writeStringOn(string, stringLength - length, length, writer);
-		} else {
-			frontPadOn_(string, length, c, writer);
-		}
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPadOrTruncateOn(int, char, StringBuffer)
-	 * </code>
-	 */
-	public static void frontPadOrTruncateOn(char[] string, int length, char c, StringBuffer sb) {
-		int stringLength = string.length;
-		if (stringLength == length) {
-			sb.append(string);
-		} else if (stringLength > length) {
-			sb.append(string, stringLength - length, length);
-		} else {
-			frontPadOn_(string, length, c, sb);
-		}
-	}
-
-	/**
-	 * Pad or truncate the specified string to the specified length.
-	 * If the string is already the specified length, it is returned unchanged.
-	 * If it is longer than the specified length, only the last part of the string is returned.
-	 * If it is shorter than the specified length, it is padded with the
-	 * specified character at the front.
-	 * <p>
-	 * <code>
-	 * String.frontPadOrTruncateOn(int, char, StringBuilder)
-	 * </code>
-	 */
-	public static void frontPadOrTruncateOn(char[] string, int length, char c, StringBuilder sb) {
-		int stringLength = string.length;
-		if (stringLength == length) {
-			sb.append(string);
-		} else if (stringLength > length) {
-			sb.append(string, stringLength - length, length);
-		} else {
-			frontPadOn_(string, length, c, sb);
-		}
-	}
-
-	/*
-	 * Front-pad the specified string without validating the parms.
-	 */
-	private static String frontPad_(String string, int length, char c) {
-		return new String(frontPad_(string.toCharArray(), length, c));
-	}
-
-	/*
-	 * Zero-pad the specified string without validating the parms.
-	 */
-	private static char[] frontPad_(char[] string, int length, char c) {
+	private static String frontPad(String string, int length, char c, int stringLength) {
 		char[] result = new char[length];
-		int stringLength = string.length;
 		int padLength = length - stringLength;
-		System.arraycopy(string, 0, result, padLength, stringLength);
+		string.getChars(0, stringLength, result, padLength);
 		Arrays.fill(result, 0, padLength, c);
-		return result;
-	}
-
-	/*
-	 * Pad the specified string without validating the parms.
-	 */
-	private static void frontPadOn_(String string, int length, char c, Writer writer) {
-		fill_(string, length, c, writer);
-		writeStringOn(string, writer);
-	}
-
-	/*
-	 * Pad the specified string without validating the parms.
-	 */
-	private static void frontPadOn_(char[] string, int length, char c, Writer writer) {
-		fill_(string, length, c, writer);
-		writeStringOn(string, writer);
-	}
-
-	/*
-	 * Pad the specified string without validating the parms.
-	 */
-	private static void frontPadOn_(String string, int length, char c, StringBuffer sb) {
-		fill_(string, length, c, sb);
-		sb.append(string);
-	}
-
-	/*
-	 * Pad the specified string without validating the parms.
-	 */
-	private static void frontPadOn_(char[] string, int length, char c, StringBuffer sb) {
-		fill_(string, length, c, sb);
-		sb.append(string);
-	}
-
-	/*
-	 * Pad the specified string without validating the parms.
-	 */
-	private static void frontPadOn_(String string, int length, char c, StringBuilder sb) {
-		fill_(string, length, c, sb);
-		sb.append(string);
-	}
-
-	/*
-	 * Pad the specified string without validating the parms.
-	 */
-	private static void frontPadOn_(char[] string, int length, char c, StringBuilder sb) {
-		fill_(string, length, c, sb);
-		sb.append(string);
+		return new String(result);
 	}
 
 
@@ -1448,95 +282,32 @@
 
 	/**
 	 * Separate the segments of the specified string with the specified
-	 * separator:<pre>
-	 *     separate("012345", '-', 2) => "01-23-45"
-	 * </pre>
+	 * separator:<p>
+	 * <code>
+	 * separate("012345", '-', 2) => "01-23-45"
+	 * </code>
 	 */
 	public static String separate(String string, char separator, int segmentSize) {
 		if (segmentSize <= 0) {
 			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
 		}
-		int len = string.length();
-		return (len <= segmentSize) ? string : new String(separate(string.toCharArray(), separator, segmentSize, len));
+		int stringLength = string.length();
+		return (stringLength <= segmentSize) ? string : separate(string, separator, segmentSize, stringLength);
 	}
 
 	/**
-	 * Separate the segments of the specified string with the specified
-	 * separator:<pre>
-	 *     separate("012345", '-', 2) => "01-23-45"
-	 * </pre>
+	 * Pre-conditions: string is longer than segment size; segment size is positive
 	 */
-	public static void separateOn(String string, char separator, int segmentSize, Writer writer) {
-		if (segmentSize <= 0) {
-			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
-		}
-		if (string.length() <= segmentSize) {
-			writeStringOn(string, writer);
-		} else {
-			separateOn_(string.toCharArray(), separator, segmentSize, writer);
-		}
-	}
-
-	/**
-	 * Separate the segments of the specified string with the specified
-	 * separator:<pre>
-	 *     separate("012345", '-', 2) => "01-23-45"
-	 * </pre>
-	 */
-	public static void separateOn(String string, char separator, int segmentSize, StringBuffer sb) {
-		if (segmentSize <= 0) {
-			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
-		}
-		if (string.length() <= segmentSize) {
-			sb.append(string);
-		} else {
-			separateOn_(string.toCharArray(), separator, segmentSize, sb);
-		}
-	}
-
-	/**
-	 * Separate the segments of the specified string with the specified
-	 * separator:<pre>
-	 *     separate("012345", '-', 2) => "01-23-45"
-	 * </pre>
-	 */
-	public static void separateOn(String string, char separator, int segmentSize, StringBuilder sb) {
-		if (segmentSize <= 0) {
-			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
-		}
-		if (string.length() <= segmentSize) {
-			sb.append(string);
-		} else {
-			separateOn_(string.toCharArray(), separator, segmentSize, sb);
-		}
-	}
-
-	/**
-	 * Separate the segments of the specified string with the specified
-	 * separator:<pre>
-	 *     separate("012345", '-', 2) => "01-23-45"
-	 * </pre>
-	 */
-	public static char[] separate(char[] string, char separator, int segmentSize) {
-		if (segmentSize <= 0) {
-			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
-		}
-		int len = string.length;
-		return (len <= segmentSize) ? string : separate(string, separator, segmentSize, len);
-	}
-
-	/**
-	 * pre-conditions: string is longer than segment size; segment size is positive
-	 */
-	private static char[] separate(char[] string, char separator, int segmentSize, int len) {
-		int resultLen = len + (len / segmentSize);
-		if ((len % segmentSize) == 0) {
+	private static String separate(String string, char separator, int segmentSize, int stringLength) {
+		int resultLen = stringLength + (stringLength / segmentSize);
+		if ((stringLength % segmentSize) == 0) {
 			resultLen--;  // no separator after the final segment if nothing following it
 		}
 		char[] result = new char[resultLen];
 		int j = 0;
 		int segCount = 0;
-		for (char c : string) {
+		for (int i = 0; i < stringLength; i++) {
+			char c = string.charAt(i);
 			if (segCount == segmentSize) {
 				result[j++] = separator;
 				segCount = 0;
@@ -1544,103 +315,7 @@
 			segCount++;
 			result[j++] = c;
 		}
-		return result;
-	}
-
-	/**
-	 * Separate the segments of the specified string with the specified
-	 * separator:<pre>
-	 *     separate("012345", '-', 2) => "01-23-45"
-	 * </pre>
-	 */
-	public static void separateOn(char[] string, char separator, int segmentSize, Writer writer) {
-		if (segmentSize <= 0) {
-			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
-		}
-		if (string.length <= segmentSize) {
-			writeStringOn(string, writer);
-		} else {
-			separateOn_(string, separator, segmentSize, writer);
-		}
-	}
-
-	/**
-	 * pre-conditions: string is longer than segment size; segment size is positive
-	 */
-	private static void separateOn_(char[] string, char separator, int segmentSize, Writer writer) {
-		int segCount = 0;
-		for (char c : string) {
-			if (segCount == segmentSize) {
-				writeCharOn(separator, writer);
-				segCount = 0;
-			}
-			segCount++;
-			writeCharOn(c, writer);
-		}
-	}
-
-	/**
-	 * Separate the segments of the specified string with the specified
-	 * separator:<pre>
-	 *     separate("012345", '-', 2) => "01-23-45"
-	 * </pre>
-	 */
-	public static void separateOn(char[] string, char separator, int segmentSize, StringBuffer sb) {
-		if (segmentSize <= 0) {
-			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
-		}
-		if (string.length <= segmentSize) {
-			sb.append(string);
-		} else {
-			separateOn_(string, separator, segmentSize, sb);
-		}
-	}
-
-	/**
-	 * pre-conditions: string is longer than segment size; segment size is positive
-	 */
-	private static void separateOn_(char[] string, char separator, int segmentSize, StringBuffer sb) {
-		int segCount = 0;
-		for (char c : string) {
-			if (segCount == segmentSize) {
-				sb.append(separator);
-				segCount = 0;
-			}
-			segCount++;
-			sb.append(c);
-		}
-	}
-
-	/**
-	 * Separate the segments of the specified string with the specified
-	 * separator:<pre>
-	 *     separate("012345", '-', 2) => "01-23-45"
-	 * </pre>
-	 */
-	public static void separateOn(char[] string, char separator, int segmentSize, StringBuilder sb) {
-		if (segmentSize <= 0) {
-			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
-		}
-		if (string.length <= segmentSize) {
-			sb.append(string);
-		} else {
-			separateOn_(string, separator, segmentSize, sb);
-		}
-	}
-
-	/**
-	 * pre-conditions: string is longer than segment size; segment size is positive
-	 */
-	private static void separateOn_(char[] string, char separator, int segmentSize, StringBuilder sb) {
-		int segCount = 0;
-		for (char c : string) {
-			if (segCount == segmentSize) {
-				sb.append(separator);
-				segCount = 0;
-			}
-			segCount++;
-			sb.append(c);
-		}
+		return new String(result);
 	}
 
 
@@ -1652,43 +327,7 @@
 	 * double quote.
 	 */
 	public static String quote(String string) {
-		return delimit(string, QUOTE);
-	}
-
-	/**
-	 * Delimit the specified string with double quotes.
-	 * Escape any occurrences of a double quote in the string with another
-	 * double quote.
-	 */
-	public static void quoteOn(String string, Writer writer) {
-		delimitOn(string, QUOTE, writer);
-	}
-
-	/**
-	 * Delimit the specified string with double quotes.
-	 * Escape any occurrences of a double quote in the string with another
-	 * double quote.
-	 */
-	public static void quoteOn(String string, StringBuffer sb) {
-		delimitOn(string, QUOTE, sb);
-	}
-
-	/**
-	 * Delimit the specified string with double quotes.
-	 * Escape any occurrences of a double quote in the string with another
-	 * double quote.
-	 */
-	public static void quoteOn(String string, StringBuilder sb) {
-		delimitOn(string, QUOTE, sb);
-	}
-
-	/**
-	 * Delimit each of the specified strings with double quotes.
-	 * Escape any occurrences of a double quote in a string with another
-	 * double quote.
-	 */
-	public static Iterator<String> quote(Iterator<String> strings) {
-		return delimit(strings, QUOTE);
+		return delimit(string, CharacterTools.QUOTE);
 	}
 
 	/**
@@ -1697,63 +336,26 @@
 	 * Escape any occurrences of the delimiter in the string with another delimiter.
 	 */
 	public static String delimit(String string, char delimiter) {
-		return new String(delimit(string.toCharArray(), delimiter));
+		int stringLength = string.length();
+		StringBuilder sb = new StringBuilder(stringLength + 2);
+		StringBuilderTools.delimit(sb, string, delimiter, stringLength);
+		return sb.toString();
 	}
 
 	/**
-	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
-	 * the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of the delimiter in the string with another delimiter.
+	 * @see #delimit(String, char)
 	 */
-	public static void delimitOn(String string, char delimiter, Writer writer) {
-		delimitOn(string.toCharArray(), delimiter, writer);
-	}
-
-	/**
-	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
-	 * the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of the delimiter in the string with another delimiter.
-	 */
-	public static void delimitOn(String string, char delimiter, StringBuffer sb) {
-		delimitOn(string.toCharArray(), delimiter, sb);
-	}
-
-	/**
-	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
-	 * the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of the delimiter in the string with another delimiter.
-	 */
-	public static void delimitOn(String string, char delimiter, StringBuilder sb) {
-		delimitOn(string.toCharArray(), delimiter, sb);
-	}
-
-	/**
-	 * Delimit each of the specified strings with the specified delimiter; i.e. put a
-	 * copy of the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of the delimiter in a string with another delimiter.
-	 */
-	public static Iterable<String> delimit(Iterable<String> strings, char delimiter) {
-		return new TransformationIterable<String, String>(strings, new CharStringDelimiter(delimiter));
-	}
-
-	/**
-	 * Delimit each of the specified strings with the specified delimiter; i.e. put a
-	 * copy of the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of the delimiter in a string with another delimiter.
-	 */
-	public static Iterator<String> delimit(Iterator<String> strings, char delimiter) {
-		return new TransformationIterator<String, String>(strings, new CharStringDelimiter(delimiter));
-	}
-
-	private static class CharStringDelimiter implements Transformer<String, String> {
-		private char delimiter;
-		CharStringDelimiter(char delimiter) {
+	public static class CharDelimiter
+		extends TransformerAdapter<String, String>
+	{
+		private final char delimiter;
+		public CharDelimiter(char delimiter) {
 			super();
 			this.delimiter = delimiter;
 		}
 		@Override
 		public String transform(String string) {
-			return StringTools.delimit(string, this.delimiter);
+			return delimit(string, this.delimiter);
 		}
 	}
 
@@ -1764,320 +366,48 @@
 	 * another delimiter.
 	 */
 	public static String delimit(String string, String delimiter) {
-		if (delimiter.length() == 1) {
-			return delimit(string, delimiter.charAt(0));
-		}
-		return new String(delimit(string.toCharArray(), delimiter.toCharArray()));
+		return delimit(string, delimiter, delimiter.length());
 	}
 
-	/**
-	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
-	 * the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of a single-character delimiter in the string with
-	 * another delimiter.
-	 */
-	public static void delimitOn(String string, String delimiter, Writer writer) {
-		if (delimiter.length() == 1) {
-			delimitOn(string, delimiter.charAt(0), writer);
-		} else {
-			delimitOn(string.toCharArray(), delimiter.toCharArray(), writer);
+	/* CU private */ static String delimit(String string, String delimiter, int delimiterLength) {
+		switch (delimiterLength) {
+			case 0:
+				return string;
+			case 1:
+				return delimit(string, delimiter.charAt(0));
+			default:
+				return delimit_(string, delimiter, delimiterLength);
 		}
 	}
 
 	/**
-	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
-	 * the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of a single-character delimiter in the string with
-	 * another delimiter.
+	 * No parm check
 	 */
-	public static void delimitOn(String string, String delimiter, StringBuffer sb) {
-		if (delimiter.length() == 1) {
-			delimitOn(string, delimiter.charAt(0), sb);
-		} else {
-			delimitOn(string.toCharArray(), delimiter.toCharArray(), sb);
-		}
+	private static String delimit_(String string, String delimiter, int delimiterLength) {
+		int stringLength = string.length();
+		char[] result = new char[stringLength + (2 * delimiterLength)];
+		delimiter.getChars(0, delimiterLength, result, 0);
+		string.getChars(0, stringLength, result, delimiterLength);
+		delimiter.getChars(0, delimiterLength, result, delimiterLength+stringLength);
+		return new String(result);
 	}
 
 	/**
-	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
-	 * the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of a single-character delimiter in the string with
-	 * another delimiter.
+	 * @see #delimit(String, String)
 	 */
-	public static void delimitOn(String string, String delimiter, StringBuilder sb) {
-		if (delimiter.length() == 1) {
-			delimitOn(string, delimiter.charAt(0), sb);
-		} else {
-			delimitOn(string.toCharArray(), delimiter.toCharArray(), sb);
-		}
-	}
-
-	/**
-	 * Delimit each of the specified strings with the specified delimiter; i.e. put a
-	 * copy of the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of a single-character delimiter in a string with
-	 * another delimiter.
-	 */
-	public static Iterable<String> delimit(Iterable<String> strings, String delimiter) {
-		return (delimiter.length() == 1) ?
-				delimit(strings, delimiter.charAt(0)) :
-				new TransformationIterable<String, String>(strings, new StringStringDelimiter(delimiter));
-	}
-
-	/**
-	 * Delimit each of the specified strings with the specified delimiter; i.e. put a
-	 * copy of the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of a single-character delimiter in a string with
-	 * another delimiter.
-	 */
-	public static Iterator<String> delimit(Iterator<String> strings, String delimiter) {
-		return (delimiter.length() == 1) ?
-				delimit(strings, delimiter.charAt(0)) :
-				new TransformationIterator<String, String>(strings, new StringStringDelimiter(delimiter));
-	}
-
-	private static class StringStringDelimiter implements Transformer<String, String> {
-		private String delimiter;
-		StringStringDelimiter(String delimiter) {
+	public static class StringDelimiter
+		extends TransformerAdapter<String, String>
+	{
+		private final String delimiter;
+		private final int delimiterLength;
+		public StringDelimiter(String delimiter) {
 			super();
 			this.delimiter = delimiter;
+			this.delimiterLength = delimiter.length();
 		}
 		@Override
 		public String transform(String string) {
-			return StringTools.delimit(string, this.delimiter);
-		}
-	}
-
-	/**
-	 * Delimit the specified string with double quotes.
-	 * Escape any occurrences of a double quote in the string with another
-	 * double quote.
-	 */
-	public static char[] quote(char[] string) {
-		return delimit(string, QUOTE);
-	}
-
-	/**
-	 * Delimit the specified string with double quotes.
-	 * Escape any occurrences of a double quote in the string with another
-	 * double quote.
-	 */
-	public static void quoteOn(char[] string, Writer writer) {
-		delimitOn(string, QUOTE, writer);
-	}
-
-	/**
-	 * Delimit the specified string with double quotes.
-	 * Escape any occurrences of a double quote in the string with another
-	 * double quote.
-	 */
-	public static void quoteOn(char[] string, StringBuffer sb) {
-		delimitOn(string, QUOTE, sb);
-	}
-
-	/**
-	 * Delimit the specified string with double quotes.
-	 * Escape any occurrences of a double quote in the string with another
-	 * double quote.
-	 */
-	public static void quoteOn(char[] string, StringBuilder sb) {
-		delimitOn(string, QUOTE, sb);
-	}
-
-	/**
-	 * Delimit each of the specified strings with double quotes.
-	 * Escape any occurrences of a double quote in a string with another
-	 * double quote.
-	 */
-	// cannot name method simply 'quote' because of type-erasure...
-	public static Iterator<char[]> quoteCharArrays(Iterator<char[]> strings) {
-		return delimitCharArrays(strings, QUOTE);
-	}
-
-	/**
-	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
-	 * the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of the delimiter in the string with another delimiter.
-	 */
-	public static char[] delimit(char[] string, char delimiter) {
-		StringBuilder sb = new StringBuilder(string.length + 2);
-		delimitOn(string, delimiter, sb);
-		return convertToCharArray(sb);
-	}
-
-	/**
-	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
-	 * the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of the delimiter in the string with another delimiter.
-	 */
-	public static void delimitOn(char[] string, char delimiter, Writer writer) {
-		writeCharOn(delimiter, writer);
-		writeStringOn(string, delimiter, writer);
-		writeCharOn(delimiter, writer);
-	}
-
-	/**
-	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
-	 * the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of the delimiter in the string with another delimiter.
-	 */
-	public static void delimitOn(char[] string, char delimiter, StringBuffer sb) {
-		sb.append(delimiter);
-		for (char c : string) {
-			if (c == delimiter) {
-				sb.append(c);
-			}
-			sb.append(c);
-		}
-		sb.append(delimiter);
-	}
-
-	/**
-	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
-	 * the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of the delimiter in the string with another delimiter.
-	 */
-	public static void delimitOn(char[] string, char delimiter, StringBuilder sb) {
-		sb.append(delimiter);
-		for (char c : string) {
-			if (c == delimiter) {
-				sb.append(c);
-			}
-			sb.append(c);
-		}
-		sb.append(delimiter);
-	}
-
-	/**
-	 * Delimit each of the specified strings with the specified delimiter; i.e. put a
-	 * copy of the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of the delimiter in a string with another delimiter.
-	 */
-	// cannot name method simply 'delimit' because of type-erasure...
-	public static Iterable<char[]> delimitCharArrays(Iterable<char[]> strings, char delimiter) {
-		return new TransformationIterable<char[], char[]>(strings, new CharCharArrayDelimiter(delimiter));
-	}
-
-	/**
-	 * Delimit each of the specified strings with the specified delimiter; i.e. put a
-	 * copy of the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of the delimiter in a string with another delimiter.
-	 */
-	// cannot name method simply 'delimit' because of type-erasure...
-	public static Iterator<char[]> delimitCharArrays(Iterator<char[]> strings, char delimiter) {
-		return new TransformationIterator<char[], char[]>(strings, new CharCharArrayDelimiter(delimiter));
-	}
-
-	private static class CharCharArrayDelimiter implements Transformer<char[], char[]> {
-		private char delimiter;
-		CharCharArrayDelimiter(char delimiter) {
-			super();
-			this.delimiter = delimiter;
-		}
-		@Override
-		public char[] transform(char[] string) {
-			return StringTools.delimit(string, this.delimiter);
-		}
-	}
-
-	/**
-	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
-	 * the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of a single-character delimiter in the string with
-	 * another delimiter.
-	 */
-	public static char[] delimit(char[] string, char[] delimiter) {
-		int delimiterLength = delimiter.length;
-		if (delimiterLength == 1) {
-			return delimit(string, delimiter[0]);
-		}
-		int stringLength = string.length;
-		char[] result = new char[stringLength+(2*delimiterLength)];
-		System.arraycopy(delimiter, 0, result, 0, delimiterLength);
-		System.arraycopy(string, 0, result, delimiterLength, stringLength);
-		System.arraycopy(delimiter, 0, result, stringLength+delimiterLength, delimiterLength);
-		return result;
-	}
-
-	/**
-	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
-	 * the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of a single-character delimiter in the string with
-	 * another delimiter.
-	 */
-	public static void delimitOn(char[] string, char[] delimiter, Writer writer) {
-		if (delimiter.length == 1) {
-			delimitOn(string, delimiter[0], writer);
-		} else {
-			writeStringOn(delimiter, writer);
-			writeStringOn(string, writer);
-			writeStringOn(delimiter, writer);
-		}
-	}
-
-	/**
-	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
-	 * the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of a single-character delimiter in the string with
-	 * another delimiter.
-	 */
-	public static void delimitOn(char[] string, char[] delimiter, StringBuffer sb) {
-		if (delimiter.length == 1) {
-			delimitOn(string, delimiter[0], sb);
-		} else {
-			sb.append(delimiter);
-			sb.append(string);
-			sb.append(delimiter);
-		}
-	}
-
-	/**
-	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
-	 * the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of a single-character delimiter in the string with
-	 * another delimiter.
-	 */
-	public static void delimitOn(char[] string, char[] delimiter, StringBuilder sb) {
-		if (delimiter.length == 1) {
-			delimitOn(string, delimiter[0], sb);
-		} else {
-			sb.append(delimiter);
-			sb.append(string);
-			sb.append(delimiter);
-		}
-	}
-
-	/**
-	 * Delimit each of the specified strings with the specified delimiter; i.e. put a
-	 * copy of the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of a single-character delimiter in a string with
-	 * another delimiter.
-	 */
-	// cannot name method simply 'delimit' because of type-erasure...
-	public static Iterable<char[]> delimitCharArrays(Iterable<char[]> strings, char[] delimiter) {
-		return new TransformationIterable<char[], char[]>(strings, new CharArrayCharArrayDelimiter(delimiter));
-	}
-
-	/**
-	 * Delimit each of the specified strings with the specified delimiter; i.e. put a
-	 * copy of the delimiter at the front and back of the resulting string.
-	 * Escape any occurrences of a single-character delimiter in a string with
-	 * another delimiter.
-	 */
-	// cannot name method simply 'delimit' because of type-erasure...
-	public static Iterator<char[]> delimitCharArrays(Iterator<char[]> strings, char[] delimiter) {
-		return new TransformationIterator<char[], char[]>(strings, new CharArrayCharArrayDelimiter(delimiter));
-	}
-
-	private static class CharArrayCharArrayDelimiter implements Transformer<char[], char[]> {
-		private char[] delimiter;
-		CharArrayCharArrayDelimiter(char[] delimiter) {
-			super();
-			this.delimiter = delimiter;
-		}
-		@Override
-		public char[] transform(char[] string) {
-			return StringTools.delimit(string, this.delimiter);
+			return delimit(string, this.delimiter, this.delimiterLength);
 		}
 	}
 
@@ -2085,117 +415,84 @@
 	// ********** delimiting queries **********
 
 	/**
-	 * Returns whether the specified string is quoted: "\"foo\"".
+	 * Return whether the specified string is quoted:
+	 * <p>
+	 * <code>
+	 * "\"foo\""
+	 * </code>
 	 */
-	public static boolean stringIsQuoted(String string) {
-		return stringIsDelimited(string, QUOTE);
+	public static boolean isQuoted(String string) {
+		return isDelimited(string, CharacterTools.QUOTE);
 	}
 
 	/**
-	 * Returns whether the specified string is parenthetical: "(foo)".
+	 * Return whether the specified string is parenthetical:
+	 * <p>
+	 * <code>
+	 * "(foo)"
+	 * </code>
 	 */
-	public static boolean stringIsParenthetical(String string) {
-		return stringIsDelimited(string, OPEN_PARENTHESIS, CLOSE_PARENTHESIS);
+	public static boolean isParenthetical(String string) {
+		return isDelimited(string, CharacterTools.OPEN_PARENTHESIS, CharacterTools.CLOSE_PARENTHESIS);
 	}
 
 	/**
-	 * Returns whether the specified string is bracketed: "[foo]".
+	 * Return whether the specified string is bracketed:
+	 * <p>
+	 * <code>
+	 * "[foo]"
+	 * </code>
 	 */
-	public static boolean stringIsBracketed(String string) {
-		return stringIsDelimited(string, OPEN_BRACKET, CLOSE_BRACKET);
+	public static boolean isBracketed(String string) {
+		return isDelimited(string, CharacterTools.OPEN_BRACKET, CharacterTools.CLOSE_BRACKET);
 	}
 
 	/**
-	 * Returns whether the specified string is braced: "{foo}".
+	 * Return whether the specified string is braced:
+	 * <p>
+	 * <code>
+	 * "{foo}"
+	 * </code>
 	 */
-	public static boolean stringIsBraced(String string) {
-		return stringIsDelimited(string, OPEN_BRACE, CLOSE_BRACE);
+	public static boolean isBraced(String string) {
+		return isDelimited(string, CharacterTools.OPEN_BRACE, CharacterTools.CLOSE_BRACE);
 	}
 
 	/**
-	 * Returns whether the specified string is chevroned: "<foo>".
+	 * Return whether the specified string is chevroned:
+	 * <p>
+	 * {@code
+	 * "<foo>"
+	 * }
 	 */
-	public static boolean stringIsChevroned(String string) {
-		return stringIsDelimited(string, OPEN_CHEVRON, CLOSE_CHEVRON);
+	public static boolean isChevroned(String string) {
+		return isDelimited(string, CharacterTools.OPEN_CHEVRON, CharacterTools.CLOSE_CHEVRON);
 	}
 
 	/**
-	 * Returns whether the specified string is delimited by the specified
+	 * Return whether the specified string is delimited by the specified
 	 * character.
 	 */
-	public static boolean stringIsDelimited(String string, char c) {
-		return stringIsDelimited(string, c, c);
+	public static boolean isDelimited(String string, char c) {
+		return isDelimited(string, c, c);
 	}
 
 	/**
-	 * Returns whether the specified string is delimited by the specified
+	 * Return whether the specified string is delimited by the specified
 	 * characters.
 	 */
-	public static boolean stringIsDelimited(String string, char start, char end) {
-		int len = string.length();
-		if (len < 2) {
-			return false;
-		}
-		return stringIsDelimited(string.toCharArray(), start, end, len);
+	public static boolean isDelimited(String string, char start, char end) {
+		int stringLength = string.length();
+		return (stringLength < 2) ?
+				false :
+				isDelimited(string, start, end, stringLength);
 	}
 
 	/**
-	 * Returns whether the specified string is quoted: "\"foo\"".
+	 * no length check
 	 */
-	public static boolean stringIsQuoted(char[] string) {
-		return stringIsDelimited(string, QUOTE);
-	}
-
-	/**
-	 * Returns whether the specified string is parenthetical: "(foo)".
-	 */
-	public static boolean stringIsParenthetical(char[] string) {
-		return stringIsDelimited(string, OPEN_PARENTHESIS, CLOSE_PARENTHESIS);
-	}
-
-	/**
-	 * Returns whether the specified string is bracketed: "[foo]".
-	 */
-	public static boolean stringIsBracketed(char[] string) {
-		return stringIsDelimited(string, OPEN_BRACKET, CLOSE_BRACKET);
-	}
-
-	/**
-	 * Returns whether the specified string is braced: "{foo}".
-	 */
-	public static boolean stringIsBraced(char[] string) {
-		return stringIsDelimited(string, OPEN_BRACE, CLOSE_BRACE);
-	}
-
-	/**
-	 * Returns whether the specified string is chevroned: "<foo>".
-	 */
-	public static boolean stringIsChevroned(char[] string) {
-		return stringIsDelimited(string, OPEN_CHEVRON, CLOSE_CHEVRON);
-	}
-
-	/**
-	 * Returns whether the specified string is delimited by the specified
-	 * character.
-	 */
-	public static boolean stringIsDelimited(char[] string, char c) {
-		return stringIsDelimited(string, c, c);
-	}
-
-	/**
-	 * Returns whether the specified string is delimited by the specified
-	 * characters.
-	 */
-	public static boolean stringIsDelimited(char[] string, char start, char end) {
-		int len = string.length;
-		if (len < 2) {
-			return false;
-		}
-		return stringIsDelimited(string, start, end, len);
-	}
-
-	private static boolean stringIsDelimited(char[] s, char start, char end, int len) {
-		return (s[0] == start) && (s[len - 1] == end);
+	private static boolean isDelimited(String string, char start, char end, int stringLength) {
+		return (string.charAt(0) == start) && (string.charAt(stringLength - 1) == end);
 	}
 
 
@@ -2203,340 +500,52 @@
 
 	/**
 	 * Remove the delimiters from the specified string, removing any escape
-	 * characters. Throw an IllegalArgumentException if the string is too short
+	 * characters. Throw an {@link IllegalArgumentException} if the string is too short
 	 * to undelimit (i.e. length < 2).
 	 */
 	public static String undelimit(String string) {
-		int len = string.length() - 2;
-		if (len < 0) {
+		int stringLength = string.length();
+		int resultLength = stringLength - 2;
+		if (resultLength < 0) {
 			throw new IllegalArgumentException("invalid string: \"" + string + '"');
 		}
-		if (len == 0) {
+		if (resultLength == 0) {
 			return EMPTY_STRING;
 		}
-		return new String(undelimit_(string.toCharArray(), len));
+		// delegate to StringBuilderTools to take care of embedded delimiters
+		StringBuilder sb = new StringBuilder(resultLength);
+		StringBuilderTools.undelimit_(sb, string, stringLength);
+		return sb.toString();
 	}
 
 	/**
 	 * Remove the first and last count characters from the specified string.
 	 * If the string is too short to be undelimited, throw an
-	 * IllegalArgumentException.
+	 * {@link IllegalArgumentException}.
 	 * Use this method to undelimit strings that do not escape embedded
 	 * delimiters.
 	 */
 	public static String undelimit(String string, int count) {
-		int len = string.length() - (2 * count);
-		if (len < 0) {
+		if (count == 0) {
+			return string;
+		}
+		int resultLength = string.length() - (2 * count);
+		if (resultLength < 0) {
 			throw new IllegalArgumentException("invalid string: \"" + string + '"');
 		}
-		if (len == 0) {
+		if (resultLength == 0) {
 			return EMPTY_STRING;
 		}
-		return new String(undelimit(string.toCharArray(), len, count));
+		return undelimit(string, count, resultLength);
 	}
 
 	/**
-	 * Remove the delimiters from the specified string, removing any escape
-	 * characters. Throw an IllegalArgumentException if the string is too short
-	 * to undelimit (i.e. length < 2).
+	 * No parm checks
 	 */
-	public static char[] undelimit(char[] string) {
-		int len = string.length - 2;
-		if (len < 0) {
-			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
-		}
-		if (len == 0) {
-			return EMPTY_CHAR_ARRAY;
-		}
-		return undelimit_(string, len);
-	}
-
-	private static char[] undelimit_(char[] string, int length) {
-		StringBuilder sb = new StringBuilder(length);
-		undelimitOn_(string, sb);
-		return convertToCharArray(sb);
-	}
-
-	/**
-	 * Remove the first and last count characters from the specified string.
-	 * If the string is too short to be undelimited, throw an
-	 * IllegalArgumentException.
-	 * Use this method to undelimit strings that do not escape embedded
-	 * delimiters.
-	 */
-	public static char[] undelimit(char[] string, int count) {
-		int len = string.length - (2 * count);
-		if (len < 0) {
-			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
-		}
-		if (len == 0) {
-			return EMPTY_CHAR_ARRAY;
-		}
-		return undelimit(string, len, count);
-	}
-
-	private static char[] undelimit(char[] string, int len, int count) {
-		char[] result = new char[len];
-		System.arraycopy(string, count, result, 0, len);
-		return result;
-	}
-
-	/**
-	 * Remove the delimiters from the specified string, removing any escape
-	 * characters. Throw an IllegalArgumentException if the string is too short
-	 * to undelimit (i.e. length < 2).
-	 */
-	public static void undelimitOn(String string, Writer writer) {
-		undelimitOn(string.toCharArray(), writer);
-	}
-
-	/**
-	 * Remove the first and last count characters from the specified string.
-	 * If the string is too short to be undelimited, throw an
-	 * IllegalArgumentException.
-	 * Use this method to undelimit strings that do not escape embedded
-	 * delimiters.
-	 */
-	public static void undelimitOn(String string, int count, Writer writer) {
-		int len = string.length() - (2 * count);
-		if (len < 0) {
-			throw new IllegalArgumentException("invalid string: \"" + string + '"');
-		}
-		if (len == 0) {
-			return;
-		}
-		writeStringOn(string, count, len, writer);
-	}
-
-	/**
-	 * Remove the delimiters from the specified string, removing any escape
-	 * characters. Throw an IllegalArgumentException if the string is too short
-	 * to undelimit (i.e. length < 2).
-	 */
-	public static void undelimitOn(String string, StringBuffer sb) {
-		undelimitOn(string.toCharArray(), sb);
-	}
-
-	/**
-	 * Remove the first and last count characters from the specified string.
-	 * If the string is too short to be undelimited, throw an
-	 * IllegalArgumentException.
-	 * Use this method to undelimit strings that do not escape embedded
-	 * delimiters.
-	 */
-	public static void undelimitOn(String string, int count, StringBuffer sb) {
-		int len = string.length() - (2 * count);
-		if (len < 0) {
-			throw new IllegalArgumentException("invalid string: \"" + string + '"');
-		}
-		if (len == 0) {
-			return;
-		}
-		sb.append(string, count, count + len);
-	}
-
-	/**
-	 * Remove the delimiters from the specified string, removing any escape
-	 * characters. Throw an IllegalArgumentException if the string is too short
-	 * to undelimit (i.e. length < 2).
-	 */
-	public static void undelimitOn(String string, StringBuilder sb) {
-		undelimitOn(string.toCharArray(), sb);
-	}
-
-	/**
-	 * Remove the first and last count characters from the specified string.
-	 * If the string is too short to be undelimited, throw an
-	 * IllegalArgumentException.
-	 * Use this method to undelimit strings that do not escape embedded
-	 * delimiters.
-	 */
-	public static void undelimitOn(String string, int count, StringBuilder sb) {
-		int len = string.length() - (2 * count);
-		if (len < 0) {
-			throw new IllegalArgumentException("invalid string: \"" + string + '"');
-		}
-		if (len == 0) {
-			return;
-		}
-		sb.append(string, count, count + len);
-	}
-
-	/**
-	 * Remove the delimiters from the specified string, removing any escape
-	 * characters. Throw an IllegalArgumentException if the string is too short
-	 * to undelimit (i.e. length < 2).
-	 */
-	public static void undelimitOn(char[] string, Writer writer) {
-		int len = string.length - 2;
-		if (len < 0) {
-			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
-		}
-		if (len == 0) {
-			return;
-		}
-		undelimitOn_(string, writer);
-	}
-
-	/**
-	 * pre-condition: string is at least 3 characters long
-	 */
-	private static void undelimitOn_(char[] string, Writer writer) {
-		char delimiter = string[0];  // the first char is the delimiter
-		char c = string[0];
-		char next = string[1];
-		int i = 1;
-		int last = string.length - 1;
-		do {
-			c = next;
-			writeCharOn(c, writer);
-			i++;
-			next = string[i];
-			if (c == delimiter) {
-				if ((next != delimiter) || (i == last)) {
-					// an embedded delimiter must be followed by another delimiter
-					return;
-				}
-				i++;
-				next = string[i];
-			}
-		} while (i != last);
-	}
-
-	/**
-	 * Remove the first and last count characters from the specified string.
-	 * If the string is too short to be undelimited, throw an
-	 * IllegalArgumentException.
-	 * Use this method to undelimit strings that do not escape embedded
-	 * delimiters.
-	 */
-	public static void undelimitOn(char[] string, int count, Writer writer) {
-		int len = string.length - (2 * count);
-		if (len < 0) {
-			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
-		}
-		if (len == 0) {
-			return;
-		}
-		writeStringOn(string, count, len, writer);
-	}
-
-	/**
-	 * Remove the delimiters from the specified string, removing any escape
-	 * characters. Throw an IllegalArgumentException if the string is too short
-	 * to undelimit (i.e. length < 2).
-	 */
-	public static void undelimitOn(char[] string, StringBuffer sb) {
-		int len = string.length - 2;
-		if (len < 0) {
-			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
-		}
-		if (len == 0) {
-			return;
-		}
-		undelimitOn_(string, sb);
-	}
-
-	/**
-	 * pre-condition: string is at least 3 characters long
-	 */
-	private static void undelimitOn_(char[] string, StringBuffer sb) {
-		char delimiter = string[0];  // the first char is the delimiter
-		char c = string[0];
-		char next = string[1];
-		int i = 1;
-		int last = string.length - 1;
-		do {
-			c = next;
-			sb.append(c);
-			i++;
-			next = string[i];
-			if (c == delimiter) {
-				if ((next != delimiter) || (i == last)) {
-					// an embedded delimiter must be followed by another delimiter
-					return;
-				}
-				i++;
-				next = string[i];
-			}
-		} while (i != last);
-	}
-
-	/**
-	 * Remove the first and last count characters from the specified string.
-	 * If the string is too short to be undelimited, throw an
-	 * IllegalArgumentException.
-	 * Use this method to undelimit strings that do not escape embedded
-	 * delimiters.
-	 */
-	public static void undelimitOn(char[] string, int count, StringBuffer sb) {
-		int len = string.length - (2 * count);
-		if (len < 0) {
-			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
-		}
-		if (len == 0) {
-			return;
-		}
-		sb.append(string, count, len);
-	}
-
-	/**
-	 * Remove the delimiters from the specified string, removing any escape
-	 * characters. Throw an IllegalArgumentException if the string is too short
-	 * to undelimit (i.e. length < 2).
-	 */
-	public static void undelimitOn(char[] string, StringBuilder sb) {
-		int len = string.length - 2;
-		if (len < 0) {
-			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
-		}
-		if (len == 0) {
-			return;
-		}
-		undelimitOn_(string, sb);
-	}
-
-	/**
-	 * pre-condition: string is at least 3 characters long
-	 */
-	private static void undelimitOn_(char[] string, StringBuilder sb) {
-		char delimiter = string[0];  // the first char is the delimiter
-		char c = string[0];
-		char next = string[1];
-		int i = 1;
-		int last = string.length - 1;
-		do {
-			c = next;
-			sb.append(c);
-			i++;
-			next = string[i];
-			if (c == delimiter) {
-				if ((next != delimiter) || (i == last)) {
-					// an embedded delimiter must be followed by another delimiter
-					return;
-				}
-				i++;
-				next = string[i];
-			}
-		} while (i != last);
-	}
-
-	/**
-	 * Remove the first and last count characters from the specified string.
-	 * If the string is too short to be undelimited, throw an
-	 * IllegalArgumentException.
-	 * Use this method to undelimit strings that do not escape embedded
-	 * delimiters.
-	 */
-	public static void undelimitOn(char[] string, int count, StringBuilder sb) {
-		int len = string.length - (2 * count);
-		if (len < 0) {
-			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
-		}
-		if (len == 0) {
-			return;
-		}
-		sb.append(string, count, len);
+	private static String undelimit(String string, int count, int resultLength) {
+		char[] result = new char[resultLength];
+		string.getChars(count, count+resultLength, result, 0);
+		return new String(result);
 	}
 
 
@@ -2544,11 +553,7 @@
 
 	/**
 	 * Remove the first occurrence of the specified character
-	 * Returns the result.
-	 * <p>
-	 * <code>
-	 * String.removeFirstOccurrence(char)
-	 * </code>
+	 * from the specified string and return the result.
 	 */
 	public static String removeFirstOccurrence(String string, char c) {
 		int index = string.indexOf(c);
@@ -2560,952 +565,117 @@
 			// character found at the front of string
 			return string.substring(1);
 		}
-		int last = string.length() - 1;
+		int stringLength = string.length();
+		int last = stringLength - 1;
 		if (index == last) {
 			// character found at the end of string
 			return string.substring(0, last);
 		}
 		// character found somewhere in the middle of the string
-		return string.substring(0, index).concat(string.substring(index + 1));
-	}
-
-	/**
-	 * Remove the first occurrence of the specified character
-	 * from the specified string and print the result on the specified stream.
-	 * <p>
-	 * <code>
-	 * String.removeFirstOccurrenceOn(char, Writer)
-	 * </code>
-	 */
-	public static void removeFirstOccurrenceOn(String string, char c, Writer writer) {
-		int index = string.indexOf(c);
-		if (index == -1) {
-			writeStringOn(string, writer);
-		} else {
-			removeCharAtIndexOn(string.toCharArray(), index, writer);
-		}
-	}
-
-	/**
-	 * Remove the first occurrence of the specified character
-	 * from the specified string and print the result on the specified stream.
-	 * <p>
-	 * <code>
-	 * String.removeFirstOccurrenceOn(char, StringBuffer)
-	 * </code>
-	 */
-	public static void removeFirstOccurrenceOn(String string, char c, StringBuffer sb) {
-		int index = string.indexOf(c);
-		if (index == -1) {
-			sb.append(string);
-		} else {
-			removeCharAtIndexOn(string.toCharArray(), index, sb);
-		}
-	}
-
-	/**
-	 * Remove the first occurrence of the specified character
-	 * from the specified string and print the result on the specified stream.
-	 * <p>
-	 * <code>
-	 * String.removeFirstOccurrenceOn(char, StringBuilder)
-	 * </code>
-	 */
-	public static void removeFirstOccurrenceOn(String string, char c, StringBuilder sb) {
-		int index = string.indexOf(c);
-		if (index == -1) {
-			sb.append(string);
-		} else {
-			removeCharAtIndexOn(string.toCharArray(), index, sb);
-		}
-	}
-
-	/**
-	 * Remove the first occurrence of the specified character
-	 * Returns the result.
-	 * <p>
-	 * <code>
-	 * String.removeFirstOccurrence(char)
-	 * </code>
-	 */
-	public static char[] removeFirstOccurrence(char[] string, char c) {
-		int index = ArrayTools.indexOf(string, c);
-		if (index == -1) {
-			// character not found
-			return string;
-		}
-		int last = string.length - 1;
-		char[] result = new char[last];
-		if (index == 0) {
-			// character found at the front of string
-			System.arraycopy(string, 1, result, 0, last);
-		} else if (index == last) {
-			// character found at the end of string
-			System.arraycopy(string, 0, result, 0, last);
-		} else {
-			// character found somewhere in the middle of the string
-			System.arraycopy(string, 0, result, 0, index);
-			System.arraycopy(string, index + 1, result, index, last - index);
-		}
-		return result;
-	}
-
-	/**
-	 * Remove the first occurrence of the specified character
-	 * from the specified string and print the result on the specified stream.
-	 * <p>
-	 * <code>
-	 * String.removeFirstOccurrenceOn(char, Writer)
-	 * </code>
-	 */
-	public static void removeFirstOccurrenceOn(char[] string, char c, Writer writer) {
-		int index = ArrayTools.indexOf(string, c);
-		if (index == -1) {
-			writeStringOn(string, writer);
-		} else {
-			removeCharAtIndexOn(string, index, writer);
-		}
-	}
-
-	private static void removeCharAtIndexOn(char[] string, int index, Writer writer) {
-		int last = string.length - 1;
-		if (index == 0) {
-			// character found at the front of string
-			writeStringOn(string, 1, last, writer);
-		} else if (index == last) {
-			// character found at the end of string
-			writeStringOn(string, 0, last, writer);
-		} else {
-			// character found somewhere in the middle of the string
-			writeStringOn(string, 0, index, writer);
-			writeStringOn(string, index + 1, last - index, writer);
-		}
-	}
-
-	/**
-	 * Remove the first occurrence of the specified character
-	 * from the specified string and print the result on the specified stream.
-	 * <p>
-	 * <code>
-	 * String.removeFirstOccurrenceOn(char, StringBuffer)
-	 * </code>
-	 */
-	public static void removeFirstOccurrenceOn(char[] string, char c, StringBuffer sb) {
-		int index = ArrayTools.indexOf(string, c);
-		if (index == -1) {
-			sb.append(string);
-		} else {
-			removeCharAtIndexOn(string, index, sb);
-		}
-	}
-
-	private static void removeCharAtIndexOn(char[] string, int index, StringBuffer sb) {
-		int last = string.length - 1;
-		if (index == 0) {
-			// character found at the front of string
-			sb.append(string, 1, last);
-		} else if (index == last) {
-			// character found at the end of string
-			sb.append(string, 0, last);
-		} else {
-			// character found somewhere in the middle of the string
-			sb.append(string, 0, index);
-			sb.append(string, index + 1, last - index);
-		}
-	}
-
-	/**
-	 * Remove the first occurrence of the specified character
-	 * from the specified string and print the result on the specified stream.
-	 * <p>
-	 * <code>
-	 * String.removeFirstOccurrenceOn(char, StringBuilder)
-	 * </code>
-	 */
-	public static void removeFirstOccurrenceOn(char[] string, char c, StringBuilder sb) {
-		int index = ArrayTools.indexOf(string, c);
-		if (index == -1) {
-			sb.append(string);
-		} else {
-			removeCharAtIndexOn(string, index, sb);
-		}
-	}
-
-	private static void removeCharAtIndexOn(char[] string, int index, StringBuilder sb) {
-		int last = string.length - 1;
-		if (index == 0) {
-			// character found at the front of string
-			sb.append(string, 1, last);
-		} else if (index == last) {
-			// character found at the end of string
-			sb.append(string, 0, last);
-		} else {
-			// character found somewhere in the middle of the string
-			sb.append(string, 0, index);
-			sb.append(string, index + 1, last - index);
-		}
+		StringBuilder sb = new StringBuilder(last);
+		sb.append(string, 0, index);  // NB: end index is exclusive
+		sb.append(string, index + 1, stringLength);  // NB: end index is exclusive
+		return sb.toString();
 	}
 
 	/**
 	 * Remove all occurrences of the specified character
-	 * Returns the result.
-	 * <p>
-	 * <code>
-	 * String.removeAllOccurrences(char)
-	 * </code>
+	 * from the specified string and return the result.
 	 */
 	public static String removeAllOccurrences(String string, char c) {
 		int first = string.indexOf(c);
-		return (first == -1) ? string : new String(removeAllOccurrences_(string.toCharArray(), c, first));
+		return (first == -1) ? string : removeAllOccurrences(string, c, first);
 	}
 
 	/**
-	 * Remove all occurrences of the specified character
-	 * from the specified string and write the result to the specified stream.
-	 * <p>
-	 * <code>
-	 * String.removeAllOccurrencesOn(char, Writer)
-	 * </code>
+	 * no occurrence check
 	 */
-	public static void removeAllOccurrencesOn(String string, char c, Writer writer) {
-		int first = string.indexOf(c);
-		if (first == -1) {
-			writeStringOn(string, writer);
-		} else {
-			removeAllOccurrencesOn_(string.toCharArray(), c, first, writer);
-		}
+	private static String removeAllOccurrences(String string, char c, int first) {
+		int stringLength = string.length();
+		StringBuilder sb = new StringBuilder(stringLength);
+		StringBuilderTools.removeAllOccurrences(sb, string, c, first, stringLength);
+		return sb.toString();
 	}
 
 	/**
-	 * Remove all occurrences of the specified character
-	 * from the specified string and write the result to the specified stream.
-	 * <p>
-	 * <code>
-	 * String.removeAllOccurrencesOn(char, StringBuffer)
-	 * </code>
-	 */
-	public static void removeAllOccurrencesOn(String string, char c, StringBuffer sb) {
-		int first = string.indexOf(c);
-		if (first == -1) {
-			sb.append(string);
-		} else {
-			removeAllOccurrencesOn_(string.toCharArray(), c, first, sb);
-		}
-	}
-
-	/**
-	 * Remove all occurrences of the specified character
-	 * from the specified string and write the result to the specified stream.
-	 * <p>
-	 * <code>
-	 * String.removeAllOccurrencesOn(char, StringBuilder)
-	 * </code>
-	 */
-	public static void removeAllOccurrencesOn(String string, char c, StringBuilder sb) {
-		int first = string.indexOf(c);
-		if (first == -1) {
-			sb.append(string);
-		} else {
-			removeAllOccurrencesOn_(string.toCharArray(), c, first, sb);
-		}
-	}
-
-	/**
-	 * Remove all occurrences of the specified character
-	 * Returns the result.
-	 * <p>
-	 * <code>
-	 * String.removeAllOccurrences(char)
-	 * </code>
-	 */
-	public static char[] removeAllOccurrences(char[] string, char c) {
-		int first = ArrayTools.indexOf(string, c);
-		return (first == -1) ? string : removeAllOccurrences_(string, c, first);
-	}
-
-	/*
-	 * The index of the first matching character is passed in.
-	 */
-	private static char[] removeAllOccurrences_(char[] string, char c, int first) {
-		StringBuilder sb = new StringBuilder(string.length);
-		removeAllOccurrencesOn_(string, c, first, sb);
-		return convertToCharArray(sb);
-	}
-
-	/**
-	 * Remove all occurrences of the specified character
-	 * from the specified string and write the result to the
-	 * specified writer.
-	 * <p>
-	 * <code>
-	 * String.removeAllOccurrencesOn(char, Writer)
-	 * </code>
-	 */
-	public static void removeAllOccurrencesOn(char[] string, char c, Writer writer) {
-		int first = ArrayTools.indexOf(string, c);
-		if (first == -1) {
-			writeStringOn(string, writer);
-		} else {
-			removeAllOccurrencesOn_(string, c, first, writer);
-		}
-	}
-
-	/*
-	 * The index of the first matching character is passed in.
-	 */
-	private static void removeAllOccurrencesOn_(char[] string, char c, int first, Writer writer) {
-		writeStringOn(string, 0, first, writer);
-		int len = string.length;
-		for (int i = first; i < len; i++) {
-			char d = string[i];
-			if (d != c) {
-				writeCharOn(d, writer);
-			}
-		}
-	}
-
-	/**
-	 * Remove all occurrences of the specified character
-	 * from the specified string and append the result to the
-	 * specified string buffer.
-	 * <p>
-	 * <code>
-	 * String.removeAllOccurrencesOn(char, StringBuffer)
-	 * </code>
-	 */
-	public static void removeAllOccurrencesOn(char[] string, char c, StringBuffer sb) {
-		int first = ArrayTools.indexOf(string, c);
-		if (first == -1) {
-			sb.append(string);
-		} else {
-			removeAllOccurrencesOn_(string, c, first, sb);
-		}
-	}
-
-	/*
-	 * The index of the first matching character is passed in.
-	 */
-	private static void removeAllOccurrencesOn_(char[] string, char c, int first, StringBuffer sb) {
-		sb.append(string, 0, first);
-		int len = string.length;
-		for (int i = first; i < len; i++) {
-			char d = string[i];
-			if (d != c) {
-				sb.append(d);
-			}
-		}
-	}
-
-	/**
-	 * Remove all occurrences of the specified character
-	 * from the specified string and append the result to the
-	 * specified string builder.
-	 * <p>
-	 * <code>
-	 * String.removeAllOccurrencesOn(char, StringBuilder)
-	 * </code>
-	 */
-	public static void removeAllOccurrencesOn(char[] string, char c, StringBuilder sb) {
-		int first = ArrayTools.indexOf(string, c);
-		if (first == -1) {
-			sb.append(string);
-		} else {
-			removeAllOccurrencesOn_(string, c, first, sb);
-		}
-	}
-
-	/*
-	 * The index of the first matching character is passed in.
-	 */
-	private static void removeAllOccurrencesOn_(char[] string, char c, int first, StringBuilder sb) {
-		sb.append(string, 0, first);
-		int len = string.length;
-		for (int i = first; i < len; i++) {
-			char d = string[i];
-			if (d != c) {
-				sb.append(d);
-			}
-		}
-	}
-
-	/**
-	 * Returns the result.
-	 * <p>
-	 * <code>
-	 * String.removeAllSpaces()
-	 * </code>
+	 * Remove all the spaces from the specified string and return the result.
 	 */
 	public static String removeAllSpaces(String string) {
 		return removeAllOccurrences(string, ' ');
 	}
 
 	/**
-	 * Remove all the spaces
-	 * from the specified string and write the result to the specified writer.
-	 * <p>
-	 * <code>
-	 * String.removeAllSpacesOn(Writer)
-	 * </code>
-	 */
-	public static void removeAllSpacesOn(String string, Writer writer) {
-		removeAllOccurrencesOn(string, ' ', writer);
-	}
-
-	/**
-	 * Remove all the spaces
-	 * from the specified string and write the result to the specified
-	 * string buffer.
-	 * <p>
-	 * <code>
-	 * String.removeAllSpacesOn(StringBuffer)
-	 * </code>
-	 */
-	public static void removeAllSpacesOn(String string, StringBuffer sb) {
-		removeAllOccurrencesOn(string, ' ', sb);
-	}
-
-	/**
-	 * Remove all the spaces
-	 * from the specified string and write the result to the specified
-	 * string builder.
-	 * <p>
-	 * <code>
-	 * String.removeAllSpacesOn(StringBuilder)
-	 * </code>
-	 */
-	public static void removeAllSpacesOn(String string, StringBuilder sb) {
-		removeAllOccurrencesOn(string, ' ', sb);
-	}
-
-	/**
-	 * Returns the result.
-	 * <p>
-	 * <code>
-	 * String.removeAllSpaces()
-	 * </code>
-	 */
-	public static char[] removeAllSpaces(char[] string) {
-		return removeAllOccurrences(string, ' ');
-	}
-
-	/**
-	 * Remove all the spaces
-	 * from the specified string and write the result to the
-	 * specified writer.
-	 * <p>
-	 * <code>
-	 * String.removeAllSpacesOn(Writer)
-	 * </code>
-	 */
-	public static void removeAllSpacesOn(char[] string, Writer writer) {
-		removeAllOccurrencesOn(string, ' ', writer);
-	}
-
-	/**
-	 * Remove all the spaces
-	 * from the specified string and append the result to the
-	 * specified string buffer.
-	 * <p>
-	 * <code>
-	 * String.removeAllSpacesOn(StringBuffer)
-	 * </code>
-	 */
-	public static void removeAllSpacesOn(char[] string, StringBuffer sb) {
-		removeAllOccurrencesOn(string, ' ', sb);
-	}
-
-	/**
-	 * Remove all the spaces
-	 * from the specified string and append the result to the
-	 * specified string builder.
-	 * <p>
-	 * <code>
-	 * String.removeAllSpacesOn(StringBuilder)
-	 * </code>
-	 */
-	public static void removeAllSpacesOn(char[] string, StringBuilder sb) {
-		removeAllOccurrencesOn(string, ' ', sb);
-	}
-
-	/**
-	 * Returns the result.
-	 * <p>
-	 * <code>
-	 * String.removeAllWhitespace()
-	 * </code>
+	 * Remove all the whitespace from the specified string and return the result.
+	 * @see Character#isWhitespace(char)
 	 */
 	public static String removeAllWhitespace(String string) {
-		char[] string2 = string.toCharArray();
-		int first = indexOfWhitespace_(string2);
-		return (first == -1) ? string : new String(removeAllWhitespace_(string2, first));
+		int first = indexOfWhitespace(string);
+		return (first == -1) ? string : removeAllWhitespace(string, first);
 	}
 
 	/**
-	 * Remove all the whitespace
-	 * from the specified string and append the result to the
-	 * specified writer.
-	 * <p>
-	 * <code>
-	 * String.removeAllWhitespaceOn(Writer)
-	 * </code>
+	 * Return the index of the first whitespace character in the specified
+	 * string. Return -1 if the specified string contains no whitespace.
+	 * @see Character#isWhitespace(char)
 	 */
-	public static void removeAllWhitespaceOn(String string, Writer writer) {
-		char[] string2 = string.toCharArray();
-		int first = indexOfWhitespace_(string2);
-		if (first == -1) {
-			writeStringOn(string, writer);
-		} else {
-			removeAllWhitespaceOn_(string2, first, writer);
-		}
-	}
-
-	/**
-	 * Remove all the whitespace
-	 * from the specified string and append the result to the
-	 * specified string buffer.
-	 * <p>
-	 * <code>
-	 * String.removeAllWhitespaceOn(StringBuffer)
-	 * </code>
-	 */
-	public static void removeAllWhitespaceOn(String string, StringBuffer sb) {
-		char[] string2 = string.toCharArray();
-		int first = indexOfWhitespace_(string2);
-		if (first == -1) {
-			sb.append(string);
-		} else {
-			removeAllWhitespaceOn_(string2, first, sb);
-		}
-	}
-
-	/**
-	 * Remove all the whitespace
-	 * from the specified string and append the result to the
-	 * specified string builder.
-	 * <p>
-	 * <code>
-	 * String.removeAllWhitespaceOn(StringBuilder)
-	 * </code>
-	 */
-	public static void removeAllWhitespaceOn(String string, StringBuilder sb) {
-		char[] string2 = string.toCharArray();
-		int first = indexOfWhitespace_(string2);
-		if (first == -1) {
-			sb.append(string);
-		} else {
-			removeAllWhitespaceOn_(string2, first, sb);
-		}
-	}
-
-	/**
-	 * Returns the result.
-	 * <p>
-	 * <code>
-	 * String.removeAllWhitespace()
-	 * </code>
-	 */
-	public static char[] removeAllWhitespace(char[] string) {
-		int first = indexOfWhitespace_(string);
-		return (first == -1) ? string : removeAllWhitespace_(string, first);
-	}
-
-	private static int indexOfWhitespace_(char[] string) {
-		int len = string.length;
-		for (int i = 0; i < len; i++) {
-			if (Character.isWhitespace(string[i])) {
+	public static int indexOfWhitespace(String string) {
+		int stringLength = string.length();
+		for (int i = 0; i < stringLength; i++) {
+			if (Character.isWhitespace(string.charAt(i))) {
 				return i;
 			}
 		}
 		return -1;
 	}
 
-	/*
-	 * The index of the first non-whitespace character is passed in.
+	/**
+	 * no whitespace check
 	 */
-	private static char[] removeAllWhitespace_(char[] string, int first) {
-		StringBuilder sb = new StringBuilder(string.length);
-		removeAllWhitespaceOn_(string, first, sb);
-		return convertToCharArray(sb);
+	private static String removeAllWhitespace(String string, int first) {
+		int stringLength = string.length();
+		StringBuilder sb = new StringBuilder(stringLength);
+		StringBuilderTools.removeAllWhitespace(sb, string, first, stringLength);
+		return sb.toString();
 	}
 
 	/**
-	 * Remove all the whitespace
-	 * from the specified string and append the result to the
-	 * specified writer.
-	 * <p>
-	 * <code>
-	 * String.removeAllWhitespaceOn(Writer)
-	 * </code>
-	 */
-	public static void removeAllWhitespaceOn(char[] string, Writer writer) {
-		int first = indexOfWhitespace_(string);
-		if (first == -1) {
-			writeStringOn(string, writer);
-		} else {
-			removeAllWhitespaceOn_(string, first, writer);
-		}
-	}
-
-	/*
-	 * The index of the first whitespace character is passed in.
-	 */
-	private static void removeAllWhitespaceOn_(char[] string, int first, Writer writer) {
-		writeStringOn(string, 0, first, writer);
-		int len = string.length;
-		for (int i = first; i < len; i++) {
-			char c = string[i];
-			if ( ! Character.isWhitespace(c)) {
-				writeCharOn(c, writer);
-			}
-		}
-	}
-
-	/**
-	 * Remove all the whitespace
-	 * from the specified string and append the result to the
-	 * specified string buffer.
-	 * <p>
-	 * <code>
-	 * String.removeAllWhitespaceOn(StringBuffer)
-	 * </code>
-	 */
-	public static void removeAllWhitespaceOn(char[] string, StringBuffer sb) {
-		int first = indexOfWhitespace_(string);
-		if (first == -1) {
-			sb.append(string);
-		} else {
-			removeAllWhitespaceOn_(string, first, sb);
-		}
-	}
-
-	/*
-	 * The index of the first whitespace character is passed in.
-	 */
-	private static void removeAllWhitespaceOn_(char[] string, int first, StringBuffer sb) {
-		sb.append(string, 0, first);
-		int len = string.length;
-		for (int i = first; i < len; i++) {
-			char c = string[i];
-			if ( ! Character.isWhitespace(c)) {
-				sb.append(c);
-			}
-		}
-	}
-
-	/**
-	 * Remove all the whitespace
-	 * from the specified string and append the result to the
-	 * specified string builder.
-	 * <p>
-	 * <code>
-	 * String.removeAllWhitespaceOn(StringBuilder)
-	 * </code>
-	 */
-	public static void removeAllWhitespaceOn(char[] string, StringBuilder sb) {
-		int first = indexOfWhitespace_(string);
-		if (first == -1) {
-			sb.append(string);
-		} else {
-			removeAllWhitespaceOn_(string, first, sb);
-		}
-	}
-
-	/*
-	 * The index of the first whitespace character is passed in.
-	 */
-	private static void removeAllWhitespaceOn_(char[] string, int first, StringBuilder sb) {
-		sb.append(string, 0, first);
-		int len = string.length;
-		for (int i = first; i < len; i++) {
-			char c = string[i];
-			if ( ! Character.isWhitespace(c)) {
-				sb.append(c);
-			}
-		}
-	}
-//===============================
-	/**
-	 * Returns the result.
+	 * Compress the whitespace in the specified string and return the result.
 	 * The whitespace is compressed by replacing any occurrence of one or more
 	 * whitespace characters with a single space.
-	 * <p>
-	 * <code>
-	 * String.compressWhitespace()
-	 * </code>
+	 * @see Character#isWhitespace(char)
 	 */
 	public static String compressWhitespace(String string) {
-		char[] string2 = string.toCharArray();
-		int first = indexOfWhitespace_(string2);
-		return (first == -1) ? string : new String(compressWhitespace_(string2, first));
+		int first = indexOfWhitespace(string);
+		return (first == -1) ? string : new String(compressWhitespace(string, first));
 	}
 
 	/**
-	 * Compress the whitespace
-	 * in the specified string and append the result to the
-	 * specified writer.
-	 * The whitespace is compressed by replacing any occurrence of one or more
-	 * whitespace characters with a single space.
-	 * <p>
-	 * <code>
-	 * String.compressWhitespaceOn(Writer)
-	 * </code>
+	 * no whitespace check
 	 */
-	public static void compressWhitespaceOn(String string, Writer writer) {
-		char[] string2 = string.toCharArray();
-		int first = indexOfWhitespace_(string2);
-		if (first == -1) {
-			writeStringOn(string, writer);
-		} else {
-			compressWhitespaceOn_(string2, first, writer);
-		}
-	}
-
-	/**
-	 * Compress the whitespace
-	 * in the specified string and append the result to the
-	 * specified string buffer.
-	 * The whitespace is compressed by replacing any occurrence of one or more
-	 * whitespace characters with a single space.
-	 * <p>
-	 * <code>
-	 * String.compressWhitespaceOn(StringBuffer)
-	 * </code>
-	 */
-	public static void compressWhitespaceOn(String string, StringBuffer sb) {
-		char[] string2 = string.toCharArray();
-		int first = indexOfWhitespace_(string2);
-		if (first == -1) {
-			sb.append(string);
-		} else {
-			compressWhitespaceOn_(string2, first, sb);
-		}
-	}
-
-	/**
-	 * Compress the whitespace
-	 * in the specified string and append the result to the
-	 * specified string builder.
-	 * The whitespace is compressed by replacing any occurrence of one or more
-	 * whitespace characters with a single space.
-	 * <p>
-	 * <code>
-	 * String.compressWhitespaceOn(StringBuilder)
-	 * </code>
-	 */
-	public static void compressWhitespaceOn(String string, StringBuilder sb) {
-		char[] string2 = string.toCharArray();
-		int first = indexOfWhitespace_(string2);
-		if (first == -1) {
-			sb.append(string);
-		} else {
-			compressWhitespaceOn_(string2, first, sb);
-		}
-	}
-
-	/**
-	 * Returns the result.
-	 * The whitespace is compressed by replacing any occurrence of one or more
-	 * whitespace characters with a single space.
-	 * <p>
-	 * <code>
-	 * String.compressWhitespace()
-	 * </code>
-	 */
-	public static char[] compressWhitespace(char[] string) {
-		int first = indexOfWhitespace_(string);
-		return (first == -1) ? string : compressWhitespace_(string, first);
-	}
-
-	/*
-	 * The index of the first whitespace character is passed in.
-	 */
-	private static char[] compressWhitespace_(char[] string, int first) {
-		StringBuilder sb = new StringBuilder(string.length);
-		compressWhitespaceOn_(string, first, sb);
-		return convertToCharArray(sb);
-	}
-
-	/**
-	 * Compress the whitespace
-	 * in the specified string and append the result to the
-	 * specified writer.
-	 * The whitespace is compressed by replacing any occurrence of one or more
-	 * whitespace characters with a single space.
-	 * <p>
-	 * <code>
-	 * String.compressWhitespaceOn(Writer)
-	 * </code>
-	 */
-	public static void compressWhitespaceOn(char[] string, Writer writer) {
-		int first = indexOfWhitespace_(string);
-		if (first == -1) {
-			writeStringOn(string, writer);
-		} else {
-			compressWhitespaceOn_(string, first, writer);
-		}
-	}
-
-	/*
-	 * The index of the first whitespace character is passed in.
-	 */
-	private static void compressWhitespaceOn_(char[] string, int first, Writer writer) {
-		writeStringOn(string, 0, first, writer);
-		boolean spaceWritten = false;
-		int len = string.length;
-		for (int i = first; i < len; i++) {
-			char c = string[i];
-			if (Character.isWhitespace(c)) {
-				if (spaceWritten) {
-					// skip subsequent whitespace characters
-				} else {
-					// replace first whitespace character with a space
-					spaceWritten = true;
-					writeCharOn(' ', writer);
-				}
-			} else {
-				spaceWritten = false;
-				writeCharOn(c, writer);
-			}
-		}
-	}
-
-	/**
-	 * Compress the whitespace
-	 * in the specified string and append the result to the
-	 * specified string buffer.
-	 * The whitespace is compressed by replacing any occurrence of one or more
-	 * whitespace characters with a single space.
-	 * <p>
-	 * <code>
-	 * String.compressWhitespaceOn(StringBuffer)
-	 * </code>
-	 */
-	public static void compressWhitespaceOn(char[] string, StringBuffer sb) {
-		int first = indexOfWhitespace_(string);
-		if (first == -1) {
-			sb.append(string);
-		} else {
-			compressWhitespaceOn_(string, first, sb);
-		}
-	}
-
-	/*
-	 * The index of the first whitespace character is passed in.
-	 */
-	private static void compressWhitespaceOn_(char[] string, int first, StringBuffer sb) {
-		sb.append(string, 0, first);
-		boolean spaceWritten = false;
-		int len = string.length;
-		for (int i = first; i < len; i++) {
-			char c = string[i];
-			if (Character.isWhitespace(c)) {
-				if (spaceWritten) {
-					// skip subsequent whitespace characters
-				} else {
-					// replace first whitespace character with a space
-					spaceWritten = true;
-					sb.append(' ');
-				}
-			} else {
-				spaceWritten = false;
-				sb.append(c);
-			}
-		}
-	}
-
-	/**
-	 * Compress the whitespace
-	 * in the specified string and append the result to the
-	 * specified string builder.
-	 * The whitespace is compressed by replacing any occurrence of one or more
-	 * whitespace characters with a single space.
-	 * <p>
-	 * <code>
-	 * String.compressWhitespaceOn(StringBuilder)
-	 * </code>
-	 */
-	public static void compressWhitespaceOn(char[] string, StringBuilder sb) {
-		int first = indexOfWhitespace_(string);
-		if (first == -1) {
-			sb.append(string);
-		} else {
-			compressWhitespaceOn_(string, first, sb);
-		}
-	}
-
-	/*
-	 * The index of the first whitespace character is passed in.
-	 */
-	private static void compressWhitespaceOn_(char[] string, int first, StringBuilder sb) {
-		sb.append(string, 0, first);
-		boolean spaceWritten = false;
-		int len = string.length;
-		for (int i = first; i < len; i++) {
-			char c = string[i];
-			if (Character.isWhitespace(c)) {
-				if (spaceWritten) {
-					// skip subsequent whitespace characters
-				} else {
-					// replace first whitespace character with a space
-					spaceWritten = true;
-					sb.append(' ');
-				}
-			} else {
-				spaceWritten = false;
-				sb.append(c);
-			}
-		}
+	private static String compressWhitespace(String string, int first) {
+		int stringLength = string.length();
+		StringBuilder sb = new StringBuilder(stringLength);
+		StringBuilderTools.compressWhitespace(sb, string, first, stringLength);
+		return sb.toString();
 	}
 
 
 	// ********** common prefix **********
 
 	/**
-	 * Returns the length of the common prefix shared by the specified strings.
-	 * <p>
-	 * <code>
-	 * String.commonPrefixLength(String)
-	 * </code>
+	 * Return the length of the common prefix shared by the specified strings.
 	 */
 	public static int commonPrefixLength(String s1, String s2) {
-		return commonPrefixLength(s1.toCharArray(), s2.toCharArray());
+		return commonPrefixLength(s1, s2, Math.min(s1.length(), s2.length()));
 	}
 
 	/**
-	 * Returns the length of the common prefix shared by the specified strings.
-	 */
-	public static int commonPrefixLength(char[] s1, char[] s2) {
-		return commonPrefixLength_(s1, s2, Math.min(s1.length, s2.length));
-	}
-
-	/**
-	 * Returns the length of the common prefix shared by the specified strings;
+	 * Return the length of the common prefix shared by the specified strings;
 	 * but limit the length to the specified maximum.
-	 * <p>
-	 * <code>
-	 * String.commonPrefixLength(String, int)
-	 * </code>
 	 */
 	public static int commonPrefixLength(String s1, String s2, int max) {
-		return commonPrefixLength(s1.toCharArray(), s2.toCharArray(), max);
-	}
-
-	/**
-	 * Returns the length of the common prefix shared by the specified strings;
-	 * but limit the length to the specified maximum.
-	 */
-	public static int commonPrefixLength(char[] s1, char[] s2, int max) {
-		return commonPrefixLength_(s1, s2, Math.min(max, Math.min(s1.length, s2.length)));
-	}
-
-	/*
-	 * Returns the length of the common prefix shared by the specified strings;
-	 * but limit the length to the specified maximum. Assume the specified
-	 * maximum is less than the lengths of the specified strings.
-	 */
-	private static int commonPrefixLength_(char[] s1, char[] s2, int max) {
 		for (int i = 0; i < max; i++) {
-			if (s1[i] != s2[i]) {
+			if (s1.charAt(i) != s2.charAt(i)) {
 				return i;
 			}
 		}
@@ -3515,253 +685,64 @@
 
 	// ********** capitalization **********
 
-	/*
-	 * no zero-length check or lower case check
-	 */
-	private static char[] capitalize_(char[] string) {
-		string[0] = Character.toUpperCase(string[0]);
-		return string;
-	}
-
 	/**
-	 * Returns the specified string with
-	 * its first letter capitalized.
-	 */
-	public static char[] capitalize(char[] string) {
-		if ((string.length == 0) || Character.isUpperCase(string[0])) {
-			return string;
-		}
-		return capitalize_(string);
-	}
-
-	/**
-	 * Returns the specified string with its first letter capitalized.
-	 * <p>
-	 * <code>
-	 * String.capitalize()
-	 * </code>
+	 * Return the specified string with its first letter capitalized.
 	 */
 	public static String capitalize(String string) {
-		if ((string.length() == 0) || Character.isUpperCase(string.charAt(0))) {
-			return string;
-		}
-		return new String(capitalize_(string.toCharArray()));
+		int stringLength = string.length();
+		return ((stringLength == 0) || Character.isUpperCase(string.charAt(0))) ?
+				string :
+				capitalize(string, stringLength);
 	}
 
 	/**
-	 * Modify each of the specified strings, capitalizing the first letter of
-	 * each.
-	 */
-	public static Iterable<String> capitalize(Iterable<String> strings) {
-		return new TransformationIterable<String, String>(strings, STRING_CAPITALIZER);
-	}
-
-	/**
-	 * Modify each of the specified strings, capitalizing the first letter of
-	 * each.
-	 */
-	public static Iterator<String> capitalize(Iterator<String> strings) {
-		return new TransformationIterator<String, String>(strings, STRING_CAPITALIZER);
-	}
-
-	private static final Transformer<String, String> STRING_CAPITALIZER = new Transformer<String, String>() {
-		@Override
-		public String transform(String string) {
-			return StringTools.capitalize(string);
-		}
-	};
-
-	/**
-	 * Modify each of the specified strings, capitalizing the first letter of
-	 * each.
-	 */
-	// cannot name method simply 'capitalize' because of type-erasure...
-	public static Iterable<char[]> capitalizeCharArrays(Iterable<char[]> strings) {
-		return new TransformationIterable<char[], char[]>(strings, CHAR_ARRAY_CAPITALIZER);
-	}
-
-	/**
-	 * Modify each of the specified strings, capitalizing the first letter of
-	 * each.
-	 */
-	// cannot name method simply 'capitalize' because of type-erasure...
-	public static Iterator<char[]> capitalizeCharArrays(Iterator<char[]> strings) {
-		return new TransformationIterator<char[], char[]>(strings, CHAR_ARRAY_CAPITALIZER);
-	}
-
-	private static final Transformer<char[], char[]> CHAR_ARRAY_CAPITALIZER = new Transformer<char[], char[]>() {
-		@Override
-		public char[] transform(char[] string) {
-			return StringTools.capitalize(string);
-		}
-	};
-
-	/*
-	 * no zero-length check or upper case check
-	 */
-	private static void capitalizeOn_(char[] string, StringBuffer sb) {
-		sb.append(Character.toUpperCase(string[0]));
-		sb.append(string, 1, string.length - 1);
-	}
-
-	/**
-	 * Append the specified string to the specified string buffer
-	 * with its first letter capitalized.
-	 */
-	public static void capitalizeOn(char[] string, StringBuffer sb) {
-		if (string.length == 0) {
-			return;
-		}
-		if (Character.isUpperCase(string[0])) {
-			sb.append(string);
-		} else {
-			capitalizeOn_(string, sb);
-		}
-	}
-
-	/**
-	 * Append the specified string to the specified string buffer
-	 * with its first letter capitalized.
-	 * <p>
-	 * <code>
-	 * String.capitalizeOn(StringBuffer)
-	 * </code>
-	 */
-	public static void capitalizeOn(String string, StringBuffer sb) {
-		if (string.length() == 0) {
-			return;
-		}
-		if (Character.isUpperCase(string.charAt(0))) {
-			sb.append(string);
-		} else {
-			capitalizeOn_(string.toCharArray(), sb);
-		}
-	}
-
-	/*
-	 * no zero-length check or upper case check
-	 */
-	private static void capitalizeOn_(char[] string, StringBuilder sb) {
-		sb.append(Character.toUpperCase(string[0]));
-		sb.append(string, 1, string.length - 1);
-	}
-
-	/**
-	 * Append the specified string to the specified string builder
-	 * with its first letter capitalized.
-	 */
-	public static void capitalizeOn(char[] string, StringBuilder sb) {
-		if (string.length == 0) {
-			return;
-		}
-		if (Character.isUpperCase(string[0])) {
-			sb.append(string);
-		} else {
-			capitalizeOn_(string, sb);
-		}
-	}
-
-	/**
-	 * Append the specified string to the specified string builder
-	 * with its first letter capitalized.
-	 * <p>
-	 * <code>
-	 * String.capitalizeOn(StringBuffer)
-	 * </code>
-	 */
-	public static void capitalizeOn(String string, StringBuilder sb) {
-		if (string.length() == 0) {
-			return;
-		}
-		if (Character.isUpperCase(string.charAt(0))) {
-			sb.append(string);
-		} else {
-			capitalizeOn_(string.toCharArray(), sb);
-		}
-	}
-
-	/*
-	 * no zero-length check or upper case check
-	 */
-	private static void capitalizeOn_(char[] string, Writer writer) {
-		writeCharOn(Character.toUpperCase(string[0]), writer);
-		writeStringOn(string, 1, string.length - 1, writer);
-	}
-
-	/**
-	 * Append the specified string to the specified string buffer
-	 * with its first letter capitalized.
-	 */
-	public static void capitalizeOn(char[] string, Writer writer) {
-		if (string.length == 0) {
-			return;
-		}
-		if (Character.isUpperCase(string[0])) {
-			writeStringOn(string, writer);
-		} else {
-			capitalizeOn_(string, writer);
-		}
-	}
-
-	/**
-	 * Append the specified string to the specified string buffer
-	 * with its first letter capitalized.
-	 * <p>
-	 * <code>
-	 * String.capitalizeOn(Writer)
-	 * </code>
-	 */
-	public static void capitalizeOn(String string, Writer writer) {
-		if (string.length() == 0) {
-			return;
-		}
-		if (Character.isUpperCase(string.charAt(0))) {
-			writeStringOn(string, writer);
-		} else {
-			capitalizeOn_(string.toCharArray(), writer);
-		}
-	}
-
-	/*
 	 * no zero-length check or lower case check
 	 */
-	private static char[] uncapitalize_(char[] string) {
-		string[0] = Character.toLowerCase(string[0]);
-		return string;
-	}
-
-	private static boolean stringNeedNotBeUncapitalized_(char[] string) {
-		if (string.length == 0) {
-			return true;
-		}
-		if (Character.isLowerCase(string[0])) {
-			return true;
-		}
-		// if both the first and second characters are capitalized,
-		// return the string unchanged
-		if ((string.length > 1)
-				&& Character.isUpperCase(string[1])
-				&& Character.isUpperCase(string[0])){
-			return true;
-		}
-		return false;
+	private static String capitalize(String string, int stringLength) {
+		char[] result = new char[stringLength];
+		result[0] = Character.toUpperCase(string.charAt(0));
+		string.getChars(1, stringLength, result, 1);
+		return new String(result);
 	}
 
 	/**
-	 * Returns the specified string with its
-	 * first letter converted to lower case.
+	 * @see #capitalize(String)
+	 */
+	public static final Transformer<String, String> CAPITALIZER = new Capitalizer();
+
+	/* CU private */ static class Capitalizer
+		extends TransformerAdapter<String, String>
+		implements Serializable
+	{
+		@Override
+		public String transform(String string) {
+			return capitalize(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return CAPITALIZER;
+		}
+	}
+
+	/**
+	 * Return the specified string with its first letter converted to lower case.
 	 * (Unless both the first and second letters are upper case,
 	 * in which case the string is returned unchanged.)
 	 */
-	public static char[] uncapitalize(char[] string) {
-		if (stringNeedNotBeUncapitalized_(string)) {
-			return string;
-		}
-		return uncapitalize_(string);
+	public static String uncapitalize(String string) {
+		int stringLength = string.length();
+		return needNotBeUncapitalized(string, stringLength) ?
+				string :
+				uncapitalize(string, stringLength);
 	}
 
-	private static boolean stringNeedNotBeUncapitalized_(String string) {
-		if (string.length() == 0) {
+	/**
+	 * Return whether the specified string need not have its first character
+	 * capitalized when the specified string is to be capitalized.
+	 */
+	public static boolean needNotBeUncapitalized(String string, int stringLength) {
+		if (stringLength == 0) {
 			return true;
 		}
 		if (Character.isLowerCase(string.charAt(0))) {
@@ -3769,7 +750,7 @@
 		}
 		// if both the first and second characters are capitalized,
 		// return the string unchanged
-		if ((string.length() > 1)
+		if ((stringLength > 1)
 				&& Character.isUpperCase(string.charAt(1))
 				&& Character.isUpperCase(string.charAt(0))){
 			return true;
@@ -3778,348 +759,59 @@
 	}
 
 	/**
-	 * Returns the specified string with its first letter converted to lower case.
-	 * (Unless both the first and second letters are upper case,
-	 * in which case the string is returned unchanged.)
-	 * <p>
-	 * <code>
-	 * String.uncapitalize()
-	 * </code>
-	 */
-	public static String uncapitalize(String string) {
-		if (stringNeedNotBeUncapitalized_(string)) {
-			return string;
-		}
-		return new String(uncapitalize_(string.toCharArray()));
-	}
-
-	/*
 	 * no zero-length check or lower case check
 	 */
-	private static void uncapitalizeOn_(char[] string, StringBuffer sb) {
-		sb.append(Character.toLowerCase(string[0]));
-		sb.append(string, 1, string.length - 1);
+	private static String uncapitalize(String string, int stringLength) {
+		char[] result = new char[stringLength];
+		result[0] = Character.toLowerCase(string.charAt(0));
+		string.getChars(1, stringLength, result, 1);
+		return new String(result);
 	}
 
 	/**
-	 * Append the specified string to the specified string buffer
-	 * with its first letter converted to lower case.
-	 * (Unless both the first and second letters are upper case,
-	 * in which case the string is returned unchanged.)
+	 * @see #uncapitalize(String)
 	 */
-	public static void uncapitalizeOn(char[] string, StringBuffer sb) {
-		if (stringNeedNotBeUncapitalized_(string)) {
-			sb.append(string);
-		} else {
-			uncapitalizeOn_(string, sb);
+	public static final Transformer<String, String> UNCAPITALIZER = new Uncapitalizer();
+
+	/* CU private */ static class Uncapitalizer
+		extends TransformerAdapter<String, String>
+		implements Serializable
+	{
+		@Override
+		public String transform(String string) {
+			return uncapitalize(string);
 		}
-	}
-
-	/**
-	 * Append the specified string to the specified string buffer
-	 * with its first letter converted to lower case.
-	 * (Unless both the first and second letters are upper case,
-	 * in which case the string is returned unchanged.)
-	 * <p>
-	 * <code>
-	 * String.uncapitalizeOn(StringBuffer)
-	 * </code>
-	 */
-	public static void uncapitalizeOn(String string, StringBuffer sb) {
-		if (stringNeedNotBeUncapitalized_(string)) {
-			sb.append(string);
-		} else {
-			uncapitalizeOn_(string.toCharArray(), sb);
-		}
-	}
-
-	/*
-	 * no zero-length check or lower case check
-	 */
-	private static void uncapitalizeOn_(char[] string, StringBuilder sb) {
-		sb.append(Character.toLowerCase(string[0]));
-		sb.append(string, 1, string.length - 1);
-	}
-
-	/**
-	 * Append the specified string to the specified string builder
-	 * with its first letter converted to lower case.
-	 * (Unless both the first and second letters are upper case,
-	 * in which case the string is returned unchanged.)
-	 */
-	public static void uncapitalizeOn(char[] string, StringBuilder sb) {
-		if (stringNeedNotBeUncapitalized_(string)) {
-			sb.append(string);
-		} else {
-			uncapitalizeOn_(string, sb);
-		}
-	}
-
-	/**
-	 * Append the specified string to the specified string builder
-	 * with its first letter converted to lower case.
-	 * (Unless both the first and second letters are upper case,
-	 * in which case the string is returned unchanged.)
-	 * <p>
-	 * <code>
-	 * String.uncapitalizeOn(StringBuffer)
-	 * </code>
-	 */
-	public static void uncapitalizeOn(String string, StringBuilder sb) {
-		if (stringNeedNotBeUncapitalized_(string)) {
-			sb.append(string);
-		} else {
-			uncapitalizeOn_(string.toCharArray(), sb);
-		}
-	}
-
-	/*
-	 * no zero-length check or upper case check
-	 */
-	private static void uncapitalizeOn_(char[] string, Writer writer) {
-		writeCharOn(Character.toLowerCase(string[0]), writer);
-		writeStringOn(string, 1, string.length - 1, writer);
-	}
-
-	/**
-	 * Append the specified string to the specified string buffer
-	 * with its first letter converted to lower case.
-	 * (Unless both the first and second letters are upper case,
-	 * in which case the string is returned unchanged.)
-	 */
-	public static void uncapitalizeOn(char[] string, Writer writer) {
-		if (stringNeedNotBeUncapitalized_(string)) {
-			writeStringOn(string, writer);
-		} else {
-			uncapitalizeOn_(string, writer);
-		}
-	}
-
-	/**
-	 * Append the specified string to the specified string buffer
-	 * with its first letter converted to lower case.
-	 * (Unless both the first and second letters are upper case,
-	 * in which case the string is returned unchanged.)
-	 * <p>
-	 * <code>
-	 * String.uncapitalizeOn(Writer)
-	 * </code>
-	 */
-	public static void uncapitalizeOn(String string, Writer writer) {
-		if (stringNeedNotBeUncapitalized_(string)) {
-			writeStringOn(string, writer);
-		} else {
-			uncapitalizeOn_(string.toCharArray(), writer);
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return UNCAPITALIZER;
 		}
 	}
 
 
-	// ********** toString() helper methods **********
+	// ********** string queries **********
 
 	/**
-	 * Build a "Dali standard" {@link Object#toString() toString()} result for
-	 * the specified object and additional information:<pre>
-	 *     ClassName[00-F3-EE-42](add'l info)
-	 * </pre>
-	 */
-	public static String buildToStringFor(Object o, Object additionalInfo) {
-		StringBuilder sb = new StringBuilder();
-		appendSimpleToString(sb, o);
-		sb.append('(');
-		sb.append(additionalInfo);
-		sb.append(')');
-		return sb.toString();
-	}
-
-	/**
-	 * Build a "Dali standard" {@link Object#toString() toString()} result for
-	 * the specified object:<pre>
-	 *     ClassName[00-F3-EE-42]
-	 * </pre>
-	 */
-	public static String buildToStringFor(Object o) {
-		StringBuilder sb = new StringBuilder();
-		appendSimpleToString(sb, o);
-		return sb.toString();
-	}
-
-	/**
-	 * Append a "Dali standard" {@link Object#toString() toString()} result for
-	 * the specified object to the specified string builder:<pre>
-	 *     ClassName[00-F3-EE-42]
-	 */
-	public static void appendSimpleToString(StringBuilder sb, Object o) {
-		appendToStringClassName(sb, o.getClass());
-		sb.append('[');
-		separateOn(buildHashCode(o), '-', 2, sb);
-		sb.append(']');
-	}
-
-	private static String buildHashCode(Object o) {
-		// use System.identityHashCode(Object), since Object.hashCode() may be overridden
-		return zeroPad(Integer.toHexString(System.identityHashCode(o)).toUpperCase(), 8);
-	}
-
-	/**
-	 * Returns a name suitable for a "Dali standard"
-	 * {@link Object#toString() toString()} implementation.
-	 * {@link Class#getSimpleName()} isn't quite useful enough:<ul>
-	 * <li>An <em>anonymous</em> class's simple name is an empty string.
-	 * Returns the "Dali standard" name of the anonymous class's super class
-	 *     instead, which is a bit more helpful.
-	 * <li>A <em>member</em> or <em>local</em> class's simple name does not
-	 *     include its context. Prefix the class's simple name with its
-	 *     enclosing class's "Dali standard" name.
-	 * </ul>
-	 */
-	public static String buildToStringClassName(Class<?> javaClass) {
-		StringBuilder sb = new StringBuilder();
-		appendToStringClassName(sb, javaClass);
-		return sb.toString();
-	}
-
-	/**
-	 * Returns a string suitable for a <em>singleton</em>; which is the simple
-	 * name of the object's class, since there should only be one.
-	 */
-	public static String buildSingletonToString(Object o) {
-		return buildToStringClassName(o.getClass());
-	}
-
-	/**
-	 * Append a name suitable for a "Dali standard"
-	 * {@link Object#toString() toString()} implementation to the specified
-	 * string builder.
-	 * @see #buildToStringClassName(Class)
-	 */
-	public static void appendToStringClassName(StringBuilder sb, Class<?> javaClass) {
-		if (javaClass.isAnonymousClass()) {
-			appendToStringClassName(sb, javaClass.getSuperclass());  // recurse
-		} else {
-			Class<?> enclosingClass = javaClass.getEnclosingClass();
-			if (enclosingClass == null) {
-				appendToStringClassName_(sb, javaClass);  // top-level class
-			} else {
-				appendToStringClassName(sb, enclosingClass);  // recurse
-				sb.append('.');
-				sb.append(javaClass.getSimpleName());
-			}
-		}
-	}
-
-	/**
-	 * pre-condition: the specified class is a top-level class
-	 */
-	private static void appendToStringClassName_(StringBuilder sb, Class<?> javaClass) {
-		String fullName = javaClass.getName();
-		int dot = fullName.lastIndexOf('.');
-		if (dot == -1) {
-			sb.append(fullName);  // "default" package
-		} else {
-			sb.append(fullName, dot + 1, fullName.length());
-		}
-	}
-
-	/**
-	 * Append the string representations of the objects in the specified array
-	 * to the specified string builder:<pre>
-	 *     ["foo", "bar", "baz"]
-	 * </pre>
-	 * <p>
-	 * <code>
-	 * StringBuilder.append(Object[])
-	 * </code>
-	 */
-	public static <T> String append(StringBuilder sb, T[] array) {
-		return append(sb, new ArrayListIterator<T>(array));
-	}
-
-	/**
-	 * Append the string representations of the objects in the specified iterable
-	 * to the specified string builder:<pre>
-	 *     ["foo", "bar", "baz"]
-	 * </pre>
-	 * <p>
-	 * <code>
-	 * StringBuilder.append(Iterable)
-	 * </code>
-	 */
-	public static <T> String append(StringBuilder sb, Iterable<T> iterable) {
-		return append(sb, iterable.iterator());
-	}
-
-	/**
-	 * Append the string representations of the objects in the specified iterator
-	 * to the specified string builder:<pre>
-	 *     ["foo", "bar", "baz"]
-	 * </pre>
-	 * <p>
-	 * <code>
-	 * StringBuilder.append(Iterator)
-	 * </code>
-	 */
-	public static <T> String append(StringBuilder sb, Iterator<T> iterator) {
-		sb.append('[');
-		while (iterator.hasNext()) {
-			sb.append(iterator.next());
-			if (iterator.hasNext()) {
-				sb.append(", ");
-			}
-		}
-		sb.append(']');
-		return sb.toString();
-	}
-
-	/**
-	 * Returns a concatenation of the given strings
-	 *
-	 * @param strings - the strings to concatenate
-	 * @return the resultant concatenated string
-	 */
-	public static String concatenate(String ... strings) {
-		StringBuilder sb = new StringBuilder();
-		for (String string : strings) {
-			sb.append(string);
-		}
-		return sb.toString();
-	}
-
-
-	// ********** queries **********
-
-	/**
-	 * Returns whether the specified string is <code>null</code>, empty, or
+	 * Return whether the specified string is <code>null</code>, empty, or
 	 * contains only whitespace characters.
 	 */
-	public static boolean stringIsEmpty(String string) {
+	public static boolean isBlank(String string) {
 		if (string == null) {
 			return true;
 		}
-		int len = string.length();
-		if (len == 0) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
 			return true;
 		}
-		return stringIsEmpty_(string.toCharArray(), len);
+		return isBlank(string, stringLength);
 	}
 
 	/**
-	 * Returns whether the specified string is <code>null</code>, empty, or
-	 * contains only whitespace characters.
+	 * no <code>null</code> or length checks
 	 */
-	public static boolean stringIsEmpty(char[] string) {
-		if (string == null) {
-			return true;
-		}
-		int len = string.length;
-		if (len == 0) {
-			return true;
-		}
-		return stringIsEmpty_(string, len);
-	}
-
-	private static boolean stringIsEmpty_(char[] s, int len) {
-		for (int i = len; i-- > 0; ) {
-			if ( ! Character.isWhitespace(s[i])) {
+	private static boolean isBlank(String string, int stringLength) {
+		for (int i = stringLength; i-- > 0; ) {
+			if ( ! Character.isWhitespace(string.charAt(i))) {
 				return false;
 			}
 		}
@@ -4127,207 +819,123 @@
 	}
 
 	/**
-	 * Returns whether the specified string is non-<code>null</code>, non-empty,
+	 * Return whether the specified string is non-<code>null</code>, non-empty,
 	 * and does not contain only whitespace characters.
 	 */
-	public static boolean stringIsNotEmpty(String string) {
-		return ! stringIsEmpty(string);
+	public static boolean isNotBlank(String string) {
+		return ! isBlank(string);
 	}
 
 	/**
-	 * Returns whether the specified string is non-<code>null</code>, non-empty,
-	 * and does not contain only whitespace characters.
+	 * @see #isNotBlank(String)
 	 */
-	public static boolean stringIsNotEmpty(char[] string) {
-		return ! stringIsEmpty(string);
+	public static final Filter<String> NON_BLANK_FILTER = new NonBlankFilter();
+
+	/* CU private */ static class NonBlankFilter
+		extends Filter.Adapter<String>
+		implements Serializable
+	{
+		@Override
+		public boolean accept(String string) {
+			return isNotBlank(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return NON_BLANK_FILTER;
+		}
 	}
 
 	/**
-	 * Returns whether the specified strings are equal.
+	 * Return whether the specified strings are equal, ignoring case.
 	 * Check for <code>null</code>s.
 	 */
-	public static boolean stringsAreEqual(String s1, String s2) {
-		return Tools.valuesAreEqual(s1, s2);
+	public static boolean equalsIgnoreCase(String s1, String s2) {
+		return (s1 == null) ? (s2 == null) : s1.equalsIgnoreCase(s2);
 	}
 
 	/**
-	 * Returns whether the specified strings are equal.
-	 * Check for <code>null</code>s.
-	 */
-	public static boolean stringsAreEqual(char[] s1, char[] s2) {
-		return (s1 == null) ?
-				(s2 == null) :
-				((s2 != null) && stringsAreEqual_(s1, s2));
-	}
-
-	/**
-	 * no <code>null</code> checks
-	 */
-	private static boolean stringsAreEqual_(char[] s1, char[] s2) {
-		int len = s1.length;
-		if (len != s2.length) {
-			return false;
-		}
-		for (int i = len; i-- > 0; ) {
-			if (s1[i] != s2[i]) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	/**
-	 * Returns whether the specified strings are equal, ignoring case.
-	 * Check for <code>null</code>s.
-	 */
-	public static boolean stringsAreEqualIgnoreCase(String s1, String s2) {
-		return (s1 == null) ?
-				(s2 == null) :
-				((s2 != null) && s1.equalsIgnoreCase(s2));
-	}
-
-	/**
-	 * Returns whether the specified strings are equal, ignoring case.
-	 * Check for <code>null</code>s.
-	 */
-	public static boolean stringsAreEqualIgnoreCase(char[] s1, char[] s2) {
-		return (s1 == null) ?
-				(s2 == null) :
-				((s2 != null) && stringsAreEqualIgnoreCase_(s1, s2));
-	}
-
-	/**
-	 * no <code>null</code> checks
-	 */
-	private static boolean stringsAreEqualIgnoreCase_(char[] s1, char[] s2) {
-		int len = s1.length;
-		if (len != s2.length) {
-			return false;
-		}
-		for (int i = len; i-- > 0; ) {
-			if ( ! charactersAreEqualIgnoreCase(s1[i], s2[i])) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	/**
-	 * Returns whether the specified string starts with the specified prefix,
+	 * Return whether the specified string starts with the specified prefix,
 	 * ignoring case.
+	 * @see String#regionMatches(boolean, int, String, int, int)
 	 */
-	public static boolean stringStartsWithIgnoreCase(char[] string, char[] prefix) {
-		int prefixLength = prefix.length;
-		if (string.length < prefixLength) {
-			return false;
-		}
-		for (int i = prefixLength; i-- > 0; ) {
-			if ( ! charactersAreEqualIgnoreCase(string[i], prefix[i])) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	/**
-	 * Returns whether the specified string starts with the specified prefix,
-	 * ignoring case.
-	 */
-	public static boolean stringStartsWithIgnoreCase(String string, String prefix) {
+	public static boolean startsWithIgnoreCase(String string, String prefix) {
 		return string.regionMatches(true, 0, prefix, 0, prefix.length());
 	}
 
 	/**
-	 * Returns whether the specified characters are are equal, ignoring case.
-	 * @see String#regionMatches(boolean, int, String, int, int)
+	 * Return whether the specified string is uppercase.
 	 */
-	public static boolean charactersAreEqualIgnoreCase(char c1, char c2) {
-		//  something about the Georgian alphabet requires us to check lower case also
-		return (c1 == c2)
-				|| (Character.toUpperCase(c1) == Character.toUpperCase(c2))
-				|| (Character.toLowerCase(c1) == Character.toLowerCase(c2));
+	public static boolean isUppercase(String string) {
+		return (string.length() != 0) && isUppercase_(string);
 	}
 
 	/**
-	 * Returns whether the specified string is uppercase.
+	 * no length check
 	 */
-	public static boolean stringIsUppercase(String string) {
-		return (string.length() == 0) ? false : stringIsUppercase_(string);
-	}
-
-	/**
-	 * Returns whether the specified string is uppercase.
-	 */
-	public static boolean stringIsUppercase(char[] string) {
-		return (string.length == 0) ? false : stringIsUppercase_(new String(string));
-	}
-
-	private static boolean stringIsUppercase_(String string) {
+	static boolean isUppercase_(String string) {
 		return string.equals(string.toUpperCase());
 	}
 
 	/**
-	 * Returns whether the specified string is lowercase.
+	 * Return whether the specified string is lowercase.
 	 */
-	public static boolean stringIsLowercase(String string) {
-		return (string.length() == 0) ? false : stringIsLowercase_(string);
+	public static boolean isLowercase(String string) {
+		return (string.length() != 0) && isLowercase_(string);
 	}
 
 	/**
-	 * Returns whether the specified string is lowercase.
+	 * no length check
 	 */
-	public static boolean stringIsLowercase(char[] string) {
-		return (string.length == 0) ? false : stringIsLowercase_(new String(string));
-	}
-
-	private static boolean stringIsLowercase_(String string) {
+	static boolean isLowercase_(String string) {
 		return string.equals(string.toLowerCase());
 	}
 
-	// ********** convert all caps to cable back **********
-	
+
+	// ********** byte arrays **********
+
 	/**
-	 * Convert the specified "all caps" string to a "camel back" string:
-	 * "LARGE_PROJECT" -> "largeProject"
-	 * Optionally capitalize the first letter.
+	 * Convert the specified string of hexadecimal characters to a byte array.
+	 * @see ByteArrayTools#convertToHexString(byte[])
 	 */
-	public static String convertAllCapsToCamelBack(String allCapsString, boolean capitalizeFirstLetter) {
-		return convertAllCapsToCamelBack(allCapsString, '_', capitalizeFirstLetter);
+	public static byte[] convertHexStringToByteArray(String hexString) {
+		int hexStringLength = hexString.length();
+		if (hexStringLength == 0) {
+			return ByteArrayTools.EMPTY_BYTE_ARRAY;
+		}
+		if (BitTools.isOdd(hexStringLength)) {
+			throw new IllegalArgumentException("Odd-sized hexadecimal string: " + hexString + " (" + hexStringLength + " characters)"); //$NON-NLS-3$
+		}
+		return convertHexStringToByteArray(hexString, hexStringLength);
 	}
 
 	/**
-	 * Convert the specified "all caps" string to a "camel back" string:
-	 * "LARGE_PROJECT" -> "largeProject"
-	 * Optionally capitalize the first letter.
+	 * Pre-condition: the string is neither empty nor odd-sized
 	 */
-	public static String convertAllCapsToCamelBack(String allCapsString, char delimitor, boolean capitalizeFirstLetter) {
-		int len = allCapsString.length();
-		if (len == 0) {
-			return EMPTY_STRING;
-		}
-		char prev = 0;
-		char c = 0;
-		StringBuilder sb = new StringBuilder(len);
-		for (int i = 0; i < len; i++) {	// NB: start at 1
-			prev = c;
-			c = allCapsString.charAt(i);
-			if (c == delimitor) {
-				continue;
+	private static byte[] convertHexStringToByteArray(String hexString, int hexStringLength) {
+		byte[] bytes = new byte[BitTools.half(hexStringLength)];
+		for (int bi = bytes.length - 1, si = hexStringLength - 2; bi >= 0; bi--, si -= 2) {
+			byte digit1 = (byte) Character.digit(hexString.charAt(si), 16);
+			if (digit1 == -1) {
+				throw new IllegalArgumentException(buildIllegalHexCharMessage(hexString, si));
 			}
-			if (sb.length() == 0) {
-				if (capitalizeFirstLetter) {
-					sb.append(Character.toUpperCase(c));
-				} else {
-					sb.append(Character.toLowerCase(c));
-				}
-			} else {
-				if (prev == delimitor) {
-					sb.append(Character.toUpperCase(c));
-				} else {
-					sb.append(Character.toLowerCase(c));
-				}
+			byte digit2 = (byte) Character.digit(hexString.charAt(si + 1), 16);
+			if (digit2 == -1) {
+				throw new IllegalArgumentException(buildIllegalHexCharMessage(hexString, si + 1));
 			}
+			bytes[bi] = (byte) ((digit1 << 4) + digit2);
 		}
+		return bytes;
+	}
+
+	static String buildIllegalHexCharMessage(String hexString, int index) {
+		StringBuilder sb = new StringBuilder(hexString.length() + 40);
+		sb.append("Illegal hexadecimal character: ");
+		sb.append(hexString, 0, index);
+		sb.append('[');
+		sb.append(hexString.charAt(index));
+		sb.append(']');
+		sb.append(hexString, index + 1, hexString.length());
 		return sb.toString();
 	}
 
@@ -4336,329 +944,74 @@
 
 	/**
 	 * Convert the specified "camel case" string to an "all caps" string:
+	 * <p>
+	 * <code>
 	 * "largeProject" -> "LARGE_PROJECT"
+	 * </code>
 	 */
 	public static String convertCamelCaseToAllCaps(String camelCaseString) {
-		int len = camelCaseString.length();
-		if (len == 0) {
-			return camelCaseString;
-		}
-		return new String(convertCamelCaseToAllCaps_(camelCaseString.toCharArray(), len));
+		int stringLength = camelCaseString.length();
+		return (stringLength == 0) ?
+				camelCaseString :
+				convertCamelCaseToAllCaps_(camelCaseString, stringLength);
 	}
 
 	/**
-	 * Convert the specified "camel case" string to an "all caps" string:
-	 * "largeProject" -> "LARGE_PROJECT"
+	 * no length check
 	 */
-	public static char[] convertCamelCaseToAllCaps(char[] camelCaseString) {
-		int len = camelCaseString.length;
-		if (len == 0) {
-			return camelCaseString;
-		}
-		return convertCamelCaseToAllCaps_(camelCaseString, len);
-	}
-
-	private static char[] convertCamelCaseToAllCaps_(char[] camelCaseString, int len) {
-		StringBuilder sb = new StringBuilder(len * 2);
-		convertCamelCaseToAllCapsOn_(camelCaseString, len, sb);
-		return convertToCharArray(sb);
+	private static String convertCamelCaseToAllCaps_(String camelCaseString, int stringLength) {
+		StringBuilder sb = new StringBuilder(stringLength + (stringLength / 4));
+		StringBuilderTools.convertCamelCaseToAllCaps_(sb, camelCaseString, stringLength);
+		return sb.toString();
 	}
 
 	/**
 	 * Convert the specified "camel case" string to an "all caps" string:
+	 * <p>
+	 * <code>
 	 * "largeProject" -> "LARGE_PROJECT"
-	 */
-	public static void convertCamelCaseToAllCapsOn(String camelCaseString, StringBuffer sb) {
-		int len = camelCaseString.length();
-		if (len != 0) {
-			convertCamelCaseToAllCapsOn_(camelCaseString.toCharArray(), len, sb);
-		}
-	}
-
-	/**
-	 * Convert the specified "camel case" string to an "all caps" string:
-	 * "largeProject" -> "LARGE_PROJECT"
-	 */
-	public static void convertCamelCaseToAllCapsOn(char[] camelCaseString, StringBuffer sb) {
-		int len = camelCaseString.length;
-		if (len != 0) {
-			convertCamelCaseToAllCapsOn_(camelCaseString, len, sb);
-		}
-	}
-
-	private static void convertCamelCaseToAllCapsOn_(char[] camelCaseString, int len, StringBuffer sb) {
-		char prev = 0;	// assume 0 is not a valid char
-		char c = 0;
-		char next = camelCaseString[0];
-		for (int i = 1; i <= len; i++) {	// NB: start at 1 and end at len!
-			c = next;
-			next = ((i == len) ? 0 : camelCaseString[i]);
-			if (camelCaseWordBreak_(prev, c, next)) {
-				sb.append('_');
-			}
-			sb.append(Character.toUpperCase(c));
-			prev = c;
-		}
-	}
-
-	/**
-	 * Convert the specified "camel case" string to an "all caps" string:
-	 * "largeProject" -> "LARGE_PROJECT"
-	 */
-	public static void convertCamelCaseToAllCapsOn(String camelCaseString, StringBuilder sb) {
-		int len = camelCaseString.length();
-		if (len != 0) {
-			convertCamelCaseToAllCapsOn_(camelCaseString.toCharArray(), len, sb);
-		}
-	}
-
-	/**
-	 * Convert the specified "camel case" string to an "all caps" string:
-	 * "largeProject" -> "LARGE_PROJECT"
-	 */
-	public static void convertCamelCaseToAllCapsOn(char[] camelCaseString, StringBuilder sb) {
-		int len = camelCaseString.length;
-		if (len != 0) {
-			convertCamelCaseToAllCapsOn_(camelCaseString, len, sb);
-		}
-	}
-
-	private static void convertCamelCaseToAllCapsOn_(char[] camelCaseString, int len, StringBuilder sb) {
-		char prev = 0;	// assume 0 is not a valid char
-		char c = 0;
-		char next = camelCaseString[0];
-		for (int i = 1; i <= len; i++) {	// NB: start at 1 and end at len!
-			c = next;
-			next = ((i == len) ? 0 : camelCaseString[i]);
-			if (camelCaseWordBreak_(prev, c, next)) {
-				sb.append('_');
-			}
-			sb.append(Character.toUpperCase(c));
-			prev = c;
-		}
-	}
-
-	/**
-	 * Convert the specified "camel case" string to an "all caps" string:
-	 * "largeProject" -> "LARGE_PROJECT"
-	 */
-	public static void convertCamelCaseToAllCapsOn(String camelCaseString, Writer writer) {
-		int len = camelCaseString.length();
-		if (len != 0) {
-			convertCamelCaseToAllCapsOn_(camelCaseString.toCharArray(), len, writer);
-		}
-	}
-
-	/**
-	 * Convert the specified "camel case" string to an "all caps" string:
-	 * "largeProject" -> "LARGE_PROJECT"
-	 */
-	public static void convertCamelCaseToAllCapsOn(char[] camelCaseString, Writer writer) {
-		int len = camelCaseString.length;
-		if (len != 0) {
-			convertCamelCaseToAllCapsOn_(camelCaseString, len, writer);
-		}
-	}
-
-	private static void convertCamelCaseToAllCapsOn_(char[] camelCaseString, int len, Writer writer) {
-		char prev = 0;	// assume 0 is not a valid char
-		char c = 0;
-		char next = camelCaseString[0];
-		for (int i = 1; i <= len; i++) {	// NB: start at 1 and end at len!
-			c = next;
-			next = ((i == len) ? 0 : camelCaseString[i]);
-			if (camelCaseWordBreak_(prev, c, next)) {
-				writeCharOn('_', writer);
-			}
-			writeCharOn(Character.toUpperCase(c), writer);
-			prev = c;
-		}
-	}
-
-	/**
-	 * Convert the specified "camel case" string to an "all caps" string:
-	 * "largeProject" -> "LARGE_PROJECT"
+	 * </code>
+	 * <p>
 	 * Limit the resulting string to the specified maximum length.
 	 */
 	public static String convertCamelCaseToAllCaps(String camelCaseString, int maxLength) {
-		int len = camelCaseString.length();
-		if ((len == 0) || (maxLength == 0)) {
-			return camelCaseString;
+		if (maxLength == 0) {
+			return EMPTY_STRING;
 		}
-		return new String(convertCamelCaseToAllCaps_(camelCaseString.toCharArray(), maxLength, len));
+		int stringLength = camelCaseString.length();
+		return (stringLength == 0) ?
+				camelCaseString :
+				convertCamelCaseToAllCaps(camelCaseString, maxLength, stringLength);
 	}
 
 	/**
-	 * Convert the specified "camel case" string to an "all caps" string:
-	 * "largeProject" -> "LARGE_PROJECT"
-	 * Limit the resulting string to the specified maximum length.
+	 * no check for empty string or zero max length
 	 */
-	public static char[] convertCamelCaseToAllCaps(char[] camelCaseString, int maxLength) {
-		int len = camelCaseString.length;
-		if ((len == 0) || (maxLength == 0)) {
-			return camelCaseString;
-		}
-		return convertCamelCaseToAllCaps_(camelCaseString, maxLength, len);
-	}
-
-	private static char[] convertCamelCaseToAllCaps_(char[] camelCaseString, int maxLength, int len) {
+	private static String convertCamelCaseToAllCaps(String camelCaseString, int maxLength, int stringLength) {
 		StringBuilder sb = new StringBuilder(maxLength);
-		convertCamelCaseToAllCapsOn_(camelCaseString, maxLength, len, sb);
-		return convertToCharArray(sb);
+		StringBuilderTools.convertCamelCaseToAllCaps(sb, camelCaseString, maxLength, stringLength);
+		return sb.toString();
 	}
 
 	/**
-	 * Convert the specified "camel case" string to an "all caps" string:
-	 * "largeProject" -> "LARGE_PROJECT"
-	 * Limit the resulting string to the specified maximum length.
+	 * Return whether the specified series of characters occur at
+	 * a "camel case" work break:<ul>
+	 * <code>
+	 * <li>"*aa" -> false
+	 * <li>"*AA" -> false
+	 * <li>"*Aa" -> false
+	 * <li>"AaA" -> false
+	 * <li>"AAA" -> false
+	 * <li>"aa*" -> false
+	 * <li>"AaA" -> false
+	 * <li>"aAa" -> true
+	 * <li>"AA*" -> false
+	 * <li>"AAa" -> true
+	 * </code>
+	 * </ul>
+	 * where <code>'*' == &lt;any char&gt;</code>
 	 */
-	public static void convertCamelCaseToAllCapsOn(String camelCaseString, int maxLength, StringBuffer sb) {
-		int len = camelCaseString.length();
-		if ((len != 0) && (maxLength != 0)) {
-			convertCamelCaseToAllCapsOn_(camelCaseString.toCharArray(), maxLength, len, sb);
-		}
-	}
-
-	/**
-	 * Convert the specified "camel case" string to an "all caps" string:
-	 * "largeProject" -> "LARGE_PROJECT"
-	 * Limit the resulting string to the specified maximum length.
-	 */
-	public static void convertCamelCaseToAllCapsOn(char[] camelCaseString, int maxLength, StringBuffer sb) {
-		int len = camelCaseString.length;
-		if ((len != 0) && (maxLength != 0)) {
-			convertCamelCaseToAllCapsOn_(camelCaseString, maxLength, len, sb);
-		}
-	}
-
-	private static void convertCamelCaseToAllCapsOn_(char[] camelCaseString, int maxLength, int len, StringBuffer sb) {
-		char prev = 0;	// assume 0 is not a valid char
-		char c = 0;
-		char next = camelCaseString[0];
-		for (int i = 1; i <= len; i++) {	// NB: start at 1 and end at len!
-			c = next;
-			next = ((i == len) ? 0 : camelCaseString[i]);
-			if (camelCaseWordBreak_(prev, c, next)) {
-				sb.append('_');
-				if (sb.length() == maxLength) {
-					return;
-				}
-			}
-			sb.append(Character.toUpperCase(c));
-			if (sb.length() == maxLength) {
-				return;
-			}
-			prev = c;
-		}
-	}
-
-	/**
-	 * Convert the specified "camel case" string to an "all caps" string:
-	 * "largeProject" -> "LARGE_PROJECT"
-	 * Limit the resulting string to the specified maximum length.
-	 */
-	public static void convertCamelCaseToAllCapsOn(String camelCaseString, int maxLength, StringBuilder sb) {
-		int len = camelCaseString.length();
-		if ((len != 0) && (maxLength != 0)) {
-			convertCamelCaseToAllCapsOn_(camelCaseString.toCharArray(), maxLength, len, sb);
-		}
-	}
-
-	/**
-	 * Convert the specified "camel case" string to an "all caps" string:
-	 * "largeProject" -> "LARGE_PROJECT"
-	 * Limit the resulting string to the specified maximum length.
-	 */
-	public static void convertCamelCaseToAllCapsOn(char[] camelCaseString, int maxLength, StringBuilder sb) {
-		int len = camelCaseString.length;
-		if ((len != 0) && (maxLength != 0)) {
-			convertCamelCaseToAllCapsOn_(camelCaseString, maxLength, len, sb);
-		}
-	}
-
-	private static void convertCamelCaseToAllCapsOn_(char[] camelCaseString, int maxLength, int len, StringBuilder sb) {
-		char prev = 0;	// assume 0 is not a valid char
-		char c = 0;
-		char next = camelCaseString[0];
-		for (int i = 1; i <= len; i++) {	// NB: start at 1 and end at len!
-			c = next;
-			next = ((i == len) ? 0 : camelCaseString[i]);
-			if (camelCaseWordBreak_(prev, c, next)) {
-				sb.append('_');
-				if (sb.length() == maxLength) {
-					return;
-				}
-			}
-			sb.append(Character.toUpperCase(c));
-			if (sb.length() == maxLength) {
-				return;
-			}
-			prev = c;
-		}
-	}
-
-	/**
-	 * Convert the specified "camel case" string to an "all caps" string:
-	 * "largeProject" -> "LARGE_PROJECT"
-	 * Limit the resulting string to the specified maximum length.
-	 */
-	public static void convertCamelCaseToAllCapsOn(String camelCaseString, int maxLength, Writer writer) {
-		int len = camelCaseString.length();
-		if ((len != 0) && (maxLength != 0)) {
-			convertCamelCaseToAllCapsOn_(camelCaseString.toCharArray(), maxLength, len, writer);
-		}
-	}
-
-	/**
-	 * Convert the specified "camel case" string to an "all caps" string:
-	 * "largeProject" -> "LARGE_PROJECT"
-	 * Limit the resulting string to the specified maximum length.
-	 */
-	public static void convertCamelCaseToAllCapsOn(char[] camelCaseString, int maxLength, Writer writer) {
-		int len = camelCaseString.length;
-		if ((len != 0) && (maxLength != 0)) {
-			convertCamelCaseToAllCapsOn_(camelCaseString, maxLength, len, writer);
-		}
-	}
-
-	private static void convertCamelCaseToAllCapsOn_(char[] camelCaseString, int maxLength, int len, Writer writer) {
-		char prev = 0;	// assume 0 is not a valid char
-		char c = 0;
-		char next = camelCaseString[0];
-		int writerLength = 0;
-		for (int i = 1; i <= len; i++) {	// NB: start at 1 and end at len!
-			c = next;
-			next = ((i == len) ? 0 : camelCaseString[i]);
-			if (camelCaseWordBreak_(prev, c, next)) {
-				writeCharOn('_', writer);
-				if (++writerLength == maxLength) {
-					return;
-				}
-			}
-			writeCharOn(Character.toUpperCase(c), writer);
-			if (++writerLength == maxLength) {
-				return;
-			}
-			prev = c;
-		}
-	}
-
-	/*
-	 * Returns whether the specified series of characters occur at
-	 * a "camel case" work break:
-	 *     "*aa" -> false
-	 *     "*AA" -> false
-	 *     "*Aa" -> false
-	 *     "AaA" -> false
-	 *     "AAA" -> false
-	 *     "aa*" -> false
-	 *     "AaA" -> false
-	 *     "aAa" -> true
-	 *     "AA*" -> false
-	 *     "AAa" -> true
-	 * where '*' == any char
-	 */
-	private static boolean camelCaseWordBreak_(char prev, char c, char next) {
+	public static boolean camelCaseWordBreak(char prev, char c, char next) {
 		if (prev == 0) {	// start of string
 			return false;
 		}
@@ -4675,515 +1028,422 @@
 	}
 
 
-	// ********** convert underscores to camel case **********
+	// ********** convert all caps to camel case **********
 
 	/**
-	 * Convert the specified "underscore" string to a "camel case" string:
+	 * Convert the specified "all caps" string to a "camel case" string:
+	 * <p>
+	 * <code>
 	 * "LARGE_PROJECT" -> "LargeProject"
+	 * </code>
+	 * <p>
 	 * Capitalize the first letter.
 	 */
-	public static String convertUnderscoresToCamelCase(String underscoreString) {
-		return convertUnderscoresToCamelCase(underscoreString, true);
+	public static String convertAllCapsToCamelCase(String allCapsString) {
+		return convertAllCapsToCamelCase(allCapsString, true);  // true => capitalize first letter
 	}
 
 	/**
-	 * Convert the specified "underscore" string to a "camel case" string:
-	 * "LARGE_PROJECT" -> "LargeProject"
-	 * Capitalize the first letter.
-	 */
-	public static char[] convertUnderscoresToCamelCase(char[] underscoreString) {
-		return convertUnderscoresToCamelCase(underscoreString, true);
-	}
-
-	/**
-	 * Convert the specified "underscore" string to a "camel case" string:
+	 * Convert the specified "all caps" string to a "camel case" string:
+	 * <p>
+	 * <code>
 	 * "LARGE_PROJECT" -> "largeProject"
+	 * </code>
+	 * <p>
 	 * Optionally capitalize the first letter.
 	 */
-	public static String convertUnderscoresToCamelCase(String underscoreString, boolean capitalizeFirstLetter) {
-		int len = underscoreString.length();
-		if (len == 0) {
-			return underscoreString;
-		}
-		return new String(convertUnderscoresToCamelCase_(underscoreString.toCharArray(), capitalizeFirstLetter, len));
+	public static String convertAllCapsToCamelCase(String allCapsString, boolean capitalizeFirstLetter) {
+		int stringLength = allCapsString.length();
+		return (stringLength == 0) ?
+			allCapsString :
+			convertAllCapsToCamelCase(allCapsString, capitalizeFirstLetter, stringLength);
 	}
 
 	/**
-	 * Convert the specified "underscore" string to a "camel case" string:
-	 * "LARGE_PROJECT" -> "largeProject"
-	 * Optionally capitalize the first letter.
+	 * no length check
 	 */
-	public static char[] convertUnderscoresToCamelCase(char[] underscoreString, boolean capitalizeFirstLetter) {
-		int len = underscoreString.length;
-		if (len == 0) {
-			return underscoreString;
-		}
-		return convertUnderscoresToCamelCase_(underscoreString, capitalizeFirstLetter, len);
-	}
-
-	private static char[] convertUnderscoresToCamelCase_(char[] underscoreString, boolean capitalizeFirstLetter, int len) {
-		StringBuilder sb = new StringBuilder(len);
-		convertUnderscoresToCamelCaseOn_(underscoreString, capitalizeFirstLetter, len, sb);
-		return convertToCharArray(sb);
-	}
-
-	/**
-	 * Convert the specified "underscore" string to a "camel case" string:
-	 * "LARGE_PROJECT" -> "largeProject"
-	 * Optionally capitalize the first letter.
-	 */
-	public static void convertUnderscoresToCamelCaseOn(String underscoreString, boolean capitalizeFirstLetter, StringBuffer sb) {
-		int len = underscoreString.length();
-		if (len != 0) {
-			convertUnderscoresToCamelCaseOn_(underscoreString.toCharArray(), capitalizeFirstLetter, len, sb);
-		}
-	}
-
-	/**
-	 * Convert the specified "underscore" string to a "camel case" string:
-	 * "LARGE_PROJECT" -> "largeProject"
-	 * Optionally capitalize the first letter.
-	 */
-	public static void convertUnderscoresToCamelCaseOn(char[] underscoreString, boolean capitalizeFirstLetter, StringBuffer sb) {
-		int len = underscoreString.length;
-		if (len != 0) {
-			convertUnderscoresToCamelCaseOn_(underscoreString, capitalizeFirstLetter, len, sb);
-		}
-	}
-
-	private static void convertUnderscoresToCamelCaseOn_(char[] underscoreString, boolean capitalizeFirstLetter, int len, StringBuffer sb) {
-		char prev = 0;
-		char c = 0;
-		boolean first = true;
-		for (int i = 0; i < len; i++) {
-			prev = c;
-			c = underscoreString[i];
-			if (c == '_') {
-				continue;
-			}
-			if (first) {
-				first = false;
-				sb.append(capitalizeFirstLetter ? Character.toUpperCase(c) : Character.toLowerCase(c));
-			} else {
-				sb.append((prev == '_') ? Character.toUpperCase(c) : Character.toLowerCase(c));
-			}
-		}
-	}
-
-	/**
-	 * Convert the specified "underscore" string to a "camel case" string:
-	 * "LARGE_PROJECT" -> "largeProject"
-	 * Optionally capitalize the first letter.
-	 */
-	public static void convertUnderscoresToCamelCaseOn(String underscoreString, boolean capitalizeFirstLetter, StringBuilder sb) {
-		int len = underscoreString.length();
-		if (len != 0) {
-			convertUnderscoresToCamelCaseOn_(underscoreString.toCharArray(), capitalizeFirstLetter, len, sb);
-		}
-	}
-
-	/**
-	 * Convert the specified "underscore" string to a "camel case" string:
-	 * "LARGE_PROJECT" -> "largeProject"
-	 * Optionally capitalize the first letter.
-	 */
-	public static void convertUnderscoresToCamelCaseOn(char[] underscoreString, boolean capitalizeFirstLetter, StringBuilder sb) {
-		int len = underscoreString.length;
-		if (len != 0) {
-			convertUnderscoresToCamelCaseOn_(underscoreString, capitalizeFirstLetter, len, sb);
-		}
-	}
-
-	private static void convertUnderscoresToCamelCaseOn_(char[] underscoreString, boolean capitalizeFirstLetter, int len, StringBuilder sb) {
-		char prev = 0;
-		char c = 0;
-		boolean first = true;
-		for (int i = 0; i < len; i++) {
-			prev = c;
-			c = underscoreString[i];
-			if (c == '_') {
-				continue;
-			}
-			if (first) {
-				first = false;
-				sb.append(capitalizeFirstLetter ? Character.toUpperCase(c) : Character.toLowerCase(c));
-			} else {
-				sb.append((prev == '_') ? Character.toUpperCase(c) : Character.toLowerCase(c));
-			}
-		}
-	}
-
-	/**
-	 * Convert the specified "underscore" string to a "camel case" string:
-	 * "LARGE_PROJECT" -> "largeProject"
-	 * Optionally capitalize the first letter.
-	 */
-	public static void convertUnderscoresToCamelCaseOn(String underscoreString, boolean capitalizeFirstLetter, Writer writer) {
-		int len = underscoreString.length();
-		if (len != 0) {
-			convertUnderscoresToCamelCaseOn_(underscoreString.toCharArray(), capitalizeFirstLetter, len, writer);
-		}
-	}
-
-	/**
-	 * Convert the specified "underscore" string to a "camel case" string:
-	 * "LARGE_PROJECT" -> "largeProject"
-	 * Optionally capitalize the first letter.
-	 */
-	public static void convertUnderscoresToCamelCaseOn(char[] underscoreString, boolean capitalizeFirstLetter, Writer writer) {
-		int len = underscoreString.length;
-		if (len != 0) {
-			convertUnderscoresToCamelCaseOn_(underscoreString, capitalizeFirstLetter, len, writer);
-		}
-	}
-
-	private static void convertUnderscoresToCamelCaseOn_(char[] underscoreString, boolean capitalizeFirstLetter, int len, Writer writer) {
-		char prev = 0;
-		char c = 0;
-		boolean first = true;
-		for (int i = 0; i < len; i++) {
-			prev = c;
-			c = underscoreString[i];
-			if (c == '_') {
-				continue;
-			}
-			if (first) {
-				first = false;
-				writeCharOn(capitalizeFirstLetter ? Character.toUpperCase(c) : Character.toLowerCase(c), writer);
-			} else {
-				writeCharOn((prev == '_') ? Character.toUpperCase(c) : Character.toLowerCase(c), writer);
-			}
-		}
+	private static String convertAllCapsToCamelCase(String allCapsString, boolean capitalizeFirstLetter, int stringLength) {
+		StringBuilder sb = new StringBuilder(stringLength);
+		StringBuilderTools.convertAllCapsToCamelCase(sb, allCapsString, capitalizeFirstLetter, stringLength);
+		return sb.toString();
 	}
 
 
 	// ********** convert to Java string literal **********
 
+	/**
+	 * Value: {@value}
+	 */
 	public static final String EMPTY_JAVA_STRING_LITERAL = "\"\"";
-	public static final char[] EMPTY_JAVA_STRING_LITERAL_CHAR_ARRAY = EMPTY_JAVA_STRING_LITERAL.toCharArray();
 
+	/**
+	 * Convert the specified string to a Java string literal, with the
+	 * appropriate escaped characters.
+	 */
 	public static String convertToJavaStringLiteral(String string) {
-		int len = string.length();
-		if (len == 0) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
 			return EMPTY_JAVA_STRING_LITERAL;
 		}
-		StringBuilder sb = new StringBuilder(len + 5);
-		convertToJavaStringLiteralOn_(string.toCharArray(), sb, len);
+		StringBuilder sb = new StringBuilder(stringLength + 6);
+		StringBuilderTools.convertToJavaStringLiteral(sb, string, stringLength);
 		return sb.toString();
 	}
 
-	public static char[] convertToJavaStringLiteral(char[] string) {
-		int len = string.length;
-		if (len == 0) {
-			return EMPTY_JAVA_STRING_LITERAL_CHAR_ARRAY;
-		}
-		StringBuilder sb = new StringBuilder(len + 5);
-		convertToJavaStringLiteralOn_(string, sb, len);
-		len = sb.length();
-		char[] result = new char[len];
-		sb.getChars(0, len, result, 0);
-		return result;
-	}
+	/**
+	 * @see #convertToJavaStringLiteral(String)
+	 */
+	public static final Transformer<String, String> JAVA_STRING_LITERAL_TRANSFORMER = new JavaStringLiteralTransformer();
 
-	public static Iterable<String> convertToJavaStringLiterals(Iterable<String> strings) {
-		return new TransformationIterable<String, String>(strings, STRING_TO_JAVA_STRING_LITERAL_TRANSFORMER);
-	}
-
-	public static Iterator<String> convertToJavaStringLiterals(Iterator<String> strings) {
-		return new TransformationIterator<String, String>(strings, STRING_TO_JAVA_STRING_LITERAL_TRANSFORMER);
-	}
-
-	private static final Transformer<String, String> STRING_TO_JAVA_STRING_LITERAL_TRANSFORMER = new Transformer<String, String>() {
+	/* CU private */ static class JavaStringLiteralTransformer
+		extends TransformerAdapter<String, String>
+		implements Serializable
+	{
 		@Override
 		public String transform(String string) {
-			return StringTools.convertToJavaStringLiteral(string);
+			return convertToJavaStringLiteral(string);
 		}
-	};
-
-	// cannot name method simply 'convertToJavaStringLiterals' because of type-erasure...
-	public static Iterable<char[]> convertToJavaCharArrayLiterals(Iterable<char[]> strings) {
-		return new TransformationIterable<char[], char[]>(strings, CHAR_ARRAY_TO_JAVA_STRING_LITERAL_TRANSFORMER);
-	}
-
-	// cannot name method simply 'convertToJavaStringLiterals' because of type-erasure...
-	public static Iterator<char[]> convertToJavaCharArrayLiterals(Iterator<char[]> strings) {
-		return new TransformationIterator<char[], char[]>(strings, CHAR_ARRAY_TO_JAVA_STRING_LITERAL_TRANSFORMER);
-	}
-
-	private static final Transformer<char[], char[]> CHAR_ARRAY_TO_JAVA_STRING_LITERAL_TRANSFORMER = new Transformer<char[], char[]>() {
-		@Override
-		public char[] transform(char[] string) {
-			return StringTools.convertToJavaStringLiteral(string);
-		}
-	};
-
-	public static void convertToJavaStringLiteralOn(String string, StringBuffer sb) {
-		int len = string.length();
-		if (len == 0) {
-			sb.append(EMPTY_JAVA_STRING_LITERAL);
-		} else {
-			convertToJavaStringLiteralOn_(string.toCharArray(), sb, len);
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return JAVA_STRING_LITERAL_TRANSFORMER;
 		}
 	}
 
-	public static void convertToJavaStringLiteralOn(char[] string, StringBuffer sb) {
-		int len = string.length;
-		if (len == 0) {
-			sb.append(EMPTY_JAVA_STRING_LITERAL);
-		} else {
-			convertToJavaStringLiteralOn_(string, sb, len);
-		}
-	}
-
-	/*
-	 * no length checks
+	/**
+	 * Convert the specified string to the contents of a Java string literal,
+	 * with the appropriate escaped characters.
 	 */
-	private static void convertToJavaStringLiteralOn_(char[] string, StringBuffer sb, int len) {
-		sb.ensureCapacity(sb.length() + len + 5);
-		sb.append(QUOTE);
-		for (char c : string) {
-			switch (c) {
-				case '\b':  // backspace
-					sb.append("\\b");
-					break;
-				case '\t':  // horizontal tab
-					sb.append("\\t");
-					break;
-				case '\n':  // line-feed LF
-					sb.append("\\n");
-					break;
-				case '\f':  // form-feed FF
-					sb.append("\\f");
-					break;
-				case '\r':  // carriage-return CR
-					sb.append("\\r");
-					break;
-				case '"':  // double-quote
-					sb.append("\\\"");
-					break;
-//				case '\'':  // single-quote
-//					sb.append("\\'");
-//					break;
-				case '\\':  // backslash
-					sb.append("\\\\");
-					break;
-				default:
-					sb.append(c);
-					break;
-			}
+	public static String convertToJavaStringLiteralContent(String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			return EMPTY_STRING;
 		}
-		sb.append(QUOTE);
-	}
-
-	public static void convertToJavaStringLiteralOn(String string, StringBuilder sb) {
-		int len = string.length();
-		if (len == 0) {
-			sb.append(EMPTY_JAVA_STRING_LITERAL);
-		} else {
-			convertToJavaStringLiteralOn_(string.toCharArray(), sb, len);
-		}
-	}
-
-	public static void convertToJavaStringLiteralOn(char[] string, StringBuilder sb) {
-		int len = string.length;
-		if (len == 0) {
-			sb.append(EMPTY_JAVA_STRING_LITERAL);
-		} else {
-			convertToJavaStringLiteralOn_(string, sb, len);
-		}
-	}
-
-	/*
-	 * no length checks
-	 */
-	private static void convertToJavaStringLiteralOn_(char[] string, StringBuilder sb, int len) {
-		sb.ensureCapacity(sb.length() + len + 5);
-		sb.append(QUOTE);
-		for (char c : string) {
-			switch (c) {
-				case '\b':  // backspace
-					sb.append("\\b");
-					break;
-				case '\t':  // horizontal tab
-					sb.append("\\t");
-					break;
-				case '\n':  // line-feed LF
-					sb.append("\\n");
-					break;
-				case '\f':  // form-feed FF
-					sb.append("\\f");
-					break;
-				case '\r':  // carriage-return CR
-					sb.append("\\r");
-					break;
-				case '"':  // double-quote
-					sb.append("\\\"");
-					break;
-//				case '\'':  // single-quote
-//					sb.append("\\'");
-//					break;
-				case '\\':  // backslash
-					sb.append("\\\\");
-					break;
-				default:
-					sb.append(c);
-					break;
-			}
-		}
-		sb.append(QUOTE);
-	}
-
-	public static void convertToJavaStringLiteralOn(String string, Writer writer) {
-		if (string.length() == 0) {
-			writeStringOn(EMPTY_JAVA_STRING_LITERAL, writer);
-		} else {
-			convertToJavaStringLiteralOn_(string.toCharArray(), writer);
-		}
-	}
-
-	public static void convertToJavaStringLiteralOn(char[] string, Writer writer) {
-		if (string.length == 0) {
-			writeStringOn(EMPTY_JAVA_STRING_LITERAL, writer);
-		} else {
-			convertToJavaStringLiteralOn_(string, writer);
-		}
-	}
-
-	/*
-	 * no length checks
-	 */
-	private static void convertToJavaStringLiteralOn_(char[] string, Writer writer) {
-		writeCharOn(QUOTE, writer);
-		for (char c : string) {
-			switch (c) {
-				case '\b':  // backspace
-					writeStringOn("\\b", writer);
-					break;
-				case '\t':  // horizontal tab
-					writeStringOn("\\t", writer);
-					break;
-				case '\n':  // line-feed LF
-					writeStringOn("\\n", writer);
-					break;
-				case '\f':  // form-feed FF
-					writeStringOn("\\f", writer);
-					break;
-				case '\r':  // carriage-return CR
-					writeStringOn("\\r", writer);
-					break;
-				case '"':  // double-quote
-					writeStringOn("\\\"", writer);
-					break;
-//				case '\'':  // single-quote
-//					writeStringOn("\\'", writer);
-//					break;
-				case '\\':  // backslash
-					writeStringOn("\\\\", writer);
-					break;
-				default:
-					writeCharOn(c, writer);
-					break;
-			}
-		}
-		writeCharOn(QUOTE, writer);
-	}
-
-	// ********** convert to XML string literal **********
-
-	public static String convertToXmlStringLiteral(String string) {
-		int len = string.length();
-		if (len == 0) {
-			return EMPTY_JAVA_STRING_LITERAL;
-		}
-		StringBuilder sb = new StringBuilder(len + 5);
-		convertToXmlStringLiteralOn_(string.toCharArray(), sb, len);
+		StringBuilder sb = new StringBuilder(stringLength + 6);
+		StringBuilderTools.convertToJavaStringLiteralContent(sb, string, stringLength);
 		return sb.toString();
 	}
 
-	//TODO need to add the rest of the predifende entities to this switch (amp, apos, lt, and gt)
-	private static void convertToXmlStringLiteralOn_(char[] string, StringBuilder sb, int len) {
-		sb.ensureCapacity(sb.length() + len + 5);
-		sb.append(QUOTE);
-		for (char c : string) {
-			switch (c) {
-				case '"':  // double-quote
-					sb.append(XML_QUOTE);
-					break;
-				default:
-					sb.append(c);
-					break;
-			}
+	/**
+	 * @see #convertToJavaStringLiteralContent(String)
+	 */
+	public static final Transformer<String, String> JAVA_STRING_LITERAL_CONTENT_TRANSFORMER = new JavaStringLiteralContentTransformer();
+
+	/* CU private */ static class JavaStringLiteralContentTransformer
+		extends TransformerAdapter<String, String>
+		implements Serializable
+	{
+		@Override
+		public String transform(String string) {
+			return convertToJavaStringLiteralContent(string);
 		}
-		sb.append(QUOTE);
-	}
-
-
-	// ********** convenience **********
-
-	public static char[] convertToCharArray(StringBuffer sb) {
-		int len = sb.length();
-		char[] result = new char[len];
-		sb.getChars(0, len, result, 0);
-		return result;
-	}
-
-	public static char[] convertToCharArray(StringBuilder sb) {
-		int len = sb.length();
-		char[] result = new char[len];
-		sb.getChars(0, len, result, 0);
-		return result;
-	}
-
-	private static void writeStringOn(char[] string, Writer writer) {
-		try {
-			writer.write(string);
-		} catch (IOException ex) {
-			throw new RuntimeException(ex);
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return JAVA_STRING_LITERAL_CONTENT_TRANSFORMER;
 		}
 	}
 
-	private static void writeStringOn(char[] string, char escape, Writer writer) {
-		try {
-			for (char c : string) {
-				if (c == escape) {
-					writer.write(c);
-				}
-				writer.write(c);
-			}
-		} catch (IOException ex) {
-			throw new RuntimeException(ex);
+
+	// ********** convert to XML **********
+
+	public static final String EMPTY_DOUBLE_QUOTED_XML_ATTRIBUTE_VALUE = "\"\"";
+	public static final String EMPTY_SINGLE_QUOTED_XML_ATTRIBUTE_VALUE = "''";
+	public static final String EMPTY_XML_ATTRIBUTE_VALUE = EMPTY_DOUBLE_QUOTED_XML_ATTRIBUTE_VALUE;
+	public static final String XML_ELEMENT_CDATA_START = "<![CDATA[";
+	public static final String XML_ELEMENT_CDATA_END = "]]>";
+	public static final String EMPTY_XML_ELEMENT_CDATA = XML_ELEMENT_CDATA_START + XML_ELEMENT_CDATA_END;
+
+	// XML predefined entities
+	public static final String XML_QUOTE = "&quot;";
+	public static final String XML_AMP   = "&amp;";
+	public static final String XML_APOS  = "&apos;";
+	public static final String XML_LT    = "&lt;";
+	public static final String XML_GT    = "&gt;";
+
+	/**
+	 * Convert the specified string to an XML attribute value, escaping the
+	 * appropriate characters. Delimit with quotes (<code>"</code>) unless
+	 * there are <em>embedded</em> quotes (<em>and</em> no embedded
+	 * apostrophes); in which case, delimit with apostrophes (<code>'</code>).
+	 */
+	public static String convertToXmlAttributeValue(String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			return EMPTY_XML_ATTRIBUTE_VALUE;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 12);
+		StringBuilderTools.convertToXmlAttributeValue(sb, string, stringLength);
+		return sb.toString();
+	}
+
+	/**
+	 * @see #convertToXmlAttributeValue(String)
+	 */
+	public static final Transformer<String, String> XML_ATTRIBUTE_VALUE_TRANSFORMER = new XmlAttributeValueTransformer();
+
+	/* CU private */ static class XmlAttributeValueTransformer
+		extends TransformerAdapter<String, String>
+		implements Serializable
+	{
+		@Override
+		public String transform(String string) {
+			return convertToXmlAttributeValue(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return XML_ATTRIBUTE_VALUE_TRANSFORMER;
 		}
 	}
 
-	private static void writeStringOn(char[] string, int off, int len, Writer writer) {
-		try {
-			writer.write(string, off, len);
-		} catch (IOException ex) {
-			throw new RuntimeException(ex);
+	/**
+	 * Convert the specified string to a double-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * double quotes).
+	 * @see #convertToXmlAttributeValue(String)
+	 */
+	public static String convertToDoubleQuotedXmlAttributeValue(String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			return EMPTY_DOUBLE_QUOTED_XML_ATTRIBUTE_VALUE;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 12);
+		StringBuilderTools.convertToDoubleQuotedXmlAttributeValue(sb, string, stringLength);
+		return sb.toString();
+	}
+
+	/**
+	 * @see #convertToDoubleQuotedXmlAttributeValue(String)
+	 */
+	public static final Transformer<String, String> DOUBLE_QUOTED_XML_ATTRIBUTE_VALUE_TRANSFORMER = new DoubleQuotedXmlAttributeValueTransformer();
+
+	/* CU private */ static class DoubleQuotedXmlAttributeValueTransformer
+		extends TransformerAdapter<String, String>
+		implements Serializable
+	{
+		@Override
+		public String transform(String string) {
+			return convertToDoubleQuotedXmlAttributeValue(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return DOUBLE_QUOTED_XML_ATTRIBUTE_VALUE_TRANSFORMER;
 		}
 	}
 
-	private static void writeStringOn(String string, int off, int len, Writer writer) {
-		try {
-			writer.write(string, off, len);
-		} catch (IOException ex) {
-			throw new RuntimeException(ex);
+	/**
+	 * Convert the specified string to the contents of a double-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * double quotes).
+	 * @see #convertToXmlAttributeValue(String)
+	 */
+	public static String convertToDoubleQuotedXmlAttributeValueContent(String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			return EMPTY_STRING;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 10);
+		StringBuilderTools.convertToDoubleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		return sb.toString();
+	}
+
+	/**
+	 * @see #convertToDoubleQuotedXmlAttributeValueContent(String)
+	 */
+	public static final Transformer<String, String> XML_DOUBLE_QUOTED_ATTRIBUTE_VALUE_CONTENT_TRANSFORMER = new XmlDoubleQuotedAttributeValueContentTransformer();
+
+	/* CU private */ static class XmlDoubleQuotedAttributeValueContentTransformer
+		extends TransformerAdapter<String, String>
+		implements Serializable
+	{
+		@Override
+		public String transform(String string) {
+			return convertToDoubleQuotedXmlAttributeValueContent(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return XML_DOUBLE_QUOTED_ATTRIBUTE_VALUE_CONTENT_TRANSFORMER;
 		}
 	}
 
-	private static void writeStringOn(String string, Writer writer) {
-		try {
-			writer.write(string);
-		} catch (IOException ex) {
-			throw new RuntimeException(ex);
+	/**
+	 * Convert the specified string to a single-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * single quotes).
+	 * @see #convertToXmlAttributeValue(String)
+	 */
+	public static String convertToSingleQuotedXmlAttributeValue(String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			return EMPTY_SINGLE_QUOTED_XML_ATTRIBUTE_VALUE;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 12);
+		StringBuilderTools.convertToSingleQuotedXmlAttributeValue(sb, string, stringLength);
+		return sb.toString();
+	}
+
+	/**
+	 * @see #convertToSingleQuotedXmlAttributeValue(String)
+	 */
+	public static final Transformer<String, String> SINGLE_QUOTED_XML_ATTRIBUTE_VALUE_TRANSFORMER = new SingleQuotedXmlAttributeValueTransformer();
+
+	/* CU private */ static class SingleQuotedXmlAttributeValueTransformer
+		extends TransformerAdapter<String, String>
+		implements Serializable
+	{
+		@Override
+		public String transform(String string) {
+			return convertToSingleQuotedXmlAttributeValue(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return SINGLE_QUOTED_XML_ATTRIBUTE_VALUE_TRANSFORMER;
 		}
 	}
 
-	private static void writeCharOn(char c, Writer writer) {
-		try {
-			writer.write(c);
-		} catch (IOException ex) {
-			throw new RuntimeException(ex);
+	/**
+	 * Convert the specified string to the contents of a single-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * single quotes).
+	 * @see #convertToXmlAttributeValue(String)
+	 */
+	public static String convertToSingleQuotedXmlAttributeValueContent(String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			return EMPTY_STRING;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 10);
+		StringBuilderTools.convertToSingleQuotedXmlAttributeValueContent(sb, string, stringLength);
+		return sb.toString();
+	}
+
+	/**
+	 * @see #convertToSingleQuotedXmlAttributeValueContent(String)
+	 */
+	public static final Transformer<String, String> XML_SINGLE_QUOTED_ATTRIBUTE_VALUE_CONTENT_TRANSFORMER = new XmlSingleQuotedAttributeValueContentTransformer();
+
+	/* CU private */ static class XmlSingleQuotedAttributeValueContentTransformer
+		extends TransformerAdapter<String, String>
+		implements Serializable
+	{
+		@Override
+		public String transform(String string) {
+			return convertToSingleQuotedXmlAttributeValueContent(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return XML_SINGLE_QUOTED_ATTRIBUTE_VALUE_CONTENT_TRANSFORMER;
+		}
+	}
+
+	/**
+	 * Convert the specified string to an XML element text, escaping the
+	 * appropriate characters.
+	 * @see #convertToXmlElementCDATA(String)
+	 */
+	public static String convertToXmlElementText(String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			return string;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 8);
+		StringBuilderTools.convertToXmlElementText(sb, string, stringLength);
+		return sb.toString();
+	}
+
+	/**
+	 * @see #convertToXmlElementText(String)
+	 */
+	public static final Transformer<String, String> XML_ELEMENT_TEXT_TRANSFORMER = new XmlElementTextTransformer();
+
+	/* CU private */ static class XmlElementTextTransformer
+		extends TransformerAdapter<String, String>
+		implements Serializable
+	{
+		@Override
+		public String transform(String string) {
+			return convertToXmlElementText(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return XML_ELEMENT_TEXT_TRANSFORMER;
+		}
+	}
+
+	/**
+	 * Convert the specified string to an XML element CDATA, escaping the
+	 * appropriate characters.
+	 * @see #convertToXmlElementText(String)
+	 */
+	public static String convertToXmlElementCDATA(String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			return EMPTY_XML_ELEMENT_CDATA;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + EMPTY_XML_ELEMENT_CDATA.length() + 6);
+		StringBuilderTools.convertToXmlElementCDATA(sb, string, stringLength);
+		return sb.toString();
+	}
+
+	/**
+	 * @see #convertToXmlElementCDATA(String)
+	 */
+	public static final Transformer<String, String> XML_ELEMENT_CDATA_TRANSFORMER = new XmlElementCDATATransformer();
+
+	/* CU private */ static class XmlElementCDATATransformer
+		extends TransformerAdapter<String, String>
+		implements Serializable
+	{
+		@Override
+		public String transform(String string) {
+			return convertToXmlElementCDATA(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return XML_ELEMENT_CDATA_TRANSFORMER;
+		}
+	}
+
+	/**
+	 * Convert the specified string to the contents of an XML element CDATA,
+	 * escaping the appropriate characters.
+	 * @see #convertToXmlElementCDATA(String)
+	 * @see #convertToXmlElementText(String)
+	 */
+	public static String convertToXmlElementCDATAContent(String string) {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			return EMPTY_STRING;
+		}
+		StringBuilder sb = new StringBuilder(stringLength + 6);
+		StringBuilderTools.convertToXmlElementCDATAContent(sb, string, stringLength);
+		return sb.toString();
+	}
+
+	/**
+	 * @see #convertToXmlElementCDATAContent(String)
+	 */
+	public static final Transformer<String, String> XML_ELEMENT_CDATA_CONTENT_TRANSFORMER = new XmlElementCDATAContentTransformer();
+
+	/* CU private */ static class XmlElementCDATAContentTransformer
+		extends TransformerAdapter<String, String>
+		implements Serializable
+	{
+		@Override
+		public String transform(String string) {
+			return convertToXmlElementCDATAContent(string);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return XML_ELEMENT_CDATA_CONTENT_TRANSFORMER;
 		}
 	}
 
@@ -5197,4 +1457,4 @@
 		super();
 		throw new UnsupportedOperationException();
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedBag.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedBag.java
deleted file mode 100644
index 9d9f4ff..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedBag.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Iterator;
-
-/**
- * Thread-safe implementation of the {@link Bag} interface.
- */
-public class SynchronizedBag<E>
-	implements Bag<E>, Serializable
-{
-	/** Backing bag. */
-	private final Bag<E> bag;
-
-	/** Object to synchronize on. */
-	private final Object mutex;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct a synchronized bag that wraps the
-	 * specified bag and locks on the specified mutex.
-	 */
-	public SynchronizedBag(Bag<E> bag, Object mutex) {
-		super();
-		if (bag == null) {
-			throw new NullPointerException();
-		}
-		this.bag = bag;
-		this.mutex = mutex;
-	}
-
-	/**
-	 * Construct a synchronized bag that wraps the
-	 * specified bag and locks on itself.
-	 */
-	public SynchronizedBag(Bag<E> bag) {
-		super();
-		if (bag == null) {
-			throw new NullPointerException();
-		}
-		this.bag = bag;
-		this.mutex = this;
-	}
-
-	/**
-	 * Construct a synchronized bag that locks on the specified mutex.
-	 */
-	public SynchronizedBag(Object mutex) {
-		this(new HashBag<E>(), mutex);
-	}
-
-	/**
-	 * Construct a synchronized bag that locks on itself.
-	 */
-	public SynchronizedBag() {
-		this(new HashBag<E>());
-	}
-
-
-	// ********** Bag implementation **********
-
-	@Override
-	public boolean add(E o, int count) {
-		synchronized (this.mutex) {
-			return this.bag.add(o, count);
-		}
-	}
-
-	@Override
-	public int count(Object o) {
-		synchronized (this.mutex) {
-			return this.bag.count(o);
-		}
-	}
-
-	@Override
-	public Iterator<Bag.Entry<E>> entries() {
-		synchronized (this.mutex) {
-			return this.bag.entries();
-		}
-	}
-
-	@Override
-	public boolean remove(Object o, int count) {
-		synchronized (this.mutex) {
-			return this.bag.remove(o, count);
-		}
-	}
-
-	@Override
-	public int uniqueCount() {
-		synchronized (this.mutex) {
-			return this.bag.uniqueCount();
-		}
-	}
-
-	@Override
-	public Iterator<E> uniqueIterator() {
-		synchronized (this.mutex) {
-			return this.bag.uniqueIterator();
-		}
-	}
-
-
-	// ********** Collection implementation **********
-
-	@Override
-	public boolean add(E e) {
-		synchronized (this.mutex) {
-			return this.bag.add(e);
-		}
-	}
-
-	@Override
-	public boolean addAll(Collection<? extends E> c) {
-		synchronized (this.mutex) {
-			return this.bag.addAll(c);
-		}
-	}
-
-	@Override
-	public void clear() {
-		synchronized (this.mutex) {
-			this.bag.clear();
-		}
-	}
-
-	@Override
-	public boolean contains(Object o) {
-		synchronized (this.mutex) {
-			return this.bag.contains(o);
-		}
-	}
-
-	@Override
-	public boolean containsAll(Collection<?> c) {
-		synchronized (this.mutex) {
-			return this.bag.containsAll(c);
-		}
-	}
-
-	@Override
-	public boolean isEmpty() {
-		synchronized (this.mutex) {
-			return this.bag.isEmpty();
-		}
-	}
-
-	@Override
-	public Iterator<E> iterator() {
-		synchronized (this.mutex) {
-			return this.bag.iterator();
-		}
-	}
-
-	@Override
-	public boolean remove(Object o) {
-		synchronized (this.mutex) {
-			return this.bag.remove(o);
-		}
-	}
-
-	@Override
-	public boolean removeAll(Collection<?> c) {
-		synchronized (this.mutex) {
-			return this.bag.removeAll(c);
-		}
-	}
-
-	@Override
-	public boolean retainAll(Collection<?> c) {
-		synchronized (this.mutex) {
-			return this.bag.retainAll(c);
-		}
-	}
-
-	@Override
-	public int size() {
-		synchronized (this.mutex) {
-			return this.bag.size();
-		}
-	}
-
-	@Override
-	public Object[] toArray() {
-		synchronized (this.mutex) {
-			return this.bag.toArray();
-		}
-	}
-
-	@Override
-	public <T> T[] toArray(T[] a) {
-		synchronized (this.mutex) {
-			return this.bag.toArray(a);
-		}
-	}
-
-
-	// ********** additional public protocol **********
-
-	/**
-	 * Returns the object the stack locks on while performing
-	 * its operations.
-	 */
-	public Object getMutex() {
-		return this.mutex;
-	}
-
-
-	// ********** Object overrides **********
-
-	@Override
-	public String toString() {
-		synchronized (this.mutex) {
-			return this.bag.toString();
-		}
-	}
-
-	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
-		synchronized (this.mutex) {
-			s.defaultWriteObject();
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedBoolean.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedBoolean.java
deleted file mode 100644
index c6d0955..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedBoolean.java
+++ /dev/null
@@ -1,665 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-import org.eclipse.persistence.tools.utility.command.InterruptibleCommand;
-import org.eclipse.persistence.tools.utility.command.InterruptibleCommandExecutor;
-
-/**
- * This class provides synchronized access to a <code>boolean</code> value.
- * It also provides protocol for suspending a thread until the
- * <code>boolean</code> value is set to <code>true</code> or <code>false</code>,
- * with optional time-outs.
- * 
- * @see SimpleBooleanReference
- */
-public class SynchronizedBoolean
-	implements InterruptibleCommandExecutor, ModifiableBooleanReference, Cloneable, Serializable
-{
-	/** Backing <code>boolean</code>. */
-	private boolean value;
-
-	/** Object to synchronize on. */
-	private final Object mutex;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Create a synchronized <code>boolean</code> with the specified
-	 * initial value and mutex.
-	 */
-	public SynchronizedBoolean(boolean value, Object mutex) {
-		super();
-		this.value = value;
-		this.mutex = mutex;
-	}
-
-	/**
-	 * Create a synchronized <code>boolean</code> with the
-	 * specified initial value.
-	 * The synchronized <code>boolean</code> itself will be the mutex.
-	 */
-	public SynchronizedBoolean(boolean value) {
-		super();
-		this.value = value;
-		this.mutex = this;
-	}
-
-	/**
-	 * Create a synchronized <code>boolean</code>
-	 * with an initial value of <code>false</code>
-	 * and specified mutex.
-	 */
-	public SynchronizedBoolean(Object mutex) {
-		this(false, mutex);
-	}
-
-	/**
-	 * Create a synchronized <code>boolean</code>
-	 * with an initial value of <code>false</code>.
-	 * The synchronized <code>boolean</code> itself will be the mutex.
-	 */
-	public SynchronizedBoolean() {
-		this(false);
-	}
-
-
-	// ********** accessors **********
-
-	@Override
-	public boolean getValue() {
-		synchronized (this.mutex) {
-			return this.value;
-		}
-	}
-
-	@Override
-	public boolean is(boolean b) {
-		synchronized (this.mutex) {
-			return this.value == b;
-		}
-	}
-
-	@Override
-	public boolean isNot(boolean b) {
-		synchronized (this.mutex) {
-			return this.value != b;
-		}
-	}
-
-	@Override
-	public boolean isTrue() {
-		synchronized (this.mutex) {
-			return this.value;
-		}
-	}
-
-	@Override
-	public boolean isFalse() {
-		synchronized (this.mutex) {
-			return ! this.value;
-		}
-	}
-
-	/**
-	 * If the value changes, all waiting threads are notified.
-	 * Returns the <em>old</em> value.
-	 */
-	@Override
-	public boolean setValue(boolean value) {
-		synchronized (this.mutex) {
-			return (value == this.value) ? value : ! this.setChangedValue_(value);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized; new value is different
-	 * <br>
-	 * Returns the <em>new</em> value.
-	 */
-	private boolean setChangedValue_(boolean v) {
-		this.value = v;
-		this.mutex.notifyAll();
-		return v;
-	}
-
-	/**
-	 * If the value changes, all waiting threads are notified.
-	 * Returns the new value.
-	 */
-	@Override
-	public boolean flip() {
-		synchronized (this.mutex) {
-			return this.setChangedValue_( ! this.value);
-		}
-	}
-
-	/**
-	 * Returns the new value.
-	 * If the value changes, all waiting threads are notified.
-	 */
-	public boolean and(boolean b) {
-		synchronized (this.mutex) {
-			return this.setValue_(this.value & b);
-		}
-	}
-
-	/**
-	 * Returns the new value.
-	 * If the value changes, all waiting threads are notified.
-	 */
-	public boolean or(boolean b) {
-		synchronized (this.mutex) {
-			return this.setValue_(this.value | b);
-		}
-	}
-
-	/**
-	 * Returns the new value.
-	 * If the value changes, all waiting threads are notified.
-	 */
-	public boolean xor(boolean b) {
-		synchronized (this.mutex) {
-			return this.setValue_(this.value ^ b);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 * <br>
-	 * Returns the <em>new</em> value.
-	 */
-	private boolean setValue_(boolean v) {
-		return (v == this.value) ? v : this.setChangedValue_(v);
-	}
-
-	/**
-	 * If the value changes, all waiting threads are notified.
-	 */
-	@Override
-	public boolean setNot(boolean b) {
-		return this.setValue( ! b);
-	}
-
-	/**
-	 * If the value changes, all waiting threads are notified.
-	 */
-	@Override
-	public boolean setTrue() {
-		return this.setValue(true);
-	}
-
-	/**
-	 * If the value changes, all waiting threads are notified.
-	 */
-	@Override
-	public boolean setFalse() {
-		return this.setValue(false);
-	}
-
-	/**
-	 * Set the value to the specified new value if it is currently the specified
-	 * expected value. If the value changes, all waiting threads are notified.
-	 * Returns whether the commit was successful.
-	 */
-	public boolean commit(boolean expectedValue, boolean newValue) {
-		synchronized (this.mutex) {
-			boolean success = (this.value == expectedValue);
-			if (success) {
-				this.setValue_(newValue);
-			}
-			return success;
-		}
-	}
-
-	/**
-	 * Atomically swap the value of this synchronized boolean with the value of
-	 * the specified synchronized boolean. Make assumptions about the value of
-	 * <em>identity hash code</em> to avoid deadlock when two synchronized
-	 * booleans swap values with each other simultaneously.
-	 * If either value changes, the corresponding waiting threads are notified.
-	 * Returns the new value.
-	 */
-	public boolean swap(SynchronizedBoolean other) {
-		if (other == this) {
-			return this.getValue();
-		}
-		boolean thisFirst = System.identityHashCode(this) < System.identityHashCode(other);
-		SynchronizedBoolean first = thisFirst ? this : other;
-		SynchronizedBoolean second = thisFirst ? other : this;
-		synchronized (first.mutex) {
-			synchronized (second.mutex) {
-				boolean thisValue = this.value;
-				boolean otherValue = other.value;
-				if (thisValue == otherValue) {
-					return thisValue;  // nothing changes
-				}
-				other.setChangedValue_(thisValue);
-				return this.setChangedValue_(otherValue);
-			}
-		}
-	}
-
-	/**
-	 * Returns the object this object locks on while performing
-	 * its operations.
-	 */
-	public Object getMutex() {
-		return this.mutex;
-	}
-
-
-	// ********** indefinite waits **********
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value changes
-	 * to the specified value. If the <code>boolean</code> value is already the
-	 * Returns immediately.
-	 */
-	public void waitUntilValueIs(boolean b) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilValueIs_(b);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private void waitUntilValueIs_(boolean b) throws InterruptedException {
-		while (this.value != b) {
-			this.mutex.wait();
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value
-	 * changes to the NOT of the specified value.
-	 * If the <code>boolean</code> value is already the NOT of the specified
-	 * Returns immediately.
-	 */
-	public void waitUntilValueIsNot(boolean b) throws InterruptedException {
-		this.waitUntilValueIs( ! b);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value
-	 * changes to <code>true</code>.
-	 * If the <code>boolean</code> value is already <code>true</code>,
-	 * Returns immediately.
-	 */
-	public void waitUntilTrue() throws InterruptedException {
-		this.waitUntilValueIs(true);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value
-	 * changes to <code>false</code>.
-	 * If the <code>boolean</code> value is already <code>false</code>,
-	 * Returns immediately.
-	 */
-	public void waitUntilFalse() throws InterruptedException {
-		this.waitUntilValueIs(false);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value changes to
-	 * the NOT of the specified value, then change it back to the specified
-	 * value and continue executing. If the <code>boolean</code> value is already
-	 * the NOT of the specified value, set the value to the specified value
-	 * immediately.
-	 */
-	public void waitToSetValue(boolean b) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilValueIs_( ! b);
-			this.setChangedValue_(b);
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value
-	 * changes to <code>false</code>,
-	 * then change it back to <code>true</code> and continue executing.
-	 * If the <code>boolean</code> value is already <code>false</code>,
-	 * set the value to <code>true</code> immediately.
-	 */
-	public void waitToSetTrue() throws InterruptedException {
-		this.waitToSetValue(true);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value
-	 * changes to <code>true</code>,
-	 * then change it back to <code>false</code> and continue executing.
-	 * If the <code>boolean</code> value is already <code>true</code>,
-	 * set the value to <code>false</code> immediately.
-	 */
-	public void waitToSetFalse() throws InterruptedException {
-		this.waitToSetValue(false);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value
-	 * changes to the specified value,
-	 * then execute the specified command.
-	 * If the <code>boolean</code> value is already equal to the specified
-	 * value, execute the specified command immediately.
-	 */
-	public void whenEqual(boolean b, InterruptibleCommand command) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilValueIs_(b);
-			command.execute();
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value
-	 * changes to the NOT of the specified value,
-	 * then execute the specified command.
-	 * If the <code>boolean</code> value is already the NOT of the specified
-	 * value, execute the specified command immediately.
-	 */
-	public void whenNotEqual(boolean b, InterruptibleCommand command) throws InterruptedException {
-		this.whenEqual( ! b, command);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value
-	 * changes to <code>true</code>,
-	 * then execute the specified command.
-	 * If the <code>boolean</code> value is already <code>true</code>,
-	 * execute the specified command immediately.
-	 */
-	public void whenTrue(InterruptibleCommand command) throws InterruptedException {
-		this.whenEqual(true, command);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value
-	 * changes to <code>false</code>,
-	 * then execute the specified command.
-	 * If the <code>boolean</code> value is already <code>false</code>,
-	 * execute the specified command immediately.
-	 */
-	public void whenFalse(InterruptibleCommand command) throws InterruptedException {
-		this.whenEqual(false, command);
-	}
-
-
-	// ********** timed waits **********
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value changes
-	 * to the specified value or the specified time-out occurs.
-	 * Returns <code>true</code> if
-	 * the specified value was achieved;
-	 * Returns <code>false</code> if a time-out occurred.
-	 * If the <code>boolean</code> value is already the specified value,
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilValueIs(boolean b, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			return this.waitUntilValueIs_(b, timeout);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private boolean waitUntilValueIs_(boolean b, long timeout) throws InterruptedException {
-		if (timeout == 0L) {
-			this.waitUntilValueIs_(b);	// wait indefinitely until notified
-			return true;	// if it ever comes back, the condition was met
-		}
-
-		long stop = System.currentTimeMillis() + timeout;
-		long remaining = timeout;
-		while ((this.value != b) && (remaining > 0L)) {
-			this.mutex.wait(remaining);
-			remaining = stop - System.currentTimeMillis();
-		}
-		return (this.value == b);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value
-	 * changes to the NOT of the specified value or the specified time-out occurs.
-	 * Returns <code>true</code> if
-	 * the NOT of the specified value was achieved;
-	 * Returns <code>false</code> if a time-out occurred.
-	 * If the <code>boolean</code> value is already the NOT of the specified
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilValueIsNot(boolean b, long timeout) throws InterruptedException {
-		return this.waitUntilValueIs( ! b, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value changes
-	 * to <code>true</code> or the specified time-out occurs.
-	 * Returns <code>true</code> if
-	 * <code>true</code> was achieved;
-	 * Returns <code>false</code> if a time-out occurred.
-	 * If the <code>boolean</code> value is already <code>true</code>,
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilTrue(long timeout) throws InterruptedException {
-		return this.waitUntilValueIs(true, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value changes
-	 * to <code>false</code> or the specified time-out occurs.
-	 * Returns <code>true</code> if
-	 * <code>false</code> was achieved;
-	 * Returns <code>false</code> if a time-out occurred.
-	 * If the <code>boolean</code> value is already <code>false</code>,
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilFalse(long timeout) throws InterruptedException {
-		return this.waitUntilValueIs(false, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value changes
-	 * to the NOT of the specified value, then change it back to the specified
-	 * value and continue executing. If the <code>boolean</code> value does not
-	 * change to <code>false</code> before the time-out, simply continue
-	 * executing without changing the value.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred.
-	 * If the <code>boolean</code> value is already
-	 * the NOT of the specified value, set the value to the specified value
-	 * Returns <code>true</code>.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitToSetValue(boolean b, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			boolean success = this.waitUntilValueIs_( ! b, timeout);
-			if (success) {
-				this.setChangedValue_(b);
-			}
-			return success;
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value changes
-	 * to <code>false</code>, then change it back to <code>true</code> and
-	 * continue executing. If the <code>boolean</code> value does not change to
-	 * <code>false</code> before the time-out, simply continue executing without
-	 * changing the value. 
-	 * The time-out is specified in milliseconds. Return
-	 * <code>true</code> if the value was set to <code>true</code>;
-	 * Returns <code>false</code> if a time-out occurred.
-	 * If the <code>boolean</code> value is already <code>false</code>, set the
-	 * Returns <code>true</code>.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitToSetTrue(long timeout) throws InterruptedException {
-		return this.waitToSetValue(true, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value changes
-	 * to <code>true</code>, then change it back to <code>false</code> and
-	 * continue executing. If the <code>boolean</code> value does not change to
-	 * <code>true</code> before the time-out, simply continue executing without
-	 * changing the value.
-	 * The time-out is specified in milliseconds. Return
-	 * <code>true</code> if the value was set to <code>false</code>;
-	 * Returns <code>false</code> if a time-out occurred.
-	 * If the <code>boolean</code> value is already <code>true</code>, set the
-	 * Returns <code>true</code>.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitToSetFalse(long timeout) throws InterruptedException {
-		return this.waitToSetValue(false, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value changes
-	 * to the specified value or the specified time-out occurs;
-	 * then, if a time-out did not occur, execute the specified command.
-	 * Returns <code>true</code> if
-	 * the command was executed;
-	 * Returns <code>false</code> if a time-out occurred.
-	 * If the <code>boolean</code> value is already the specified value,
-	 * Returns <code>true</code>.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean whenEqual(boolean b, InterruptibleCommand command, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			boolean success = this.waitUntilValueIs_(b, timeout);
-			if (success) {
-				command.execute();
-			}
-			return success;
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value changes
-	 * to the NOT of the specified value or the specified time-out occurs;
-	 * then, if a time-out did not occur, execute the specified command.
-	 * Returns <code>true</code> if
-	 * the command was executed;
-	 * Returns <code>false</code> if a time-out occurred.
-	 * If the <code>boolean</code> value is already the NOT of the specified value,
-	 * Returns <code>true</code>.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean whenNotEqual(boolean b, InterruptibleCommand command, long timeout) throws InterruptedException {
-		return this.whenEqual( ! b, command, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value changes
-	 * to <code>true</code> or the specified time-out occurs;
-	 * then, if a time-out did not occur, execute the specified command.
-	 * Returns <code>true</code> if
-	 * the command was executed;
-	 * Returns <code>false</code> if a time-out occurred.
-	 * If the <code>boolean</code> value is already <code>true</code>,
-	 * Returns <code>true</code>.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean whenTrue(InterruptibleCommand command, long timeout) throws InterruptedException {
-		return this.whenEqual(true, command, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the <code>boolean</code> value changes
-	 * to <code>false</code> or the specified time-out occurs;
-	 * then, if a time-out did not occur, execute the specified command.
-	 * Returns <code>true</code> if
-	 * the command was executed;
-	 * Returns <code>false</code> if a time-out occurred.
-	 * If the <code>boolean</code> value is already <code>false</code>,
-	 * Returns <code>true</code>.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean whenFalse(InterruptibleCommand command, long timeout) throws InterruptedException {
-		return this.whenEqual(false, command, timeout);
-	}
-
-
-	// ********** synchronized behavior **********
-
-	/**
-	 * If the current thread is not interrupted, execute the specified command 
-	 * with the mutex locked. This is useful for initializing the value from another
-	 * thread.
-	 */
-	@Override
-	public void execute(InterruptibleCommand command) throws InterruptedException {
-		if (Thread.currentThread().isInterrupted()) {
-			throw new InterruptedException();
-		}
-		synchronized (this.mutex) {
-			command.execute();
-		}
-	}
-
-
-	// ********** standard methods **********
-
-	@Override
-	public SynchronizedBoolean clone() {
-		try {
-			synchronized (this.mutex) {
-				return (SynchronizedBoolean) super.clone();
-			}
-		} catch (CloneNotSupportedException ex) {
-			throw new InternalError();
-		}
-	}
-
-	/**
-	 * Object identity is critical to synchronized booleans.
-	 * There is no reason for two different synchronized booleans to be
-	 * <em>equal</em>.
-	 */
-	@Override
-	public boolean equals(Object obj) {
-		return super.equals(obj);
-	}
-
-	/**
-	 * @see #equals(Object)
-	 */
-	@Override
-	public int hashCode() {
-		return super.hashCode();
-	}
-
-	@Override
-	public String toString() {
-		return '[' + String.valueOf(this.getValue()) + ']';
-	}
-
-	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
-		synchronized (this.mutex) {
-			s.defaultWriteObject();
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedInt.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedInt.java
deleted file mode 100644
index 7694210..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedInt.java
+++ /dev/null
@@ -1,945 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-import org.eclipse.persistence.tools.utility.command.Command;
-
-/**
- * This class provides synchronized access to an <code>int</code>.
- * It also provides protocol for suspending a thread until the
- * value is set to a specified value, with optional time-outs.
- * 
- * @see SimpleIntReference
- */
-public class SynchronizedInt
-	implements ModifiableIntReference, Cloneable, Serializable
-{
-	/** Backing <code>int</code>. */
-	private int value;
-
-	/** Object to synchronize on. */
-	private final Object mutex;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Create a synchronized integer with the specified initial value
-	 * and mutex.
-	 */
-	public SynchronizedInt(int value, Object mutex) {
-		super();
-		this.value = value;
-		this.mutex = mutex;
-	}
-
-	/**
-	 * Create a synchronized integer with the specified initial value.
-	 * The synchronized integer itself will be the mutex.
-	 */
-	public SynchronizedInt(int value) {
-		super();
-		this.value = value;
-		this.mutex = this;
-	}
-
-	/**
-	 * Create a synchronized integer with an initial value of zero
-	 * and the specified mutex.
-	 */
-	public SynchronizedInt(Object mutex) {
-		this(0, mutex);
-	}
-
-	/**
-	 * Create a synchronized object with an initial value of zero.
-	 * The synchronized integer itself will be the mutex.
-	 */
-	public SynchronizedInt() {
-		this(0);
-	}
-
-
-	// ********** methods **********
-
-	@Override
-	public int getValue() {
-		synchronized (this.mutex) {
-			return this.value;
-		}
-	}
-
-	@Override
-	public boolean equals(int v) {
-		synchronized (this.mutex) {
-			return this.value == v;
-		}
-	}
-
-	@Override
-	public boolean notEqual(int v) {
-		synchronized (this.mutex) {
-			return this.value != v;
-		}
-	}
-
-	@Override
-	public boolean isZero() {
-		synchronized (this.mutex) {
-			return this.value == 0;
-		}
-	}
-
-	@Override
-	public boolean isNotZero() {
-		synchronized (this.mutex) {
-			return this.value != 0;
-		}
-	}
-
-	@Override
-	public boolean isGreaterThan(int v) {
-		synchronized (this.mutex) {
-			return this.value > v;
-		}
-	}
-
-	@Override
-	public boolean isGreaterThanOrEqual(int v) {
-		synchronized (this.mutex) {
-			return this.value >= v;
-		}
-	}
-
-	@Override
-	public boolean isLessThan(int v) {
-		synchronized (this.mutex) {
-			return this.value < v;
-		}
-	}
-
-	@Override
-	public boolean isLessThanOrEqual(int v) {
-		synchronized (this.mutex) {
-			return this.value <= v;
-		}
-	}
-
-	@Override
-	public boolean isPositive() {
-		return this.isGreaterThan(0);
-	}
-
-	@Override
-	public boolean isNotPositive() {
-		return this.isLessThanOrEqual(0);
-	}
-
-	@Override
-	public boolean isNegative() {
-		return this.isLessThan(0);
-	}
-
-	@Override
-	public boolean isNotNegative() {
-		return this.isGreaterThanOrEqual(0);
-	}
-
-	@Override
-	public int abs() {
-		synchronized (this.mutex) {
-			return Math.abs(this.value);
-		}
-	}
-
-	@Override
-	public int neg() {
-		synchronized (this.mutex) {
-			return -this.value;
-		}
-	}
-
-	@Override
-	public int add(int v) {
-		synchronized (this.mutex) {
-			return this.value + v;
-		}
-	}
-
-	@Override
-	public int subtract(int v) {
-		synchronized (this.mutex) {
-			return this.value - v;
-		}
-	}
-
-	@Override
-	public int multiply(int v) {
-		synchronized (this.mutex) {
-			return this.value * v;
-		}
-	}
-
-	@Override
-	public int divide(int v) {
-		synchronized (this.mutex) {
-			return this.value / v;
-		}
-	}
-
-	@Override
-	public int remainder(int v) {
-		synchronized (this.mutex) {
-			return this.value % v;
-		}
-	}
-
-	@Override
-	public int min(int v) {
-		synchronized (this.mutex) {
-			return Math.min(this.value, v);
-		}
-	}
-
-	@Override
-	public int max(int v) {
-		synchronized (this.mutex) {
-			return Math.max(this.value, v);
-		}
-	}
-
-	@Override
-	public double pow(int v) {
-		synchronized (this.mutex) {
-			return Math.pow(this.value, v);
-		}
-	}
-
-	/**
-	 * If the value changes, all waiting threads are notified.
-	 */
-	@Override
-	public int setValue(int value) {
-		synchronized (this.mutex) {
-			return this.setValue_(value);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private int setValue_(int v) {
-		int old = this.value;
-		return (old == v) ? old : this.setValue_(v, old);
-	}
-
-	/**
-	 * Pre-condition: synchronized and new value is different
-	 */
-	private int setChangedValue_(int v) {
-		return this.setValue_(v, this.value);
-	}
-
-	/**
-	 * Pre-condition: synchronized and new value is different
-	 */
-	private int setValue_(int v, int old) {
-		this.value = v;
-		this.mutex.notifyAll();
-		return old;
-	}
-
-	/**
-	 * Set the value to zero. If the value changes, all waiting
-	 * Returns the previous value.
-	 */
-	@Override
-	public int setZero() {
-		return this.setValue(0);
-	}
-
-	/**
-	 * Increment the value by one.
-	 * Returns the new value.
-	 */
-	@Override
-	public int increment() {
-		synchronized (this.mutex) {
-			this.value++;
-			this.mutex.notifyAll();
-			return this.value;
-		}
-	}
-
-	/**
-	 * Decrement the value by one.
-	 * Returns the new value.
-	 */
-	@Override
-	public int decrement() {
-		synchronized (this.mutex) {
-			this.value--;
-			this.mutex.notifyAll();
-			return this.value;
-		}
-	}
-
-	/**
-	 * If the current value is the specified expected value, set it to the
-	 * Returns the previous value.
-	 */
-	public int compareAndSwap(int expectedValue, int newValue) {
-		synchronized (this.mutex) {
-			return this.compareAndSwap_(expectedValue, newValue);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private int compareAndSwap_(int expectedValue, int newValue) {
-		return (this.value == expectedValue) ? this.setValue_(newValue) : this.value;
-	}
-
-	/**
-	 * Returns the object the synchronized integer locks on while performing
-	 * its operations.
-	 */
-	public Object getMutex() {
-		return this.mutex;
-	}
-
-
-	// ********** indefinite waits **********
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to the specified value. If the value is already the
-	 * Returns immediately.
-	 */
-	public void waitUntilEqual(int v) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilEqual_(v);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private void waitUntilEqual_(int v) throws InterruptedException {
-		while (this.value != v) {
-			this.mutex.wait();
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to something other than the specified value. If the
-	 * value is already <em>not</em> the specified value,
-	 * Returns immediately.
-	 */
-	public void waitUntilNotEqual(int v) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilNotEqual_(v);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private void waitUntilNotEqual_(int v) throws InterruptedException {
-		while (this.value == v) {
-			this.mutex.wait();
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to zero.
-	 * Returns immediately.
-	 */
-	public void waitUntilZero() throws InterruptedException {
-		this.waitUntilEqual(0);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to something other than zero.
-	 * If the value is already <em>not</em> zero,
-	 * Returns immediately.
-	 */
-	public void waitUntilNotZero() throws InterruptedException {
-		this.waitUntilNotEqual(0);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to a value greater than the specified value. If the value is already
-	 * Returns immediately.
-	 */
-	public void waitUntilGreaterThan(int v) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilGreaterThan_(v);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private void waitUntilGreaterThan_(int v) throws InterruptedException {
-		while (this.value <= v) {
-			this.mutex.wait();
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to a value greater than or equal to the specified value. If the value is already
-	 * Returns immediately.
-	 */
-	public void waitUntilGreaterThanOrEqual(int v) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilGreaterThanOrEqual_(v);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private void waitUntilGreaterThanOrEqual_(int v) throws InterruptedException {
-		while (this.value < v) {
-			this.mutex.wait();
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to a value less than the specified value. If the value is already
-	 * Returns immediately.
-	 */
-	public void waitUntilLessThan(int v) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilLessThan_(v);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private void waitUntilLessThan_(int v) throws InterruptedException {
-		while (this.value >= v) {
-			this.mutex.wait();
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to a value less than or equal to the specified value. If the value is already
-	 * Returns immediately.
-	 */
-	public void waitUntilLessThanOrEqual(int v) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilLessThanOrEqual_(v);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private void waitUntilLessThanOrEqual_(int v) throws InterruptedException {
-		while (this.value > v) {
-			this.mutex.wait();
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the value is positive.
-	 * Returns immediately.
-	 */
-	public void waitUntilPositive() throws InterruptedException {
-		this.waitUntilGreaterThan(0);
-	}
-
-	/**
-	 * Suspend the current thread until the value is not positive
-	 * (i.e. negative or zero).
-	 * If the value is already <em>not</em> positive,
-	 * Returns immediately.
-	 */
-	public void waitUntilNotPositive() throws InterruptedException {
-		this.waitUntilLessThanOrEqual(0);
-	}
-
-	/**
-	 * Suspend the current thread until the value is negative.
-	 * Returns immediately.
-	 */
-	public void waitUntilNegative() throws InterruptedException {
-		this.waitUntilLessThan(0);
-	}
-
-	/**
-	 * Suspend the current thread until the value is not negative
-	 * (i.e. zero or positive).
-	 * If the value is already <em>not</em> negative,
-	 * Returns immediately.
-	 */
-	public void waitUntilNotNegative() throws InterruptedException {
-		this.waitUntilGreaterThanOrEqual(0);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to
-	 * something other than the specified value, then change
-	 * it back to the specified value and continue executing.
-	 * If the value is already <em>not</em> the specified value, set
-	 * the value immediately.
-	 * Returns the previous value.
-	 */
-	public int waitToSetValue(int v) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilNotEqual_(v);
-			return this.setChangedValue_(v);
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to
-	 * something other than zero, then change it
-	 * back to zero and continue executing.
-	 * If the value is already <em>not</em> zero,
-	 * set the value to zero immediately.
-	 * Returns the previous value.
-	 */
-	public int waitToSetZero() throws InterruptedException {
-		return this.waitToSetValue(0);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to
-	 * the specified expected value, then change it
-	 * to the specified new value and continue executing.
-	 * If the value is already the specified expected value,
-	 * set the value to the specified new value immediately.
-	 * Returns the previous value.
-	 */
-	public int waitToSwap(int expectedValue, int newValue) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilEqual_(expectedValue);
-			return this.setValue_(newValue);
-		}
-	}
-
-
-	// ********** timed waits **********
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to the specified value or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred.
-	 * Returns true immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilEqual(int v, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			return this.waitUntilEqual_(v, timeout);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private boolean waitUntilEqual_(int v, long timeout) throws InterruptedException {
-		if (timeout == 0L) {
-			this.waitUntilEqual_(v);  // wait indefinitely until notified
-			return true;  // if it ever comes back, the condition was met
-		}
-
-		long stop = System.currentTimeMillis() + timeout;
-		long remaining = timeout;
-		while ((this.value != v) && (remaining > 0L)) {
-			this.mutex.wait(remaining);
-			remaining = stop - System.currentTimeMillis();
-		}
-		return (this.value == v);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to something
-	 * other than the specified value or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code> if a
-	 * time-out occurred. If the value is already <em>not</em> the specified
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilNotEqual(int v, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			return this.waitUntilNotEqual_(v, timeout);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private boolean waitUntilNotEqual_(int v, long timeout) throws InterruptedException {
-		if (timeout == 0L) {
-			this.waitUntilNotEqual_(v);	// wait indefinitely until notified
-			return true;	// if it ever comes back, the condition was met
-		}
-
-		long stop = System.currentTimeMillis() + timeout;
-		long remaining = timeout;
-		while ((this.value == v) && (remaining > 0L)) {
-			this.mutex.wait(remaining);
-			remaining = stop - System.currentTimeMillis();
-		}
-		return (this.value != v);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to zero or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred. If the value is already zero,
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilZero(long timeout) throws InterruptedException {
-		return this.waitUntilEqual(0, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to something other than zero or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred. If the value is already <em>not</em>
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilNotZero(long timeout) throws InterruptedException {
-		return this.waitUntilNotEqual(0, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to a value greater
-	 * than the specified value or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred.
-	 * Returns immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilGreaterThan(int v, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			return this.waitUntilGreaterThan_(v, timeout);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private boolean waitUntilGreaterThan_(int v, long timeout) throws InterruptedException {
-		if (timeout == 0L) {
-			this.waitUntilGreaterThan_(v);  // wait indefinitely until notified
-			return true;  // if it ever comes back, the condition was met
-		}
-
-		long stop = System.currentTimeMillis() + timeout;
-		long remaining = timeout;
-		while ((this.value <= v) && (remaining > 0L)) {
-			this.mutex.wait(remaining);
-			remaining = stop - System.currentTimeMillis();
-		}
-		return (this.value > v);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to a value greater
-	 * than or equal to the specified value or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred.
-	 * If the value is already greater than or equal to the specified value,
-	 * Returns immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilGreaterThanOrEqual(int v, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			return this.waitUntilGreaterThanOrEqual_(v, timeout);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private boolean waitUntilGreaterThanOrEqual_(int v, long timeout) throws InterruptedException {
-		if (timeout == 0L) {
-			this.waitUntilGreaterThanOrEqual_(v);  // wait indefinitely until notified
-			return true;  // if it ever comes back, the condition was met
-		}
-
-		long stop = System.currentTimeMillis() + timeout;
-		long remaining = timeout;
-		while ((this.value < v) && (remaining > 0L)) {
-			this.mutex.wait(remaining);
-			remaining = stop - System.currentTimeMillis();
-		}
-		return (this.value >= v);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to a value less
-	 * than the specified value or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred.
-	 * Returns immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilLessThan(int v, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			return this.waitUntilLessThan_(v, timeout);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private boolean waitUntilLessThan_(int v, long timeout) throws InterruptedException {
-		if (timeout == 0L) {
-			this.waitUntilLessThan_(v);  // wait indefinitely until notified
-			return true;  // if it ever comes back, the condition was met
-		}
-
-		long stop = System.currentTimeMillis() + timeout;
-		long remaining = timeout;
-		while ((this.value >= v) && (remaining > 0L)) {
-			this.mutex.wait(remaining);
-			remaining = stop - System.currentTimeMillis();
-		}
-		return (this.value < v);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to a value less
-	 * than or equal to the specified value or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred.
-	 * If the value is already less than or equal to the specified value,
-	 * Returns immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilLessThanOrEqual(int v, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			return this.waitUntilLessThanOrEqual_(v, timeout);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private boolean waitUntilLessThanOrEqual_(int v, long timeout) throws InterruptedException {
-		if (timeout == 0L) {
-			this.waitUntilLessThanOrEqual_(v);  // wait indefinitely until notified
-			return true;  // if it ever comes back, the condition was met
-		}
-
-		long stop = System.currentTimeMillis() + timeout;
-		long remaining = timeout;
-		while ((this.value > v) && (remaining > 0L)) {
-			this.mutex.wait(remaining);
-			remaining = stop - System.currentTimeMillis();
-		}
-		return (this.value <= v);
-	}
-
-	/**
-	 * Suspend the current thread until the value is positive
-	 * or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred. If the value is already positive,
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilPositive(long timeout) throws InterruptedException {
-		return this.waitUntilGreaterThan(0, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the value is not positive
-	 * or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred. If the value is already not positive,
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilNotPositive(long timeout) throws InterruptedException {
-		return this.waitUntilLessThanOrEqual(0, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the value is negative
-	 * or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred. If the value is already negative,
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilNegative(long timeout) throws InterruptedException {
-		return this.waitUntilLessThan(0, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the value is not negative
-	 * or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred. If the value is already not negative,
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilNotNegative(long timeout) throws InterruptedException {
-		return this.waitUntilGreaterThanOrEqual(0, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to
-	 * something other than the specified value, then change
-	 * it back to the specified value and continue executing.
-	 * If the value does not change to something other than the
-	 * specified value before the time-out, simply continue executing
-	 * without changing the value.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred.
-	 * If the value is already something other than the specified value, set
-	 * Returns <code>true</code>.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitToSetValue(int v, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			boolean success = this.waitUntilNotEqual_(v, timeout);
-			if (success) {
-				this.setChangedValue_(v);
-			}
-			return success;
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to something
-	 * other than zero, then change it back to zero
-	 * and continue executing. If the value does not change to something
-	 * other than zero before the time-out, simply continue
-	 * executing without changing the value.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred.
-	 * If the value is already something other than zero, set
-	 * Returns <code>true</code>.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitToSetZero(long timeout) throws InterruptedException {
-		return this.waitToSetValue(0, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to
-	 * the specified expected value, then change it
-	 * to the specified new value and continue executing.
-	 * If the value does not change to the specified expected value
-	 * before the time-out, simply continue executing without changing
-	 * the value.
-	 * Returns <code>true</code>
-	 * if the value was set to the specified new value; return
-	 * <code>false</code> if a time-out occurred.
-	 * If the value is already the specified expected value,
-	 * set the value to the specified new value immediately.
-	 * Returns the previous value.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitToSwap(int expectedValue, int newValue, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			boolean success = this.waitUntilEqual_(expectedValue, timeout);
-			if (success) {
-				this.setValue_(newValue);
-			}
-			return success;
-		}
-	}
-
-
-	// ********** synchronized behavior **********
-
-	/**
-	 * If current thread is not interrupted, execute the specified command 
-	 * with the mutex locked. This is useful for initializing the value from another
-	 * thread.
-	 */
-	public void execute(Command command) throws InterruptedException {
-		if (Thread.currentThread().isInterrupted()) {
-			throw new InterruptedException();
-		}
-		synchronized (this.mutex) {
-			command.execute();
-		}
-	}
-
-
-	// ********** Comparable implementation **********
-
-	@Override
-	public int compareTo(IntReference ref) {
-		int thisValue = this.getValue();
-		int otherValue = ref.getValue();
-		return (thisValue < otherValue) ? -1 : ((thisValue == otherValue) ? 0 : 1);
-	}
-
-
-	// ********** standard methods **********
-
-	@Override
-	public SynchronizedInt clone() {
-		try {
-			synchronized (this.mutex) {
-				return (SynchronizedInt) super.clone();
-			}
-		} catch (CloneNotSupportedException ex) {
-			throw new InternalError();
-		}
-	}
-
-	@Override
-	public String toString() {
-		return '[' + String.valueOf(this.getValue()) + ']';
-	}
-
-	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
-		synchronized (this.mutex) {
-			s.defaultWriteObject();
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedObject.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedObject.java
deleted file mode 100644
index 55dec93..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedObject.java
+++ /dev/null
@@ -1,481 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-import org.eclipse.persistence.tools.utility.command.Command;
-
-/**
- * This class provides synchronized access to an object of type <code>V</code>.
- * It also provides protocol for suspending a thread until the
- * value is set to <code>null</code> or a non-<code>null</code> value,
- * with optional time-outs.
- *
- * @parm V the type of the synchronized object's value
- * @see SimpleObjectReference
- */
-public class SynchronizedObject<V>
-	implements ModifiableObjectReference<V>, Cloneable, Serializable
-{
-	/** Backing value. */
-	private V value;
-
-	/** Object to synchronize on. */
-	private final Object mutex;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Create a synchronized object with the specified initial value
-	 * and mutex.
-	 */
-	public SynchronizedObject(V value, Object mutex) {
-		super();
-		this.value = value;
-		this.mutex = mutex;
-	}
-
-	/**
-	 * Create a synchronized object with the specified initial value.
-	 * The synchronized object itself will be the mutex.
-	 */
-	public SynchronizedObject(V value) {
-		super();
-		this.value = value;
-		this.mutex = this;
-	}
-
-	/**
-	 * Create a synchronized object with an initial value of <code>null</code>.
-	 * The synchronized object itself will be the mutex.
-	 */
-	public SynchronizedObject() {
-		this(null);
-	}
-
-
-	// ********** accessors **********
-
-	@Override
-	public V getValue() {
-		synchronized (this.mutex) {
-			return this.value;
-		}
-	}
-
-	@Override
-	public boolean valueEquals(Object object) {
-		return Tools.valuesAreEqual(this.getValue(), object);
-	}
-
-	@Override
-	public boolean valueNotEqual(Object object) {
-		return Tools.valuesAreDifferent(this.getValue(), object);
-	}
-
-	@Override
-	public boolean isNull() {
-		synchronized (this.mutex) {
-			return this.value == null;
-		}
-	}
-
-	@Override
-	public boolean isNotNull() {
-		synchronized (this.mutex) {
-			return this.value != null;
-		}
-	}
-
-	/**
-	 * Set the value. If the value changes, all waiting
-	 * Returns the previous value.
-	 */
-	@Override
-	public V setValue(V value) {
-		synchronized (this.mutex) {
-			return this.setValue_(value);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private V setValue_(V v) {
-		V old = this.value;
-		return Tools.valuesAreEqual(old, v) ? old : this.setValue_(v, old);
-	}
-
-	/**
-	 * Pre-condition: synchronized and new value is different
-	 */
-	private V setChangedValue_(V v) {
-		return this.setValue_(v, this.value);
-	}
-
-	/**
-	 * Pre-condition: synchronized and new value is different
-	 */
-	private V setValue_(V v, V old) {
-		this.value = v;
-		this.mutex.notifyAll();
-		return old;
-	}
-
-	/**
-	 * Set the value to <code>null</code>. If the value changes, all waiting
-	 * Returns the previous value.
-	 */
-	@Override
-	public V setNull() {
-		return this.setValue(null);
-	}
-
-	/**
-	 * If the current value is the specified expected value, set it to the
-	 * Returns the previous value.
-	 */
-	public V compareAndSwap(V expectedValue, V newValue) {
-		synchronized (this.mutex) {
-			return this.compareAndSwap_(expectedValue, newValue);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private V compareAndSwap_(V expectedValue, V newValue) {
-		return Tools.valuesAreEqual(this.value, expectedValue) ? this.setValue_(newValue) : this.value;
-	}
-
-	/**
-	 * Returns the object the synchronized object locks on while performing
-	 * its operations.
-	 */
-	public Object getMutex() {
-		return this.mutex;
-	}
-
-
-	// ********** indefinite waits **********
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to the specified value. If the value is already the
-	 * Returns immediately.
-	 */
-	public void waitUntilValueIs(V v) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilValueIs_(v);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private void waitUntilValueIs_(V v) throws InterruptedException {
-		while (Tools.valuesAreDifferent(this.value, v)) {
-			this.mutex.wait();
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to something other than the specified value. If the
-	 * value is already <em>not</em> the specified value,
-	 * Returns immediately.
-	 */
-	public void waitUntilValueIsNot(V v) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilValueIsNot_(v);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private void waitUntilValueIsNot_(V v) throws InterruptedException {
-		while (Tools.valuesAreEqual(this.value, v)) {
-			this.mutex.wait();
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to <code>null</code>.
-	 * Returns immediately.
-	 */
-	public void waitUntilNull() throws InterruptedException {
-		this.waitUntilValueIs(null);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to something other than <code>null</code>.
-	 * If the value is already <em>not</em> <code>null</code>,
-	 * Returns immediately.
-	 */
-	public void waitUntilNotNull() throws InterruptedException {
-		this.waitUntilValueIsNot(null);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to
-	 * something other than the specified value, then change
-	 * it back to the specified value and continue executing.
-	 * If the value is already <em>not</em> the specified value, set
-	 * the value immediately.
-	 * Returns the previous value.
-	 */
-	public V waitToSetValue(V v) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilValueIsNot_(v);
-			return this.setChangedValue_(v);
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to
-	 * something other than <code>null</code>, then change it
-	 * back to <code>null</code> and continue executing.
-	 * If the value is already <em>not</em> <code>null</code>,
-	 * set the value to <code>null</code> immediately.
-	 * Returns the previous value.
-	 */
-	public V waitToSetNull() throws InterruptedException {
-		return this.waitToSetValue(null);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to
-	 * the specified expected value, then change it
-	 * to the specified new value and continue executing.
-	 * If the value is already the specified expected value,
-	 * set the value to the specified new value immediately.
-	 * Returns the previous value.
-	 */
-	public V waitToSwap(V expectedValue, V newValue) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilValueIs_(expectedValue);
-			return this.setValue_(newValue);
-		}
-	}
-
-
-	// ********** timed waits **********
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to the specified value or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred.
-	 * Returns true immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilValueIs(V v, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			return this.waitUntilValueIs_(v, timeout);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private boolean waitUntilValueIs_(V v, long timeout) throws InterruptedException {
-		if (timeout == 0L) {
-			this.waitUntilValueIs_(v);  // wait indefinitely until notified
-			return true;  // if it ever comes back, the condition was met
-		}
-
-		long stop = System.currentTimeMillis() + timeout;
-		long remaining = timeout;
-		while (Tools.valuesAreDifferent(this.value, v) && (remaining > 0L)) {
-			this.mutex.wait(remaining);
-			remaining = stop - System.currentTimeMillis();
-		}
-		return Tools.valuesAreEqual(this.value, v);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to something
-	 * other than the specified value or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code> if a
-	 * time-out occurred. If the value is already <em>not</em> the specified
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilValueIsNot(V v, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			return this.waitUntilValueIsNot_(v, timeout);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private boolean waitUntilValueIsNot_(V v, long timeout) throws InterruptedException {
-		if (timeout == 0L) {
-			this.waitUntilValueIsNot_(v);	// wait indefinitely until notified
-			return true;	// if it ever comes back, the condition was met
-		}
-
-		long stop = System.currentTimeMillis() + timeout;
-		long remaining = timeout;
-		while (Tools.valuesAreEqual(this.value, v) && (remaining > 0L)) {
-			this.mutex.wait(remaining);
-			remaining = stop - System.currentTimeMillis();
-		}
-		return Tools.valuesAreDifferent(this.value, v);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to <code>null</code> or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred. If the value is already <code>null</code>,
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilNull(long timeout) throws InterruptedException {
-		return this.waitUntilValueIs(null, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes
-	 * to something other than <code>null</code> or the specified time-out occurs.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred. If the value is already <em>not</em>
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilNotNull(long timeout) throws InterruptedException {
-		return this.waitUntilValueIsNot(null, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to
-	 * something other than the specified value, then change
-	 * it back to the specified value and continue executing.
-	 * If the value does not change to something other than the
-	 * specified value before the time-out, simply continue executing
-	 * without changing the value.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred.
-	 * If the value is already something other than the specified value, set
-	 * Returns <code>true</code>.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitToSetValue(V v, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			boolean success = this.waitUntilValueIsNot_(v, timeout);
-			if (success) {
-				this.setChangedValue_(v);
-			}
-			return success;
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to something
-	 * other than <code>null</code>, then change it back to <code>null</code>
-	 * and continue executing. If the value does not change to something
-	 * other than <code>null</code> before the time-out, simply continue
-	 * executing without changing the value.
-	 * Returns <code>true</code>
-	 * Returns <code>false</code>
-	 * if a time-out occurred.
-	 * If the value is already something other than <code>null</code>, set
-	 * Returns <code>true</code>.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitToSetNull(long timeout) throws InterruptedException {
-		return this.waitToSetValue(null, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the value changes to
-	 * the specified expected value, then change it
-	 * to the specified new value and continue executing.
-	 * If the value does not change to the specified expected value
-	 * before the time-out, simply continue executing without changing
-	 * the value.
-	 * Returns <code>true</code>
-	 * if the value was set to the specified new value; return
-	 * <code>false</code> if a time-out occurred.
-	 * If the value is already the specified expected value,
-	 * set the value to the specified new value immediately.
-	 * Returns the previous value.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitToSwap(V expectedValue, V newValue, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			boolean success = this.waitUntilValueIs_(expectedValue, timeout);
-			if (success) {
-				this.setValue_(newValue);
-			}
-			return success;
-		}
-	}
-
-
-	// ********** synchronized behavior **********
-
-	/**
-	 * If current thread is not interrupted, execute the specified command
-	 * with the mutex locked. This is useful for initializing the value from another
-	 * thread.
-	 */
-	public void execute(Command command) throws InterruptedException {
-		if (Thread.currentThread().isInterrupted()) {
-			throw new InterruptedException();
-		}
-		synchronized (this.mutex) {
-			command.execute();
-		}
-	}
-
-
-	// ********** standard methods **********
-
-	@Override
-	public SynchronizedObject<V> clone() {
-		try {
-			synchronized (this.mutex) {
-				@SuppressWarnings("unchecked")
-				SynchronizedObject<V> clone = (SynchronizedObject<V>) super.clone();
-				return clone;
-			}
-		} catch (CloneNotSupportedException ex) {
-			throw new InternalError();
-		}
-	}
-
-	@Override
-	public String toString() {
-		return '[' + String.valueOf(this.getValue()) + ']';
-	}
-
-	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
-		synchronized (this.mutex) {
-			s.defaultWriteObject();
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedQueue.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedQueue.java
deleted file mode 100644
index 081451c..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedQueue.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.command.Command;
-
-/**
- * Thread-safe implementation of the {@link Queue} interface.
- * This also provides protocol for suspending a thread until the
- * queue is empty or not empty, with optional time-outs.
- */
-public class SynchronizedQueue<E>
-	implements Queue<E>, Serializable
-{
-	/** Backing queue. */
-	private final Queue<E> queue;
-
-	/** Object to synchronize on. */
-	private final Object mutex;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct a synchronized queue that wraps the
-	 * specified queue and locks on the specified mutex.
-	 */
-	public SynchronizedQueue(Queue<E> queue, Object mutex) {
-		super();
-		if ((queue == null) || (mutex == null)) {
-			throw new NullPointerException();
-		}
-		this.queue = queue;
-		this.mutex = mutex;
-	}
-
-	/**
-	 * Construct a synchronized queue that wraps the
-	 * specified queue and locks on itself.
-	 */
-	public SynchronizedQueue(Queue<E> queue) {
-		super();
-		if (queue == null) {
-			throw new NullPointerException();
-		}
-		this.queue = queue;
-		this.mutex = this;
-	}
-
-	/**
-	 * Construct an empty synchronized queue that locks on the specified mutex.
-	 */
-	public SynchronizedQueue(Object mutex) {
-		this(new SimpleQueue<E>(), mutex);
-	}
-
-	/**
-	 * Construct an empty synchronized queue that locks on itself.
-	 */
-	public SynchronizedQueue() {
-		this(new SimpleQueue<E>());
-	}
-
-
-	// ********** Queue implementation **********
-
-	@Override
-	public void enqueue(E element) {
-		synchronized (this.mutex) {
-			this.enqueue_(element);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private void enqueue_(E element) {
-		this.queue.enqueue(element);
-		this.mutex.notifyAll();
-	}
-
-	@Override
-	public E dequeue() {
-		synchronized (this.mutex) {
-			return this.dequeue_();
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private E dequeue_() {
-		E element = this.queue.dequeue();
-		this.mutex.notifyAll();
-		return element;
-	}
-
-	@Override
-	public E peek() {
-		synchronized (this.mutex) {
-			return this.queue.peek();
-		}
-	}
-
-	@Override
-	public boolean isEmpty() {
-		synchronized (this.mutex) {
-			return this.queue.isEmpty();
-		}
-	}
-
-
-	// ********** indefinite waits **********
-
-	/**
-	 * Suspend the current thread until the queue's empty status changes
-	 * to the specified value.
-	 */
-	public void waitUntilEmptyIs(boolean empty) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilEmptyIs_(empty);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private void waitUntilEmptyIs_(boolean empty) throws InterruptedException {
-		while (this.queue.isEmpty() != empty) {
-			this.mutex.wait();
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the queue is empty.
-	 */
-	public void waitUntilEmpty() throws InterruptedException {
-		this.waitUntilEmptyIs(true);
-	}
-
-	/**
-	 * Suspend the current thread until the queue has something on it.
-	 */
-	public void waitUntilNotEmpty() throws InterruptedException {
-		this.waitUntilEmptyIs(false);
-	}
-
-	/**
-	 * Suspend the current thread until the queue is empty,
-	 * then "enqueue" the specified item to the tail of the queue
-	 * and continue executing.
-	 */
-	public void waitToEnqueue(E element) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilEmptyIs_(true);
-			this.enqueue_(element);
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the queue has something on it,
-	 * Returns it.
-	 */
-	public Object waitToDequeue() throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilEmptyIs_(false);
-			return this.dequeue_();
-		}
-	}
-
-
-	// ********** timed waits **********
-
-	/**
-	 * Suspend the current thread until the queue's empty status changes
-	 * to the specified value or the specified time-out occurs.
-	 * Returns <code>true</code> if the specified
-	 * Returns <code>false</code> if a time-out occurred.
-	 * If the queue's empty status is already the specified value,
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilEmptyIs(boolean empty, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			return this.waitUntilEmptyIs_(empty, timeout);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private boolean waitUntilEmptyIs_(boolean empty, long timeout) throws InterruptedException {
-		if (timeout == 0L) {
-			this.waitUntilEmptyIs_(empty);	// wait indefinitely until notified
-			return true;	// if it ever comes back, the condition was met
-		}
-
-		long stop = System.currentTimeMillis() + timeout;
-		long remaining = timeout;
-		while ((this.queue.isEmpty() != empty) && (remaining > 0L)) {
-			this.mutex.wait(remaining);
-			remaining = stop - System.currentTimeMillis();
-		}
-		return (this.queue.isEmpty() == empty);
-	}
-
-	/**
-	 * Suspend the current thread until the queue is empty
-	 * or the specified time-out occurs.
-	 * Returns <code>true</code> if
-	 * Returns <code>false</code> if a time-out occurred.
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilEmpty(long timeout) throws InterruptedException {
-		return this.waitUntilEmptyIs(true, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the queue has something on it.
-	 * or the specified time-out occurs.
-	 * Returns <code>true</code> if
-	 * Returns <code>false</code> if a time-out occurred.
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilNotEmpty(long timeout) throws InterruptedException {
-		return this.waitUntilEmptyIs(false, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the queue is empty,
-	 * then "enqueue" the specified item to the tail of the queue
-	 * and continue executing. If the queue is not emptied out
-	 * before the time-out, simply continue executing without
-	 * "enqueueing" the item.
-	 * Returns <code>true</code> if the
-	 * Returns <code>false</code> if a time-out occurred.
-	 * If the queue is already empty, "enqueue" the specified item and
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitToEnqueue(E element, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			boolean success = this.waitUntilEmptyIs_(true, timeout);
-			if (success) {
-				this.enqueue_(element);
-			}
-			return success;
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the queue has something on it,
-	 * Returns it.
-	 * If the queue is empty and nothing is "enqueued" on to it before the
-	 * time-out, throw a no such element exception.
-	 * The time-out is specified in milliseconds.
-	 * If the queue is not empty, "dequeue" an item and
-	 * Returns it immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public Object waitToDequeue(long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			boolean success = this.waitUntilEmptyIs_(false, timeout);
-			if (success) {
-				return this.dequeue_();
-			}
-			throw new NoSuchElementException();
-		}
-	}
-
-
-	// ********** synchronized behavior **********
-
-	/**
-	 * If the current thread is not interrupted, execute the specified command 
-	 * with the mutex locked. This is useful for initializing the queue in another
-	 * thread.
-	 */
-	public void execute(Command command) throws InterruptedException {
-		if (Thread.currentThread().isInterrupted()) {
-			throw new InterruptedException();
-		}
-		synchronized (this.mutex) {
-			command.execute();
-		}
-	}
-
-
-	// ********** additional public protocol **********
-
-	/**
-	 * "Drain" all the current items from the queue into specified queue.
-	 */
-	public void drainTo(Queue<E> q) {
-		synchronized (this.mutex) {
-			this.drainTo_(q);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private void drainTo_(Queue<E> q) {
-		boolean changed = false;
-		while ( ! this.queue.isEmpty()) {
-			q.enqueue(this.queue.dequeue());
-			changed = true;
-		}
-		if (changed) {
-			this.mutex.notifyAll();
-		}
-	}
-
-	/**
-	 * Returns the object the queue locks on while performing
-	 * its operations.
-	 */
-	public Object getMutex() {
-		return this.mutex;
-	}
-
-
-	// ********** standard methods **********
-
-	@Override
-	public String toString() {
-		synchronized (this.mutex) {
-			return '[' + this.queue.toString() + ']';
-		}
-	}
-
-	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
-		synchronized (this.mutex) {
-			s.defaultWriteObject();
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedStack.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedStack.java
deleted file mode 100644
index 9f6037e..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SynchronizedStack.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-import java.util.EmptyStackException;
-
-import org.eclipse.persistence.tools.utility.command.Command;
-
-/**
- * Thread-safe implementation of the {@link Stack} interface. This also provides protocol for
- * suspending a thread until the stack is empty or not empty, with optional time-outs.
- *
- * @version 2.5
- */
-public class SynchronizedStack<E> implements Stack<E>, Serializable {
-
-	/** Backing stack. */
-	private final Stack<E> stack;
-
-	/** Object to synchronize on. */
-	private final Object mutex;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct a synchronized stack that wraps the
-	 * specified stack and locks on the specified mutex.
-	 */
-	public SynchronizedStack(Stack<E> stack, Object mutex) {
-		super();
-		if (stack == null) {
-			throw new NullPointerException();
-		}
-		this.stack = stack;
-		this.mutex = mutex;
-	}
-
-	/**
-	 * Construct a synchronized stack that wraps the
-	 * specified stack and locks on itself.
-	 */
-	public SynchronizedStack(Stack<E> stack) {
-		super();
-		if (stack == null) {
-			throw new NullPointerException();
-		}
-		this.stack = stack;
-		this.mutex = this;
-	}
-
-	/**
-	 * Construct an empty synchronized stack that locks on the specified mutex.
-	 */
-	public SynchronizedStack(Object mutex) {
-		this(new SimpleStack<E>(), mutex);
-	}
-
-	/**
-	 * Construct an empty synchronized stack that locks on itself.
-	 */
-	public SynchronizedStack() {
-		this(new SimpleStack<E>());
-	}
-
-
-	// ********** Stack implementation **********
-
-	@Override
-	public void push(E element) {
-		synchronized (this.mutex) {
-			this.push_(element);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private void push_(E element) {
-		this.stack.push(element);
-		this.mutex.notifyAll();
-	}
-
-	@Override
-	public E pop() {
-		synchronized (this.mutex) {
-			return this.pop_();
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private E pop_() {
-		E o = this.stack.pop();
-		this.mutex.notifyAll();
-		return o;
-	}
-
-	@Override
-	public E peek() {
-		synchronized (this.mutex) {
-			return this.stack.peek();
-		}
-	}
-
-	@Override
-	public boolean isEmpty() {
-		synchronized (this.mutex) {
-			return this.stack.isEmpty();
-		}
-	}
-
-
-	// ********** indefinite waits **********
-
-	/**
-	 * Suspend the current thread until the stack's empty status changes
-	 * to the specified value.
-	 */
-	public void waitUntilEmptyIs(boolean empty) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilEmptyIs_(empty);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private void waitUntilEmptyIs_(boolean empty) throws InterruptedException {
-		while (this.stack.isEmpty() != empty) {
-			this.mutex.wait();
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the stack is empty.
-	 */
-	public void waitUntilEmpty() throws InterruptedException {
-		this.waitUntilEmptyIs(true);
-	}
-
-	/**
-	 * Suspend the current thread until the stack has something on it.
-	 */
-	public void waitUntilNotEmpty() throws InterruptedException {
-		this.waitUntilEmptyIs(false);
-	}
-
-	/**
-	 * Suspend the current thread until the stack is empty,
-	 * then "push" the specified item on to the top of the stack
-	 * and continue executing.
-	 */
-	public void waitToPush(E element) throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilEmptyIs_(true);
-			this.push_(element);
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the stack has something on it,
-	 * Returns it.
-	 */
-	public Object waitToPop() throws InterruptedException {
-		synchronized (this.mutex) {
-			this.waitUntilEmptyIs_(false);
-			return this.pop_();
-		}
-	}
-
-
-	// ********** timed waits **********
-
-	/**
-	 * Suspend the current thread until the stack's empty status changes
-	 * to the specified value or the specified time-out occurs.
-	 * Returns <code>true</code> if the specified
-	 * Returns <code>false</code> if a time-out occurred.
-	 * If the stack's empty status is already the specified value,
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilEmptyIs(boolean empty, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			return this.waitUntilEmptyIs_(empty, timeout);
-		}
-	}
-
-	/**
-	 * Pre-condition: synchronized
-	 */
-	private boolean waitUntilEmptyIs_(boolean empty, long timeout) throws InterruptedException {
-		if (timeout == 0L) {
-			this.waitUntilEmptyIs_(empty);	// wait indefinitely until notified
-			return true;	// if it ever comes back, the condition was met
-		}
-
-		long stop = System.currentTimeMillis() + timeout;
-		long remaining = timeout;
-		while ((this.stack.isEmpty() != empty) && (remaining > 0L)) {
-			this.mutex.wait(remaining);
-			remaining = stop - System.currentTimeMillis();
-		}
-		return (this.stack.isEmpty() == empty);
-	}
-
-	/**
-	 * Suspend the current thread until the stack is empty
-	 * or the specified time-out occurs.
-	 * Returns <code>true</code> if
-	 * Returns <code>false</code> if a time-out occurred.
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilEmpty(long timeout) throws InterruptedException {
-		return this.waitUntilEmptyIs(true, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the stack has something on it.
-	 * or the specified time-out occurs.
-	 * Returns <code>true</code> if
-	 * Returns <code>false</code> if a time-out occurred.
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitUntilNotEmpty(long timeout) throws InterruptedException {
-		return this.waitUntilEmptyIs(false, timeout);
-	}
-
-	/**
-	 * Suspend the current thread until the stack is empty,
-	 * then "push" the specified item on to the top of the stack
-	 * and continue executing. If the stack is not emptied out
-	 * before the time-out, simply continue executing without
-	 * "pushing" the item.
-	 * Returns <code>true</code> if the
-	 * Returns <code>false</code> if a time-out occurred.
-	 * If the stack is already empty, "push" the specified item and
-	 * Returns <code>true</code> immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public boolean waitToPush(E element, long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			boolean success = this.waitUntilEmptyIs_(true, timeout);
-			if (success) {
-				this.push_(element);
-			}
-			return success;
-		}
-	}
-
-	/**
-	 * Suspend the current thread until the stack has something on it,
-	 * Returns it.
-	 * If the stack is empty and nothing is "pushed" on to it before the
-	 * time-out, throw an empty stack exception.
-	 * The time-out is specified in milliseconds.
-	 * If the stack is not empty, "pop" an item and
-	 * Returns it immediately.
-	 * If the time-out is zero, wait indefinitely.
-	 */
-	public Object waitToPop(long timeout) throws InterruptedException {
-		synchronized (this.mutex) {
-			boolean success = this.waitUntilEmptyIs_(false, timeout);
-			if (success) {
-				return this.pop_();
-			}
-			throw new EmptyStackException();
-		}
-	}
-
-
-	// ********** synchronized behavior **********
-
-	/**
-	 * If the current thread is not interrupted, execute the specified command
-	 * with the mutex locked. This is useful for initializing the stack in another
-	 * thread.
-	 */
-	public void execute(Command command) throws InterruptedException {
-		if (Thread.currentThread().isInterrupted()) {
-			throw new InterruptedException();
-		}
-		synchronized (this.mutex) {
-			command.execute();
-		}
-	}
-
-
-	// ********** additional public protocol **********
-
-	/**
-	 * Returns the object the stack locks on while performing
-	 * its operations.
-	 */
-	public Object getMutex() {
-		return this.mutex;
-	}
-
-
-	// ********** standard methods **********
-
-	@Override
-	public String toString() {
-		synchronized (this.mutex) {
-			return '[' + this.stack.toString() + ']';
-		}
-	}
-
-	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
-		synchronized (this.mutex) {
-			s.defaultWriteObject();
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SystemTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SystemTools.java
new file mode 100644
index 0000000..85c5113
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/SystemTools.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+/**
+ * Various system utility methods.
+ * @see System#getProperty(String)
+ */
+@SuppressWarnings("nls")
+public final class SystemTools {
+
+	// ********** JVM **********
+
+	/**
+	 * Return whether the current JVM is IBM's.
+	 */
+	public static boolean jvmIsIBM() {
+		return jvmIs("IBM");
+	}
+
+	/**
+	 * Return whether the current JVM is Oracle's (or Sun's).
+	 */
+	public static boolean jvmIsOracle() {
+		return jvmIsSun();
+	}
+
+	/**
+	 * Return whether the current JVM is Sun's (or Oracle's).
+	 */
+	public static boolean jvmIsSun() {
+		return jvmIsStrictlySun() || jvmIsStrictlyOracle();
+	}
+
+	/**
+	 * Return whether the current JVM is <em>strictly</em> Oracle's
+	 * (as opposed to Sun's).
+	 */
+	public static boolean jvmIsStrictlyOracle() {
+		return jvmIs("Oracle");
+	}
+
+	/**
+	 * Return whether the current JVM is <em>strictly</em> Sun's
+	 * (as opposed to Oracle's).
+	 */
+	public static boolean jvmIsStrictlySun() {
+		return jvmIs("Sun");
+	}
+
+	private static boolean jvmIs(String jvmVendorName) {
+		return System.getProperty("java.vendor").startsWith(jvmVendorName);
+	}
+
+
+	// ********** Java specification version **********
+
+	/**
+	 * Return whether the Java specification version of the current JVM
+	 * is greater than the specified version (e.g. <code>"1.5"</code>).
+	 * <p>
+	 * This is useful for a test that should fail if it encounters a newer
+	 * JVM than what the current code supports, serving as a reminder to the
+	 * developers. :-)
+	 */
+	public static boolean javaSpecificationVersionIsGreaterThan(String version) {
+		return VersionComparator.INTEGER_VERSION_COMPARATOR.compare(javaSpecificationVersion(), version) > 0;
+	}
+
+	/**
+	 * Return whether the Java specification version of the current JVM
+	 * is less than or equal to the specified version (e.g. <code>"1.5"</code>).
+	 */
+	public static boolean javaSpecificationVersionIsLessThanOrEqualTo(String version) {
+		return ! javaSpecificationVersionIsGreaterThan(version);
+	}
+
+	/**
+	 * Return whether the Java specification version of the current JVM
+	 * is less than the specified version (e.g. <code>"1.5"</code>).
+	 */
+	public static boolean javaSpecificationVersionIsLessThan(String version) {
+		return VersionComparator.INTEGER_VERSION_COMPARATOR.compare(javaSpecificationVersion(), version) < 0;
+	}
+
+	/**
+	 * Return whether the Java specification version of the current JVM
+	 * is greater than or equal to the specified version (e.g. <code>"1.5"</code>).
+	 */
+	public static boolean javaSpecificationVersionIsGreaterThanOrEqualTo(String version) {
+		return ! javaSpecificationVersionIsLessThan(version);
+	}
+
+	/**
+	 * Return the Java specification version of the current JVM.
+	 */
+	public static String javaSpecificationVersion() {
+		return System.getProperty("java.specification.version");
+	}
+
+
+	// ********** file encoding **********
+
+	/**
+	 * Return whether the current file encoding is Microsoft Windows
+	 * (i.e. "Cp1252").
+	 */
+	public static boolean fileEncodingIsWindows() {
+		return fileEncoding().equals("Cp1252");
+	}
+
+	/**
+	 * Return whether the current file encoding is UTF-8.
+	 */
+	public static boolean fileEncodingIsUTF8() {
+		return fileEncoding().equals("UTF-8");
+	}
+
+	private static String fileEncoding() {
+		return System.getProperty("file.encoding");
+	}
+
+
+	// ********** O/S **********
+
+	/**
+	 * Return whether the current operating system is Microsoft Windows.
+	 */
+	public static boolean osIsWindows() {
+		return osIs("Windows");
+	}
+
+	/**
+	 * Return whether the current operating system is Linux.
+	 */
+	public static boolean osIsLinux() {
+		return osIs("Linux");
+	}
+
+	/**
+	 * Return whether the current operating system is Mac OS X.
+	 */
+	public static boolean osIsMac() {
+		return osIs("Mac");
+	}
+
+	private static boolean osIs(String osName) {
+		return System.getProperty("os.name").indexOf(osName) != -1;
+	}
+
+
+	// ********** constructor **********
+
+	/**
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private SystemTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Tools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Tools.java
deleted file mode 100644
index 1ba6273..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Tools.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-/**
- * Various utility methods.
- *
- * @version 2.5
- */
-@SuppressWarnings("nls")
-public final class Tools {
-
-	// ********** object comparison **********
-
-	/**
-	 * Returns whether the specified values are equal, with the appropriate
-	 * <code>null</code> checks.
-	 */
-	public static boolean valuesAreEqual(Object value1, Object value2) {
-		return (value1 == null) ?
-				(value2 == null) :
-				((value2 != null) && value1.equals(value2));
-	}
-
-	/**
-	 * Returns whether the specified values are different, with the appropriate
-	 * <code>null</code> checks.
-	 */
-	public static boolean valuesAreDifferent(Object value1, Object value2) {
-		return (value1 == null) ?
-				(value2 != null) :
-				((value2 == null) || ! value1.equals(value2));
-	}
-
-
-	// ********** System properties **********
-
-	/**
-	 * Returns whether the current JVM is Sun's (or Oracle's).
-	 */
-	public static boolean jvmIsSun() {
-		return jvmIs("Sun") || jvmIs("Oracle");
-	}
-
-	/**
-	 * Returns whether the current JVM is IBM's.
-	 */
-	public static boolean jvmIsIBM() {
-		return jvmIs("IBM");
-	}
-
-	private static boolean jvmIs(String jvmVendorName) {
-		return System.getProperty("java.vendor").startsWith(jvmVendorName);
-	}
-
-	/**
-	 * Returns whether the current operating system is Microsoft Windows.
-	 */
-	public static boolean osIsWindows() {
-		return osIs("Windows");
-	}
-
-	/**
-	 * Returns whether the current operating system is Linux.
-	 */
-	public static boolean osIsLinux() {
-		return osIs("Linux");
-	}
-
-	/**
-	 * Returns whether the current operating system is Mac OS X.
-	 */
-	public static boolean osIsMac() {
-		return osIs("Mac");
-	}
-
-	private static boolean osIs(String osName) {
-		return System.getProperty("os.name").indexOf(osName) != -1;
-	}
-
-
-	// ********** constructor **********
-
-	/**
-	 * Suppress default constructor, ensuring non-instantiability.
-	 */
-	private Tools() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Transformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Transformer.java
deleted file mode 100644
index 867d98a..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/Transformer.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.Serializable;
-
-/**
- * Used by various "pluggable" classes to transform objects. Transform an object of type
- * <code>T2</code> to an object of type <code>T1</code>.
- *
- * @param <T1> the type of the object returned by the transformer
- * @param <T2> the type of the object passed to the transformer
- * @version 2.5
- */
-public interface Transformer<T1, T2> {
-
-	/**
-	 * Returns the transformed object. The semantics of "transform" is determined by the contract
-	 * between the client and the server.
-	 */
-	T1 transform(T2 object);
-
-	/**
-	 * A "null" transformer will perform no transformation at all;
-	 * returns the object "untransformed".
-	 */
-	final class Null<S1, S2> implements Transformer<S1, S2>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final Transformer INSTANCE = new Null();
-		@SuppressWarnings("unchecked")
-		public static <R1, R2> Transformer<R1, R2> instance() {
-			return INSTANCE;
-		}
-		// ensure single instance
-		private Null() {
-			super();
-		}
-		// Returns the object, unchanged
-		@Override
-		@SuppressWarnings("unchecked")
-		public S1 transform(S2 o) {
-			return (S1) o;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-		private static final long serialVersionUID = 1L;
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-	}
-
-	/**
-	 * A "disabled" transformer will throw an exception if
-	 * {@link #transform(Object)} is called. This is useful in situations
-	 * where a transformer is optional and the default transformer should
-	 * not be used.
-	 */
-	final class Disabled<S1, S2> implements Transformer<S1, S2>, Serializable {
-		@SuppressWarnings("rawtypes")
-		public static final Transformer INSTANCE = new Disabled();
-		@SuppressWarnings("unchecked")
-		public static <R1, R2> Transformer<R1, R2> instance() {
-			return INSTANCE;
-		}
-		// ensure single instance
-		private Disabled() {
-			super();
-		}
-		// throw an exception
-		@Override
-		public S1 transform(S2 o) {
-			throw new UnsupportedOperationException();
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-		private static final long serialVersionUID = 1L;
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/TransformerAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/TransformerAdapter.java
deleted file mode 100644
index 9660770..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/TransformerAdapter.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-/**
- * Convenience transformer that returns <code>null</code> for every transformation.
- *
- * @version 2.5
- */
-public class TransformerAdapter<T1, T2> implements Transformer<T1, T2> {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public T1 transform(T2 object) {
-		return null;
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/TypeDeclarationTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/TypeDeclarationTools.java
new file mode 100644
index 0000000..9089638
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/TypeDeclarationTools.java
@@ -0,0 +1,659 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility;
+
+import java.util.Arrays;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+
+/**
+ * Convenience methods related to dealing with Java source code level
+ * type declarations (i.e. text descriptions of Java types as they appear
+ * in Java source code as opposed to the value returned by
+ * {@link java.lang.Class#getName()}).
+ */
+@SuppressWarnings("nls")
+public final class TypeDeclarationTools {
+
+	// ********** is array **********
+
+	/**
+	 * Return whether the specified type declaration is an array type; e.g.<ul>
+	 * <li><code>"int"</code> returns <code>false</code>
+	 * <li><code>"int[]"</code> returns <code>true</code>
+	 * <li><code>"java.lang.String"</code> returns <code>false</code>
+	 * <li><code>"java.lang.String[][][]"</code> returns <code>true</code>
+	 * </ul>
+	 */
+	public static boolean isArray(String typeDeclaration) {
+		return isArray_(StringTools.removeAllWhitespace(typeDeclaration));
+	}
+
+	/**
+	 * Pre-condition: no whitespace in the type declaration.
+	 */
+	private static boolean isArray_(String typeDeclaration) {
+		return StringTools.last(typeDeclaration) == ']';
+	}
+
+	/**
+	 * @see #isArray(String)
+	 */
+	public static boolean isArray(char[] typeDeclaration) {
+		return isArray_(CharArrayTools.removeAllWhitespace(typeDeclaration));
+	}
+
+	/**
+	 * Pre-condition: no whitespace in the type declaration.
+	 */
+	private static boolean isArray_(char[] typeDeclaration) {
+		return CharArrayTools.last(typeDeclaration) == ']';
+	}
+
+
+	// ********** array depth **********
+
+	/**
+	 * Return the array depth for the specified type declaration; e.g.<ul>
+	 * <li><code>"int[]"</code> returns <code>1</code>
+	 * <li><code>"java.lang.String[][][]"</code> returns <code>3</code>
+	 * </ul>
+	 */
+	public static int arrayDepth(String typeDeclaration) {
+		return arrayDepth_(StringTools.removeAllWhitespace(typeDeclaration));
+	}
+
+	/**
+	 * Pre-condition: no whitespace in the type declaration.
+	 */
+	static int arrayDepth_(String typeDeclaration) {
+		int last = typeDeclaration.length() - 1;
+		int depth = 0;
+		int close = last;
+		while (typeDeclaration.charAt(close) == ']') {
+			if (typeDeclaration.charAt(close - 1) == '[') {
+				depth++;
+			} else {
+				throw new IllegalArgumentException("invalid type declaration: " + typeDeclaration);
+			}
+			close = last - (depth << 1);
+		}
+		return depth;
+	}
+
+	/**
+	 * @see #arrayDepth(String)
+	 */
+	public static int arrayDepth(char[] typeDeclaration) {
+		return arrayDepth_(CharArrayTools.removeAllWhitespace(typeDeclaration));
+	}
+
+	/**
+	 * Pre-condition: no whitespace in the type declaration.
+	 */
+	static int arrayDepth_(char[] typeDeclaration) {
+		int last = typeDeclaration.length - 1;
+		int depth = 0;
+		int close = last;
+		while (typeDeclaration[close] == ']') {
+			if (typeDeclaration[close - 1] == '[') {
+				depth++;
+			} else {
+				throw new IllegalArgumentException("invalid type declaration: " + String.copyValueOf(typeDeclaration));
+			}
+			close = last - (depth << 1);
+		}
+		return depth;
+	}
+
+
+	// ********** element type name **********
+
+	/**
+	 * Return the element type name for the specified type declaration; e.g.<ul>
+	 * <li><code>"int[]"</code> returns <code>"int"</code>
+	 * <li><code>"java.lang.String[][][]"</code> returns <code>"java.lang.String"</code>
+	 * </ul>
+	 */
+	public static String elementTypeName(String typeDeclaration) {
+		typeDeclaration = StringTools.removeAllWhitespace(typeDeclaration);
+		return elementTypeName_(typeDeclaration, arrayDepth_(typeDeclaration));
+	}
+
+	/**
+	 * @see #elementTypeName(String)
+	 */
+	public static char[] elementTypeName(char[] typeDeclaration) {
+		typeDeclaration = CharArrayTools.removeAllWhitespace(typeDeclaration);
+		return elementTypeName_(typeDeclaration, arrayDepth_(typeDeclaration));
+	}
+
+	/**
+	 * Return the element type name for the specified type declaration; e.g.<ul>
+	 * <li><code>"int[]"</code> returns <code>"int"</code>
+	 * <li><code>"java.lang.String[][][]"</code> returns <code>"java.lang.String"</code>
+	 * </ul>
+	 * Useful for clients that have already queried the type declaration's array depth.
+	 */
+	public static String elementTypeName(String typeDeclaration, int arrayDepth) {
+		return elementTypeName_(StringTools.removeAllWhitespace(typeDeclaration), arrayDepth);
+	}
+
+	/**
+	 * Pre-condition: no whitespace in the type declaration.
+	 */
+	static String elementTypeName_(String typeDeclaration, int arrayDepth) {
+		return typeDeclaration.substring(0, typeDeclaration.length() - (arrayDepth << 1));
+	}
+
+	/**
+	 * @see #elementTypeName(String, int)
+	 */
+	public static char[] elementTypeName(char[] typeDeclaration, int arrayDepth) {
+		return elementTypeName_(CharArrayTools.removeAllWhitespace(typeDeclaration), arrayDepth);
+	}
+
+	/**
+	 * Pre-condition: no whitespace in the type declaration.
+	 */
+	static char[] elementTypeName_(char[] typeDeclaration, int arrayDepth) {
+		return ArrayTools.subArray(typeDeclaration, 0, typeDeclaration.length - (arrayDepth << 1));
+	}
+
+
+	// ********** component type declaration **********
+
+	/**
+	 * Return the specified type declaration's component type.
+	 * Return <code>null</code> if the specified type declaration is not an array type.
+	 */
+	public static String componentTypeDeclaration(String typeDeclaration) {
+		return componentTypeDeclaration_(StringTools.removeAllWhitespace(typeDeclaration));
+	}
+
+	/**
+	 * Pre-condition: no whitespace in the type declaration.
+	 */
+	private static String componentTypeDeclaration_(String typeDeclaration) {
+		int arrayDepth = arrayDepth_(typeDeclaration);
+		return (arrayDepth == 0) ? null : elementTypeName_(typeDeclaration, 1);
+	}
+
+	/**
+	 * @see #componentTypeDeclaration(String)
+	 */
+	public static char[] componentTypeDeclaration(char[] typeDeclaration) {
+		return componentTypeDeclaration_(CharArrayTools.removeAllWhitespace(typeDeclaration));
+	}
+
+	/**
+	 * Pre-condition: no whitespace in the type declaration.
+	 */
+	private static char[] componentTypeDeclaration_(char[] typeDeclaration) {
+		int arrayDepth = arrayDepth_(typeDeclaration);
+		return (arrayDepth == 0) ? null : elementTypeName_(typeDeclaration, 1);
+	}
+
+
+	// ********** class name **********
+
+	/**
+	 * Return the class name for the specified type declaration; e.g.<ul>
+	 * <li><code>"int"</code> returns <code>"int"</code>
+	 * <li><code>"int[]"</code> returns <code>"[I"</code>
+	 * <li><code>"java.lang.String"</code> returns <code>"java.lang.String"</code>
+	 * <li><code>"java.lang.String[][][]"</code> returns <code>"[[[Ljava.lang.String;"</code>
+	 * </ul>
+	 * @see java.lang.Class#getName()
+	 */
+	public static String className(String typeDeclaration) {
+		return className_(StringTools.removeAllWhitespace(typeDeclaration));
+	}
+
+	/**
+	 * Pre-condition: no whitespace in the type declaration.
+	 */
+	private static String className_(String typeDeclaration) {
+		int arrayDepth = arrayDepth_(typeDeclaration);
+		String elementTypeName = elementTypeName_(typeDeclaration, arrayDepth);
+		return className(elementTypeName, arrayDepth);
+	}
+
+	/**
+	 * @see #className(String)
+	 */
+	public static char[] className(char[] typeDeclaration) {
+		return className_(CharArrayTools.removeAllWhitespace(typeDeclaration));
+	}
+
+	/**
+	 * Pre-condition: no whitespace in the type declaration.
+	 */
+	private static char[] className_(char[] typeDeclaration) {
+		int arrayDepth = arrayDepth_(typeDeclaration);
+		char[] elementTypeName = elementTypeName_(typeDeclaration, arrayDepth);
+		return className(elementTypeName, arrayDepth);
+	}
+
+	/**
+	 * Return the class name for the specified type declaration.
+	 * @see java.lang.Class#getName()
+	 */
+	public static String className(String elementTypeName, int arrayDepth) {
+		// non-array
+		if (arrayDepth == 0) {
+			return elementTypeName;
+		}
+
+		if (elementTypeName.equals(ClassNameTools.VOID)) {
+			throw new IllegalArgumentException('\'' + ClassNameTools.VOID + "' must have an array depth of zero: " + arrayDepth + '.');
+		}
+		// array
+		StringBuilder sb = new StringBuilder(100);
+		for (int i = arrayDepth; i-- > 0; ) {
+			sb.append('[');
+		}
+
+		// look for a primitive first
+		char prim = ClassNameTools.primitiveClassCode(elementTypeName);
+		if (prim == 0) {
+			ClassNameTools.appendReferenceNameTo(elementTypeName, sb);
+		} else {
+			sb.append(prim);
+		}
+
+		return sb.toString();
+	}
+
+	/**
+	 * @see #className(String, int)
+	 */
+	public static char[] className(char[] elementTypeName, int arrayDepth) {
+		// non-array
+		if (arrayDepth == 0) {
+			return elementTypeName;
+		}
+
+		if (Arrays.equals(elementTypeName, ClassNameTools.VOID_CHAR_ARRAY)) {
+			throw new IllegalArgumentException('\'' + ClassNameTools.VOID + "' must have an array depth of zero: " + arrayDepth + '.');
+		}
+		// array
+		StringBuilder sb = new StringBuilder(100);
+		for (int i = arrayDepth; i-- > 0; ) {
+			sb.append('[');
+		}
+
+		// look for a primitive first
+		char prim = ClassNameTools.primitiveClassCode(elementTypeName);
+		if (prim == 0) {
+			ClassNameTools.appendReferenceNameTo(elementTypeName, sb);
+		} else {
+			sb.append(prim);
+		}
+
+		return StringBuilderTools.convertToCharArray(sb);
+	}
+
+
+	// ********** package/simple name **********
+
+	/**
+	 * Return the specified type declaration's simple name.
+	 */
+	public static String simpleName(String typeDeclaration) {
+		return simpleName_(StringTools.removeAllWhitespace(typeDeclaration));
+	}
+
+	/**
+	 * Pre-condition: no whitespace in the type declaration.
+	 */
+	private static String simpleName_(String typeDeclaration) {
+		return typeDeclaration.substring(typeDeclaration.lastIndexOf('.') + 1);
+	}
+
+	/**
+	 * @see #simpleName(String)
+	 */
+	public static char[] simpleName(char[] typeDeclaration) {
+		return simpleName_(CharArrayTools.removeAllWhitespace(typeDeclaration));
+	}
+
+	/**
+	 * Pre-condition: no whitespace in the type declaration.
+	 */
+	private static char[] simpleName_(char[] typeDeclaration) {
+		return ArrayTools.subArray(typeDeclaration, ArrayTools.lastIndexOf(typeDeclaration, '.') + 1);
+	}
+
+	/**
+	 * Return the specified type declaration's package name (e.g.
+	 * <code>"java.lang.Object"</code> returns
+	 * <code>"java.lang"</code>).
+	 * Return an empty string if the specified class is:<ul>
+	 * <li>in the "default" package
+	 * <li>an array class
+	 * <li>a primtive class
+	 * </ul>
+	 */
+	public static String packageName(String typeDeclaration) {
+		return packageName_(StringTools.removeAllWhitespace(typeDeclaration));
+	}
+
+	/**
+	 * Pre-condition: no whitespace in the type declaration.
+	 */
+	private static String packageName_(String typeDeclaration) {
+		if (isArray_(typeDeclaration)) {
+			return StringTools.EMPTY_STRING;
+		}
+		int lastPeriod = typeDeclaration.lastIndexOf('.');
+		return (lastPeriod == -1) ? StringTools.EMPTY_STRING : typeDeclaration.substring(0, lastPeriod);
+	}
+
+	/**
+	 * @see #packageName(String)
+	 */
+	public static char[] packageName(char[] typeDeclaration) {
+		return packageName_(CharArrayTools.removeAllWhitespace(typeDeclaration));
+	}
+
+	/**
+	 * Pre-condition: no whitespace in the type declaration.
+	 */
+	private static char[] packageName_(char[] typeDeclaration) {
+		if (isArray_(typeDeclaration)) {
+			return CharArrayTools.EMPTY_CHAR_ARRAY;
+		}
+		int lastPeriod = ArrayTools.lastIndexOf(typeDeclaration, '.');
+		return (lastPeriod == -1) ? CharArrayTools.EMPTY_CHAR_ARRAY : ArrayTools.subArray(typeDeclaration, 0, lastPeriod);
+	}
+
+
+	// ********** java.lang classes **********
+
+	/**
+	 * Return whether the specified "simple" class name is a public class in the
+	 * current release of the <code>java.lang</code> package (i.e. a class that
+	 * can be declared with a "simple" name and no corresponding
+	 * <code>import</code> statement).\
+	 * <p>
+	 * The current release is jdk 1.7.
+	 */
+	public static boolean isJavaLangClass(String simpleClassName) {
+		return ArrayTools.binarySearch(JAVA_LANG_CLASS_NAMES_ARRAY, simpleClassName);
+	}
+
+	/**
+	 * @see #isJavaLangClass(String)
+	 */
+	public static boolean isJavaLangClass(char[] simpleClassName) {
+		return isJavaLangClass(String.copyValueOf(simpleClassName));
+	}
+
+	/**
+	 * JDK 1.5
+	 * @see #isJavaLangClass(String)
+	 */
+	public static boolean isJavaLangClass5(String simpleClassName) {
+		return ArrayTools.binarySearch(JAVA_LANG_CLASS_NAMES_ARRAY_5, simpleClassName);
+	}
+
+	/**
+	 * @see #isJavaLangClass5(String)
+	 */
+	public static boolean isJavaLangClass5(char[] simpleClassName) {
+		return isJavaLangClass5(String.copyValueOf(simpleClassName));
+	}
+
+	// JDK 1.5
+	private static final String[] JAVA_LANG_CLASS_NAMES_ARRAY_5 = ArrayTools.sort(new String[] {
+		"AbstractMethodError",
+		"Appendable",
+		"ArithmeticException",
+		"ArrayIndexOutOfBoundsException",
+		"ArrayStoreException",
+		"AssertionError",
+		"Boolean",
+		"Byte",
+		"Character",
+		"Character.Subset",
+		"Character.UnicodeBlock",
+		"CharSequence",
+		"Class",
+		"ClassCastException",
+		"ClassCircularityError",
+		"ClassFormatError",
+		"ClassLoader",
+		"ClassNotFoundException",
+		"Cloneable",
+		"CloneNotSupportedException",
+		"Comparable",
+		"Compiler",
+		"Deprecated",
+		"Double",
+		"Enum",
+		"EnumConstantNotPresentException",
+		"Error",
+		"Exception",
+		"ExceptionInInitializerError",
+		"Float",
+		"IllegalAccessError",
+		"IllegalAccessException",
+		"IllegalArgumentException",
+		"IllegalMonitorStateException",
+		"IllegalStateException",
+		"IllegalThreadStateException",
+		"IncompatibleClassChangeError",
+		"IndexOutOfBoundsException",
+		"InheritableThreadLocal",
+		"InstantiationError",
+		"InstantiationException",
+		"Integer",
+		"InternalError",
+		"InterruptedException",
+		"Iterable",
+		"LinkageError",
+		"Long",
+		"Math",
+		"NegativeArraySizeException",
+		"NoClassDefFoundError",
+		"NoSuchFieldError",
+		"NoSuchFieldException",
+		"NoSuchMethodError",
+		"NoSuchMethodException",
+		"NullPointerException",
+		"Number",
+		"NumberFormatException",
+		"Object",
+		"OutOfMemoryError",
+		"Override",
+		"Package",
+		"Process",
+		"ProcessBuilder",
+		"Readable",
+		"Runnable",
+		"Runtime",
+		"RuntimeException",
+		"RuntimePermission",
+		"SecurityException",
+		"SecurityManager",
+		"Short",
+		"StackOverflowError",
+		"StackTraceElement",
+		"StrictMath",
+		"String",
+		"StringBuffer",
+		"StringBuilder",
+		"StringIndexOutOfBoundsException",
+		"SuppressWarnings",
+		"System",
+		"Thread",
+		"Thread.State",
+		"Thread.UncaughtExceptionHandler",
+		"ThreadDeath",
+		"ThreadGroup",
+		"ThreadLocal",
+		"Throwable",
+		"TypeNotPresentException",
+		"UnknownError",
+		"UnsatisfiedLinkError",
+		"UnsupportedClassVersionError",
+		"UnsupportedOperationException",
+		"VerifyError",
+		"VirtualMachineError",
+		"Void",
+	});
+
+	/**
+	 * JDK 1.5.
+	 */
+	public static final Iterable<String> JAVA_LANG_CLASS_NAMES_5 = IterableTools.iterable(JAVA_LANG_CLASS_NAMES_ARRAY_5);
+
+	/**
+	 * JDK 1.6
+	 * @see #isJavaLangClass(String)
+	 */
+	public static boolean isJavaLangClass6(String simpleClassName) {
+		return ArrayTools.binarySearch(JAVA_LANG_CLASS_NAMES_ARRAY_6, simpleClassName);
+	}
+
+	/**
+	 * @see #isJavaLangClass6(String)
+	 */
+	public static boolean isJavaLangClass6(char[] simpleClassName) {
+		return isJavaLangClass6(String.copyValueOf(simpleClassName));
+	}
+
+	// JDK 1.6 - no changes from jdk 1.5
+	private static final String[] JAVA_LANG_CLASS_NAMES_ARRAY_6 = JAVA_LANG_CLASS_NAMES_ARRAY_5;
+
+	/**
+	 * JDK 1.6.
+	 */
+	public static final Iterable<String> JAVA_LANG_CLASS_NAMES_6 = IterableTools.iterable(JAVA_LANG_CLASS_NAMES_ARRAY_6);
+
+	/**
+	 * JDK 1.7
+	 * @see #isJavaLangClass(String)
+	 */
+	public static boolean isJavaLangClass7(String simpleClassName) {
+		return ArrayTools.binarySearch(JAVA_LANG_CLASS_NAMES_ARRAY_7, simpleClassName);
+	}
+
+	/**
+	 * @see #isJavaLangClass7(String)
+	 */
+	public static boolean isJavaLangClass7(char[] simpleClassName) {
+		return isJavaLangClass7(String.copyValueOf(simpleClassName));
+	}
+
+	// jdk 1.7
+	private static final String[] JAVA_LANG_CLASS_NAMES_ARRAY_7 = ArrayTools.sort(
+		ArrayTools.concatenate(
+			JAVA_LANG_CLASS_NAMES_ARRAY_6,
+			new String[] {
+				"AutoCloseable",
+				"BootstrapMethodError",
+				"Character.UnicodeScript",
+				"ClassValue",
+				"ProcessBuilder.Redirect",
+				"ProcessBuilder.Redirect.Type",
+				"ReflectiveOperationException",
+				"SafeVarargs"
+			}
+		)
+	);
+
+	/**
+	 * JDK 1.7.
+	 */
+	public static final Iterable<String> JAVA_LANG_CLASS_NAMES_7 = IterableTools.iterable(JAVA_LANG_CLASS_NAMES_ARRAY_7);
+
+	// the current release is jdk 1.7
+	private static final String[] JAVA_LANG_CLASS_NAMES_ARRAY = JAVA_LANG_CLASS_NAMES_ARRAY_7;
+
+	/**
+	 * The current release is jdk 1.7.
+	 */
+	public static final Iterable<String> JAVA_LANG_CLASS_NAMES = IterableTools.iterable(JAVA_LANG_CLASS_NAMES_ARRAY);
+
+
+	// ********** load class **********
+
+	/**
+	 * Return the class for the specified type declaration.
+	 */
+	public static Class<?> loadClass(String typeDeclaration) {
+		return ClassTools.forTypeDeclaration(typeDeclaration);
+	}
+
+	/**
+	 * Return the class for the specified type declaration.
+	 */
+	public static Class<?> loadClass(String typeDeclaration, ClassLoader classLoader) {
+		return ClassTools.forTypeDeclaration(typeDeclaration, classLoader);
+	}
+
+	/**
+	 * Return the class for the specified type declaration.
+	 */
+	public static Class<?> loadClass_(String typeDeclaration) throws ClassNotFoundException {
+		return ClassTools.forTypeDeclaration_(typeDeclaration);
+	}
+
+	/**
+	 * Return the class for the specified type declaration.
+	 */
+	public static Class<?> loadClass_(String typeDeclaration, ClassLoader classLoader) throws ClassNotFoundException {
+		return ClassTools.forTypeDeclaration_(typeDeclaration, classLoader);
+	}
+
+	/**
+	 * Return the class for the specified type declaration.
+	 */
+	public static Class<?> loadClass(char[] typeDeclaration) {
+		return ClassTools.forTypeDeclaration(typeDeclaration);
+	}
+
+	/**
+	 * Return the class for the specified type declaration.
+	 */
+	public static Class<?> loadClass(char[] typeDeclaration, ClassLoader classLoader) {
+		return ClassTools.forTypeDeclaration(typeDeclaration, classLoader);
+	}
+
+	/**
+	 * Return the class for the specified type declaration.
+	 */
+	public static Class<?> loadClass_(char[] typeDeclaration) throws ClassNotFoundException {
+		return ClassTools.forTypeDeclaration_(typeDeclaration);
+	}
+
+	/**
+	 * Return the class for the specified type declaration.
+	 */
+	public static Class<?> loadClass_(char[] typeDeclaration, ClassLoader classLoader) throws ClassNotFoundException {
+		return ClassTools.forTypeDeclaration_(typeDeclaration, classLoader);
+	}
+
+
+	// ********** suppressed constructor **********
+
+	/**
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private TypeDeclarationTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/VersionComparator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/VersionComparator.java
index fed95ab..344c3a2 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/VersionComparator.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/VersionComparator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -19,52 +19,32 @@
 import java.util.StringTokenizer;
 
 /**
- * This comparator can be used to compare version strings (e.g. "2.2.2" vs.
- * "2.14.3"). Clients can specify the delimiter(s) that separates a version's
+ * This comparator can be used to compare version strings
+ * (e.g. <code>"2.2.2"</code> vs. <code>"2.14.3"</code>).
+ * Clients can specify the delimiter(s) that separates a version's
  * <em>segments</em> as well as a parser to be used for parsing each
  * <em>segment</em>.
  *
  * @see #INTEGER_VERSION_COMPARATOR
- * @version 2.5
  */
 @SuppressWarnings("nls")
-public class VersionComparator<T extends Comparable<T>> implements Comparator<String> {
-
+public class VersionComparator<T extends Comparable<T>>
+	implements Comparator<String>
+{
 	private final String delimiters;
 	private final SegmentParser<T> segmentParser;
 
+
 	/**
 	 * Static implementation of the version comparator interface that converts
 	 * each version into a series of integers and compares them.
 	 * <p>
-	 * <strong>NB:</strong> With this comparator <code>"2.14" > "2.2"</code>
+	 * <strong>NB:</strong> With this comparator
+	 * <code>"2.<strong>14</strong>" > "2.<strong>2</strong>"</code>
+	 * is <code>true</code>.
 	 */
 	public static final Comparator<String> INTEGER_VERSION_COMPARATOR = new VersionComparator<Integer>(SegmentParser.IntegerSegmentParser.instance());
 
-	/**
-	 * The default delimiter is <code>'.'</code>.
-	 * The default segment parser is disabled.
-	 * <p>
-	 * <strong>NB:</strong> Subclass must override:<ul>
-	 *     <li>{@link #parseSegment(int, String)}
-	 *     <li>{@link #getZero()}
-	 * </ul>
-	 */
-	protected VersionComparator() {
-		this(".");
-	}
-
-	/**
-	 * The default segment parser is disabled.
-	 * <p>
-	 * <strong>NB:</strong> Subclass must override:<ul>
-	 *     <li>{@link #parseSegment(int, String)}
-	 *     <li>{@link #getZero()}
-	 * </ul>
-	 */
-	protected VersionComparator(String delimiters) {
-		this(delimiters, SegmentParser.Disabled.<T>instance());
-	}
 
 	/**
 	 * Use the specified segment parser.
@@ -77,15 +57,32 @@
 	/**
 	 * Use the specified delimiters and segment parser.
 	 */
+	public VersionComparator(char delimiter, SegmentParser<T> segmentParser) {
+		this(new char[] {delimiter}, segmentParser);
+	}
+
+	/**
+	 * Use the specified delimiters and segment parser.
+	 */
+	public VersionComparator(char[] delimiters, SegmentParser<T> segmentParser) {
+		this(new String(delimiters), segmentParser);
+	}
+
+	/**
+	 * Use the specified delimiters and segment parser.
+	 */
 	public VersionComparator(String delimiters, SegmentParser<T> segmentParser) {
 		super();
+		if ((delimiters == null) || (segmentParser == null)) {
+			throw new NullPointerException();
+		}
 		this.delimiters = delimiters;
 		this.segmentParser = segmentParser;
 	}
 
 
 	/**
-	 * <strong>NB:</strong> Callers must handle any exceptions thrown by the
+	 * <strong>NB:</strong> Callers must handle any runtime exceptions thrown by the
 	 * segment parser supplied to the comparator. In particular, the pre-built
 	 * integer segment parser {@link #INTEGER_VERSION_COMPARATOR} can throw a
 	 * {@link NumberFormatException} if any segement string contains non-numeric
@@ -137,20 +134,11 @@
 		ArrayList<T> segments = new ArrayList<T>();
 		int i = 0;
 		for (StringTokenizer stream = new StringTokenizer(s, this.delimiters); stream.hasMoreTokens(); ) {
-			segments.add(this.parseSegment(i++, stream.nextToken()));
+			segments.add(this.segmentParser.parse(i++, stream.nextToken()));
 		}
 		return segments;
 	}
 
-	/**
-	 * Parse the specified segment into the appropriate comparable.
-	 * Subclasses must override this method if a segment parser is not passed
-	 * to the version comparator's constructor.
-	 */
-	protected T parseSegment(int index, String s) {
-		return this.segmentParser.parse(index, s);
-	}
-
 	protected T getZero() {
 		return this.segmentParser.getZero();
 	}
@@ -170,7 +158,7 @@
 		T parse(int segmentIndex, String segment);
 
 		/**
-		 * Returns a "zero" <em>segment</em> value that can be compared to
+		 * Return a "zero" <em>segment</em> value that can be compared to
 		 * trailing segments when two version have differing numbers of
 		 * <em>segments</em>.
 		 */
@@ -205,7 +193,7 @@
 			private static final Integer ZERO = Integer.valueOf(0);
 			@Override
 			public String toString() {
-				return StringTools.buildSingletonToString(this);
+				return ObjectTools.singletonToString(this);
 			}
 			private static final long serialVersionUID = 1L;
 			private Object readResolve() {
@@ -242,7 +230,7 @@
 			}
 			@Override
 			public String toString() {
-				return StringTools.buildSingletonToString(this);
+				return ObjectTools.singletonToString(this);
 			}
 			private static final long serialVersionUID = 1L;
 			private Object readResolve() {
@@ -251,4 +239,4 @@
 			}
 		}
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/XMLStringEncoder.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/XMLStringEncoder.java
deleted file mode 100644
index cf52a2d..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/XMLStringEncoder.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-
-/**
- * This encoder will replace any of a specified set of characters with an XML "character reference":
- * '/' => "&#x2f;"
- *
- * @version 2.5
- */
-@SuppressWarnings("nls")
-public final class XMLStringEncoder {
-
-	/** The set of characters to be converted into XML character references. */
-	private final char[] chars;
-
-	/** Cache the value of the highest character in the set above. */
-	private final char maxChar;
-
-	// ********** constructors/initialization **********
-
-	/**
-	 * Construct an encoder that converts the specified set of characters
-	 * into XML character references.
-	 */
-	public XMLStringEncoder(char[] chars) {
-		super();
-		if (chars == null) {
-			throw new NullPointerException();
-		}
-		// the ampersand must be included since it is the escape character
-		if (ArrayTools.contains(chars, '&')) {
-			this.chars = chars;
-		} else {
-			this.chars = ArrayTools.add(chars, '&');
-		}
-		this.maxChar = this.calculateMaxInvalidFileNameChar();
-	}
-
-	/**
-	 * Calculate the maximum value of the set of characters to be converted
-	 * into XML character references. This will be used to short-circuit the
-	 * search for a character in the set.
-	 * @see #charIsToBeEncoded(char)
-	 */
-	private char calculateMaxInvalidFileNameChar() {
-		char[] localChars = this.chars;
-		char max = 0;
-		for (int i = localChars.length; i-- > 0; ) {
-			char c = localChars[i];
-			if (max < c) {
-				max = c;
-			}
-		}
-		return max;
-	}
-
-
-	// ********** API **********
-
-	/**
-	 * Returns the specified string with any characters in the set
-	 * replaced with XML character references.
-	 */
-	public String encode(String s) {
-		int len = s.length();
-		// allow for a few encoded characters
-		StringBuilder sb = new StringBuilder(len + 20);
-		for (int i = 0; i < len; i++) {
-			this.appendCharacterTo(s.charAt(i), sb);
-		}
-		return sb.toString();
-	}
-
-	/**
-	 * Returns the specified string with any XML character references
-	 * replaced by the characters themselves.
-	 */
-	public String decode(String s) {
-		StringBuilder sb = new StringBuilder(s.length());
-		StringBuilder temp = new StringBuilder();	// performance tweak
-		this.decodeTo(new StringReader(s), sb, temp);
-		return sb.toString();
-	}
-
-
-	// ********** internal methods **********
-
-	/**
-	 * Append the specified character to the string buffer,
-	 * converting it to an XML character reference if necessary.
-	 */
-	private void appendCharacterTo(char c, StringBuilder sb) {
-		if (this.charIsToBeEncoded(c)) {
-			this.appendCharacterReferenceTo(c, sb);
-		} else {
-			sb.append(c);
-		}
-	}
-
-	/**
-	 * Returns whether the specified character is one of the characters
-	 * to be converted to XML character references.
-	 */
-	private boolean charIsToBeEncoded(char c) {
-		return (c <= this.maxChar) && ArrayTools.contains(this.chars, c);
-	}
-
-	/**
-	 * Append the specified character's XML character reference to the
-	 * specified string buffer (e.g. '/' => "&#x2f;").
-	 */
-	private void appendCharacterReferenceTo(char c, StringBuilder sb) {
-		sb.append("&#x");
-		sb.append(Integer.toString(c, 16));
-		sb.append(';');
-	}
-
-	private void decodeTo(Reader reader, StringBuilder sb, StringBuilder temp) {
-		try {
-			this.decodeTo_(reader, sb, temp);
-		} catch (IOException ex) {
-			throw new RuntimeException(ex);
-		}
-	}
-
-	private void decodeTo_(Reader reader, StringBuilder sb, StringBuilder temp) throws IOException {
-		int c = reader.read();
-		while (c != -1) {
-			if (c == '&') {
-				this.decodeCharacterReferenceTo(reader, sb, temp);
-			} else {
-				sb.append((char) c);
-			}
-			c = reader.read();
-		}
-		reader.close();
-	}
-
-	private void decodeCharacterReferenceTo(Reader reader, StringBuilder sb, StringBuilder temp) throws IOException {
-		int c = reader.read();
-		this.checkChar(c, '#');
-		c = reader.read();
-		this.checkChar(c, 'x');
-
-		temp.setLength(0);  // re-use temp
-		c = reader.read();
-		while (c != ';') {
-			this.checkEndOfStream(c);
-			temp.append((char) c);
-			c = reader.read();
-		}
-		String charValue = temp.toString();
-		if (charValue.length() == 0) {
-			throw new IllegalStateException("missing numeric string");
-		}
-		sb.append((char) Integer.parseInt(charValue, 16));
-	}
-
-	private void checkChar(int c, int expected) {
-		this.checkEndOfStream(c);
-		if (c != expected) {
-			throw new IllegalStateException("expected '" + (char) expected + "', but encountered '" + (char) c + "'"); //$NON-NLS-2$ //$NON-NLS-3$
-		}
-	}
-
-	private void checkEndOfStream(int c) {
-		if (c == -1) {
-			throw new IllegalStateException("unexpected end of string");
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/XMLTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/XMLTools.java
index 50a8b50..391fa78 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/XMLTools.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/XMLTools.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -8,8 +8,9 @@
  * http://www.eclipse.org/org/documents/edl-v10.php.
  *
  * Contributors:
- *     Oracle - initial API and implementation from Oracle TopLink
-******************************************************************************/
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
 package org.eclipse.persistence.tools.utility;
 
 import java.io.BufferedInputStream;
@@ -25,10 +26,10 @@
 import java.io.Reader;
 import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
-import java.util.List;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Result;
 import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
@@ -37,7 +38,6 @@
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
-
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -50,72 +50,48 @@
  * In particular, it facilitates the getting and setting of the values
  * of the children of a particular node (e.g. when reading and writing
  * the attributes of an object from and to an XML document).
- *
- * @version 2.5
  */
 @SuppressWarnings("nls")
 public final class XMLTools {
+	/**
+	 * The DOM parser factory.
+	 * Lazily initialized.
+	 */
+	private static DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY;
 
-	/**The DOM parser factory. */
-	private static DocumentBuilderFactory documentBuilderFactory;
+	/**
+	 * The DOM parser.
+	 * Just keep one around and synchronize access to it.
+	 * Lazily initialized.
+	 */
+	private static DocumentBuilder DOCUMENT_BUILDER;
 
-	/**The DOM parser. Just keep one around and synchronize access to it. */
-	private static DocumentBuilder documentBuilder;
 
-	/**The transformer factory. */
-	private static TransformerFactory transformerFactory;
+	/**
+	 * The transformer factory.
+	 * Lazily initialized.
+	 */
+	private static TransformerFactory TRANSFORMER_FACTORY;
 
-	/**The transformer. Just keep one around and synchronize access to it. */
-	private static Transformer transformer;
+	/**
+	 * The transformer.
+	 * Just keep one around and synchronize access to it.
+	 * Lazily initialized.
+	 */
+	private static Transformer TRANSFORMER;
+
 
 	// ********** parsing **********
 
 	/**
-	 * @see javax.xml.parsers.DocumentBuilderFactory#newInstance() for
-	 * documentation on how the implementation class is determined
-	 */
-	private static synchronized DocumentBuilderFactory documentBuilderFactory() {
-		if (documentBuilderFactory == null) {
-			documentBuilderFactory = DocumentBuilderFactory.newInstance();
-		}
-		return documentBuilderFactory;
-	}
-
-	private static synchronized DocumentBuilder documentBuilder() {
-		if (documentBuilder == null) {
-			try {
-				documentBuilder = documentBuilderFactory().newDocumentBuilder();
-			} catch (ParserConfigurationException ex) {
-				throw new RuntimeException(ex);
-			}
-		}
-		return documentBuilder;
-	}
-
-	/**
-	 * Returns an XML document based on the contents
+	 * Build and return an XML document based on the contents
 	 * of the specified input source.
-	 * DocumentBuilder#parse(InputSource inputSource) throws RuntimeExceptions
+	 * {@link DocumentBuilder#parse(InputSource inputSource)}
+	 * throws {@link RuntimeException}s.
 	 */
 	public static synchronized Document parse(InputSource inputSource) {
 		try {
-			return documentBuilder().parse(inputSource);
-		} catch (SAXException ex) {
-			throw new RuntimeException(ex);
-		} catch (IOException ex) {
-			throw new RuntimeException(ex);
-		}
-	}
-
-
-	/**
-	 * Returns an XML document based on the contents
-	 * of the specified input source.
-	 * DocumentBuilder#parse(String string) throws RuntimeExceptions
-	 */
-	public static synchronized Document parse(String string) {
-		try {
-			return documentBuilder().parse(string);
+			return getDocumentBuilder().parse(inputSource);
 		} catch (SAXException ex) {
 			throw new RuntimeException(ex);
 		} catch (IOException ex) {
@@ -124,9 +100,8 @@
 	}
 
 	/**
-	 * Returns an XML document based on the contents
+	 * Build and return an XML document based on the contents
 	 * of the specified reader.
-	 * DocumentBuilder#parse(Reader reader)
 	 */
 	public static Document parse(Reader reader) {
 		Document document = null;
@@ -143,9 +118,8 @@
 	}
 
 	/**
-	 * Returns an XML document based on the contents
+	 * Build and return an XML document based on the contents
 	 * of the specified input stream.
-	 * DocumentBuilder#parse(InputStream inputStream) throws RuntimeExceptions
 	 */
 	public static Document parse(InputStream inputStream) {
 		try {
@@ -156,9 +130,8 @@
 	}
 
 	/**
-	 * Returns an XML document based on the contents
+	 * Build and return an XML document based on the contents
 	 * of the specified file.
-	 * DocumentBuilder#parse(File file) throws RuntimeExceptions
 	 */
 	public static Document parse(File file) {
 		InputStream inputStream;
@@ -176,18 +149,38 @@
 		return document;
 	}
 
-
-	// ********** reading **********
+	private static synchronized DocumentBuilder getDocumentBuilder() {
+		if (DOCUMENT_BUILDER == null) {
+			try {
+				DOCUMENT_BUILDER = getDocumentBuilderFactory().newDocumentBuilder();
+			} catch (ParserConfigurationException ex) {
+				throw new RuntimeException(ex);
+			}
+		}
+		return DOCUMENT_BUILDER;
+	}
 
 	/**
-	 * Returns the child element node of the specified parent node with
-	 * Returns null if the child is not found.
-	 * Node#getChildElement(String childName)
+	 * See {@link javax.xml.parsers.DocumentBuilderFactory#newInstance()} for
+	 * documentation on how the implementation class is determined.
 	 */
-	public static Node child(Node parent, String childName) {
+	private static synchronized DocumentBuilderFactory getDocumentBuilderFactory() {
+		if (DOCUMENT_BUILDER_FACTORY == null) {
+			DOCUMENT_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
+		}
+		return DOCUMENT_BUILDER_FACTORY;
+	}
+
+
+	// ********** reading DOM **********
+
+	/**
+	 * Return the child element node of the specified parent node with
+	 * the specified name. Return <code>null</code> if the child is not found.
+	 */
+	public static Node getChild(Node parent, String childName) {
 		for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {
-			if ((child.getNodeType() == Node.ELEMENT_NODE)
-					&& child.getNodeName().equals(childName)) {
+			if ((child.getNodeType() == Node.ELEMENT_NODE) && child.getNodeName().equals(childName)) {
 				return child;
 			}
 		}
@@ -195,31 +188,29 @@
 	}
 
 	/**
-	 * Returns all the child element nodes of the specified node.
-	 * Node#getChildElements()
+	 * Return all the child element nodes of the specified node.
 	 */
-	public static Node[] children(Node node) {
+	public static Iterable<Node> getChildren(Node node) {
 		NodeList children = node.getChildNodes();
 		int len = children.getLength();
-		List<Node> result = new ArrayList<Node>(len);
+		ArrayList<Node> result = new ArrayList<Node>(len);
 		for (int i = 0; i < len; i++) {
 			Node child = children.item(i);
 			if (child.getNodeType() == Node.ELEMENT_NODE) {
 				result.add(child);
 			}
 		}
-		return result.toArray(new Node[result.size()]);
+		return result;
 	}
 
 	/**
-	 * Returns all the child element nodes of the specified node
+	 * Return all the child element nodes of the specified node
 	 * with the specified name.
-	 * Node#getChildElements(String childName)
 	 */
-	public static Node[] children(Node node, String childName) {
+	public static Iterable<Node> getChildren(Node node, String childName) {
 		NodeList children = node.getChildNodes();
 		int len = children.getLength();
-		List<Node> result = new ArrayList<Node>(len);
+		ArrayList<Node> result = new ArrayList<Node>(len);
 		for (int i = 0; i < len; i++) {
 			Node child = children.item(i);
 			if ((child.getNodeType() == Node.ELEMENT_NODE)
@@ -227,15 +218,14 @@
 				result.add(child);
 			}
 		}
-		return result.toArray(new Node[result.size()]);
+		return result;
 	}
 
 	/**
-	 * Returns the text content of the specified node.
+	 * Return the text content of the specified node.
 	 * Throw an exception if the node is not a "simple" node.
-	 * Node#getTextContent()
 	 */
-	public static String textContent(Node node) {
+	public static String getTextContent(Node node) {
 		NodeList children = node.getChildNodes();
 		// <foo></foo> or <foo/>
 		if (children.getLength() == 0) {
@@ -255,56 +245,46 @@
 	}
 
 	/**
-	 * Returns the text content of the specified child node.
-	 * The child node must exist (or you will get a NPE).
-	 *
+	 * Return the text content of the specified child node.
+	 * The child node must exist (or you will get a {@link NullPointerException}).
+	 * <p>
 	 * For example, given the following XML:
-	 *
-	 * 	<parent>
-	 * 		<child>Charlie</child>
-	 * 	</parent>
-	 *
-	 * XMLTools.childTextContent(parentNode, "child")
-	 * Returns "Charlie".
-	 * Node#getChildTextContent(String childName)
+	 * <pre>
+	 * &lt;parent>
+	 *     &lt;child>Charlie&lt;/child>
+	 * &lt;/parent>
+	 * </pre>
+	 * <code>XML.getChildTextContent(parentNode, "child")</code>
+	 * will return <code>"Charlie"</code>.
 	 */
-	public static String childTextContent(Node parent, String childName) {
-		return textContent(child(parent, childName));
+	public static String getChildTextContent(Node parent, String childName) {
+		return getTextContent(getChild(parent, childName));
 	}
 
 	/**
-	 * Returns the text content of the specified child node.
-	 * Returns the specified default value.
-	 * Node#getChildTextContent(String childName, String defaultValue)
+	 * Return the text content of the specified child node.
+	 * If the child node does not exist, return the specified default value.
 	 */
-	public static String childTextContent(Node parent, String childName, String defaultValue) {
-		Node child = child(parent, childName);
-		if (child == null) {
-			return defaultValue;
-		}
-		return textContent(child);
+	public static String getChildTextContent(Node parent, String childName, String defaultValue) {
+		Node child = getChild(parent, childName);
+		return (child == null) ? defaultValue : getTextContent(child);
 	}
 
 	/**
-	 * Returns the int content of the specified child node.
-	 * The child node must exist (or you will get a NPE).
-	 * Node#getChildIntContent(String childName)
+	 * Return the <code>int</code> content of the specified child node.
+	 * The child node must exist (or you will get a {@link NullPointerException}).
 	 */
-	public static int childIntContent(Node parent, String childName) {
-		return convertToInt(textContent(child(parent, childName)));
+	public static int getChildIntContent(Node parent, String childName) {
+		return convertToInt(getTextContent(getChild(parent, childName)));
 	}
 
 	/**
-	 * Returns the int content of the specified child node.
-	 * Returns the specified default value.
-	 * Node#getChildIntContent(String childName, int defaultValue)
+	 * Return the <code>int</code> content of the specified child node.
+	 * If the child node does not exist, return the specified default value.
 	 */
 	public static int childIntContent(Node parent, String childName, int defaultValue) {
-		Node child = child(parent, childName);
-		if (child == null) {
-			return defaultValue;
-		}
-		return convertToInt(textContent(child));
+		Node child = getChild(parent, childName);
+		return (child == null) ? defaultValue : convertToInt(getTextContent(child));
 	}
 
 	/**
@@ -315,61 +295,56 @@
 	}
 
 	/**
-	 * Returns the boolean content of the specified child node.
-	 * The child node must exist (or you will get a NPE).
-	 * Node#getChildBooleanContent(String childName)
+	 * Return the <code>boolean</code> content of the specified child node.
+	 * The child node must exist (or you will get a {@link NullPointerException}).
 	 */
-	public static boolean childBooleanContent(Node parent, String childName) {
-		return convertToBoolean(textContent(child(parent, childName)));
+	public static boolean getChildBooleanContent(Node parent, String childName) {
+		return convertToBoolean(getTextContent(getChild(parent, childName)));
 	}
 
 	/**
-	 * Returns the boolean content of the specified child node.
-	 * Returns the specified default value.
-	 * Node#getChildBooleanContent(String childName, boolean defaultValue)
+	 * Return the <code>boolean</code> content of the specified child node.
+	 * If the child node does not exist, return the specified default value.
 	 */
-	public static boolean childBooleanContent(Node parent, String childName, boolean defaultValue) {
-		Node child = child(parent, childName);
-		if (child == null) {
-			return defaultValue;
-		}
-		return convertToBoolean(textContent(child));
+	public static boolean getChildBooleanContent(Node parent, String childName, boolean defaultValue) {
+		Node child = getChild(parent, childName);
+		return (child == null) ? defaultValue : convertToBoolean(getTextContent(child));
 	}
 
 	/**
-	 * Convert the specified string to a boolean.
+	 * Convert the specified string to a <code>boolean</code>.
 	 */
 	private static boolean convertToBoolean(String string) {
 		String s = string.toLowerCase();
-		if (s.equals("t") || s.equals("true") || s.equals("1")) {
+		if (s.equals("t") || s.equals("true") || s.equals("1")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 			return true;
 		}
-		if (s.equals("f") || s.equals("false") || s.equals("0")) {
+		if (s.equals("f") || s.equals("false") || s.equals("0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 			return false;
 		}
 		throw new IllegalArgumentException(string);
 	}
 
 
-	// ********** writing **********
+	// ********** writing DOM **********
 
 	/**
-	 * Returns a new document. Once the document has been
-	 * built, it can be printed later by calling XMLTools.print(Document, File)
-	 * or XMLTools.print(Document, OutputStream).
+	 * Build and return a new document. Once the document has been
+	 * built, it can be printed later by calling {@link #print(Document, File)}
+	 * or {@link #print(Document, OutputStream)}.
 	 */
 	public static Document newDocument() {
-		return documentBuilder().newDocument();
+		return getDocumentBuilder().newDocument();
 	}
 
 	/**
 	 * Add a simple text node with the specified name and text
 	 * to the specified parent node.
-	 * Node#addSimpleTextNode(String childName, String text)
 	 */
 	public static void addSimpleTextNode(Node parent, String childName, String text) {
-		Node child = parent.getOwnerDocument().createElement(childName);
-		Node childTextNode = parent.getOwnerDocument().createTextNode(text);
+		Document document = parent.getOwnerDocument();
+		Node child = document.createElement(childName);
+		Node childTextNode = document.createTextNode(text);
 		child.appendChild(childTextNode);
 		parent.appendChild(child);
 	}
@@ -378,7 +353,6 @@
 	 * Add a simple text node with the specified name and text
 	 * to the specified parent node. If the text equals the default
 	 * value, do not add the simple text node at all.
-	 * Node#addSimpleTextNode(String childName, String text, String defaultValue)
 	 */
 	public static void addSimpleTextNode(Node parent, String childName, String text, String defaultValue) {
 		if ( ! text.equals(defaultValue)) {
@@ -389,7 +363,6 @@
 	/**
 	 * Add a simple text node with the specified name and numeric text
 	 * to the specified parent node.
-	 * Node#addSimpleTextNode(String childName, int text)
 	 */
 	public static void addSimpleTextNode(Node parent, String childName, int text) {
 		addSimpleTextNode(parent, childName, String.valueOf(text));
@@ -399,7 +372,6 @@
 	 * Add a simple text node with the specified name and numeric text
 	 * to the specified parent node. If numeric text equals the default
 	 * value, do not add the simple text node at all.
-	 * Node#addSimpleTextNode(String childName, int text, int defaultValue)
 	 */
 	public static void addSimpleTextNode(Node parent, String childName, int text, int defaultValue) {
 		if (text != defaultValue) {
@@ -410,7 +382,6 @@
 	/**
 	 * Add a simple text node with the specified name and boolean text
 	 * to the specified parent node.
-	 * Node#addSimpleTextNode(String childName, boolean text)
 	 */
 	public static void addSimpleTextNode(Node parent, String childName, boolean text) {
 		addSimpleTextNode(parent, childName, String.valueOf(text));
@@ -420,7 +391,6 @@
 	 * Add a simple text node with the specified name and boolean text
 	 * to the specified parent node. If the boolean text equals the default
 	 * value, do not add the simple text node at all.
-	 * Node#addSimpleTextNode(String childName, boolean text, boolean defaultValue)
 	 */
 	public static void addSimpleTextNode(Node parent, String childName, boolean text, boolean defaultValue) {
 		if (text != defaultValue) {
@@ -431,23 +401,23 @@
 	/**
 	 * Add a list of simple text nodes with the specified name and text
 	 * to the specified parent node's children node.
-	 *
+	 * <p>
 	 * For example, the following call:
-	 * 	XMLTools.addSimpleTextNodes(parentNode, "children", "child", new String[] {"foo", "bar", "baz"})
+	 * <pre>
+	 * XML.addSimpleTextNodes(parentNode, "children", "child", new String[] {"foo", "bar", "baz"})
+	 * </pre>
 	 * will generate the following XML:
-	 *
-	 * 	<parent>
-	 * 		...
-	 * 		<children>
-	 * 			<child>foo</child>
-	 * 			<child>bar</child>
-	 * 			<child>baz</child>
-	 * 		</children>
-	 * 	</parent>
-	 *
-	 *
-	 * Returns a list of three "child" nodes.
-	 * Node#addSimpleTextNodes(String childrenName, String childName, String[] childrenTexts)
+	 * <pre>
+	 * &lt;parent>
+	 *     ...
+	 *     &lt;children>
+	 *         &lt;child>foo&lt;/child>
+	 *         &lt;child>bar&lt;/child>
+	 *         &lt;child>baz&lt;/child>
+	 *     &lt;/children>
+	 *     ...
+	 * &lt;/parent>
+	 * </pre>
 	 */
 	public static void addSimpleTextNodes(Node parent, String childrenName, String childName, String[] childrenTexts) {
 		Node childrenNode = parent.getOwnerDocument().createElement(childrenName);
@@ -459,39 +429,11 @@
 	}
 
 	/**
-	 * @see javax.xml.transform.TransformerFactory#newInstance() for
-	 * documentation on how the implementation class is determined
-	 */
-	private static synchronized TransformerFactory transformerFactory() {
-		if (transformerFactory == null) {
-			transformerFactory = TransformerFactory.newInstance();
-		}
-		return transformerFactory;
-	}
-
-	private static synchronized Transformer transformer() {
-		if (transformer == null) {
-			try {
-				transformer = transformerFactory().newTransformer();
-			} catch (TransformerConfigurationException ex) {
-				throw new RuntimeException(ex);
-			}
-			try {
-				transformer.setOutputProperty("indent", "yes");
-				transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "3");
-			} catch (IllegalArgumentException ex) {
-				// ignore exception - the output will still be valid XML, it just won't be very user-friendly
-			}
-		}
-		return transformer;
-	}
-
-	/**
 	 * Print the specified source to the specified result.
 	 */
 	public static synchronized void print(Source source, Result result) {
 		try {
-			transformer().transform(source, result);
+			getTransformer().transform(source, result);
 		} catch (TransformerException ex) {
 			throw new RuntimeException(ex);
 		}
@@ -524,6 +466,33 @@
 		}
 	}
 
+	private static synchronized Transformer getTransformer() {
+		if (TRANSFORMER == null) {
+			try {
+				TRANSFORMER = getTransformerFactory().newTransformer();
+			} catch (TransformerConfigurationException ex) {
+				throw new RuntimeException(ex);
+			}
+			try {
+				TRANSFORMER.setOutputProperty(OutputKeys.INDENT, "yes");
+			} catch (IllegalArgumentException ex) {
+				// ignore exception - the output will still be valid XML, it just won't be very user-friendly
+			}
+		}
+		return TRANSFORMER;
+	}
+
+	/**
+	 * See {@link javax.xml.transform.TransformerFactory#newInstance()}
+	 * for documentation on how the implementation class is determined
+	 */
+	private static synchronized TransformerFactory getTransformerFactory() {
+		if (TRANSFORMER_FACTORY == null) {
+			TRANSFORMER_FACTORY = TransformerFactory.newInstance();
+		}
+		return TRANSFORMER_FACTORY;
+	}
+
 
 	// ********** constructor **********
 
@@ -534,5 +503,4 @@
 		super();
 		throw new UnsupportedOperationException();
 	}
-
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/AbstractRepeatingElementList.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/AbstractRepeatingElementList.java
new file mode 100644
index 0000000..d283b91
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/AbstractRepeatingElementList.java
@@ -0,0 +1,249 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * A <em>read-only</em> repeating element list (i.e. the list contains only
+ * one or more references to the same element).
+ */
+@SuppressWarnings("nls")
+public abstract class AbstractRepeatingElementList<E>
+	implements List<E>, Serializable
+{
+	// never negative
+	private final int size;
+
+	/**
+	 * Construct a <em>read-only</em> list with the specified number of
+	 * objects in it.
+	 */
+	protected AbstractRepeatingElementList(int size) {
+		super();
+		if (size < 0) {
+			throw new IllegalArgumentException("Invalid size: " + size);
+		}
+		this.size = size;
+	}
+
+	@Override
+	public boolean add(E o) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void add(int index, E element) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Replicate behavior of
+	 * {@link java.util.AbstractCollection#addAll(Collection)}.
+	 */
+	@Override
+	public boolean addAll(Collection<? extends E> c) {
+		if (c.isEmpty()) {
+			return false;
+		}
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Replicate behavior of
+	 * {@link java.util.AbstractList#addAll(int, Collection)}.
+	 */
+	@Override
+	public boolean addAll(int index, Collection<? extends E> c) {
+		return this.addAll(c);  // ignore the index
+	}
+
+	/**
+	 * Replicate behavior of
+	 * {@link java.util.AbstractCollection#clear()}.
+	 */
+	@Override
+	public void clear() {
+		if (this.size != 0) {
+			throw new UnsupportedOperationException();
+		}
+	}
+
+	@Override
+	public boolean contains(Object o) {
+		return (this.elementIs(o) && (this.size > 0));
+	}
+
+	/**
+	 * Replicate behavior of
+	 * {@link java.util.AbstractCollection#containsAll(Collection)}.
+	 */
+	@Override
+	public boolean containsAll(Collection<?> c) {
+		if (c.isEmpty()) {
+			return true;
+		}
+		if (this.size == 0) {
+			return false;
+		}
+		for (Iterator<?> iterator = c.iterator(); iterator.hasNext(); ) {
+			if (this.elementIsNot(iterator.next())) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	@Override
+	public E get(int index) {
+		this.checkIndex(index);
+		return this.getElement();
+	}
+
+	private void checkIndex(int index) {
+		if ((index < 0) || (index >= this.size)) {
+			throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + this.size);
+		}
+	}
+
+	@Override
+	public int indexOf(Object o) {
+		return (this.elementIs(o) && (this.size > 0)) ? 0 : -1;
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return (this.size == 0);
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return this.iterator(this.size);
+	}
+
+	protected abstract Iterator<E> iterator(int iteratorSize);
+
+	@Override
+	public int lastIndexOf(Object o) {
+		return (this.elementIs(o) && (this.size > 0)) ? (this.size - 1) : -1;
+	}
+
+	@Override
+	public ListIterator<E> listIterator() {
+		return this.listIterator_(this.size);
+	}
+
+	@Override
+	public ListIterator<E> listIterator(int index) {
+		return this.listIterator_(this.size - index);
+	}
+
+	protected abstract ListIterator<E> listIterator_(int iteratorSize);
+
+	/**
+	 * Replicate behavior of
+	 * {@link java.util.AbstractCollection#remove(Object)}.
+	 */
+	@Override
+	public boolean remove(Object o) {
+		if ((this.size > 0) && this.elementIs(o)) {
+			throw new UnsupportedOperationException();
+		}
+		return false;
+	}
+
+	@Override
+	public E remove(int index) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Replicate behavior of
+	 * {@link java.util.AbstractCollection#removeAll(Collection)}.
+	 */
+	@Override
+	public boolean removeAll(Collection<?> c) {
+		if ((this.size > 0) && c.contains(this.getElement())) {
+			throw new UnsupportedOperationException();
+		}
+		return false;
+	}
+
+	/**
+	 * Replicate behavior of
+	 * {@link java.util.AbstractCollection#retainAll(Collection)}.
+	 */
+	@Override
+	public boolean retainAll(Collection<?> c) {
+		if ((this.size > 0) && ! c.contains(this.getElement())) {
+			throw new UnsupportedOperationException();
+		}
+		return false;
+	}
+
+	@Override
+	public E set(int index, E element) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public int size() {
+		return this.size;
+	}
+
+	@Override
+	public List<E> subList(int fromIndex, int toIndex) {
+		return this.subList(toIndex - fromIndex);
+	}
+
+	protected abstract List<E> subList(int subListSize);
+
+	@Override
+	public Object[] toArray() {
+		return ArrayTools.fill(new Object[this.size], this.getElement());
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public <T> T[] toArray(T[] a) {
+		int sz = this.size;
+		return (T[]) ArrayTools.fill(((a.length >= sz) ? a : ArrayTools.newInstance(a, sz)), 0, sz, this.getElement());
+	}
+
+	private boolean elementIsNot(Object o) {
+		return ! this.elementIs(o);
+	}
+
+	private boolean elementIs(Object o) {
+		return ObjectTools.equals(o, this.getElement());
+	}
+
+	/**
+	 * Return the list's repeating element.
+	 */
+	protected abstract E getElement();
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.size);
+	}
+
+	private static final long serialVersionUID = 1L;
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/ArrayQueue.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/ArrayQueue.java
new file mode 100644
index 0000000..defd443
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/ArrayQueue.java
@@ -0,0 +1,225 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.NoSuchElementException;
+
+/**
+ * Resizable-array implementation of the {@link Queue} interface.
+ * @see java.util.ArrayList
+ */
+@SuppressWarnings("nls")
+public class ArrayQueue<E>
+	implements Queue<E>, Cloneable, Serializable
+{
+	private transient E[] elements;
+
+	/** Index of next element to be "dequeued". */
+	private transient int head = 0;
+
+	/** Index of next element to be "enqueued". */
+	private transient int tail = 0;
+
+	private int size = 0;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an empty queue.
+	 */
+	public ArrayQueue() {
+		this(10);
+	}
+
+	/**
+	 * Construct an empty queue with the specified initial capacity.
+	 */
+	@SuppressWarnings("unchecked")
+	public ArrayQueue(int initialCapacity) {
+		super();
+		if (initialCapacity < 0) {
+			throw new IllegalArgumentException("Illegal capacity: " + initialCapacity);
+		}
+		this.elements = (E[]) new Object[initialCapacity];
+	}
+
+	/**
+	 * Construct a queue containing the elements of the specified
+	 * collection. The queue will dequeue its elements in the same
+	 * order they are returned by the collection's iterator (i.e. the
+	 * first element returned by the collection's iterator will be the
+	 * first element returned by {@link #dequeue()}).
+	 */
+	@SuppressWarnings("unchecked")
+	public ArrayQueue(Collection<? extends E> c) {
+		super();
+		this.size = c.size();
+		// add 10% for growth
+		int capacity = (int) Math.min((this.size * 110L) / 100, Integer.MAX_VALUE);
+		this.elements = (E[]) c.toArray(new Object[capacity]);
+	}
+
+
+	// ********** Queue implementation **********
+
+	@Override
+	public void enqueue(E element) {
+		this.ensureCapacity(this.size + 1);
+		this.elements[this.tail] = element;
+		if (++this.tail == this.elements.length) {
+			this.tail = 0;
+		}
+		this.size++;
+	}
+
+	/**
+	 * Increase the queue's capacity, if necessary, to ensure it has at least
+	 * the specified minimum capacity.
+	 */
+	public void ensureCapacity(int minCapacity) {
+		int oldCapacity = this.elements.length;
+		if (oldCapacity < minCapacity) {
+			int newCapacity = ((oldCapacity * 3) >> 1) + 1;
+			if (newCapacity < minCapacity) {
+				newCapacity = minCapacity;
+			}
+			this.elements = this.copyElements(newCapacity);
+			this.head = 0;
+			this.tail = this.size;
+		}
+	}
+
+	/**
+	 * Decrease the queue's capacity, if necessary, to match its current size.
+	 */
+	public void trimToSize() {
+		if (this.elements.length > this.size) {
+			this.elements = this.copyElements(this.size);
+			this.head = 0;
+			this.tail = this.size;
+		}
+	}
+
+	private E[] copyElements(int newCapacity) {
+		@SuppressWarnings("unchecked")
+		E[] newElements = (E[]) new Object[newCapacity];
+		if (this.size != 0) {
+			Object oldElements[] = this.elements;
+			if ((this.head == 0) || (this.head < this.tail) || (this.tail == 0)) {
+				// elements are contiguous
+				System.arraycopy(oldElements, this.head, newElements, 0, this.size);
+			} else {
+				// elements wrap past end of array
+				int fragmentSize = oldElements.length - this.head;
+				System.arraycopy(oldElements, this.head, newElements, 0, fragmentSize);
+				System.arraycopy(oldElements, 0, newElements, fragmentSize, this.size - fragmentSize);
+			}
+		}
+		return newElements;
+	}
+
+	@Override
+	public E dequeue() {
+		if (this.size == 0) {
+			throw new NoSuchElementException();
+		}
+		E element = this.elements[this.head];
+		this.elements[this.head] = null; // allow GC to work
+		if (++this.head == this.elements.length) {
+			this.head = 0;
+		}
+		this.size--;
+		return element;
+	}
+
+	@Override
+	public E peek() {
+		if (this.size == 0) {
+			throw new NoSuchElementException();
+		}
+		return this.elements[this.head];
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return this.size == 0;
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public ArrayQueue<E> clone() {
+		try {
+			@SuppressWarnings("unchecked")
+			ArrayQueue<E> clone = (ArrayQueue<E>) super.clone();
+			@SuppressWarnings("cast")
+			E[] array = (E[]) this.elements.clone();
+			clone.elements = array;
+			return clone;
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	@Override
+	public String toString() {
+		return Arrays.toString(this.copyElements(this.size));
+	}
+
+
+	// ********** Serializable "implementation" **********
+
+	private void writeObject(java.io.ObjectOutputStream stream) throws java.io.IOException {
+		// write size (and any hidden stuff)
+		stream.defaultWriteObject();
+		Object[] array = this.elements;
+		int elementsLength = array.length;
+		stream.writeInt(elementsLength);
+		if (this.head < this.tail) { // elements are contiguous
+			for (int i = this.head; i < this.tail; i++) {
+				stream.writeObject(array[i]);
+			}
+		} else if (this.head > this.tail) { // elements wrap past end of array
+			for (int i = this.head; i < elementsLength; i++) {
+				stream.writeObject(array[i]);
+			}
+			for (int i = 0; i < this.tail; i++) {
+				stream.writeObject(array[i]);
+			}
+		} else { // (this.head == this.tail)
+			// nothing to write
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException {
+		// read size (and any hidden stuff)
+		stream.defaultReadObject();
+		int elementsLength = stream.readInt();
+		Object[] array = new Object[elementsLength];
+		for (int i = 0; i < this.size; i++) {
+			array[i] = stream.readObject();
+		}
+		this.elements = (E[]) array;
+		this.head = 0;
+		this.tail = this.size;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/ArrayStack.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/ArrayStack.java
new file mode 100644
index 0000000..1134d8c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/ArrayStack.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EmptyStackException;
+
+/**
+ * Resizable-array implementation of the {@link Stack} interface.
+ * @see ArrayList
+ */
+public class ArrayStack<E>
+	implements Stack<E>, Cloneable, Serializable
+{
+	private ArrayList<E> elements;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an empty stack.
+	 */
+	public ArrayStack() {
+		this(10);
+	}
+
+	/**
+	 * Construct an empty stack with the specified initial capacity.
+	 */
+	public ArrayStack(int initialCapacity) {
+		super();
+		this.elements = new ArrayList<E>(initialCapacity);
+	}
+
+	/**
+	 * Construct a stack containing the elements of the specified
+	 * collection. The stack will pop its elements in reverse of the
+	 * order they are returned by the collection's iterator (i.e. the
+	 * last element returned by the collection's iterator will be the
+	 * first element returned by {@link #pop()}).
+	 */
+	public ArrayStack(Collection<? extends E> collection) {
+		super();
+		this.elements = new ArrayList<E>(collection);
+	}
+
+
+	// ********** Stack implementation **********
+
+	@Override
+	public void push(E element) {
+		this.elements.add(element);
+	}
+
+	@Override
+	public E pop() {
+		try {
+			return this.elements.remove(this.elements.size() - 1);
+		} catch (IndexOutOfBoundsException ex) {
+			throw new EmptyStackException();
+		}
+	}
+
+	@Override
+	public E peek() {
+		try {
+			return this.elements.get(this.elements.size() - 1);
+		} catch (IndexOutOfBoundsException ex) {
+			throw new EmptyStackException();
+		}
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return this.elements.isEmpty();
+	}
+
+	/**
+	 * Increase the stack's capacity, if necessary, to ensure it has at least
+	 * the specified minimum capacity.
+	 */
+	public void ensureCapacity(int minCapacity) {
+		this.elements.ensureCapacity(minCapacity);
+	}
+
+	/**
+	 * Decrease the stack's capacity, if necessary, to match its current size.
+	 */
+	public void trimToSize() {
+		this.elements.trimToSize();
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public ArrayStack<E> clone() {
+		try {
+			@SuppressWarnings("unchecked")
+			ArrayStack<E> clone = (ArrayStack<E>) super.clone();
+			@SuppressWarnings("unchecked")
+			ArrayList<E> list = (ArrayList<E>) this.elements.clone();
+			clone.elements = list;
+			return clone;
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	/**
+	 * Print the elements in the order in which they are "pushed" on to
+	 * the stack (as opposed to the order in which they will be "popped"
+	 * off of the stack).
+	 */
+	@Override
+	public String toString() {
+		return this.elements.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/Bag.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/Bag.java
new file mode 100644
index 0000000..ebc6cdd
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/Bag.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+
+/**
+ * A collection that allows duplicate elements.
+ * <p>
+ * The <code>Bag</code> interface places additional stipulations,
+ * beyond those inherited from the {@link java.util.Collection} interface,
+ * on the contracts of the {@link #equals(Object)} and {@link #hashCode()} methods.
+ * <p>
+ * 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.
+ * @see org.eclipse.jpt.common.utility.internal.collection.HashBag
+ */
+public interface Bag<E>
+	extends java.util.Collection<E>
+{
+	/**
+	 * Compares the specified object with this bag for equality. Returns
+	 * <code>true</code> if the specified object is also a bag, the two bags
+	 * have the same size, and every member of the specified bag is
+	 * contained in this bag with the same number of occurrences (or equivalently,
+	 * every member of this bag is contained in the specified bag with the same
+	 * number of occurrences). This definition ensures that the
+	 * equals method works properly across different implementations of the
+	 * bag interface.
+	 */
+	@Override
+	boolean equals(Object o);
+
+	/**
+	 * Returns the hash code value for this bag. The hash code of a bag is
+	 * defined to be the sum of the hash codes of the elements in the bag,
+	 * where the hashcode of a <code>null</code> element is defined to be zero.
+	 * This ensures that <code>b1.equals(b2)</code> implies that
+	 * <code>b1.hashCode() == b2.hashCode()</code> for any two bags
+	 * <code>b1</code> and <code>b2</code>, as required by the general
+	 * contract of the {@link Object#hashCode()} method.
+	 */
+	@Override
+	int hashCode();
+
+	/**
+	 * Return the number of times the specified object occurs in the bag.
+	 */
+	int count(Object o);
+
+	/**
+	 * Add the specified object the specified number of times to the bag.
+	 * Return whether the bag changed.
+	 */
+	boolean add(E o, int count);
+
+	/**
+	 * Remove the specified number of occurrences of the specified object
+	 * from the bag. Return whether the bag changed.
+	 */
+	boolean remove(Object o, int count);
+
+	/**
+	 * Return an iterator that returns each item in the bag
+	 * once and only once, irrespective of how many times
+	 * the item was added to the bag.
+	 */
+	java.util.Iterator<E> uniqueIterator();
+
+	/**
+	 * Return the number of unique items in the bag.
+	 */
+	int uniqueCount();
+
+	/**
+	 * Return an iterator that returns an entry for each item in the bag
+	 * once and only once, irrespective of how many times
+	 * the item was added to the bag. The entry will indicate the item's
+	 * count.
+	 */
+	java.util.Iterator<Entry<E>> entries();
+
+
+	/**
+	 * A bag entry (element-count pair).
+	 * The {@link Bag#entries()} method returns an iterator whose
+	 * elements are of this class. The <em>only</em> way to obtain a reference
+	 * to a bag entry is from the iterator returned by this method. These
+	 * <code>Bag.Entry</code> objects are valid <em>only</em> for the duration
+	 * of the iteration; more formally, the behavior of a bag entry is
+	 * undefined if the backing bag has been modified after the entry was
+	 * returned by the iterator, except through the {@link #setCount(int)}
+	 * operation on the bag entry.
+	 */
+	interface Entry<E> {
+		/**
+		 * Return the entry's element.
+		 */
+		E getElement();
+
+		/**
+		 * Return entry's count; i.e. the number of times the entry's element
+		 * occurs in the bag.
+		 * @see Bag#count(Object)
+		 */
+		int getCount();
+
+		/**
+		 * Set the entry's count; i.e. the number of times the entry's element
+		 * occurs in the bag. The new count must be a positive number.
+		 * Return the previous count of the entry's element.
+		 * NB: Use {@link java.util.Iterator#remove()} to set the
+		 * count to zero.
+		 */
+		int setCount(int count);
+
+		/**
+		 * Return whether the entry is equal to the specified object;
+		 * i.e. the specified object is a <code>Bag.Entry</code> and its
+		 * element and count are the same as the entry's.
+		 */
+		@Override
+		boolean equals(Object obj);
+
+		/**
+		 * Return the entry's hash code.
+		 */
+		@Override
+		int hashCode();
+	}
+
+
+	final class Empty<E>
+		extends java.util.AbstractCollection<E>
+		implements Bag<E>, java.io.Serializable
+	{
+		@SuppressWarnings("rawtypes")
+		public static final Bag INSTANCE = new Empty();
+		@SuppressWarnings("unchecked")
+		public static <T> Bag<T> instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Empty() {
+			super();
+		}
+		@Override
+		public java.util.Iterator<E> iterator() {
+			return EmptyIterator.instance();
+		}
+		@Override
+		public int size() {
+			return 0;
+		}
+		@Override
+		public java.util.Iterator<E> uniqueIterator() {
+			return EmptyIterator.instance();
+		}
+		@Override
+		public int uniqueCount() {
+			return 0;
+		}
+		@Override
+		public int count(Object o) {
+			return 0;
+		}
+		@Override
+		public java.util.Iterator<Bag.Entry<E>> entries() {
+			return EmptyIterator.instance();
+		}
+		@Override
+		public boolean remove(Object o, int count) {
+			return false;
+		}
+		@Override
+		public boolean add(E o, int count) {
+			throw new UnsupportedOperationException();
+		}
+		@Override
+		public boolean equals(Object o) {
+			if (o == this) {
+				return true;
+			}
+			if ( ! (o instanceof Bag<?>)) {
+				return false;
+			}
+			return ((Bag<?>) o).size() == 0;
+		}
+		@Override
+		public int hashCode() {
+			return 0;
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/CollectionTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/CollectionTools.java
new file mode 100644
index 0000000..bbed458
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/CollectionTools.java
@@ -0,0 +1,721 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2012 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.persistence.tools.utility.collection;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeSet;
+import java.util.Vector;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * {@link Collection} utility methods.
+ * @see org.eclipse.jpt.common.utility.internal.ArrayTools
+ * @see org.eclipse.jpt.common.utility.internal.iterable.IterableTools
+ * @see org.eclipse.jpt.common.utility.internal.iterator.IteratorTools
+ * @see ListTools
+ */
+public final class CollectionTools {
+
+	// ********** add all **********
+
+	/**
+	 * Add all the elements returned by the specified iterable
+	 * to the specified collection.
+	 * Return whether the collection changed as a result.
+	 */
+	public static <E> boolean addAll(Collection<? super E> collection, Iterable<? extends E> iterable) {
+		return addAll(collection, iterable.iterator());
+	}
+
+	/**
+	 * Add all the elements returned by the specified iterable
+	 * to the specified collection.
+	 * Return whether the collection changed as a result.
+	 */
+	public static <E> boolean addAll(Collection<? super E> collection, Iterable<? extends E> iterable, int size) {
+		return addAll(collection, iterable.iterator(), size);
+	}
+
+	/**
+	 * Add all the elements returned by the specified iterator
+	 * to the specified collection.
+	 * Return whether the collection changed as a result.
+	 */
+	public static <E> boolean addAll(Collection<? super E> collection, Iterator<? extends E> iterator) {
+		return iterator.hasNext() ? addAll_(collection, iterator) : false;
+	}
+
+	/**
+	 * assume the iterator is not empty
+	 */
+	private static <E> boolean addAll_(Collection<? super E> collection, Iterator<? extends E> iterator) {
+		boolean modified = false;
+		while (iterator.hasNext()) {
+			modified |= collection.add(iterator.next());
+		}
+		return modified;
+	}
+
+	/**
+	 * Add all the elements returned by the specified iterator
+	 * to the specified collection.
+	 * Return whether the collection changed as a result.
+	 */
+	public static <E> boolean addAll(Collection<? super E> collection, Iterator<? extends E> iterator, int size) {
+		return iterator.hasNext() ? collection.addAll(ListTools.list(iterator, size)) : false;
+	}
+
+	/**
+	 * Add all the elements in the specified array
+	 * to the specified collection.
+	 * Return whether the collection changed as a result.
+	 */
+	public static <E> boolean addAll(Collection<? super E> collection, E... array) {
+		return (array.length == 0) ? false : addAll_(collection, array);
+	}
+
+	/**
+	 * assume the array is not empty
+	 */
+	private static <E> boolean addAll_(Collection<? super E> collection, E... array) {
+		boolean modified = false;
+		for (E element : array) {
+			modified |= collection.add(element);
+		}
+		return modified;
+	}
+
+
+	// ********** contains all **********
+
+	/**
+	 * Return whether the specified collection contains all of the
+	 * elements in the specified iterable.
+	 */
+	public static boolean containsAll(Collection<?> collection, Iterable<?> iterable) {
+		return containsAll(collection, iterable.iterator());
+	}
+
+	/**
+	 * Return whether the specified collection contains all of the
+	 * elements in the specified iterator.
+	 */
+	public static boolean containsAll(Collection<?> collection, Iterator<?> iterator) {
+		while (iterator.hasNext()) {
+			if ( ! collection.contains(iterator.next())) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Return whether the specified collection contains all of the
+	 * elements in the specified array.
+	 */
+	public static boolean containsAll(Collection<?> collection, Object... array) {
+		for (int i = array.length; i-- > 0; ) {
+			if ( ! collection.contains(array[i])) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+
+	// ********** filter **********
+
+	/**
+	 * Return a new collection with the filtered
+	 * elements of the specified collection.
+	 */
+	public static <E> HashBag<E> filter(Collection<? extends E> collection, Filter<E> filter) {
+		HashBag<E> result = new HashBag<E>(collection.size());
+		for (E e : collection) {
+			if (filter.accept(e)) {
+				result.add(e);
+			}
+		}
+		return result;
+	}
+
+
+	// ********** remove all **********
+
+	/**
+	 * Remove all the elements returned by the specified iterable
+	 * from the specified collection.
+	 * Return whether the collection changed as a result.
+	 */
+	public static boolean removeAll(Collection<?> collection, Iterable<?> iterable) {
+		return removeAll(collection, iterable.iterator());
+	}
+
+	/**
+	 * Remove all the elements returned by the specified iterable
+	 * from the specified collection.
+	 * Return whether the collection changed as a result.
+	 * The specified iterable size is a performance hint.
+	 */
+	public static boolean removeAll(Collection<?> collection, Iterable<?> iterable, int iterableSize) {
+		return removeAll(collection, iterable.iterator(), iterableSize);
+	}
+
+	/**
+	 * Remove all the elements returned by the specified iterator
+	 * from the specified collection.
+	 * Return whether the collection changed as a result.
+	 */
+	public static boolean removeAll(Collection<?> collection, Iterator<?> iterator) {
+		return iterator.hasNext() ? collection.removeAll(set(iterator)) : false;
+	}
+
+	/**
+	 * Remove all the elements returned by the specified iterator
+	 * from the specified collection.
+	 * Return whether the collection changed as a result.
+	 * The specified iterator size is a performance hint.
+	 */
+	public static boolean removeAll(Collection<?> collection, Iterator<?> iterator, int iteratorSize) {
+		return iterator.hasNext() ? collection.removeAll(set(iterator, iteratorSize)) : false;
+	}
+
+	/**
+	 * Remove all the elements in the specified array
+	 * from the specified collection.
+	 * Return whether the collection changed as a result.
+	 */
+	public static boolean removeAll(Collection<?> collection, Object... array) {
+		return (array.length == 0) ? false : collection.removeAll(set(array));
+	}
+
+
+	// ********** remove all occurrences **********
+
+	/**
+	 * Remove all occurrences of the specified element
+	 * from the specified collection.
+	 * Return whether the collection changed as a result.
+	 */
+	public static boolean removeAllOccurrences(Collection<?> collection, Object value) {
+		boolean modified = false;
+		Iterator<?> stream = collection.iterator();
+		if (value == null) {
+			while (stream.hasNext()) {
+				if (stream.next() == null) {
+					stream.remove();
+					modified = true;
+				}
+			}
+		} else {
+			while (stream.hasNext()) {
+				if (value.equals(stream.next())) {
+					stream.remove();
+					modified = true;
+				}
+			}
+		}
+		return modified;
+	}
+
+
+	// ********** retain all **********
+
+	/**
+	 * Retain only the elements in the specified iterable
+	 * in the specified collection.
+	 * Return whether the collection changed as a result.
+	 */
+	public static boolean retainAll(Collection<?> collection, Iterable<?> iterable) {
+		return retainAll(collection, iterable.iterator());
+	}
+
+	/**
+	 * Retain only the elements in the specified iterable
+	 * in the specified collection.
+	 * Return whether the collection changed as a result.
+	 * The specified iterable size is a performance hint.
+	 */
+	public static boolean retainAll(Collection<?> collection, Iterable<?> iterable, int iterableSize) {
+		return retainAll(collection, iterable.iterator(), iterableSize);
+	}
+
+	/**
+	 * Retain only the elements in the specified iterator
+	 * in the specified collection.
+	 * Return whether the collection changed as a result.
+	 */
+	public static boolean retainAll(Collection<?> collection, Iterator<?> iterator) {
+		if (iterator.hasNext()) {
+			return collection.retainAll(set(iterator));
+		}
+		if (collection.isEmpty()) {
+			return false;
+		}
+		collection.clear();
+		return true;
+	}
+
+	/**
+	 * Retain only the elements in the specified iterator
+	 * in the specified collection.
+	 * Return whether the collection changed as a result.
+	 * The specified iterator size is a performance hint.
+	 */
+	public static boolean retainAll(Collection<?> collection, Iterator<?> iterator, int iteratorSize) {
+		if (iterator.hasNext()) {
+			return collection.retainAll(set(iterator, iteratorSize));
+		}
+		if (collection.isEmpty()) {
+			return false;
+		}
+		collection.clear();
+		return true;
+	}
+
+	/**
+	 * Retain only the elements in the specified array
+	 * in the specified collection.
+	 * Return whether the collection changed as a result.
+	 */
+	public static boolean retainAll(Collection<?> collection, Object... array) {
+		if (array.length > 0) {
+			return collection.retainAll(set(array));
+		}
+		if (collection.isEmpty()) {
+			return false;
+		}
+		collection.clear();
+		return true;
+	}
+
+
+	// ********** transform **********
+
+	/**
+	 * Return a new collection with transformations of the
+	 * elements in the specified collection.
+	 */
+	public static <E1, E2> HashBag<E2> transform(Collection<E1> collection, Transformer<E1, ? extends E2> transformer) {
+		HashBag<E2> result = new HashBag<E2>(collection.size());
+		for (E1 e : collection) {
+			result.add(transformer.transform(e));
+		}
+		return result;
+	}
+
+
+	// ********** bag factory methods **********
+
+	/**
+	 * Return a bag corresponding to the specified iterable.
+	 */
+	public static <E> HashBag<E> bag(Iterable<? extends E> iterable) {
+		return bag(iterable.iterator());
+	}
+
+	/**
+	 * Return a bag corresponding to the specified iterable.
+	 * The specified iterable size is a performance hint.
+	 */
+	public static <E> HashBag<E> bag(Iterable<? extends E> iterable, int iterableSize) {
+		return bag(iterable.iterator(), iterableSize);
+	}
+
+	/**
+	 * Return a bag corresponding to the specified iterator.
+	 */
+	public static <E> HashBag<E> bag(Iterator<? extends E> iterator) {
+		return bag(iterator, new HashBag<E>());
+	}
+
+	/**
+	 * Return a bag corresponding to the specified iterator.
+	 * The specified iterator size is a performance hint.
+	 */
+	public static <E> HashBag<E> bag(Iterator<? extends E> iterator, int iteratorSize) {
+		return bag(iterator, new HashBag<E>(iteratorSize));
+	}
+
+	private static <E> HashBag<E> bag(Iterator<? extends E> iterator, HashBag<E> bag) {
+		while (iterator.hasNext()) {
+			bag.add(iterator.next());
+		}
+		return bag;
+	}
+
+	/**
+	 * Return a bag corresponding to the specified array.
+	 */
+	public static <E> HashBag<E> bag(E... array) {
+		int len = array.length;
+		HashBag<E> bag = new HashBag<E>(len);
+		for (E item : array) {
+			bag.add(item);
+		}
+		return bag;
+	}
+
+
+	// ********** collection factory methods **********
+
+	/**
+	 * Return a collection corresponding to the specified iterable.
+	 */
+	public static <E> HashBag<E> collection(Iterable<? extends E> iterable) {
+		return collection(iterable.iterator());
+	}
+
+	/**
+	 * Return a collection corresponding to the specified iterable.
+	 * The specified iterable size is a performance hint.
+	 */
+	public static <E> HashBag<E> collection(Iterable<? extends E> iterable, int iterableSize) {
+		return collection(iterable.iterator(), iterableSize);
+	}
+
+	/**
+	 * Return a collection corresponding to the specified iterator.
+	 */
+	public static <E> HashBag<E> collection(Iterator<? extends E> iterator) {
+		return bag(iterator);
+	}
+
+	/**
+	 * Return a collection corresponding to the specified iterator.
+	 * The specified iterator size is a performance hint.
+	 */
+	public static <E> HashBag<E> collection(Iterator<? extends E> iterator, int iteratorSize) {
+		return bag(iterator, iteratorSize);
+	}
+
+	/**
+	 * Return a collection corresponding to the specified array.
+	 */
+	public static <E> HashBag<E> collection(E... array) {
+		return bag(array);
+	}
+
+
+	// ********** queue factory methods **********
+
+	/**
+	 * Return a queue corresponding to the specified iterable.
+	 */
+	public static <E> ArrayQueue<E> queue(Iterable<? extends E> iterable) {
+		return queue(iterable.iterator());
+	}
+
+	/**
+	 * Return a queue corresponding to the specified iterable.
+	 * The specified iterable size is a performance hint.
+	 */
+	public static <E> ArrayQueue<E> queue(Iterable<? extends E> iterable, int iterableSize) {
+		return queue(iterable.iterator(), iterableSize);
+	}
+
+	/**
+	 * Return a queue corresponding to the specified iterator.
+	 */
+	public static <E> ArrayQueue<E> queue(Iterator<? extends E> iterator) {
+		return queue(iterator, new ArrayQueue<E>());
+	}
+
+	/**
+	 * Return a queue corresponding to the specified iterator.
+	 * The specified iterator size is a performance hint.
+	 */
+	public static <E> ArrayQueue<E> queue(Iterator<? extends E> iterator, int iteratorSize) {
+		return queue(iterator, new ArrayQueue<E>(iteratorSize));
+	}
+
+	private static <E> ArrayQueue<E> queue(Iterator<? extends E> iterator, ArrayQueue<E> queue) {
+		while (iterator.hasNext()) {
+			queue.enqueue(iterator.next());
+		}
+		return queue;
+	}
+
+	/**
+	 * Return a queue corresponding to the specified array.
+	 */
+	public static <E> ArrayQueue<E> queue(E... array) {
+		int len = array.length;
+		ArrayQueue<E> queue = new ArrayQueue<E>(len);
+		for (E item : array) {
+			queue.enqueue(item);
+		}
+		return queue;
+	}
+
+
+	// ********** set factory methods **********
+
+	/**
+	 * Return a set corresponding to the specified iterable.
+	 */
+	public static <E> HashSet<E> set(Iterable<? extends E> iterable) {
+		return set(iterable.iterator());
+	}
+
+	/**
+	 * Return a set corresponding to the specified iterable.
+	 * The specified iterable size is a performance hint.
+	 */
+	public static <E> HashSet<E> set(Iterable<? extends E> iterable, int iterableSize) {
+		return set(iterable.iterator(), iterableSize);
+	}
+
+	/**
+	 * Return a set corresponding to the specified iterator.
+	 */
+	public static <E> HashSet<E> set(Iterator<? extends E> iterator) {
+		return set(iterator, new HashSet<E>());
+	}
+
+	/**
+	 * Return a set corresponding to the specified iterator.
+	 * The specified iterator size is a performance hint.
+	 */
+	public static <E> HashSet<E> set(Iterator<? extends E> iterator, int iteratorSize) {
+		return set(iterator, new HashSet<E>(iteratorSize));
+	}
+
+	private static <E> HashSet<E> set(Iterator<? extends E> iterator, HashSet<E> set) {
+		while (iterator.hasNext()) {
+			set.add(iterator.next());
+		}
+		return set;
+	}
+
+	/**
+	 * Return a set corresponding to the specified array.
+	 */
+	public static <E> HashSet<E> set(E... array) {
+		HashSet<E> set = new HashSet<E>(array.length);
+		for (int i = array.length; i-- > 0;) {
+			set.add(array[i]);
+		}
+		return set;
+	}
+
+
+	// ********** sorted set factory methods **********
+
+	/**
+	 * Return a sorted set corresponding to the specified iterable.
+	 */
+	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterable<? extends E> iterable) {
+		return sortedSet(iterable.iterator());
+	}
+
+	/**
+	 * Return a sorted set corresponding to the specified iterable.
+	 * The specified iterable size is a performance hint.
+	 */
+	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterable<? extends E> iterable, int iterableSize) {
+		return sortedSet(iterable.iterator(), iterableSize);
+	}
+
+	/**
+	 * Return a sorted set corresponding to the specified iterable
+	 * and comparator.
+	 */
+	public static <E> TreeSet<E> sortedSet(Iterable<? extends E> iterable, Comparator<? super E> comparator) {
+		return sortedSet(iterable.iterator(), comparator);
+	}
+
+	/**
+	 * Return a sorted set corresponding to the specified iterable
+	 * and comparator.
+	 * The specified iterable size is a performance hint.
+	 */
+	public static <E> TreeSet<E> sortedSet(Iterable<? extends E> iterable, Comparator<? super E> comparator, int iterableSize) {
+		return sortedSet(iterable.iterator(), comparator, iterableSize);
+	}
+
+	/**
+	 * Return a sorted set corresponding to the specified iterator.
+	 */
+	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterator<? extends E> iterator) {
+		return sortedSet(iterator, null);
+	}
+
+	/**
+	 * Return a sorted set corresponding to the specified iterator.
+	 * The specified iterator size is a performance hint.
+	 */
+	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(Iterator<? extends E> iterator, int iteratorSize) {
+		return sortedSet(iterator, null, iteratorSize);
+	}
+
+	/**
+	 * Return a sorted set corresponding to the specified iterator
+	 * and comparator.
+	 */
+	public static <E> TreeSet<E> sortedSet(Iterator<? extends E> iterator, Comparator<? super E> comparator) {
+		return sortedSet(ListTools.list(iterator), comparator);
+	}
+
+	/**
+	 * Return a sorted set corresponding to the specified iterator
+	 * and comparator.
+	 * The specified iterator size is a performance hint.
+	 */
+	public static <E> TreeSet<E> sortedSet(Iterator<? extends E> iterator, Comparator<? super E> comparator, int iteratorSize) {
+		return sortedSet(ListTools.list(iterator, iteratorSize), comparator);
+	}
+
+	private static <E> TreeSet<E> sortedSet(List<E> list, Comparator<? super E> comparator) {
+		TreeSet<E> sortedSet = new TreeSet<E>(comparator);
+		sortedSet.addAll(list);
+		return sortedSet;
+	}
+
+	/**
+	 * Return a sorted set corresponding to the specified array.
+	 */
+	public static <E extends Comparable<? super E>> TreeSet<E> sortedSet(E... array) {
+		return sortedSet(array, null);
+	}
+
+	/**
+	 * Return a sorted set corresponding to the specified array
+	 * and comparator.
+	 */
+	public static <E> TreeSet<E> sortedSet(E[] array, Comparator<? super E> comparator) {
+		TreeSet<E> sortedSet = new TreeSet<E>(comparator);
+		sortedSet.addAll(Arrays.asList(array));
+		return sortedSet;
+	}
+
+
+	// ********** stack factory methods **********
+
+	/**
+	 * Return a stack corresponding to the specified iterable.
+	 */
+	public static <E> ArrayStack<E> stack(Iterable<? extends E> iterable) {
+		return stack(iterable.iterator());
+	}
+
+	/**
+	 * Return a stack corresponding to the specified iterable.
+	 * The specified iterable size is a performance hint.
+	 */
+	public static <E> ArrayStack<E> stack(Iterable<? extends E> iterable, int iterableSize) {
+		return stack(iterable.iterator(), iterableSize);
+	}
+
+	/**
+	 * Return a stack corresponding to the specified iterator.
+	 */
+	public static <E> ArrayStack<E> stack(Iterator<? extends E> iterator) {
+		return stack(iterator, new ArrayStack<E>());
+	}
+
+	/**
+	 * Return a stack corresponding to the specified iterator.
+	 * The specified iterator size is a performance hint.
+	 */
+	public static <E> ArrayStack<E> stack(Iterator<? extends E> iterator, int iteratorSize) {
+		return stack(iterator, new ArrayStack<E>(iteratorSize));
+	}
+
+	private static <E> ArrayStack<E> stack(Iterator<? extends E> iterator, ArrayStack<E> stack) {
+		while (iterator.hasNext()) {
+			stack.push(iterator.next());
+		}
+		return stack;
+	}
+
+	/**
+	 * Return a stack corresponding to the specified array.
+	 */
+	public static <E> ArrayStack<E> stack(E... array) {
+		int len = array.length;
+		ArrayStack<E> stack = new ArrayStack<E>(len);
+		for (E item : array) {
+			stack.push(item);
+		}
+		return stack;
+	}
+
+
+	// ********** Old School Vector factory methods **********
+
+	/**
+	 * Return a vector corresponding to the specified iterable.
+	 * This is useful for legacy code that requires a {@link Vector}.
+	 */
+	public static <E> Vector<E> vector(Iterable<? extends E> iterable) {
+		return vector(iterable.iterator());
+	}
+
+	/**
+	 * Return a vector corresponding to the specified iterable.
+	 * This is useful for legacy code that requires a {@link Vector}.
+	 */
+	public static <E> Vector<E> vector(Iterable<? extends E> iterable, int size) {
+		return vector(iterable.iterator(), size);
+	}
+
+	/**
+	 * Return a vector corresponding to the specified iterator.
+	 * This is useful for legacy code that requires a {@link Vector}.
+	 */
+	public static <E> Vector<E> vector(Iterator<? extends E> iterator) {
+		return vector(iterator, new Vector<E>());
+	}
+
+	/**
+	 * Return a vector corresponding to the specified iterator.
+	 * This is useful for legacy code that requires a {@link Vector}.
+	 */
+	public static <E> Vector<E> vector(Iterator<? extends E> iterator, int size) {
+		return vector(iterator, new Vector<E>(size));
+	}
+
+	private static <E> Vector<E> vector(Iterator<? extends E> iterator, Vector<E> v) {
+		while (iterator.hasNext()) {
+			v.addElement(iterator.next());
+		}
+		return v;
+	}
+
+	/**
+	 * Return a vector corresponding to the specified array.
+	 * This is useful for legacy code that requires a {@link Vector}.
+	 */
+	public static <E> Vector<E> vector(E... array) {
+		Vector<E> v = new Vector<E>(array.length);
+		for (E item : array) {
+			v.addElement(item);
+		}
+		return v;
+	}
+
+
+	// ********** constructor **********
+
+	/**
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private CollectionTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/HashBag.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/HashBag.java
new file mode 100644
index 0000000..2f4e2ce
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/HashBag.java
@@ -0,0 +1,909 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.io.Serializable;
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * This class implements the {@link Bag} interface, backed by a
+ * hash table. It makes no guarantees as to the iteration order of
+ * the bag's elements; in particular, it does not guarantee the order
+ * will remain constant over time. This class permits the <code>null</code>
+ * element.
+ * <p>
+ * This class offers constant time performance for the basic operations
+ * (<code>add</code>, <code>remove</code>, <code>contains</code> and
+ * <code>size</code>), assuming the hash function disperses the elements
+ * properly among the buckets. Iterating over this bag requires time
+ * proportional to the sum of the bag's size (the number of elements) plus the
+ * "capacity" of the backing hash table (the number of buckets). Thus, it is
+ * important not to set the initial capacity too high (or the load factor too
+ * low) if iteration performance is important.
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If multiple
+ * threads access a bag concurrently, and at least one of the threads modifies
+ * the bag, it <em>must</em> be synchronized externally. This is typically
+ * accomplished by synchronizing on some object that naturally encapsulates
+ * the bag. If no such object exists, the bag should be "wrapped" using the
+ * <code>Collections.synchronizedCollection</code> method. This is
+ * best done at creation time, to prevent accidental unsynchronized access
+ * to the bag:
+ * <pre>
+ * Collection c = Collections.synchronizedCollection(new HashBag(...));
+ * </pre>
+ * <p>
+ * The iterators returned by this class's <code>iterator</code> method are
+ * <em>fail-fast</em>: if the bag is modified at any time after the iterator is
+ * created, in any way except through the iterator's own <code>remove</code>
+ * method, the iterator throws a {@link ConcurrentModificationException}.
+ * Thus, in the face of concurrent modification, the iterator fails quickly
+ * and cleanly, rather than risking arbitrary, non-deterministic behavior at
+ * an undetermined time in the future.
+ * <p>
+ * Note that the fail-fast behavior of an iterator cannot be guaranteed
+ * as it is, generally speaking, impossible to make any hard guarantees in the
+ * presence of unsynchronized concurrent modification. Fail-fast iterators
+ * throw <code>ConcurrentModificationException</code> on a best-effort basis.
+ * Therefore, it would be wrong to write a program that depended on this
+ * exception for its correctness: <em>the fail-fast behavior of iterators
+ * should be used only to detect bugs.</em>
+ *
+ * @param <E> the type of elements maintained by the bag
+ *
+ * @see Collection
+ * @see Bag
+ * @see SynchronizedBag
+ * @see	java.util.Collections#synchronizedCollection(Collection)
+ * @see IdentityHashBag
+ */
+@SuppressWarnings("nls")
+public class HashBag<E>
+	extends AbstractCollection<E>
+	implements Bag<E>, Cloneable, Serializable
+{
+	/** The hash table. Resized as necessary. Length MUST Always be a power of two. */
+	transient Entry<E>[] table;
+
+	/** The total number of entries in the bag. */
+	transient int size = 0;
+
+	/** The number of UNIQUE entries in the bag. */
+	transient int uniqueCount = 0;
+
+	/**
+	 * The hash table is rehashed when its size exceeds this threshold. (The
+	 * value of this field is <code>(int) (capacity * loadFactor)</code>.)
+	 *
+	 * @serial threshold
+	 */
+	private int threshold;
+
+	/**
+	 * The load factor for the hash table.
+	 *
+	 * @serial load factor
+	 */
+	private final float loadFactor;
+
+	/**
+	 * The number of times this bag has been structurally modified.
+	 * Structural modifications are those that change the number of entries in
+	 * the bag or otherwise modify its internal structure (e.g. rehash).
+	 * This field is used to make iterators on this bag fail-fast.
+	 *
+	 * @see java.util.ConcurrentModificationException
+	 */
+	transient int modCount = 0;
+
+	/**
+	 * The default initial capacity - MUST be a power of two.
+	 */
+	private static final int DEFAULT_INITIAL_CAPACITY = 16;
+
+	/**
+	 * The maximum capacity, used if a higher value is implicitly specified
+	 * by either of the constructors with arguments.
+	 * MUST be a power of two <= (1 << 30).
+	 */
+	private static final int MAXIMUM_CAPACITY = 1 << 30;
+
+	/**
+	 * The load factor used when none specified in constructor.
+	 */
+	private static final float DEFAULT_LOAD_FACTOR = 0.75f;
+
+	/**
+	 * Construct a new, empty bag with the
+	 * default capacity, which is 16, and load factor, which is 0.75.
+	 */
+	public HashBag() {
+		this(DEFAULT_INITIAL_CAPACITY);
+	}
+
+	/**
+	 * Construct a new, empty bag with the specified initial capacity
+	 * and the default load factor, which is 0.75.
+	 *
+	 * @param initialCapacity the initial capacity
+	 * @throws IllegalArgumentException if the initial capacity is less
+	 *     than zero
+	 */
+	public HashBag(int initialCapacity) {
+		this(initialCapacity, DEFAULT_LOAD_FACTOR, false);  // false = do not validate parms
+	}
+
+	/**
+	 * Construct a new, empty bag with
+	 * the specified initial capacity and load factor.
+	 *
+	 * @param initialCapacity the initial capacity
+	 * @param loadFactor the load factor
+	 * @throws IllegalArgumentException if the initial capacity is less
+	 *     than zero or if the load factor is non-positive
+	 */
+	public HashBag(int initialCapacity, float loadFactor) {
+		this(initialCapacity, loadFactor, true);  // true = validate parms
+	}
+
+	private HashBag(int initialCapacity, float loadFactor, boolean validateParms) {
+		super();
+		int capacity = initialCapacity;
+		if (validateParms) {
+			if (capacity < 0) {
+				throw new IllegalArgumentException("Illegal Initial Capacity: " + capacity);
+			}
+			if (capacity > MAXIMUM_CAPACITY) {
+				capacity = MAXIMUM_CAPACITY;
+			}
+			if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
+				throw new IllegalArgumentException("Illegal Load factor: " + loadFactor);
+			}
+
+			// find a power of 2 >= 'initialCapacity'
+			capacity = 1;
+			while (capacity < initialCapacity) {
+				capacity <<= 1;
+			}
+		}
+
+		this.loadFactor = loadFactor;
+		this.table = this.buildTable(capacity);
+		this.threshold = (int) (capacity * loadFactor);
+	}
+
+	/**
+	 * Construct a new bag containing the elements in the specified
+	 * collection. The bag's load factor will be the default, which is 0.75,
+	 * and its initial capacity will be sufficient to hold all the elements in
+	 * the specified collection.
+	 *
+	 * @param c the collection whose elements are to be placed into this bag.
+	 */
+	public HashBag(Collection<? extends E> c) {
+		this(Math.max((int) (c.size() / DEFAULT_LOAD_FACTOR) + 1, DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
+		this.addAll_(c);
+	}
+
+	/**
+	 * Return a hash for the specified object.
+	 */
+	private int hash(Object o) {
+		return (o == null) ? 0 : this.tweakHash(o.hashCode());
+	}
+
+	/**
+	 * Tweak the specified hash, to defend against poor implementations
+	 * of {@link Object#hashCode()}.
+	 */
+	private int tweakHash(int h) {
+		h ^= (h >>> 20) ^ (h >>> 12);
+		return h ^ (h >>> 7) ^ (h >>> 4);
+	}
+
+	/**
+	 * Return the index for the specified hash.
+	 */
+	private int index(int hash) {
+		return this.index(hash, this.table.length);
+	}
+
+	/**
+	 * Return the index for the specified hash
+	 * within a table with the specified length.
+	 */
+	int index(int hash, int length) {
+		return hash & (length - 1);
+	}
+
+	/**
+	 * Internal {@link #addAll(Collection)} for construction and cloning.
+	 * (No check for re-hash; no change to mod count; no return value.)
+	 */
+	private void addAll_(Iterable<? extends E> c) {
+		for (E e : c) {
+			this.add_(e);
+		}
+	}
+
+	/**
+	 * Internal {@link #add(Object)} for construction and cloning.
+	 * (No check for re-hash; no change to mod count; no return value.)
+	 */
+	private void add_(E o) {
+		this.add_(o, 1);
+	}
+
+	/**
+	 * Internal {@link #add(Object, int)} for construction, cloning, and serialization.
+	 * (No check for re-hash; no change to mod count; no return value.)
+	 */
+	private void add_(E o, int cnt) {
+		int hash = this.hash(o);
+		int index = this.index(hash);
+		for (Entry<E> e = this.table[index]; e != null; e = e.next) {
+			Object eo;
+			if ((e.hash == hash) && (((eo = e.object) == o) || ((o != null) && o.equals(eo)))) {
+				e.count += cnt;
+				this.size += cnt;
+				return;
+			}
+		}
+
+		// create the new entry and put it in the table
+		Entry<E> e = this.buildEntry(hash, o, cnt, this.table[index]);
+		this.table[index] = e;
+		this.size += cnt;
+		this.uniqueCount++;
+	}
+
+	/**
+	 * This implementation simply returns the maintained size.
+	 */
+	@Override
+	public int size() {
+		return this.size;
+	}
+
+	/**
+	 * This implementation simply compares the maintained size to zero.
+	 */
+	@Override
+	public boolean isEmpty() {
+		return this.size == 0;
+	}
+
+	/**
+	 * Search for the object's entry in the hash table by calculating
+	 * the object's hash code and examining the entries in the corresponding hash
+	 * table bucket.
+	 */
+	private Entry<E> getEntry(Object o) {
+		int hash = this.hash(o);
+		for (Entry<E> e = this.table[this.index(hash)]; e != null; e = e.next) {
+			Object eo;
+			if ((e.hash == hash) && (((eo = e.object) == o) || ((o != null) && o.equals(eo)))) {
+				return e;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public boolean contains(Object o) {
+		return this.getEntry(o) != null;
+	}
+
+	@Override
+	public int count(Object o) {
+		Entry<E> e = this.getEntry(o);
+		return (e == null) ? 0 : e.count;
+	}
+
+	/**
+	 * Rehash the contents of the bag into a new hash table
+	 * with a larger capacity. This method is called when the
+	 * number of different elements in the bag exceeds its
+	 * capacity and load factor.
+	 */
+	private void rehash() {
+		Entry<E>[] oldTable = this.table;
+		int oldCapacity = oldTable.length;
+
+		if (oldCapacity == MAXIMUM_CAPACITY) {
+			this.threshold = Integer.MAX_VALUE;
+			return;
+		}
+
+		int newCapacity = 2 * oldCapacity;
+		Entry<E>[] newTable = this.buildTable(newCapacity);
+
+		for (int i = oldCapacity; i-- > 0; ) {
+			for (Entry<E> old = oldTable[i]; old != null; ) {
+				Entry<E> e = old;
+				old = old.next;
+
+				int index = this.index(e.hash, newCapacity);
+				e.next = newTable[index];
+				newTable[index] = e;
+			}
+		}
+
+		this.table = newTable;
+		this.threshold = (int) (newCapacity * this.loadFactor);
+	}
+
+	// minimize scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	private Entry<E>[] buildTable(int capacity) {
+		return new Entry[capacity];
+	}
+
+	/**
+	 * This implementation searches for the object in the hash table by calculating
+	 * the object's hash code and examining the entries in the corresponding hash
+	 * table bucket.
+	 */
+	@Override
+	public boolean add(E o) {
+		return this.add(o, 1);
+	}
+
+	/**
+	 * This implementation searches for the object in the hash table by calculating
+	 * the object's hash code and examining the entries in the corresponding hash
+	 * table bucket.
+	 */
+	@Override
+	public boolean add(E o, int cnt) {
+		if (cnt <= 0) {
+			return false;
+		}
+		this.modCount++;
+		int hash = this.hash(o);
+		int index = this.index(hash);
+
+		// if the object is already in the bag, simply bump its count
+		for (Entry<E> e = this.table[index]; e != null; e = e.next) {
+			Object eo;
+			if ((e.hash == hash) && (((eo = e.object) == o) || ((o != null) && o.equals(eo)))) {
+				e.count += cnt;
+				this.size += cnt;
+				return true;
+			}
+		}
+
+		// rehash the table if we are going to exceed the threshold
+		if (this.uniqueCount >= this.threshold) {
+			this.rehash();
+			index = this.index(hash);  // need to re-calculate the index
+		}
+
+		// create the new entry and put it in the table
+		Entry<E> e = this.buildEntry(hash, o, cnt, this.table[index]);
+		this.table[index] = e;
+		this.size += cnt;
+		this.uniqueCount++;
+		return true;
+	}
+
+	// minimize scope of suppressed warnings
+	@SuppressWarnings({ "rawtypes", "unchecked" } )
+	private Entry<E> buildEntry(int hash, Object o, int cnt, Entry next) {
+		return new Entry<E>(hash, (E) o, cnt, (Entry<E>) next);
+	}
+
+	/**
+	 * This implementation searches for the object in the hash table by calculating
+	 * the object's hash code and examining the entries in the corresponding hash
+	 * table bucket.
+	 */
+	@Override
+	public boolean remove(Object o) {
+		return this.remove(o, 1);
+	}
+
+	/**
+	 * This implementation searches for the object in the hash table by calculating
+	 * the object's hash code and examining the entries in the corresponding hash
+	 * table bucket.
+	 */
+	@Override
+	public boolean remove(Object o, int cnt) {
+		if (cnt <= 0) {
+			return false;
+		}
+		int hash = this.hash(o);
+		int index = this.index(hash);
+
+		for (Entry<E> e = this.table[index], prev = null; e != null; prev = e, e = e.next) {
+			Object eo;
+			if ((e.hash == hash) && (((eo = e.object) == o) || ((o != null) && o.equals(eo)))) {
+				this.modCount++;
+				cnt = (cnt < e.count) ? cnt : e.count;
+				e.count -= cnt;
+				// if we are removing the last element(s), remove the entry from the table
+				if (e.count == 0) {
+					if (prev == null) {
+						this.table[index] = e.next;
+					} else {
+						prev.next = e.next;
+					}
+					this.uniqueCount--;
+				}
+				this.size -= cnt;
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * This implementation simply clears out all of the hash table buckets.
+	 */
+	@Override
+	public void clear() {
+		Entry<E>[] tab = this.table;
+		this.modCount++;
+		for (int i = tab.length; i-- > 0; ) {
+			tab[i] = null;
+		}
+		this.size = 0;
+		this.uniqueCount = 0;
+	}
+
+	/**
+	 * Returns a shallow copy of this bag: the elements
+	 * themselves are not cloned.
+	 *
+	 * @return a shallow copy of this bag.
+	 */
+	@Override
+	public HashBag<E> clone() {
+		try {
+			@SuppressWarnings("unchecked")
+			HashBag<E> clone = (HashBag<E>) super.clone();
+			clone.table = this.buildTable(this.table.length);
+			clone.size = 0;
+			clone.uniqueCount = 0;
+			clone.modCount = 0;
+			clone.addAll_(this);
+			return clone;
+		} catch (CloneNotSupportedException e) {
+			throw new InternalError();
+		}
+	}
+
+
+	/**
+	 * Hash table collision list entry.
+	 */
+	private static class Entry<E>
+		implements Bag.Entry<E>
+	{
+		final int hash;
+		final E object;
+		int count;
+		Entry<E> next;
+
+		Entry(int hash, E object, int count, Entry<E> next) {
+			this.hash = hash;
+			this.object = object;
+			this.count = count;
+			this.next = next;
+		}
+
+		// ***** Bag.Entry implementation
+		@Override
+		public E getElement() {
+			return this.object;
+		}
+
+		@Override
+		public int getCount() {
+			return this.count;
+		}
+
+		@Override
+		public int setCount(int count) {
+			if (count <= 0) {
+				throw new IllegalArgumentException("count must be greater than zero: " + count);
+			}
+			int old = this.count;
+			this.count = count;
+			return old;
+		}
+
+		@Override
+		public boolean equals(Object o) {
+			if ( ! (o instanceof Bag.Entry<?>)) {
+				return false;
+			}
+			@SuppressWarnings("rawtypes")
+			Bag.Entry e = (Bag.Entry) o;
+			return (this.count == e.getCount()) &&
+					ObjectTools.equals(this.object, e.getElement());
+		}
+
+		@Override
+		public int hashCode() {
+			E o = this.object;
+			return (o == null) ? 0 : (this.count * o.hashCode());
+		}
+
+		@Override
+		public String toString() {
+			return this.object + "=>" + this.count;
+		}
+	}
+
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Iterator<E> iterator() {
+		return (this.size == 0) ? EMPTY_ITERATOR : new HashIterator();
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Iterator<E> uniqueIterator() {
+		return (this.size == 0) ? EMPTY_ITERATOR : new UniqueIterator();
+	}
+
+	@Override
+	public int uniqueCount() {
+		return this.uniqueCount;
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Iterator<Bag.Entry<E>> entries() {
+		return (this.size == 0) ? EMPTY_ITERATOR : new EntryIterator();
+	}
+
+
+	/**
+	 * Empty iterator that does just about nothing.
+	 */
+	@SuppressWarnings("rawtypes")
+	private static final Iterator EMPTY_ITERATOR = new EmptyIterator();
+
+	@SuppressWarnings("rawtypes")
+	private static class EmptyIterator
+		implements Iterator
+	{
+		EmptyIterator() {
+			super();
+		}
+
+		@Override
+		public boolean hasNext() {
+			return false;
+		}
+
+		@Override
+		public Object next() {
+			throw new NoSuchElementException();
+		}
+
+		@Override
+		public void remove() {
+			throw new IllegalStateException();
+		}
+	}
+
+
+	private class HashIterator
+		implements Iterator<E>
+	{
+		private int index = HashBag.this.table.length;	// start at the end of the table
+		private Entry<E> nextEntry = null;
+		private int nextEntryCount = 0;
+		private Entry<E> lastReturnedEntry = null;
+
+		/**
+		 * The modCount value that the iterator believes that the backing
+		 * bag should have. If this expectation is violated, the iterator
+		 * has detected a concurrent modification.
+		 */
+		private int expectedModCount = HashBag.this.modCount;
+
+		HashIterator() {
+			super();
+		}
+
+		@Override
+		public boolean hasNext() {
+			Entry<E> e = this.nextEntry;
+			int i = this.index;
+			Entry<E>[] tab = HashBag.this.table;
+			// Use locals for faster loop iteration
+			while ((e == null) && (i > 0)) {
+				e = tab[--i];		// move backwards through the table
+			}
+			this.nextEntry = e;
+			this.index = i;
+			return e != null;
+		}
+
+		@Override
+		public E next() {
+			if (HashBag.this.modCount != this.expectedModCount) {
+				throw new ConcurrentModificationException();
+			}
+			Entry<E> et = this.nextEntry;
+			int i = this.index;
+			Entry<E>[] tab = HashBag.this.table;
+			// Use locals for faster loop iteration
+			while ((et == null) && (i > 0)) {
+				et = tab[--i];		// move backwards through the table
+			}
+			this.nextEntry = et;
+			this.index = i;
+			if (et == null) {
+				throw new NoSuchElementException();
+			}
+			Entry<E> e = this.lastReturnedEntry = this.nextEntry;
+			this.nextEntryCount++;
+			if (this.nextEntryCount == e.count) {
+				this.nextEntry = e.next;
+				this.nextEntryCount = 0;
+			}
+			return e.object;
+		}
+
+		@Override
+		public void remove() {
+			if (this.lastReturnedEntry == null) {
+				throw new IllegalStateException();
+			}
+			if (HashBag.this.modCount != this.expectedModCount) {
+				throw new ConcurrentModificationException();
+			}
+			int slot = HashBag.this.index(this.lastReturnedEntry.hash, HashBag.this.table.length);
+			for (Entry<E> e = HashBag.this.table[slot], prev = null; e != null; prev = e, e = e.next) {
+				if (e == this.lastReturnedEntry) {
+					HashBag.this.modCount++;
+					this.expectedModCount++;
+					e.count--;
+					if (e.count == 0) {
+						// if we are removing the last one, remove the entry from the table
+						if (prev == null) {
+							HashBag.this.table[slot] = e.next;
+						} else {
+							prev.next = e.next;
+						}
+						HashBag.this.uniqueCount--;
+					} else {
+						// slide back the count to account for the just-removed element
+						this.nextEntryCount--;
+					}
+					HashBag.this.size--;
+					this.lastReturnedEntry = null;	// it cannot be removed again
+					return;
+				}
+			}
+			throw new ConcurrentModificationException();
+		}
+	}
+
+
+	private class EntryIterator
+		implements Iterator<Entry<E>>
+	{
+		private int index = HashBag.this.table.length;	// start at the end of the table
+		private Entry<E> nextEntry = null;
+		private Entry<E> lastReturnedEntry = null;
+
+		/**
+		 * The modCount value that the iterator believes that the backing
+		 * bag should have. If this expectation is violated, the iterator
+		 * has detected a concurrent modification.
+		 */
+		private int expectedModCount = HashBag.this.modCount;
+
+		EntryIterator() {
+			super();
+		}
+
+		@Override
+		public boolean hasNext() {
+			Entry<E> e = this.nextEntry;
+			int i = this.index;
+			Entry<E>[] tab = HashBag.this.table;
+			// Use locals for faster loop iteration
+			while ((e == null) && (i > 0)) {
+				e = tab[--i];		// move backwards through the table
+			}
+			this.nextEntry = e;
+			this.index = i;
+			return e != null;
+		}
+
+		@Override
+		public Entry<E> next() {
+			if (HashBag.this.modCount != this.expectedModCount) {
+				throw new ConcurrentModificationException();
+			}
+			Entry<E> et = this.nextEntry;
+			int i = this.index;
+			Entry<E>[] tab = HashBag.this.table;
+			// Use locals for faster loop iteration
+			while ((et == null) && (i > 0)) {
+				et = tab[--i];		// move backwards through the table
+			}
+			this.nextEntry = et;
+			this.index = i;
+			if (et == null) {
+				throw new NoSuchElementException();
+			}
+			Entry<E> e = this.lastReturnedEntry = this.nextEntry;
+			this.nextEntry = e.next;
+			return e;
+		}
+
+		@Override
+		public void remove() {
+			if (this.lastReturnedEntry == null) {
+				throw new IllegalStateException();
+			}
+			if (HashBag.this.modCount != this.expectedModCount) {
+				throw new ConcurrentModificationException();
+			}
+			int slot = HashBag.this.index(this.lastReturnedEntry.hash, HashBag.this.table.length);
+			for (Entry<E> e = HashBag.this.table[slot], prev = null; e != null; prev = e, e = e.next) {
+				if (e == this.lastReturnedEntry) {
+					HashBag.this.modCount++;
+					this.expectedModCount++;
+					// remove the entry from the table
+					if (prev == null) {
+						HashBag.this.table[slot] = e.next;
+					} else {
+						prev.next = e.next;
+					}
+					HashBag.this.uniqueCount--;
+					HashBag.this.size -= this.lastReturnedEntry.count;
+					this.lastReturnedEntry = null;	// it cannot be removed again
+					return;
+				}
+			}
+			throw new ConcurrentModificationException();
+		}
+	}
+
+
+	private class UniqueIterator
+		implements Iterator<E>
+	{
+		private EntryIterator entryIterator = new EntryIterator();
+
+		UniqueIterator() {
+			super();
+		}
+
+		@Override
+		public boolean hasNext() {
+			return this.entryIterator.hasNext();
+		}
+
+		@Override
+		public E next() {
+			return this.entryIterator.next().object;
+		}
+
+		@Override
+		public void remove() {
+			this.entryIterator.remove();
+		}
+	}
+
+
+	@Override
+	public boolean equals(Object o) {
+		if (o == this) {
+			return true;
+		}
+		if ( ! (o instanceof Bag<?>)) {
+			return false;
+		}
+		@SuppressWarnings("unchecked")
+		Bag<E> b = (Bag<E>) o;
+		if (b.size() != this.size()) {
+			return false;
+		}
+		if (b.uniqueCount() != this.uniqueCount()) {
+			return false;
+		}
+		for (Iterator<Bag.Entry<E>> stream = b.entries(); stream.hasNext(); ) {
+			Bag.Entry<E> entry = stream.next();
+			if (entry.getCount() != this.count(entry.getElement())) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		int h = 0;
+		for (E o : this) {
+			if (o != null) {
+				h += o.hashCode();
+			}
+		}
+		return h;
+	}
+
+	/**
+	 * Save the state of this bag to a stream (i.e. serialize it).
+	 *
+	 * @serialData Emit the capacity of the bag (int),
+	 *     followed by the number of unique elements in the bag (int),
+	 *     followed by all of the bag's elements (each an Object) and
+	 *     their counts (each an int), in no particular order.
+	 */
+	private void writeObject(java.io.ObjectOutputStream s)
+				throws java.io.IOException {
+		// write out the threshold, load factor, and any hidden stuff
+		s.defaultWriteObject();
+
+		// write out number of buckets
+		s.writeInt(this.table.length);
+
+		// write out number of unique elements
+		s.writeInt(this.uniqueCount);
+
+		// write out elements and counts (alternating)
+		if (this.uniqueCount > 0) {
+			for (Entry<E> entry : this.table) {
+				while (entry != null) {
+					s.writeObject(entry.object);
+					s.writeInt(entry.count);
+					entry = entry.next;
+				}
+			}
+		}
+	}
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Reconstitute the bag from a stream (i.e. deserialize it).
+	 */
+	private void readObject(java.io.ObjectInputStream s)
+				throws java.io.IOException, ClassNotFoundException {
+		// read in the threshold, loadfactor, and any hidden stuff
+		s.defaultReadObject();
+
+		// read in number of buckets and allocate the bucket array
+		this.table = this.buildTable(s.readInt());
+
+		// read in number of unique elements
+		int unique = s.readInt();
+
+		// read the elements and counts, and put the elements in the bag
+		for (int i = 0; i < unique; i++) {
+			@SuppressWarnings("unchecked")
+			E element = (E) s.readObject();
+			int elementCount = s.readInt();
+			this.add_(element, elementCount);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/IdentityHashBag.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/IdentityHashBag.java
new file mode 100644
index 0000000..8815783
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/IdentityHashBag.java
@@ -0,0 +1,955 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.io.Serializable;
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * This class implements the {@link Bag} interface with a
+ * hash table, using object-identity in place of object-equality when
+ * comparing elements. In other words, in an <code>IdentityHashBag</code>,
+ * two objects <code>o1</code> and <code>o2</code> are considered
+ * equal if and only if <code>(o1 == o2)</code>. (In normal {@link Bag}
+ * implementations (like {@link HashBag}) two objects <code>o1</code>
+ * and <code>o2</code> are considered equal if and only if
+ * <code>(o1 == null ? o2 == null : o1.equals(o2))</code>.)
+ * <p>
+ * <strong>
+ * This class is <em>not</em> a general-purpose {@link Bag}
+ * implementation! While this class implements the {@link Bag} interface, it
+ * intentionally violates {@link Bag}'s general contract, which mandates the
+ * use of the <code>equals</code> method when comparing objects. This class is
+ * designed for use only in the rare cases wherein object-identity
+ * semantics are required.
+ * </strong>
+ * <p>
+ * This class makes no guarantees as to the iteration order of
+ * the bag's elements; in particular, it does not guarantee that the order
+ * will remain constant over time. This class permits the <code>null</code>
+ * element.
+ * <p>
+ * This class offers constant time performance for the basic operations
+ * (<code>add</code>, <code>remove</code>, <code>contains</code> and
+ * <code>size</code>), assuming the system identity hash function
+ * ({@link System#identityHashCode(Object)}) disperses elements properly
+ * among the buckets. Iterating over this bag requires time
+ * proportional to the sum of the bag's size (the number of elements) plus the
+ * "capacity" of the backing hash table (the number of buckets). Thus, it is
+ * important not to set the initial capacity too high (or the load factor too
+ * low) if iteration performance is important.
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If multiple
+ * threads access a bag concurrently, and at least one of the threads modifies
+ * the bag, it <em>must</em> be synchronized externally. This is typically
+ * accomplished by synchronizing on some object that naturally encapsulates
+ * the bag. If no such object exists, the bag should be "wrapped" using the
+ * <code>Collections.synchronizedCollection</code> method. This is
+ * best done at creation time, to prevent accidental unsynchronized access
+ * to the bag:
+ * <pre>
+ * Collection c = Collections.synchronizedCollection(new IdentityHashBag(...));
+ * </pre>
+ * <p>
+ * The iterators returned by this class's <code>iterator</code> method are
+ * <em>fail-fast</em>: if the bag is modified at any time after the iterator is
+ * created, in any way except through the iterator's own <code>remove</code>
+ * method, the iterator throws a {@link ConcurrentModificationException}.
+ * Thus, in the face of concurrent modification, the iterator fails quickly
+ * and cleanly, rather than risking arbitrary, non-deterministic behavior at
+ * an undetermined time in the future.
+ * <p>
+ * Note that the fail-fast behavior of an iterator cannot be guaranteed
+ * as it is, generally speaking, impossible to make any hard guarantees in the
+ * presence of unsynchronized concurrent modification. Fail-fast iterators
+ * throw <code>ConcurrentModificationException</code> on a best-effort basis.
+ * Therefore, it would be wrong to write a program that depended on this
+ * exception for its correctness: <em>the fail-fast behavior of iterators
+ * should be used only to detect bugs.</em>
+ *
+ * @param <E> the type of elements maintained by the bag
+ *
+ * @see Collection
+ * @see Bag
+ * @see SynchronizedBag
+ * @see	java.util.Collections#synchronizedCollection(Collection)
+ * @see HashBag
+ */
+@SuppressWarnings("nls")
+public class IdentityHashBag<E>
+	extends AbstractCollection<E>
+	implements Bag<E>, Cloneable, Serializable
+{
+	/** The hash table. Resized as necessary. Length MUST Always be a power of two. */
+	transient Entry<E>[] table;
+
+	/** The total number of entries in the bag. */
+	transient int size = 0;
+
+	/** The number of UNIQUE entries in the bag. */
+	transient int uniqueCount = 0;
+
+	/**
+	 * The hash table is rehashed when its size exceeds this threshold. (The
+	 * value of this field is <code>(int) (capacity * loadFactor)</code>.)
+	 *
+	 * @serial threshold
+	 */
+	private int threshold;
+
+	/**
+	 * The load factor for the hash table.
+	 *
+	 * @serial load factor
+	 */
+	private final float loadFactor;
+
+	/**
+	 * The number of times this bag has been structurally modified.
+	 * Structural modifications are those that change the number of entries in
+	 * the bag or otherwise modify its internal structure (e.g. rehash).
+	 * This field is used to make iterators on this bag fail-fast.
+	 *
+	 * @see java.util.ConcurrentModificationException
+	 */
+	transient int modCount = 0;
+
+	/**
+	 * The default initial capacity - MUST be a power of two.
+	 */
+	private static final int DEFAULT_INITIAL_CAPACITY = 16;
+
+	/**
+	 * The maximum capacity, used if a higher value is implicitly specified
+	 * by either of the constructors with arguments.
+	 * MUST be a power of two <= (1 << 30).
+		 */
+	private static final int MAXIMUM_CAPACITY = 1 << 30;
+
+	/**
+	 * The load factor used when none specified in constructor.
+	 */
+	private static final float DEFAULT_LOAD_FACTOR = 0.75f;
+
+	/**
+	 * Construct a new, empty bag with the
+	 * default capacity, which is 16, and load factor, which is 0.75.
+	 */
+	public IdentityHashBag() {
+		this(DEFAULT_INITIAL_CAPACITY);
+	}
+
+	/**
+	 * Construct a new, empty bag with the specified initial capacity
+	 * and the default load factor, which is 0.75.
+	 *
+	 * @param initialCapacity the initial capacity
+	 * @throws IllegalArgumentException if the initial capacity is less
+	 *     than zero
+	 */
+	public IdentityHashBag(int initialCapacity) {
+		this(initialCapacity, DEFAULT_LOAD_FACTOR, false);  // false = do not validate parms
+	}
+
+	/**
+	 * Construct a new, empty bag with
+	 * the specified initial capacity and load factor.
+	 *
+	 * @param initialCapacity the initial capacity
+	 * @param loadFactor the load factor
+	 * @throws IllegalArgumentException if the initial capacity is less
+	 *     than zero or if the load factor is non-positive
+	 */
+	public IdentityHashBag(int initialCapacity, float loadFactor) {
+		this(initialCapacity, loadFactor, true);  // true = validate parms
+	}
+
+	private IdentityHashBag(int initialCapacity, float loadFactor, boolean validateParms) {
+		super();
+		int capacity = initialCapacity;
+		if (validateParms) {
+			if (capacity < 0) {
+				throw new IllegalArgumentException("Illegal Initial Capacity: " + capacity);
+			}
+			if (capacity > MAXIMUM_CAPACITY) {
+				capacity = MAXIMUM_CAPACITY;
+			}
+			if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
+				throw new IllegalArgumentException("Illegal Load factor: " + loadFactor);
+			}
+
+			// find a power of 2 >= 'initialCapacity'
+			capacity = 1;
+			while (capacity < initialCapacity) {
+				capacity <<= 1;
+			}
+		}
+
+		this.loadFactor = loadFactor;
+		this.table = this.buildTable(capacity);
+		this.threshold = (int) (capacity * loadFactor);
+	}
+
+	/**
+	 * Construct a new bag containing the elements in the specified
+	 * collection. The bag's load factor will be the default, which is 0.75,
+	 * and its initial capacity will be sufficient to hold all the elements in
+	 * the specified collection.
+	 *
+	 * @param c the collection whose elements are to be placed into this bag.
+	 */
+	public IdentityHashBag(Collection<? extends E> c) {
+		this(Math.max((int) (c.size() / DEFAULT_LOAD_FACTOR) + 1, DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
+		this.addAll_(c);
+	}
+
+	/**
+	 * Return a index for the specified object.
+	 */
+	private int index(Object o) {
+		return this.index(this.hash(o));
+	}
+
+	/**
+	 * Return a hash for the specified object.
+	 */
+	private int hash(Object o) {
+		return (o == null) ? 0 : this.tweakHash(System.identityHashCode(o));
+	}
+
+	/**
+	 * Tweak the specified hash.
+	 */
+	private int tweakHash(int h) {
+		return h;
+//		h ^= (h >>> 20) ^ (h >>> 12);
+//		return h ^ (h >>> 7) ^ (h >>> 4);
+	}
+
+	/**
+	 * Return the index for the specified hash.
+	 */
+	private int index(int hash) {
+		return this.index(hash, this.table.length);
+	}
+
+	/**
+	 * Return the index for the specified hash
+	 * within a table with the specified length.
+	 */
+	int index(int hash, int length) {
+		return hash & (length - 1);
+	}
+
+	/**
+	 * Internal {@link #addAll(Collection)} for construction and cloning.
+	 * (No check for re-hash; no change to mod count; no return value.)
+	 */
+	private void addAll_(Iterable<? extends E> c) {
+		for (E e : c) {
+			this.add_(e);
+		}
+	}
+
+	/**
+	 * Internal {@link #add(Object)} for construction and cloning.
+	 * (No check for re-hash; no change to mod count; no return value.)
+	 */
+	private void add_(E o) {
+		this.add_(o, 1);
+	}
+
+	/**
+	 * Internal {@link #add(Object, int)} for construction, cloning, and serialization.
+	 * (No check for re-hash; no change to mod count; no return value.)
+	 */
+	private void add_(E o, int cnt) {
+		int hash = this.hash(o);
+		int index = this.index(hash);
+		for (Entry<E> e = this.table[index]; e != null; e = e.next) {
+			if (e.object == o) {
+				e.count += cnt;
+				this.size += cnt;
+				return;
+			}
+		}
+
+		// create the new entry and put it in the table
+		Entry<E> e = this.buildEntry(hash, o, cnt, this.table[index]);
+		this.table[index] = e;
+		this.size += cnt;
+		this.uniqueCount++;
+	}
+
+	/**
+	 * This implementation simply returns the maintained size.
+	 */
+	@Override
+	public int size() {
+		return this.size;
+	}
+
+	/**
+	 * This implementation simply compares the maintained size to zero.
+	 */
+	@Override
+	public boolean isEmpty() {
+		return this.size == 0;
+	}
+
+	/**
+	 * Search for the object's entry in the hash table by calculating
+	 * the object's identity hash code and examining the entries in the corresponding hash
+	 * table bucket.
+	 */
+	private Entry<E> getEntry(Object o) {
+		for (Entry<E> e = this.table[this.index(o)]; e != null; e = e.next) {
+			if (e.object == o) {
+				return e;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public boolean contains(Object o) {
+		return this.getEntry(o) != null;
+	}
+
+	@Override
+	public int count(Object o) {
+		Entry<E> e = this.getEntry(o);
+		return (e == null) ? 0 : e.count;
+	}
+
+	/**
+	 * Rehash the contents of the bag into a new hash table
+	 * with a larger capacity. This method is called when the
+	 * number of different elements in the bag exceeds its
+	 * capacity and load factor.
+	 */
+	private void rehash() {
+		Entry<E>[] oldTable = this.table;
+		int oldCapacity = oldTable.length;
+
+		if (oldCapacity == MAXIMUM_CAPACITY) {
+			this.threshold = Integer.MAX_VALUE;
+			return;
+		}
+
+		int newCapacity = 2 * oldCapacity;
+		Entry<E>[] newTable = this.buildTable(newCapacity);
+
+		for (int i = oldCapacity; i-- > 0; ) {
+			for (Entry<E> old = oldTable[i]; old != null; ) {
+				Entry<E> e = old;
+				old = old.next;
+
+				int index = this.index(e.hash, newCapacity);
+				e.next = newTable[index];
+				newTable[index] = e;
+			}
+		}
+
+		this.table = newTable;
+		this.threshold = (int) (newCapacity * this.loadFactor);
+	}
+
+	// minimize scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	private Entry<E>[] buildTable(int capacity) {
+		return new Entry[capacity];
+	}
+
+	/**
+	 * This implementation searches for the object in the hash table by calculating
+	 * the object's identity hash code and examining the entries in the corresponding hash
+	 * table bucket.
+	 */
+	@Override
+	public boolean add(E o) {
+		return this.add(o, 1);
+	}
+
+	/**
+	 * This implementation searches for the object in the hash table by calculating
+	 * the object's identity hash code and examining the entries in the corresponding hash
+	 * table bucket.
+	 */
+	@Override
+	public boolean add(E o, int cnt) {
+		if (cnt <= 0) {
+			return false;
+		}
+		this.modCount++;
+		int hash = this.hash(o);
+		int index = this.index(hash);
+
+		// if the object is already in the bag, simply bump its count
+		for (Entry<E> e = this.table[index]; e != null; e = e.next) {
+			if (e.object == o) {
+				e.count += cnt;
+				this.size += cnt;
+				return true;
+			}
+		}
+
+		// rehash the table if we are going to exceed the threshold
+		if (this.uniqueCount >= this.threshold) {
+			this.rehash();
+			index = this.index(hash);  // need to re-calculate the index
+		}
+
+		// create the new entry and put it in the table
+		Entry<E> e = this.buildEntry(hash, o, cnt, this.table[index]);
+		this.table[index] = e;
+		this.size += cnt;
+		this.uniqueCount++;
+		return true;
+	}
+
+	// minimize scope of suppressed warnings
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	private Entry<E> buildEntry(int hash, Object o, int cnt, Entry next) {
+		return new Entry<E>(hash, (E) o, cnt, (Entry<E>) next);
+	}
+
+	/**
+	 * This implementation searches for the object in the hash table by calculating
+	 * the object's identity hash code and examining the entries in the corresponding hash
+	 * table bucket.
+	 */
+	@Override
+	public boolean remove(Object o) {
+		return this.remove(o, 1);
+	}
+
+	/**
+	 * This implementation searches for the object in the hash table by calculating
+	 * the object's identity hash code and examining the entries in the corresponding hash
+	 * table bucket.
+	 */
+	@Override
+	public boolean remove(Object o, int cnt) {
+		if (cnt <= 0) {
+			return false;
+		}
+		int index = this.index(o);
+
+		for (Entry<E> e = this.table[index], prev = null; e != null; prev = e, e = e.next) {
+			if (e.object == o) {
+				this.modCount++;
+				cnt = (cnt < e.count) ? cnt : e.count;
+				e.count -= cnt;
+				// if we are removing the last element(s), remove the entry from the table
+				if (e.count == 0) {
+					if (prev == null) {
+						this.table[index] = e.next;
+					} else {
+						prev.next = e.next;
+					}
+					this.uniqueCount--;
+				}
+				this.size -= cnt;
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * This implementation uses object-identity to determine whether the
+	 * specified collection contains a particular element.
+	 */
+	@Override
+	public boolean removeAll(Collection<?> c) {
+		return super.removeAll(new IdentityHashBag<Object>(c));
+	}
+
+	/**
+	 * This implementation uses object-identity to determine whether the
+	 * specified collection contains a particular element.
+	 */
+	@Override
+	public boolean retainAll(Collection<?> c) {
+		return super.retainAll(new IdentityHashBag<Object>(c));
+	}
+
+	/**
+	 * This implementation simply clears out all of the hash table buckets.
+	 */
+	@Override
+	public void clear() {
+		Entry<E>[] tab = this.table;
+		this.modCount++;
+		for (int i = tab.length; i-- > 0; ) {
+			tab[i] = null;
+		}
+		this.size = 0;
+		this.uniqueCount = 0;
+	}
+
+	/**
+	 * Returns a shallow copy of this bag: the elements
+	 * themselves are not cloned.
+	 *
+	 * @return a shallow copy of this bag.
+	 */
+	@Override
+	public IdentityHashBag<E> clone() {
+		try {
+			@SuppressWarnings("unchecked")
+			IdentityHashBag<E> clone = (IdentityHashBag<E>) super.clone();
+			clone.table = this.buildTable(this.table.length);
+			clone.size = 0;
+			clone.uniqueCount = 0;
+			clone.modCount = 0;
+			clone.addAll_(this);
+			return clone;
+		} catch (CloneNotSupportedException e) {
+			throw new InternalError();
+		}
+	}
+
+
+	/**
+	 * Hash table collision list entry.
+	 */
+	private static class Entry<E>
+		implements Bag.Entry<E>
+	{
+		final int hash;  // cache the hash for re-hashes
+		final E object;
+		int count;
+		Entry<E> next;
+
+		Entry(int hash, E object, int count, Entry<E> next) {
+			this.hash = hash;
+			this.object = object;
+			this.count = count;
+			this.next = next;
+		}
+
+		// ***** Bag.Entry implementation
+		@Override
+		public E getElement() {
+			return this.object;
+		}
+
+		@Override
+		public int getCount() {
+			return this.count;
+		}
+
+		@Override
+		public int setCount(int count) {
+			if (count <= 0) {
+				throw new IllegalArgumentException("count must be greater than zero: " + count);
+			}
+			int old = this.count;
+			this.count = count;
+			return old;
+		}
+
+		@Override
+		public boolean equals(Object o) {
+			if ( ! (o instanceof Bag.Entry<?>)) {
+				return false;
+			}
+			@SuppressWarnings("rawtypes")
+			Bag.Entry e = (Bag.Entry) o;
+			return (this.object == e.getElement())
+					&& (this.count == e.getCount());
+		}
+
+		@Override
+		public int hashCode() {
+			E o = this.object;
+			return (o == null) ? 0 : (this.count * o.hashCode());
+		}
+
+		@Override
+		public String toString() {
+			return this.object + "=>" + this.count;
+		}
+	}
+
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Iterator<E> iterator() {
+		return (this.size == 0) ? EMPTY_ITERATOR : new HashIterator();
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Iterator<E> uniqueIterator() {
+		return (this.size == 0) ? EMPTY_ITERATOR : new UniqueIterator();
+	}
+
+	@Override
+	public int uniqueCount() {
+		return this.uniqueCount;
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Iterator<Bag.Entry<E>> entries() {
+		return (this.size == 0) ? EMPTY_ITERATOR : new EntryIterator();
+	}
+
+
+	/**
+	 * Empty iterator that does just about nothing.
+	 */
+	@SuppressWarnings("rawtypes")
+	private static final Iterator EMPTY_ITERATOR = new EmptyIterator();
+
+	@SuppressWarnings("rawtypes")
+	private static class EmptyIterator
+		implements Iterator
+	{
+		EmptyIterator() {
+			super();
+		}
+
+		@Override
+		public boolean hasNext() {
+			return false;
+		}
+
+		@Override
+		public Object next() {
+			throw new NoSuchElementException();
+		}
+
+		@Override
+		public void remove() {
+			throw new IllegalStateException();
+		}
+	}
+
+
+	private class HashIterator
+		implements Iterator<E>
+	{
+		private int index = IdentityHashBag.this.table.length;	// start at the end of the table
+		private Entry<E> nextEntry = null;
+		private int nextEntryCount = 0;
+		private Entry<E> lastReturnedEntry = null;
+
+		/**
+		 * The modCount value that the iterator believes that the backing
+		 * bag should have. If this expectation is violated, the iterator
+		 * has detected a concurrent modification.
+		 */
+		private int expectedModCount = IdentityHashBag.this.modCount;
+
+		HashIterator() {
+			super();
+		}
+
+		@Override
+		public boolean hasNext() {
+			Entry<E> e = this.nextEntry;
+			int i = this.index;
+			Entry<E>[] tab = IdentityHashBag.this.table;
+			// Use locals for faster loop iteration
+			while ((e == null) && (i > 0)) {
+				e = tab[--i];		// move backwards through the table
+			}
+			this.nextEntry = e;
+			this.index = i;
+			return e != null;
+		}
+
+		@Override
+		public E next() {
+			if (IdentityHashBag.this.modCount != this.expectedModCount) {
+				throw new ConcurrentModificationException();
+			}
+			Entry<E> et = this.nextEntry;
+			int i = this.index;
+			Entry<E>[] tab = IdentityHashBag.this.table;
+			// Use locals for faster loop iteration
+			while ((et == null) && (i > 0)) {
+				et = tab[--i];		// move backwards through the table
+			}
+			this.nextEntry = et;
+			this.index = i;
+			if (et == null) {
+				throw new NoSuchElementException();
+			}
+			Entry<E> e = this.lastReturnedEntry = this.nextEntry;
+			this.nextEntryCount++;
+			if (this.nextEntryCount == e.count) {
+				this.nextEntry = e.next;
+				this.nextEntryCount = 0;
+			}
+			return e.object;
+		}
+
+		@Override
+		public void remove() {
+			if (this.lastReturnedEntry == null) {
+				throw new IllegalStateException();
+			}
+			if (IdentityHashBag.this.modCount != this.expectedModCount) {
+				throw new ConcurrentModificationException();
+			}
+			int slot = IdentityHashBag.this.index(this.lastReturnedEntry.hash, IdentityHashBag.this.table.length);
+			for (Entry<E> e = IdentityHashBag.this.table[slot], prev = null; e != null; prev = e, e = e.next) {
+				if (e == this.lastReturnedEntry) {
+					IdentityHashBag.this.modCount++;
+					this.expectedModCount++;
+					e.count--;
+					if (e.count == 0) {
+						// if we are removing the last one, remove the entry from the table
+						if (prev == null) {
+							IdentityHashBag.this.table[slot] = e.next;
+						} else {
+							prev.next = e.next;
+						}
+						IdentityHashBag.this.uniqueCount--;
+					} else {
+						// slide back the count to account for the just-removed element
+						this.nextEntryCount--;
+					}
+					IdentityHashBag.this.size--;
+					this.lastReturnedEntry = null;	// it cannot be removed again
+					return;
+				}
+			}
+			throw new ConcurrentModificationException();
+		}
+	}
+
+
+	private class EntryIterator
+		implements Iterator<Entry<E>>
+	{
+		private int index = IdentityHashBag.this.table.length;	// start at the end of the table
+		private Entry<E> nextEntry = null;
+		private Entry<E> lastReturnedEntry = null;
+
+		/**
+		 * The modCount value that the iterator believes that the backing
+		 * bag should have. If this expectation is violated, the iterator
+		 * has detected a concurrent modification.
+		 */
+		private int expectedModCount = IdentityHashBag.this.modCount;
+
+		EntryIterator() {
+			super();
+		}
+
+		@Override
+		public boolean hasNext() {
+			Entry<E> e = this.nextEntry;
+			int i = this.index;
+			Entry<E>[] tab = IdentityHashBag.this.table;
+			// Use locals for faster loop iteration
+			while ((e == null) && (i > 0)) {
+				e = tab[--i];		// move backwards through the table
+			}
+			this.nextEntry = e;
+			this.index = i;
+			return e != null;
+		}
+
+		@Override
+		public Entry<E> next() {
+			if (IdentityHashBag.this.modCount != this.expectedModCount) {
+				throw new ConcurrentModificationException();
+			}
+			Entry<E> et = this.nextEntry;
+			int i = this.index;
+			Entry<E>[] tab = IdentityHashBag.this.table;
+			// Use locals for faster loop iteration
+			while ((et == null) && (i > 0)) {
+				et = tab[--i];		// move backwards through the table
+			}
+			this.nextEntry = et;
+			this.index = i;
+			if (et == null) {
+				throw new NoSuchElementException();
+			}
+			Entry<E> e = this.lastReturnedEntry = this.nextEntry;
+			this.nextEntry = e.next;
+			return e;
+		}
+
+		@Override
+		public void remove() {
+			if (this.lastReturnedEntry == null) {
+				throw new IllegalStateException();
+			}
+			if (IdentityHashBag.this.modCount != this.expectedModCount) {
+				throw new ConcurrentModificationException();
+			}
+			int slot = IdentityHashBag.this.index(this.lastReturnedEntry.hash, IdentityHashBag.this.table.length);
+			for (Entry<E> e = IdentityHashBag.this.table[slot], prev = null; e != null; prev = e, e = e.next) {
+				if (e == this.lastReturnedEntry) {
+					IdentityHashBag.this.modCount++;
+					this.expectedModCount++;
+					// remove the entry from the table
+					if (prev == null) {
+						IdentityHashBag.this.table[slot] = e.next;
+					} else {
+						prev.next = e.next;
+					}
+					IdentityHashBag.this.uniqueCount--;
+					IdentityHashBag.this.size -= this.lastReturnedEntry.count;
+					this.lastReturnedEntry = null;	// it cannot be removed again
+					return;
+				}
+			}
+			throw new ConcurrentModificationException();
+		}
+	}
+
+
+	private class UniqueIterator
+		implements Iterator<E>
+	{
+		private EntryIterator entryIterator = new EntryIterator();
+
+		UniqueIterator() {
+			super();
+		}
+
+		@Override
+		public boolean hasNext() {
+			return this.entryIterator.hasNext();
+		}
+
+		@Override
+		public E next() {
+			return this.entryIterator.next().object;
+		}
+
+		@Override
+		public void remove() {
+			this.entryIterator.remove();
+		}
+	}
+
+
+	@Override
+	public boolean equals(Object o) {
+		if (o == this) {
+			return true;
+		} else if (o instanceof IdentityHashBag<?>) {
+			@SuppressWarnings("unchecked")
+			IdentityHashBag<E> b = (IdentityHashBag<E>) o;
+			if (b.size() != this.size()) {
+				return false;
+			}
+			if (b.uniqueCount() != this.uniqueCount()) {
+				return false;
+			}
+			for (Iterator<Bag.Entry<E>> stream = b.entries(); stream.hasNext(); ) {
+				Bag.Entry<E> entry = stream.next();
+				if (entry.getCount() != this.count(entry.getElement())) {
+					return false;
+				}
+			}
+			return true;
+		} else {
+			return this.equals_(o);
+		}
+//		} else if (o instanceof Bag<?>) {
+//			// hmmm...
+//			return new HashBag<Object>(this).equals(o);
+//		} else {
+//			return false;
+//		}
+	}
+
+	private boolean equals_(Object o) {
+		// hmmm...
+		return (o instanceof Bag<?>) &&
+				new HashBag<Object>(this).equals(o);
+	}
+
+	@Override
+	public int hashCode() {
+		int h = 0;
+		for (E o : this) {
+			h += System.identityHashCode(o);
+		}
+		return h;
+	}
+
+	/**
+	 * Save the state of this bag to a stream (i.e. serialize it).
+	 *
+	 * @serialData Emit the capacity of the bag (int),
+	 *     followed by the number of unique elements in the bag (int),
+	 *     followed by all of the bag's elements (each an Object) and
+	 *     their counts (each an int), in no particular order.
+	 */
+	private void writeObject(java.io.ObjectOutputStream s)
+				throws java.io.IOException {
+		// write out the threshold, load factor, and any hidden stuff
+		s.defaultWriteObject();
+
+		// write out number of buckets
+		s.writeInt(this.table.length);
+
+		// write out number of unique elements
+		s.writeInt(this.uniqueCount);
+
+		// write out elements and counts (alternating)
+		if (this.uniqueCount > 0) {
+			for (Entry<E> entry : this.table) {
+				while (entry != null) {
+					s.writeObject(entry.object);
+					s.writeInt(entry.count);
+					entry = entry.next;
+				}
+			}
+		}
+	}
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Reconstitute the bag from a stream (i.e. deserialize it).
+	 */
+	private void readObject(java.io.ObjectInputStream s)
+				throws java.io.IOException, ClassNotFoundException {
+		// read in the threshold, loadfactor, and any hidden stuff
+		s.defaultReadObject();
+
+		// read in number of buckets and allocate the bucket array
+		this.table = this.buildTable(s.readInt());
+
+		// read in number of unique elements
+		int unique = s.readInt();
+
+		// read the elements and counts, and put the elements in the bag
+		for (int i = 0; i < unique; i++) {
+			@SuppressWarnings("unchecked")
+			E element = (E) s.readObject();
+			int elementCount = s.readInt();
+			this.add_(element, elementCount);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/LinkedQueue.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/LinkedQueue.java
new file mode 100644
index 0000000..1245be0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/LinkedQueue.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.LinkedList;
+
+/**
+ * Linked list implementation of the {@link Queue} interface.
+ * @see LinkedList
+ */
+public class LinkedQueue<E>
+	implements Queue<E>, Cloneable, Serializable
+{
+	private LinkedList<E> elements;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an empty queue.
+	 */
+	public LinkedQueue() {
+		super();
+		this.elements = new LinkedList<E>();
+	}
+
+	/**
+	 * Construct a queue containing the elements of the specified
+	 * collection. The queue will dequeue its elements in the same
+	 * order they are returned by the collection's iterator (i.e. the
+	 * first element returned by the collection's iterator will be the
+	 * first element returned by {@link #dequeue()}).
+	 */
+	public LinkedQueue(Collection<? extends E> c) {
+		super();
+		this.elements = new LinkedList<E>(c);
+	}
+
+
+	// ********** Queue implementation **********
+
+	@Override
+	public void enqueue(E element) {
+		this.elements.addLast(element);
+	}
+
+	@Override
+	public E dequeue() {
+		return this.elements.removeFirst();
+	}
+
+	@Override
+	public E peek() {
+		return this.elements.getFirst();
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return this.elements.isEmpty();
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public LinkedQueue<E> clone() {
+		try {
+			@SuppressWarnings("unchecked")
+			LinkedQueue<E> clone = (LinkedQueue<E>) super.clone();
+			@SuppressWarnings("unchecked")
+			LinkedList<E> list = (LinkedList<E>) this.elements.clone();
+			clone.elements = list;
+			return clone;
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	@Override
+	public String toString() {
+		return this.elements.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/LinkedStack.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/LinkedStack.java
new file mode 100644
index 0000000..3f8e59d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/LinkedStack.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.EmptyStackException;
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+
+/**
+ * Linked list implementation of the {@link Stack} interface.
+ * @see LinkedList
+ */
+public class LinkedStack<E>
+	implements Stack<E>, Cloneable, Serializable
+{
+	private LinkedList<E> elements;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an empty stack.
+	 */
+	public LinkedStack() {
+		super();
+		this.elements = new LinkedList<E>();
+	}
+
+	/**
+	 * Construct a stack containing the elements of the specified
+	 * collection. The stack will pop its elements in reverse of the
+	 * order they are returned by the collection's iterator (i.e. the
+	 * last element returned by the collection's iterator will be the
+	 * first element returned by {@link #pop()}).
+	 */
+	public LinkedStack(Collection<? extends E> collection) {
+		super();
+		this.elements = new LinkedList<E>(collection);
+	}
+
+
+	// ********** Stack implementation **********
+
+	@Override
+	public void push(E element) {
+		this.elements.addLast(element);
+	}
+
+	@Override
+	public E pop() {
+		try {
+			return this.elements.removeLast();
+		} catch (NoSuchElementException ex) {
+			throw new EmptyStackException();
+		}
+	}
+
+	@Override
+	public E peek() {
+		try {
+			return this.elements.getLast();
+		} catch (NoSuchElementException ex) {
+			throw new EmptyStackException();
+		}
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return this.elements.isEmpty();
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public LinkedStack<E> clone() {
+		try {
+			@SuppressWarnings("unchecked")
+			LinkedStack<E> clone = (LinkedStack<E>) super.clone();
+			@SuppressWarnings("unchecked")
+			LinkedList<E> list = (LinkedList<E>) this.elements.clone();
+			clone.elements = list;
+			return clone;
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	/**
+	 * Print the elements in the order in which they are "pushed" on to
+	 * the stack (as opposed to the order in which they will be "popped"
+	 * off of the stack).
+	 */
+	@Override
+	public String toString() {
+		return this.elements.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/ListTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/ListTools.java
new file mode 100644
index 0000000..9c5a6e1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/ListTools.java
@@ -0,0 +1,586 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.RandomAccess;
+import org.eclipse.persistence.tools.utility.Range;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * {@link List} utility methods.
+ */
+public final class ListTools {
+
+	// ********** add all **********
+
+	/**
+	 * Add all the elements returned by the specified iterable
+	 * to the specified list at the specified index.
+	 * Return whether the list changed as a result.
+	 */
+	public static <E> boolean addAll(List<? super E> list, int index, Iterable<? extends E> iterable) {
+		return addAll(list, index, iterable.iterator());
+	}
+
+	/**
+	 * Add all the elements returned by the specified iterable
+	 * to the specified list at the specified index.
+	 * Return whether the list changed as a result.
+	 * The specified iterable size is a performance hint.
+	 */
+	public static <E> boolean addAll(List<? super E> list, int index, Iterable<? extends E> iterable, int iterableSize) {
+		return addAll(list, index, iterable.iterator(), iterableSize);
+	}
+
+	/**
+	 * Add all the elements returned by the specified iterator
+	 * to the specified list at the specified index.
+	 * Return whether the list changed as a result.
+	 */
+	public static <E> boolean addAll(List<? super E> list, int index, Iterator<? extends E> iterator) {
+		return iterator.hasNext() ? list.addAll(index, list(iterator)) : false;
+	}
+
+	/**
+	 * Add all the elements returned by the specified iterator
+	 * to the specified list at the specified index.
+	 * Return whether the list changed as a result.
+	 */
+	public static <E> boolean addAll(List<? super E> list, int index, Iterator<? extends E> iterator, int iteratorSize) {
+		return iterator.hasNext() ? list.addAll(index, list(iterator, iteratorSize)) : false;
+	}
+
+	/**
+	 * Add all the elements in the specified array
+	 * to the specified list at the specified index.
+	 * Return whether the list changed as a result.
+	 */
+	public static <E> boolean addAll(List<? super E> list, int index, E... array) {
+		return (array.length == 0) ? false : list.addAll(index, Arrays.asList(array));
+	}
+
+
+	// ********** diff **********
+
+	/**
+	 * Return the range of elements in the specified
+	 * arrays that are different.
+	 * If the arrays are identical, return <code>[size, -1]</code>.
+	 * Use the elements' {@link Object#equals(Object)} method to compare the
+	 * elements.
+	 * @see #indexOfDifference(List, List)
+	 * @see #lastIndexOfDifference(List, List)
+	 */
+	public static Range differenceRange(List<?> list1, List<?> list2) {
+		int end = lastIndexOfDifference(list1, list2);
+		if (end == -1) {
+			// the lists are identical, the start is the size of the two lists
+			return new Range(list1.size(), end);
+		}
+		// the lists are different, calculate the start of the range
+		return new Range(indexOfDifference(list1, list2), end);
+	}
+
+	/**
+	 * Return the index of the first elements in the specified
+	 * lists that are different. If the lists are identical, return
+	 * the size of the two lists (i.e. one past the last index).
+	 * If the lists are different sizes and all the elements in
+	 * the shorter list match their corresponding elements in
+	 * the longer list, return the size of the shorter list
+	 * (i.e. one past the last index of the shorter list).
+	 * Use the elements' {@link Object#equals(Object)} method to compare the
+	 * elements.
+	 */
+	public static int indexOfDifference(List<?> list1, List<?> list2) {
+		int end = Math.min(list1.size(), list2.size());
+		for (int i = 0; i < end; i++) {
+			Object o = list1.get(i);
+			if (o == null) {
+				if (list2.get(i) != null) {
+					return i;
+				}
+			} else {
+				if ( ! o.equals(list2.get(i))) {
+					return i;
+				}
+			}
+		}
+		return end;
+	}
+
+	/**
+	 * Return the index of the first elements in the specified
+	 * lists that are different, beginning at the end.
+	 * If the lists are identical, return -1.
+	 * If the lists are different sizes, return the index of the
+	 * last element in the longer list.
+	 * Use the elements' {@link Object#equals(Object)} method to compare the
+	 * elements.
+	 */
+	public static int lastIndexOfDifference(List<?> list1, List<?> list2) {
+		int len1 = list1.size();
+		int len2 = list2.size();
+		if (len1 != len2) {
+			return Math.max(len1, len2) - 1;
+		}
+		for (int i = len1 - 1; i > -1; i--) {
+			Object o = list1.get(i);
+			if (o == null) {
+				if (list2.get(i) != null) {
+					return i;
+				}
+			} else {
+				if ( ! o.equals(list2.get(i))) {
+					return i;
+				}
+			}
+		}
+		return -1;
+	}
+
+
+	// ********** filter **********
+
+	/**
+	 * Return a new list with the filtered
+	 * elements of the specified list.
+	 */
+	public static <E> ArrayList<E> filter(Collection<? extends E> list, Filter<E> filter) {
+		ArrayList<E> result = new ArrayList<E>(list.size());
+		for (E e : list) {
+			if (filter.accept(e)) {
+				result.add(e);
+			}
+		}
+		return result;
+	}
+
+
+	// ********** identity diff **********
+
+	/**
+	 * Return the range of elements in the specified
+	 * arrays that are different.
+	 * If the arrays are identical, return <code>[size, -1]</code>.
+	 * Use object identity to compare the elements.
+	 * @see #indexOfIdentityDifference(List, List)
+	 * @see #lastIndexOfIdentityDifference(List, List)
+	 */
+	public static Range identityDifferenceRange(List<?> list1, List<?> list2) {
+		int end = lastIndexOfIdentityDifference(list1, list2);
+		if (end == -1) {
+			// the lists are identical, the start is the size of the two lists
+			return new Range(list1.size(), end);
+		}
+		// the lists are different, calculate the start of the range
+		return new Range(indexOfIdentityDifference(list1, list2), end);
+	}
+
+	/**
+	 * Return the index of the first elements in the specified
+	 * lists that are different. If the lists are identical, return
+	 * the size of the two lists (i.e. one past the last index).
+	 * If the lists are different sizes and all the elements in
+	 * the shorter list match their corresponding elements in
+	 * the longer list, return the size of the shorter list
+	 * (i.e. one past the last index of the shorter list).
+	 * Use object identity to compare the elements.
+	 */
+	public static int indexOfIdentityDifference(List<?> list1, List<?> list2) {
+		int end = Math.min(list1.size(), list2.size());
+		for (int i = 0; i < end; i++) {
+			if (list1.get(i) != list2.get(i)) {
+				return i;
+			}
+		}
+		return end;
+	}
+
+	/**
+	 * Return the index of the first elements in the specified
+	 * lists that are different, beginning at the end.
+	 * If the lists are identical, return -1.
+	 * If the lists are different sizes, return the index of the
+	 * last element in the longer list.
+	 * Use object identity to compare the elements.
+	 */
+	public static int lastIndexOfIdentityDifference(List<?> list1, List<?> list2) {
+		int len1 = list1.size();
+		int len2 = list2.size();
+		if (len1 != len2) {
+			return Math.max(len1, len2) - 1;
+		}
+		for (int i = len1 - 1; i > -1; i--) {
+			if (list1.get(i) != list2.get(i)) {
+				return i;
+			}
+		}
+		return -1;
+	}
+
+
+	// ********** insertion index **********
+
+	/**
+	 * Return an index of where the specified comparable object
+	 * can be inserted into the specified sorted list and still keep
+	 * the list sorted. If the specified sorted list is an instance of
+	 * {@link RandomAccess} return the <em>maximum</em> insertion index;
+	 * otherwise return the <em>minimum</em> insertion index.
+	 */
+	public static <E extends Comparable<? super E>> int insertionIndexOf(List<E> sortedList, Comparable<E> value) {
+		if (sortedList instanceof RandomAccess) {
+			for (int i = sortedList.size(); i-- > 0; ) {
+				if (value.compareTo(sortedList.get(i)) >= 0) {
+					return i + 1;
+				}
+			}
+			return 0;
+		}
+		int i = 0;
+		for (E element : sortedList) {
+			if (value.compareTo(element) <= 0) {
+				return i;
+			}
+			i++;
+		}
+		return i;
+	}
+
+	/**
+	 * Return an index of where the specified comparable object
+	 * can be inserted into the specified sorted list and still keep
+	 * the list sorted. If the specified sorted list is an instance of
+	 * {@link RandomAccess} return the <em>maximum</em> insertion index;
+	 * otherwise return the <em>minimum</em> insertion index.
+	 */
+	public static <E> int insertionIndexOf(List<E> sortedList, E value, Comparator<? super E> comparator) {
+		if (sortedList instanceof RandomAccess) {
+			for (int i = sortedList.size(); i-- > 0; ) {
+				if (comparator.compare(value, sortedList.get(i)) >= 0) {
+					return i + 1;
+				}
+			}
+			return 0;
+		}
+		int i = 0;
+		for (E element : sortedList) {
+			if (comparator.compare(value, element) <= 0) {
+				return i;
+			}
+			i++;
+		}
+		return i;
+	}
+
+
+	// ********** move **********
+
+	/**
+	 * Move an element from the specified source index to the specified target
+	 * index. Return the altered list.
+	 */
+	public static <E> List<E> move(List<E> list, int targetIndex, int sourceIndex) {
+		return (targetIndex == sourceIndex) ? list : move_(list, targetIndex, sourceIndex);
+	}
+
+	/**
+	 * assume targetIndex != sourceIndex
+	 */
+	private static <E> List<E> move_(List<E> list, int targetIndex, int sourceIndex) {
+		if (list instanceof RandomAccess) {
+			// move elements, leaving the list in place
+			E temp = list.get(sourceIndex);
+			if (targetIndex < sourceIndex) {
+				for (int i = sourceIndex; i-- > targetIndex; ) {
+					list.set(i + 1, list.get(i));
+				}
+			} else {
+				for (int i = sourceIndex; i < targetIndex; i++) {
+					list.set(i, list.get(i + 1));
+				}
+			}
+			list.set(targetIndex, temp);
+		} else {
+			// remove the element and re-add it at the target index
+			list.add(targetIndex, list.remove(sourceIndex));
+		}
+		return list;
+	}
+
+	/**
+	 * Move elements from the specified source index to the specified target
+	 * index. Return the altered list.
+	 */
+	public static <E> List<E> move(List<E> list, int targetIndex, int sourceIndex, int length) {
+		if ((targetIndex == sourceIndex) || (length == 0)) {
+			return list;
+		}
+		if (length == 1) {
+			return move_(list, targetIndex, sourceIndex);
+		}
+		if (list instanceof RandomAccess) {
+			// move elements, leaving the list in place
+			ArrayList<E> temp = new ArrayList<E>(list.subList(sourceIndex, sourceIndex + length));
+			if (targetIndex < sourceIndex) {
+				for (int i = sourceIndex; i-- > targetIndex; ) {
+					list.set(i + length, list.get(i));
+				}
+			} else {
+				for (int i = sourceIndex; i < targetIndex; i++) {
+					list.set(i, list.get(i + length));
+				}
+			}
+			for (int i = 0; i < length; i++) {
+				list.set(targetIndex + i, temp.get(i));
+			}
+		} else {
+			// remove the elements and re-add them at the target index
+			list.addAll(targetIndex, removeElementsAtIndex(list, sourceIndex, length));
+		}
+		return list;
+	}
+
+
+	// ********** remove **********
+
+	/**
+	 * Remove the elements at the specified index.
+	 * Return the removed elements.
+	 */
+	public static <E> ArrayList<E> removeElementsAtIndex(List<E> list, int index, int length) {
+		List<E> subList = list.subList(index, index + length);
+		ArrayList<E> removed = new ArrayList<E>(subList);
+		subList.clear();
+		return removed;
+	}
+
+	/**
+	 * Remove any duplicate elements from the specified list,
+	 * while maintaining the order.
+	 * Return whether the list changed as a result.
+	 */
+	public static <E> boolean removeDuplicateElements(List<E> list) {
+		int listSize = list.size();
+		if ((listSize == 0) || (listSize == 1)) {
+			return false;
+		}
+
+		LinkedHashSet<E> temp = new LinkedHashSet<E>(listSize);		// take advantage of hashed look-up
+		boolean modified = false;
+		for (E item : list) {
+			if ( ! temp.add(item)) {
+				modified = true;  // duplicate item
+			}
+		}
+		if (modified) {
+			int i = 0;
+			for (E e : temp) {
+				list.set(i, e);
+				i++;
+			}
+			int tempSize = temp.size();
+			for (i = list.size(); i-- > tempSize; ) {
+				list.remove(i);  // pull off the end
+			}
+		}
+		return modified;
+	}
+
+
+	// ********** rotate **********
+
+	/**
+	 * Return the list after it has been "rotated" by one position.
+	 */
+	public static <E> List<E> rotate(List<E> list) {
+		return rotate(list, 1);
+	}
+
+
+	// ********** transform **********
+
+	/**
+	 * Return a new list with transformations of the
+	 * elements in the specified list.
+	 */
+	public static <E1, E2> ArrayList<E2> transform(List<E1> list, Transformer<E1, ? extends E2> transformer) {
+		ArrayList<E2> result = new ArrayList<E2>(list.size());
+		for (E1 e : list) {
+			result.add(transformer.transform(e));
+		}
+		return result;
+	}
+
+
+	// ********** java.util.Collections enhancements **********
+
+	/**
+	 * Return the destination list after the source list has been copied into it.
+	 * @see Collections#copy(List, List)
+	 */
+	public static <E> List<E> copy(List<E> dest, List<? extends E> src) {
+		Collections.copy(dest, src);
+		return dest;
+	}
+
+	/**
+	 * Return the list after it has been "filled".
+	 * @see Collections#fill(List, Object)
+	 */
+	public static <E> List<E> fill(List<E> list, E value) {
+		Collections.fill(list, value);
+		return list;
+	}
+
+	/**
+	 * Return the list after it has been "reversed".
+	 * @see Collections#reverse(List)
+	 */
+	public static <E> List<E> reverse(List<E> list) {
+		Collections.reverse(list);
+		return list;
+	}
+
+	/**
+	 * Return the list after it has been "rotated".
+	 * @see Collections#rotate(List, int)
+	 */
+	public static <E> List<E> rotate(List<E> list, int distance) {
+		Collections.rotate(list, distance);
+		return list;
+	}
+
+	/**
+	 * Return the list after it has been "shuffled".
+	 * @see Collections#shuffle(List)
+	 */
+	public static <E> List<E> shuffle(List<E> list) {
+		Collections.shuffle(list);
+		return list;
+	}
+
+	/**
+	 * Return the list after it has been "shuffled".
+	 * @see Collections#shuffle(List, Random)
+	 */
+	public static <E> List<E> shuffle(List<E> list, Random random) {
+		Collections.shuffle(list, random);
+		return list;
+	}
+
+	/**
+	 * Return the list after it has been "sorted".
+	 * NB: The list is sorted in place as a side-effect.
+	 * @see Collections#sort(List)
+	 */
+	public static <E extends Comparable<? super E>> List<E> sort(List<E> list) {
+		Collections.sort(list);
+		return list;
+	}
+
+	/**
+	 * Return the list after it has been "sorted".
+	 * NB: The list is sorted in place as a side-effect.
+	 * @see Collections#sort(List, Comparator)
+	 */
+	public static <E> List<E> sort(List<E> list, Comparator<? super E> comparator) {
+		Collections.sort(list, comparator);
+		return list;
+	}
+
+	/**
+	 * Return the list after the specified elements have been "swapped".
+	 * @see Collections#swap(List, int, int)
+	 */
+	public static <E> List<E> swap(List<E> list, int i, int j) {
+		Collections.swap(list, i, j);
+		return list;
+	}
+
+
+	// ********** factory methods **********
+
+	/**
+	 * Return a list corresponding to the specified iterable.
+	 */
+	public static <E> ArrayList<E> list(Iterable<? extends E> iterable) {
+		return list(iterable.iterator());
+	}
+
+	/**
+	 * Return a list corresponding to the specified iterable.
+	 * The specified iterable size is a performance hint.
+	 */
+	public static <E> ArrayList<E> list(Iterable<? extends E> iterable, int iterableSize) {
+		return list(iterable.iterator(), iterableSize);
+	}
+
+	/**
+	 * Return a list corresponding to the specified iterator.
+	 */
+	public static <E> ArrayList<E> list(Iterator<? extends E> iterator) {
+		return list(iterator, new ArrayList<E>());
+	}
+
+	/**
+	 * Return a list corresponding to the specified iterator.
+	 * The specified iterator size is a performance hint.
+	 */
+	public static <E> ArrayList<E> list(Iterator<? extends E> iterator, int iteratorSize) {
+		return list(iterator, new ArrayList<E>(iteratorSize));
+	}
+
+	private static <E> ArrayList<E> list(Iterator<? extends E> iterator, ArrayList<E> list) {
+		while (iterator.hasNext()) {
+			list.add(iterator.next());
+		}
+		return list;
+	}
+
+	/**
+	 * Return a list corresponding to the specified array.
+	 * Unlike {@link Arrays#asList(Object[])}, the list
+	 * is modifiable and is not backed by the array.
+	 */
+	public static <E> ArrayList<E> list(E... array) {
+		ArrayList<E> list = new ArrayList<E>(array.length);
+		for (E e : array) {
+			list.add(e);
+		}
+		return list;
+	}
+
+
+	// ********** constructor **********
+
+	/**
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private ListTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/NullElementList.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/NullElementList.java
new file mode 100644
index 0000000..02e9de5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/NullElementList.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.NullElementIterator;
+import org.eclipse.persistence.tools.utility.iterator.NullElementListIterator;
+
+/**
+ * A <em>read-only</em> "null element" list.
+ */
+public class NullElementList<E>
+	extends AbstractRepeatingElementList<E>
+{
+	/**
+	 * Construct a <em>read-only</em> list with the specified number of
+	 * <code>null</code>s in it.
+	 */
+	public NullElementList(int size) {
+		super(size);
+	}
+
+	@Override
+	protected Iterator<E> iterator(int iteratorSize) {
+		return new NullElementIterator<E>(iteratorSize);
+	}
+
+	@Override
+	protected ListIterator<E> listIterator_(int iteratorSize) {
+		return new NullElementListIterator<E>(iteratorSize);
+	}
+
+	@Override
+	protected List<E> subList(int subListSize) {
+		return new NullElementList<E>(subListSize);
+	}
+
+	@Override
+	protected E getElement() {
+		return null;
+	}
+
+	private static final long serialVersionUID = 1L;
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/NullList.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/NullList.java
new file mode 100644
index 0000000..54028ad
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/NullList.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+import org.eclipse.persistence.tools.utility.iterator.EmptyListIterator;
+
+/**
+ * A "null" list is a bit different from an "empty" list: it allows clients to
+ * add/remove elements to/from it but never changes. This is useful
+ * for passing to methods that require a "collecting parameter" but the
+ * client will ignore the resulting "collection".
+ */
+@SuppressWarnings("nls")
+public final class NullList<E>
+	implements List<E>, Serializable
+{
+	// singleton
+	@SuppressWarnings("rawtypes")
+	private static final NullList INSTANCE = new NullList();
+
+	/**
+	 * Return the singleton.
+	 */
+	@SuppressWarnings("unchecked")
+	public static <E> List<E> instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure single instance.
+	 */
+	private NullList() {
+		super();
+	}
+
+	@Override
+	public boolean add(E o) {
+		return false;  // the list did not change
+	}
+
+	@Override
+	public void add(int index, E element) {
+		// ignore
+	}
+
+	@Override
+	public boolean addAll(Collection<? extends E> c) {
+		return false;  // the list did not change
+	}
+
+	@Override
+	public boolean addAll(int index, Collection<? extends E> c) {
+		return false;  // the list did not change
+	}
+
+	@Override
+	public void clear() {
+		// ignore
+	}
+
+	@Override
+	public boolean contains(Object o) {
+		return false;
+	}
+
+	@Override
+	public boolean containsAll(Collection<?> c) {
+		return c.isEmpty();
+	}
+
+	@Override
+	public E get(int index) {
+		throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0");
+	}
+
+	@Override
+	public int indexOf(Object o) {
+		return -1;
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return true;
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return EmptyIterator.instance();
+	}
+
+	@Override
+	public int lastIndexOf(Object o) {
+		return -1;
+	}
+
+	@Override
+	public ListIterator<E> listIterator() {
+		return EmptyListIterator.instance();
+	}
+
+	@Override
+	public ListIterator<E> listIterator(int index) {
+		return EmptyListIterator.instance();
+	}
+
+	@Override
+	public boolean remove(Object o) {
+		return false;  // the list did not change
+	}
+
+	@Override
+	public E remove(int index) {
+		throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0");
+	}
+
+	@Override
+	public boolean removeAll(Collection<?> c) {
+		return false;  // the list did not change
+	}
+
+	@Override
+	public boolean retainAll(Collection<?> c) {
+		return false;  // the list did not change
+	}
+
+	@Override
+	public E set(int index, E element) {
+		throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0");
+	}
+
+	@Override
+	public int size() {
+		return 0;
+	}
+
+	@Override
+	public List<E> subList(int fromIndex, int toIndex) {
+		return this;
+	}
+
+	@Override
+	public Object[] toArray() {
+		return ObjectTools.EMPTY_OBJECT_ARRAY;
+	}
+
+	@Override
+	public <T> T[] toArray(T[] a) {
+		return a;
+	}
+
+	@Override
+	public String toString() {
+		return this.getClass().getSimpleName();
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the singleton
+		return INSTANCE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/Queue.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/Queue.java
new file mode 100644
index 0000000..aadf7c0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/Queue.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.io.Serializable;
+import java.util.NoSuchElementException;
+
+/**
+ * Interface defining the classic queue behavior,
+ * without the backdoors allowed by {@link java.util.Queue}.
+ * <p>
+ * 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.
+ *
+ * @param <E> the type of elements contained by the queue
+ * @see org.eclipse.jpt.common.utility.internal.collection.ArrayQueue
+ * @see org.eclipse.jpt.common.utility.internal.collection.LinkedQueue
+ */
+@SuppressWarnings("nls")
+public interface Queue<E> {
+
+	/**
+	 * "Enqueue" the specified item to the tail of the queue.
+	 */
+	void enqueue(E element);
+
+	/**
+	 * "Dequeue" an item from the head of the queue.
+	 */
+	E dequeue();
+
+	/**
+	 * Return the item on the head of the queue
+	 * without removing it from the queue.
+	 */
+	E peek();
+
+	/**
+	 * Return whether the queue is empty.
+	 */
+	boolean isEmpty();
+
+
+	final class Empty<E>
+		implements Queue<E>, Serializable
+	{
+		@SuppressWarnings("rawtypes")
+		public static final Queue INSTANCE = new Empty();
+		@SuppressWarnings("unchecked")
+		public static <T> Queue<T> instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Empty() {
+			super();
+		}
+		@Override
+		public void enqueue(E o) {
+			throw new UnsupportedOperationException();
+		}
+		@Override
+		public E dequeue() {
+			throw new NoSuchElementException();
+		}
+		@Override
+		public E peek() {
+			throw new NoSuchElementException();
+		}
+		@Override
+		public boolean isEmpty() {
+			return true;
+		}
+		@Override
+		public String toString() {
+			return "[]";
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/RepeatingElementList.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/RepeatingElementList.java
new file mode 100644
index 0000000..1b3cfbe
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/RepeatingElementList.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.RepeatingElementIterator;
+import org.eclipse.persistence.tools.utility.iterator.RepeatingElementListIterator;
+
+/**
+ * A <em>read-only</em> repeating element list.
+ */
+public class RepeatingElementList<E>
+	extends AbstractRepeatingElementList<E>
+{
+	private final E element;
+
+	/**
+	 * Construct a <em>read-only</em> list with the specified number of
+	 * elements in it.
+	 */
+	public RepeatingElementList(E element, int size) {
+		super(size);
+		this.element = element;
+	}
+
+	@Override
+	protected Iterator<E> iterator(int iteratorSize) {
+		return new RepeatingElementIterator<E>(this.element, iteratorSize);
+	}
+
+	@Override
+	protected ListIterator<E> listIterator_(int iteratorSize) {
+		return new RepeatingElementListIterator<E>(this.element, iteratorSize);
+	}
+
+	@Override
+	protected List<E> subList(int subListSize) {
+		return new RepeatingElementList<E>(this.element, subListSize);
+	}
+
+	@Override
+	protected E getElement() {
+		return this.element;
+	}
+
+	private static final long serialVersionUID = 1L;
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/Stack.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/Stack.java
new file mode 100644
index 0000000..f83b9a8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/Stack.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.io.Serializable;
+import java.util.EmptyStackException;
+
+/**
+ * Interface defining the classic stack behavior,
+ * without the backdoors allowed by {@link java.util.Stack}.
+ * <p>
+ * 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.
+ *
+ * @param <E> the type of elements contained by the stack
+ * @see org.eclipse.jpt.common.utility.internal.collection.ArrayStack
+ * @see org.eclipse.jpt.common.utility.internal.collection.LinkedStack
+ */
+@SuppressWarnings("nls")
+public interface Stack<E> {
+
+	/**
+	 * "Push" the specified item on to the top of the stack.
+	 */
+	void push(E element);
+
+	/**
+	 * "Pop" an item from the top of the stack.
+	 */
+	E pop();
+
+	/**
+	 * Return the item on the top of the stack
+	 * without removing it from the stack.
+	 */
+	E peek();
+
+	/**
+	 * Return whether the stack is empty.
+	 */
+	boolean isEmpty();
+
+
+	final class Empty<E>
+		implements Stack<E>, Serializable
+	{
+		@SuppressWarnings("rawtypes")
+		public static final Stack INSTANCE = new Empty();
+		@SuppressWarnings("unchecked")
+		public static <T> Stack<T> instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Empty() {
+			super();
+		}
+		@Override
+		public void push(E element) {
+			throw new UnsupportedOperationException();
+		}
+		@Override
+		public E pop() {
+			throw new EmptyStackException();
+		}
+		@Override
+		public E peek() {
+			throw new EmptyStackException();
+		}
+		@Override
+		public boolean isEmpty() {
+			return true;
+		}
+		@Override
+		public String toString() {
+			return "[]";
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/SynchronizedBag.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/SynchronizedBag.java
new file mode 100644
index 0000000..272f3ff
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/SynchronizedBag.java
@@ -0,0 +1,242 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * Thread-safe implementation of the {@link Bag} interface.
+ */
+public class SynchronizedBag<E>
+	implements Bag<E>, Serializable
+{
+	/** Backing bag. */
+	private final Bag<E> bag;
+
+	/** Object to synchronize on. */
+	private final Object mutex;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a synchronized bag that wraps the
+	 * specified bag and locks on the specified mutex.
+	 */
+	public SynchronizedBag(Bag<E> bag, Object mutex) {
+		super();
+		if ((bag == null) || (mutex == null)) {
+			throw new NullPointerException();
+		}
+		this.bag = bag;
+		this.mutex = mutex;
+	}
+
+	/**
+	 * Construct a synchronized bag that wraps the
+	 * specified bag and locks on itself.
+	 */
+	public SynchronizedBag(Bag<E> bag) {
+		super();
+		if (bag == null) {
+			throw new NullPointerException();
+		}
+		this.bag = bag;
+		this.mutex = this;
+	}
+
+	/**
+	 * Construct a synchronized bag that locks on the specified mutex.
+	 */
+	public SynchronizedBag(Object mutex) {
+		this(new HashBag<E>(), mutex);
+	}
+
+	/**
+	 * Construct a synchronized bag that locks on itself.
+	 */
+	public SynchronizedBag() {
+		this(new HashBag<E>());
+	}
+
+
+	// ********** Bag implementation **********
+
+	@Override
+	public boolean add(E o, int count) {
+		synchronized (this.mutex) {
+			return this.bag.add(o, count);
+		}
+	}
+
+	@Override
+	public int count(Object o) {
+		synchronized (this.mutex) {
+			return this.bag.count(o);
+		}
+	}
+
+	@Override
+	public Iterator<Bag.Entry<E>> entries() {
+		synchronized (this.mutex) {
+			return this.bag.entries();
+		}
+	}
+
+	@Override
+	public boolean remove(Object o, int count) {
+		synchronized (this.mutex) {
+			return this.bag.remove(o, count);
+		}
+	}
+
+	@Override
+	public int uniqueCount() {
+		synchronized (this.mutex) {
+			return this.bag.uniqueCount();
+		}
+	}
+
+	@Override
+	public Iterator<E> uniqueIterator() {
+		synchronized (this.mutex) {
+			return this.bag.uniqueIterator();
+		}
+	}
+
+
+	// ********** Collection implementation **********
+
+	@Override
+	public boolean add(E e) {
+		synchronized (this.mutex) {
+			return this.bag.add(e);
+		}
+	}
+
+	@Override
+	public boolean addAll(Collection<? extends E> c) {
+		synchronized (this.mutex) {
+			return this.bag.addAll(c);
+		}
+	}
+
+	@Override
+	public void clear() {
+		synchronized (this.mutex) {
+			this.bag.clear();
+		}
+	}
+
+	@Override
+	public boolean contains(Object o) {
+		synchronized (this.mutex) {
+			return this.bag.contains(o);
+		}
+	}
+
+	@Override
+	public boolean containsAll(Collection<?> c) {
+		synchronized (this.mutex) {
+			return this.bag.containsAll(c);
+		}
+	}
+
+	@Override
+	public boolean isEmpty() {
+		synchronized (this.mutex) {
+			return this.bag.isEmpty();
+		}
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		synchronized (this.mutex) {
+			return this.bag.iterator();
+		}
+	}
+
+	@Override
+	public boolean remove(Object o) {
+		synchronized (this.mutex) {
+			return this.bag.remove(o);
+		}
+	}
+
+	@Override
+	public boolean removeAll(Collection<?> c) {
+		synchronized (this.mutex) {
+			return this.bag.removeAll(c);
+		}
+	}
+
+	@Override
+	public boolean retainAll(Collection<?> c) {
+		synchronized (this.mutex) {
+			return this.bag.retainAll(c);
+		}
+	}
+
+	@Override
+	public int size() {
+		synchronized (this.mutex) {
+			return this.bag.size();
+		}
+	}
+
+	@Override
+	public Object[] toArray() {
+		synchronized (this.mutex) {
+			return this.bag.toArray();
+		}
+	}
+
+	@Override
+	public <T> T[] toArray(T[] a) {
+		synchronized (this.mutex) {
+			return this.bag.toArray(a);
+		}
+	}
+
+
+	// ********** additional public protocol **********
+
+	/**
+	 * Return the object the stack locks on while performing
+	 * its operations.
+	 */
+	public Object getMutex() {
+		return this.mutex;
+	}
+
+
+	// ********** Object overrides **********
+
+	@Override
+	public String toString() {
+		synchronized (this.mutex) {
+			return this.bag.toString();
+		}
+	}
+
+	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+		synchronized (this.mutex) {
+			s.defaultWriteObject();
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/SynchronizedQueue.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/SynchronizedQueue.java
new file mode 100644
index 0000000..613a768
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/SynchronizedQueue.java
@@ -0,0 +1,364 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.io.Serializable;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.command.Command;
+import org.eclipse.persistence.tools.utility.iterable.QueueIterable;
+
+/**
+ * Thread-safe implementation of the {@link Queue} interface.
+ * This also provides protocol for suspending a thread until the
+ * queue is empty or not empty, with optional time-outs.
+ */
+public class SynchronizedQueue<E>
+	implements Queue<E>, Serializable
+{
+	/** Backing queue. */
+	private final Queue<E> queue;
+
+	/** Object to synchronize on. */
+	private final Object mutex;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a synchronized queue that wraps the
+	 * specified queue and locks on the specified mutex.
+	 */
+	public SynchronizedQueue(Queue<E> queue, Object mutex) {
+		super();
+		if ((queue == null) || (mutex == null)) {
+			throw new NullPointerException();
+		}
+		this.queue = queue;
+		this.mutex = mutex;
+	}
+
+	/**
+	 * Construct a synchronized queue that wraps the
+	 * specified queue and locks on itself.
+	 */
+	public SynchronizedQueue(Queue<E> queue) {
+		super();
+		if (queue == null) {
+			throw new NullPointerException();
+		}
+		this.queue = queue;
+		this.mutex = this;
+	}
+
+	/**
+	 * Construct an empty synchronized queue that locks on the specified mutex.
+	 */
+	public SynchronizedQueue(Object mutex) {
+		this(new LinkedQueue<E>(), mutex);
+	}
+
+	/**
+	 * Construct an empty synchronized queue that locks on itself.
+	 */
+	public SynchronizedQueue() {
+		this(new LinkedQueue<E>());
+	}
+
+
+	// ********** Queue implementation **********
+
+	@Override
+	public void enqueue(E element) {
+		synchronized (this.mutex) {
+			this.enqueue_(element);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void enqueue_(E element) {
+		this.queue.enqueue(element);
+		this.mutex.notifyAll();
+	}
+
+	@Override
+	public E dequeue() {
+		synchronized (this.mutex) {
+			return this.dequeue_();
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private E dequeue_() {
+		E element = this.queue.dequeue();
+		this.mutex.notifyAll();
+		return element;
+	}
+
+	@Override
+	public E peek() {
+		synchronized (this.mutex) {
+			return this.queue.peek();
+		}
+	}
+
+	@Override
+	public boolean isEmpty() {
+		synchronized (this.mutex) {
+			return this.queue.isEmpty();
+		}
+	}
+
+
+	// ********** indefinite waits **********
+
+	/**
+	 * Suspend the current thread until the queue's empty status changes
+	 * to the specified value.
+	 */
+	public void waitUntilEmptyIs(boolean empty) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilEmptyIs_(empty);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void waitUntilEmptyIs_(boolean empty) throws InterruptedException {
+		while (this.queue.isEmpty() != empty) {
+			this.mutex.wait();
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the queue is empty.
+	 */
+	public void waitUntilEmpty() throws InterruptedException {
+		this.waitUntilEmptyIs(true);
+	}
+
+	/**
+	 * Suspend the current thread until the queue has something on it.
+	 */
+	public void waitUntilNotEmpty() throws InterruptedException {
+		this.waitUntilEmptyIs(false);
+	}
+
+	/**
+	 * Suspend the current thread until the queue is empty,
+	 * then "enqueue" the specified item to the tail of the queue
+	 * and continue executing.
+	 */
+	public void waitToEnqueue(E element) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilEmptyIs_(true);
+			this.enqueue_(element);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the queue has something on it,
+	 * then "dequeue" an item from the head of the queue and return it.
+	 */
+	public Object waitToDequeue() throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilEmptyIs_(false);
+			return this.dequeue_();
+		}
+	}
+
+
+	// ********** timed waits **********
+
+	/**
+	 * Suspend the current thread until the queue's empty status changes
+	 * to the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if the specified
+	 * empty status was achieved; return <code>false</code> if a time-out occurred.
+	 * If the queue's empty status is already the specified value,
+	 * return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilEmptyIs(boolean empty, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilEmptyIs_(empty, timeout);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private boolean waitUntilEmptyIs_(boolean empty, long timeout) throws InterruptedException {
+		if (timeout == 0L) {
+			this.waitUntilEmptyIs_(empty);	// wait indefinitely until notified
+			return true;	// if it ever comes back, the condition was met
+		}
+
+		long stop = System.currentTimeMillis() + timeout;
+		long remaining = timeout;
+		while ((this.queue.isEmpty() != empty) && (remaining > 0L)) {
+			this.mutex.wait(remaining);
+			remaining = stop - System.currentTimeMillis();
+		}
+		return (this.queue.isEmpty() == empty);
+	}
+
+	/**
+	 * Suspend the current thread until the queue is empty
+	 * or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if
+	 * the queue is empty; return <code>false</code> if a time-out occurred.
+	 * If the queue is already empty, return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilEmpty(long timeout) throws InterruptedException {
+		return this.waitUntilEmptyIs(true, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the queue has something on it.
+	 * or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if
+	 * the queue is not empty; return <code>false</code> if a time-out occurred.
+	 * If the queue already has something on it, return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilNotEmpty(long timeout) throws InterruptedException {
+		return this.waitUntilEmptyIs(false, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the queue is empty,
+	 * then "enqueue" the specified item to the tail of the queue
+	 * and continue executing. If the queue is not emptied out
+	 * before the time-out, simply continue executing without
+	 * "enqueueing" the item.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if the
+	 * item was enqueued; return <code>false</code> if a time-out occurred.
+	 * If the queue is already empty, "enqueue" the specified item and
+	 * return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitToEnqueue(E element, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilEmptyIs_(true, timeout);
+			if (success) {
+				this.enqueue_(element);
+			}
+			return success;
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the queue has something on it,
+	 * then "dequeue" an item from the head of the queue and return it.
+	 * If the queue is empty and nothing is "enqueued" on to it before the
+	 * time-out, throw a no such element exception.
+	 * The time-out is specified in milliseconds.
+	 * If the queue is not empty, "dequeue" an item and
+	 * return it immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public Object waitToDequeue(long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilEmptyIs_(false, timeout);
+			if (success) {
+				return this.dequeue_();
+			}
+			throw new NoSuchElementException();
+		}
+	}
+
+
+	// ********** synchronized behavior **********
+
+	/**
+	 * If the current thread is not interrupted, execute the specified command
+	 * with the mutex locked. This is useful for initializing the queue in another
+	 * thread.
+	 */
+	public void execute(Command command) throws InterruptedException {
+		if (Thread.currentThread().isInterrupted()) {
+			throw new InterruptedException();
+		}
+		synchronized (this.mutex) {
+			command.execute();
+		}
+	}
+
+
+	// ********** additional public protocol **********
+
+	/**
+	 * "Drain" all the current items from the queue and return them.
+	 */
+	public Iterable<E> drain() {
+		ArrayQueue<E> q = new ArrayQueue<E>();
+		this.drainTo(q);
+		return new QueueIterable<E>(q);
+	}
+
+	/**
+	 * "Drain" all the current items from the queue into specified queue.
+	 */
+	public void drainTo(Queue<E> q) {
+		synchronized (this.mutex) {
+			this.drainTo_(q);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void drainTo_(Queue<E> q) {
+		boolean changed = false;
+		while ( ! this.queue.isEmpty()) {
+			q.enqueue(this.queue.dequeue());
+			changed = true;
+		}
+		if (changed) {
+			this.mutex.notifyAll();
+		}
+	}
+
+	/**
+	 * Return the object the queue locks on while performing
+	 * its operations.
+	 */
+	public Object getMutex() {
+		return this.mutex;
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		synchronized (this.mutex) {
+			return this.queue.toString();
+		}
+	}
+
+	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+		synchronized (this.mutex) {
+			s.defaultWriteObject();
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/SynchronizedStack.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/SynchronizedStack.java
new file mode 100644
index 0000000..4b17589
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/collection/SynchronizedStack.java
@@ -0,0 +1,364 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.collection;
+
+import java.io.Serializable;
+import java.util.EmptyStackException;
+import org.eclipse.persistence.tools.utility.command.Command;
+import org.eclipse.persistence.tools.utility.iterable.StackIterable;
+
+/**
+ * Thread-safe implementation of the {@link Stack} interface.
+ * This also provides protocol for suspending a thread until the
+ * stack is empty or not empty, with optional time-outs.
+ */
+public class SynchronizedStack<E>
+	implements Stack<E>, Serializable
+{
+	/** Backing stack. */
+	private final Stack<E> stack;
+
+	/** Object to synchronize on. */
+	private final Object mutex;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a synchronized stack that wraps the
+	 * specified stack and locks on the specified mutex.
+	 */
+	public SynchronizedStack(Stack<E> stack, Object mutex) {
+		super();
+		if ((stack == null) || (mutex == null)) {
+			throw new NullPointerException();
+		}
+		this.stack = stack;
+		this.mutex = mutex;
+	}
+
+	/**
+	 * Construct a synchronized stack that wraps the
+	 * specified stack and locks on itself.
+	 */
+	public SynchronizedStack(Stack<E> stack) {
+		super();
+		if (stack == null) {
+			throw new NullPointerException();
+		}
+		this.stack = stack;
+		this.mutex = this;
+	}
+
+	/**
+	 * Construct an empty synchronized stack that locks on the specified mutex.
+	 */
+	public SynchronizedStack(Object mutex) {
+		this(new LinkedStack<E>(), mutex);
+	}
+
+	/**
+	 * Construct an empty synchronized stack that locks on itself.
+	 */
+	public SynchronizedStack() {
+		this(new LinkedStack<E>());
+	}
+
+
+	// ********** Stack implementation **********
+
+	@Override
+	public void push(E element) {
+		synchronized (this.mutex) {
+			this.push_(element);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void push_(E element) {
+		this.stack.push(element);
+		this.mutex.notifyAll();
+	}
+
+	@Override
+	public E pop() {
+		synchronized (this.mutex) {
+			return this.pop_();
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private E pop_() {
+		E o = this.stack.pop();
+		this.mutex.notifyAll();
+		return o;
+	}
+
+	@Override
+	public E peek() {
+		synchronized (this.mutex) {
+			return this.stack.peek();
+		}
+	}
+
+	@Override
+	public boolean isEmpty() {
+		synchronized (this.mutex) {
+			return this.stack.isEmpty();
+		}
+	}
+
+
+	// ********** indefinite waits **********
+
+	/**
+	 * Suspend the current thread until the stack's empty status changes
+	 * to the specified value.
+	 */
+	public void waitUntilEmptyIs(boolean empty) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilEmptyIs_(empty);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void waitUntilEmptyIs_(boolean empty) throws InterruptedException {
+		while (this.stack.isEmpty() != empty) {
+			this.mutex.wait();
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the stack is empty.
+	 */
+	public void waitUntilEmpty() throws InterruptedException {
+		this.waitUntilEmptyIs(true);
+	}
+
+	/**
+	 * Suspend the current thread until the stack has something on it.
+	 */
+	public void waitUntilNotEmpty() throws InterruptedException {
+		this.waitUntilEmptyIs(false);
+	}
+
+	/**
+	 * Suspend the current thread until the stack is empty,
+	 * then "push" the specified item on to the top of the stack
+	 * and continue executing.
+	 */
+	public void waitToPush(E element) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilEmptyIs_(true);
+			this.push_(element);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the stack has something on it,
+	 * then "pop" an item from the top of the stack and return it.
+	 */
+	public Object waitToPop() throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilEmptyIs_(false);
+			return this.pop_();
+		}
+	}
+
+
+	// ********** timed waits **********
+
+	/**
+	 * Suspend the current thread until the stack's empty status changes
+	 * to the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if the specified
+	 * empty status was achieved; return <code>false</code> if a time-out occurred.
+	 * If the stack's empty status is already the specified value,
+	 * return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilEmptyIs(boolean empty, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilEmptyIs_(empty, timeout);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private boolean waitUntilEmptyIs_(boolean empty, long timeout) throws InterruptedException {
+		if (timeout == 0L) {
+			this.waitUntilEmptyIs_(empty);	// wait indefinitely until notified
+			return true;	// if it ever comes back, the condition was met
+		}
+
+		long stop = System.currentTimeMillis() + timeout;
+		long remaining = timeout;
+		while ((this.stack.isEmpty() != empty) && (remaining > 0L)) {
+			this.mutex.wait(remaining);
+			remaining = stop - System.currentTimeMillis();
+		}
+		return (this.stack.isEmpty() == empty);
+	}
+
+	/**
+	 * Suspend the current thread until the stack is empty
+	 * or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if
+	 * the stack is empty; return <code>false</code> if a time-out occurred.
+	 * If the stack is already empty, return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilEmpty(long timeout) throws InterruptedException {
+		return this.waitUntilEmptyIs(true, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the stack has something on it.
+	 * or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if
+	 * the stack is not empty; return <code>false</code> if a time-out occurred.
+	 * If the stack already has something on it, return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilNotEmpty(long timeout) throws InterruptedException {
+		return this.waitUntilEmptyIs(false, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the stack is empty,
+	 * then "push" the specified item on to the top of the stack
+	 * and continue executing. If the stack is not emptied out
+	 * before the time-out, simply continue executing without
+	 * "pushing" the item.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if the
+	 * item was pushed; return <code>false</code> if a time-out occurred.
+	 * If the stack is already empty, "push" the specified item and
+	 * return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitToPush(E element, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilEmptyIs_(true, timeout);
+			if (success) {
+				this.push_(element);
+			}
+			return success;
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the stack has something on it,
+	 * then "pop" an item from the top of the stack and return it.
+	 * If the stack is empty and nothing is "pushed" on to it before the
+	 * time-out, throw an empty stack exception.
+	 * The time-out is specified in milliseconds.
+	 * If the stack is not empty, "pop" an item and
+	 * return it immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public Object waitToPop(long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilEmptyIs_(false, timeout);
+			if (success) {
+				return this.pop_();
+			}
+			throw new EmptyStackException();
+		}
+	}
+
+
+	// ********** synchronized behavior **********
+
+	/**
+	 * If the current thread is not interrupted, execute the specified command
+	 * with the mutex locked. This is useful for initializing the stack in another
+	 * thread.
+	 */
+	public void execute(Command command) throws InterruptedException {
+		if (Thread.currentThread().isInterrupted()) {
+			throw new InterruptedException();
+		}
+		synchronized (this.mutex) {
+			command.execute();
+		}
+	}
+
+
+	// ********** additional public protocol **********
+
+	/**
+	 * "Drain" all the current items from the stack and return them.
+	 */
+	public Iterable<E> drain() {
+		ArrayStack<E> q = new ArrayStack<E>();
+		this.drainTo(q);
+		return new StackIterable<E>(q);
+	}
+
+	/**
+	 * "Drain" all the current items from the stack into specified stack.
+	 */
+	public void drainTo(Stack<E> s) {
+		synchronized (this.mutex) {
+			this.drainTo_(s);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void drainTo_(Stack<E> s) {
+		boolean changed = false;
+		while ( ! this.stack.isEmpty()) {
+			s.push(this.stack.pop());
+			changed = true;
+		}
+		if (changed) {
+			this.mutex.notifyAll();
+		}
+	}
+
+	/**
+	 * Return the object the stack locks on while performing
+	 * its operations.
+	 */
+	public Object getMutex() {
+		return this.mutex;
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		synchronized (this.mutex) {
+			return this.stack.toString();
+		}
+	}
+
+	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+		synchronized (this.mutex) {
+			s.defaultWriteObject();
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractAsynchronousCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractAsynchronousCommandExecutor.java
index 1c4c21b..2197359 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractAsynchronousCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractAsynchronousCommandExecutor.java
@@ -1,31 +1,26 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2012 Oracle. All rights reserved.
  * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ * 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.persistence.tools.utility.command;
 
 import java.util.concurrent.ThreadFactory;
-
 import org.eclipse.persistence.tools.utility.ConsumerThreadCoordinator;
 import org.eclipse.persistence.tools.utility.ExceptionHandler;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.SimpleThreadFactory;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.SynchronizedQueue;
+import org.eclipse.persistence.tools.utility.collection.SynchronizedQueue;
 
 /**
  * This command executor will dispatch commands to be executed in a separate
  * thread, allowing calls to
- * {@link org.eclipse.persistence.tools.utility.command.CommandExecutor#execute(Command)}
- * Returns immediately.
+ * {@link org.eclipse.jpt.common.utility.command.CommandExecutor#execute(Command)}
+ * to return immediately.
  * <p>
  * <strong>NB:</strong> If a client-supplied command throws a runtime exception
  * while it is executing, the command executor will use its
@@ -53,6 +48,7 @@
 	 */
 	private final ConsumerThreadCoordinator consumerThreadCoordinator;
 
+
 	// ********** construction **********
 
 	/**
@@ -114,7 +110,7 @@
 	 * <li>{@link #stop()} was called when there were still outstanding commands
 	 *     remaining in the command queue
 	 * </ul>
-	 * 
+	 *
 	 * @exception IllegalStateException if the executor has already been started
 	 */
 	@Override
@@ -141,7 +137,7 @@
 	 * wrap them in a composite exception and throw the composite exception.
 	 * Any remaining commands will be executed once the exector is, if ever,
 	 * restarted.
-	 * 
+	 *
 	 * @exception IllegalStateException if the executor has not been started
 	 */
 	@Override
@@ -163,7 +159,7 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.consumerThreadCoordinator);
+		return ObjectTools.toString(this, this.commands);
 	}
 
 
@@ -171,7 +167,7 @@
 
 	/**
 	 * This implementation of
-	 * {@link org.eclipse.persistence.tools.utility.ConsumerThreadCoordinator.Consumer}
+	 * {@link org.eclipse.jpt.common.utility.internal.ConsumerThreadCoordinator.Consumer}
 	 * will execute the commands enqueued by the asynchronous command executor.
 	 * It will wait until the shared command queue is non-empty to begin executing the
 	 * commands in the queue. Once a comand is executed, the thread will quiesce until
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractQueueingCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractQueueingCommandExecutor.java
index a19896d..4f91f35 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractQueueingCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractQueueingCommandExecutor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -13,9 +13,9 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-import org.eclipse.persistence.tools.utility.SimpleQueue;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.SynchronizedBoolean;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.LinkedQueue;
+import org.eclipse.persistence.tools.utility.reference.SynchronizedBoolean;
 
 /**
  * This is a command executor that queues up any commands
@@ -29,7 +29,8 @@
 {
 	protected final E commandExecutor;
 	protected final SynchronizedBoolean active = new SynchronizedBoolean(false);
-	private SimpleQueue<Command> queue = new SimpleQueue<Command>();
+	private LinkedQueue<Command> queue = new LinkedQueue<Command>();
+
 
 	protected AbstractQueueingCommandExecutor(E commandExecutor) {
 		super();
@@ -68,7 +69,7 @@
 	}
 
 	/**
-	 * Returns whether the command executor is active and, if it is <em>in</em>active,
+	 * Return whether the command executor is active and, if it is <em>in</em>active,
 	 * place the specified command in the queue for later execution.
 	 */
 	private synchronized boolean commandIsToBeExecuted(Command command) {
@@ -94,11 +95,8 @@
 		this.commandExecutor.stop();
 	}
 
-	/**
-	 * {@inheritDoc}
-	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.queue);
+		return ObjectTools.toString(this, this.queue);
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractSafeCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractSafeCommandExecutor.java
index e63a6de..15d5bcb 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractSafeCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractSafeCommandExecutor.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -14,7 +14,7 @@
 package org.eclipse.persistence.tools.utility.command;
 
 import org.eclipse.persistence.tools.utility.ExceptionHandler;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
  * This command executor wraps another command executor and uses an exception
@@ -26,6 +26,7 @@
 	protected final E commandExecutor;
 	protected final ExceptionHandler exceptionHandler;
 
+
 	/**
 	 * <strong>NB:</strong> The default exception handler simply
 	 * <em>ignores</em> any and all exceptions.
@@ -47,13 +48,13 @@
 	public void execute(Command command) {
 		try {
 			this.commandExecutor.execute(command);
-		} catch (RuntimeException ex) {
+		} catch (Throwable ex) {
 			this.exceptionHandler.handleException(ex);
 		}
 	}
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.commandExecutor);
+		return ObjectTools.toString(this, this.commandExecutor);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractSingleUseQueueingCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractSingleUseQueueingCommandExecutor.java
index 4900a46..302641f 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractSingleUseQueueingCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractSingleUseQueueingCommandExecutor.java
@@ -1,20 +1,20 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-import org.eclipse.persistence.tools.utility.SimpleQueue;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.LinkedQueue;
 
 /**
  * This is a command executor that queues up any commands that are
@@ -32,7 +32,7 @@
 {
 	protected final E commandExecutor;
 	private State state;
-	private SimpleQueue<Command> queue = new SimpleQueue<Command>();
+	private LinkedQueue<Command> queue = new LinkedQueue<Command>();
 
 	private enum State {
 		PRE_START,
@@ -41,7 +41,6 @@
 		DEAD
 	}
 
-
 	protected AbstractSingleUseQueueingCommandExecutor(E commandExecutor) {
 		super();
 		if (commandExecutor == null) {
@@ -96,8 +95,9 @@
 			case DEAD:
 				// ignore
 				return false;
+			default:
+				throw this.buildISE();
 		}
-		throw this.buildISE();
 	}
 
 	/**
@@ -152,6 +152,7 @@
 				break;
 			case PRE_START:
 			case DEAD:
+			default:
 				throw this.buildISE();
 		}
 
@@ -165,6 +166,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.state);
+		return ObjectTools.toString(this, this.state);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractStatefulCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractStatefulCommandExecutor.java
index 3865846..02ded1b 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractStatefulCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractStatefulCommandExecutor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -13,8 +13,8 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.SynchronizedBoolean;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.reference.SynchronizedBoolean;
 
 /**
  * Straightforward implementation of {@link StatefulCommandExecutor}
@@ -30,6 +30,7 @@
 	protected final SynchronizedBoolean active = new SynchronizedBoolean(false);
 	protected final E commandExecutor;
 
+
 	protected AbstractStatefulCommandExecutor(E commandExecutor) {
 		super();
 		if (commandExecutor == null) {
@@ -64,11 +65,8 @@
 		this.active.setFalse();
 	}
 
-	/**
-	 * {@inheritDoc}
-	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.commandExecutor);
+		return ObjectTools.toString(this, this.commandExecutor);
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractThreadLocalCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractThreadLocalCommandExecutor.java
index 64bc587..614835e 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractThreadLocalCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AbstractThreadLocalCommandExecutor.java
@@ -1,19 +1,18 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-
 /**
  * This command executor allows the client to
  * specify a different command executor for each thread.
@@ -24,6 +23,7 @@
 	protected final ThreadLocal<E> threadLocal;
 	protected final E defaultCommandExecutor;
 
+
 	protected AbstractThreadLocalCommandExecutor(E defaultCommandExecutor) {
 		super();
 		if (defaultCommandExecutor == null) {
@@ -55,11 +55,11 @@
 	}
 
 	/**
-	 * Returns the string representation of the current thread's command
+	 * Return the string representation of the current thread's command
 	 * executor.
 	 */
 	@Override
 	public String toString() {
 		return '[' + this.getThreadLocalCommandExecutor().toString() + ']';
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousCommandExecutor.java
index e09ecc0..89b5a90 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousCommandExecutor.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -99,4 +99,4 @@
 			return new SimpleStatefulCommandExecutor();
 		}
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousExtendedCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousExtendedCommandExecutor.java
index 2dc0682..97466ba 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousExtendedCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousExtendedCommandExecutor.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -21,7 +21,7 @@
  * {@link Command}s executed via calls to {@link #waitToExecute(Command)} will
  * execute on the <em>current</em> thread <em>after</em> all the commands
  * already dispatched to the other thread have executed.
- * 
+ *
  * @see AbstractAsynchronousCommandExecutor
  */
 public class AsynchronousExtendedCommandExecutor
@@ -153,4 +153,4 @@
 			return new SimpleStatefulExtendedCommandExecutor();
 		}
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousNotifyingRepeatingCommandWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousNotifyingRepeatingCommandWrapper.java
index 8b13133..de0ed1a 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousNotifyingRepeatingCommandWrapper.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousNotifyingRepeatingCommandWrapper.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -14,7 +14,6 @@
 package org.eclipse.persistence.tools.utility.command;
 
 import java.util.concurrent.ThreadFactory;
-
 import org.eclipse.persistence.tools.utility.ConsumerThreadCoordinator;
 import org.eclipse.persistence.tools.utility.ExceptionHandler;
 import org.eclipse.persistence.tools.utility.ListenerList;
@@ -26,10 +25,6 @@
  * This notification is <em>not</em> guaranteed to occur with <em>every</em>
  * execution "cycle"; since other, unrelated, executions can be
  * triggered concurrently.
- * <p>
- * <strong>NB:</strong> Listeners should handle any exceptions
- * Returns gracefully so the thread
- * can continue the synchronization process).
  */
 public class AsynchronousNotifyingRepeatingCommandWrapper
 	extends AsynchronousRepeatingCommandWrapper
@@ -42,6 +37,7 @@
 	 */
 	private final ExceptionHandler exceptionHandler;
 
+
 	// ********** construction **********
 
 	/**
@@ -119,7 +115,7 @@
 		for (Listener listener : this.listenerList.getListeners()) {
 			try {
 				listener.executionQuiesced(this);
-			} catch (RuntimeException ex) {
+			} catch (Throwable ex) {
 				// we could let the ConsumerThreadCoordinator handle these;
 				// but then the loop would be stopped with the first exception...
 				this.exceptionHandler.handleException(ex);
@@ -139,7 +135,7 @@
 	 * initiate another execution until the command's listeners have been
 	 * notified. Note also, the command's listeners can, themselves,
 	 * trigger another execution (by directly or indirectly calling
-	 * {@link org.eclipse.persistence.tools.utility.command.Command#execute()});
+	 * {@link org.eclipse.jpt.common.utility.command.Command#execute()});
 	 * but this execution will not occur until <em>after</em> all the
 	 * listeners have been notified.
 	 */
@@ -161,4 +157,4 @@
 		}
 
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousRepeatingCommandWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousRepeatingCommandWrapper.java
index 8f29531..d9a813c 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousRepeatingCommandWrapper.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/AsynchronousRepeatingCommandWrapper.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -15,25 +15,21 @@
 
 import java.util.ArrayList;
 import java.util.concurrent.ThreadFactory;
-
 import org.eclipse.persistence.tools.utility.ConsumerThreadCoordinator;
 import org.eclipse.persistence.tools.utility.ExceptionHandler;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.SimpleThreadFactory;
 import org.eclipse.persistence.tools.utility.StackTrace;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.SynchronizedBoolean;
+import org.eclipse.persistence.tools.utility.reference.SynchronizedBoolean;
 
 /**
  * This repeating command will perform a client-supplied command in a separate
- * thread, allowing calls to {@link org.eclipse.persistence.tools.utility.command.Command#execute()}
- * Returns immediately.
- * <p>
- * <strong>NB:</strong> The client-supplied command should handle any exceptions
- * Returns gracefully so the thread
- * can continue the execution process).
+ * thread, allowing calls to {@link org.eclipse.jpt.common.utility.command.Command#execute()}
+ * to return immediately.
  */
-public class AsynchronousRepeatingCommandWrapper implements RepeatingCommand {
-
+public class AsynchronousRepeatingCommandWrapper
+	implements RepeatingCommand
+{
 	/**
 	 * This flag is shared with the execution/consumer thread. Setting it to
 	 * <code>true</code> will trigger the execution to begin or, if the
@@ -56,6 +52,7 @@
 	// see AsynchronousRepeatingCommandWrapperTests.testDEBUG()
 	private static final boolean DEBUG = false;
 
+
 	// ********** construction **********
 
 	/**
@@ -174,7 +171,7 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.consumerThreadCoordinator);
+		return ObjectTools.toString(this, this.consumerThreadCoordinator);
 	}
 
 
@@ -182,7 +179,7 @@
 
 	/**
 	 * This implementation of
-	 * {@link org.eclipse.persistence.tools.utility.ConsumerThreadCoordinator.Consumer}
+	 * {@link org.eclipse.jpt.common.utility.internal.ConsumerThreadCoordinator.Consumer}
 	 * will execute the client-supplied command.
 	 * It will wait until the shared "execute" flag is set to execute the
 	 * command. Once the comand is executed, the thread will quiesce until
@@ -227,7 +224,7 @@
 
 		@Override
 		public String toString() {
-			return StringTools.buildToStringFor(this, this.command);
+			return ObjectTools.toString(this, this.command);
 		}
 	}
 
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/Command.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/Command.java
index 2ce3be1..06fa037 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/Command.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/Command.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,80 +14,87 @@
 package org.eclipse.persistence.tools.utility.command;
 
 import java.io.Serializable;
-
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
- * Simple interface for implementing the GOF Command design pattern, and it doesn't carry the
- * baggage of {@link java.lang.Runnable Runnable}.
+ * Simple interface for implementing the GOF Command design pattern,
+ * and it doesn't carry the baggage of {@link java.lang.Runnable}.
  * <p>
- * 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.
- *
- * @version 2.5
+ * 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 Command extends InterruptibleCommand {
-
+public interface Command
+	extends InterruptibleCommand
+{
 	/**
-	 * {@inheritDoc}
+	 * Execute the command. The semantics of the command
+	 * is determined by the contract between the client and server.
 	 */
 	@Override
 	void execute();
 
+
 	/**
-	 * Singleton implementation of the command interface that will throw an exception when executed.
+	 * Singleton implementation of the command interface that will do nothing
+	 * when executed.
 	 */
-	final class Disabled implements Command, Serializable {
-		public static final Command INSTANCE = new Disabled();
+	final class Null
+		implements Command, Serializable
+	{
+		public static final Command INSTANCE = new Null();
+		public static Command instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Null() {
+			super();
+		}
+		@Override
+		public void execute() {
+			// do nothing
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
 		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+
+	/**
+	 * Singleton implementation of the command interface that will throw an
+	 * exception when executed.
+	 */
+	final class Disabled
+		implements Command, Serializable
+	{
+		public static final Command INSTANCE = new Disabled();
+		public static Command instance() {
+			return INSTANCE;
+		}
 		// ensure single instance
 		private Disabled() {
 			super();
 		}
-		public static Command instance() {
-			return INSTANCE;
-		}
 		// throw an exception
 		@Override
 		public void execute() {
 			throw new UnsupportedOperationException();
 		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
 		@Override
 		public String toString() {
-			return StringTools.buildSingletonToString(this);
+			return ObjectTools.singletonToString(this);
 		}
-	}
-
-	/**
-	 * Singleton implementation of the command interface that will do nothing when executed.
-	 */
-	final class Null implements Command, Serializable {
-		public static final Command INSTANCE = new Null();
 		private static final long serialVersionUID = 1L;
-		// ensure single instance
-		private Null() {
-			super();
-		}
-		public static Command instance() {
-			return INSTANCE;
-		}
-		@Override
-		public void execute() {
-			// do nothing
-		}
 		private Object readResolve() {
 			// replace this object with the singleton
 			return INSTANCE;
 		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CommandAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CommandAdapter.java
new file mode 100644
index 0000000..7079d79
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CommandAdapter.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.command;
+
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Convenience command that does nothing.
+ */
+public class CommandAdapter
+	implements Command
+{
+	@Override
+	public void execute() {
+		// NOP
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CommandExecutor.java
index 27189ce..8667d79 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CommandExecutor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,82 +14,89 @@
 package org.eclipse.persistence.tools.utility.command;
 
 import java.io.Serializable;
-
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
- * This interface allows clients to control how a command is executed. This is useful when the
- * server provides the command but the client provides the context (e.g. the client would like
- * to dispatch the command to the UI thread).
+ * This interface allows clients to control how a command is executed.
+ * This is useful when the server provides the command but the client provides
+ * the context (e.g. the client would like to dispatch the command to the UI
+ * thread).
  * <p>
- * 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.
- *
- * @version 2.5
+ * 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 CommandExecutor {
 
 	/**
-	 * Executes the specified command, synchronously or asynchronously. The commands themselves must
-	 * be executed in the order in which they are passed to the command executor (at least when passed
+	 * Execute the specified command, synchronously or asynchronously.
+	 * The commands themselves must be executed in the order in which
+	 * they are passed to the command executor (at least when passed
 	 * from clients executing on the same thread).
 	 */
 	void execute(Command command);
 
+
 	/**
-	 * Singleton implementation of the command executor interface that simply executes the command
-	 * without any sort of enhancement.
+	 * Singleton implementation of the command executor interface
+	 * that simply executes the command without any sort of enhancement.
 	 */
-	final class Default implements CommandExecutor, Serializable {
+	final class Default
+		implements CommandExecutor, Serializable
+	{
 		public static final CommandExecutor INSTANCE = new Default();
-		private static final long serialVersionUID = 1L;
+		public static CommandExecutor instance() {
+			return INSTANCE;
+		}
 		// ensure single instance
 		private Default() {
 			super();
 		}
-		public static CommandExecutor instance() {
-			return INSTANCE;
-		}
 		@Override
 		public void execute(Command command) {
 			command.execute();
 		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
 		private Object readResolve() {
 			// replace this object with the singleton
 			return INSTANCE;
 		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
 	}
 
+
 	/**
-	 * Singleton implementation of the command executor interface that ignores any commands.
+	 * Singleton implementation of the command executor interface
+	 * that ignores any commands.
 	 */
-	final class Inactive implements CommandExecutor, Serializable {
+	final class Inactive
+		implements CommandExecutor, Serializable
+	{
 		public static final CommandExecutor INSTANCE = new Inactive();
-		private static final long serialVersionUID = 1L;
+		public static CommandExecutor instance() {
+			return INSTANCE;
+		}
 		// ensure single instance
 		private Inactive() {
 			super();
 		}
-		public static CommandExecutor instance() {
-			return INSTANCE;
-		}
 		@Override
 		public void execute(Command command) {
 			// do nothing
 		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
 		private Object readResolve() {
 			// replace this object with the singleton
 			return INSTANCE;
 		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CommandRunnable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CommandRunnable.java
index dc67490..f904102 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CommandRunnable.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CommandRunnable.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -13,13 +13,13 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-
 /**
  * Wrap a {@link Command} so it can be used as a {@link Runnable}.
  */
 @SuppressWarnings("nls")
-public class CommandRunnable implements Runnable {
-
+public class CommandRunnable
+	implements Runnable
+{
 	protected final Command command;
 
 	public CommandRunnable(Command command) {
@@ -30,17 +30,11 @@
 		this.command = command;
 	}
 
-	/**
-	 * {@inheritDoc}
-	 */
 	@Override
 	public void run() {
 		this.command.execute();
 	}
 
-	/**
-	 * {@inheritDoc}
-	 */
 	@Override
 	public String toString() {
 		return "Runnable[" + this.command +']';
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CommandWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CommandWrapper.java
new file mode 100644
index 0000000..54d9857
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CommandWrapper.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.command;
+
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Command wrapper that can have its wrapped command changed,
+ * allowing a client to change a previously-supplied command's
+ * behavior mid-stream.
+ *
+ * @see #setCommand(Command)
+ */
+public class CommandWrapper
+	implements Command
+{
+	protected volatile Command command;
+
+	public CommandWrapper(Command command) {
+		super();
+		if (command == null) {
+			throw new NullPointerException();
+		}
+		this.command = command;
+	}
+
+	@Override
+	public void execute() {
+		this.command.execute();
+	}
+
+	public void setCommand(Command command) {
+		if (command == null) {
+			throw new NullPointerException();
+		}
+		this.command = command;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.command);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CompositeCommand.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CompositeCommand.java
index 10a8ab8..0428ce8 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CompositeCommand.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/CompositeCommand.java
@@ -1,20 +1,20 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
 
 /**
  * <code>CompositeCommand</code> provides support for treating a collection of
@@ -46,6 +46,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.commands);
+		return ObjectTools.toString(this, this.commands);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ExtendedCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ExtendedCommandExecutor.java
index 8912538..c073807 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ExtendedCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ExtendedCommandExecutor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,73 +14,66 @@
 package org.eclipse.persistence.tools.utility.command;
 
 import java.io.Serializable;
-
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
- * This interface extends the normal command executor; it allows the client to specify when a
- * command <em>must</em> be executed synchronously.
+ * This interface extends the normal command executor; it allows the client
+ * to specify when a command <em>must</em> be executed synchronously.
  * <p>
- * 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.
- *
- * @version 2.5
+ * 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 ExtendedCommandExecutor extends CommandExecutor {
-
+public interface ExtendedCommandExecutor
+	extends CommandExecutor
+{
 	/**
-	 * Suspends the current thread until the specified command is executed. The command itself must
-	 * be executed <em>after</em> any other commands previously passed to the command executor (at
-	 * least when passed from clients executing on the same thread).
-	 *
+	 * Suspend the current thread until the specified command is executed.
+	 * The command itself must be executed <em>after</em> any other commands
+	 * previously passed to the command executor (at least when passed
+	 * from clients executing on the same thread).
 	 * @see #execute(Command)
 	 */
 	void waitToExecute(Command command) throws InterruptedException;
 
 	/**
-	 * Suspends the current thread until the specified command is executed or the specified time-out
-	 * occurs.
-	 * <ul>
-	 * <li>Returns <code>true</code> if the command was executed in the allotted time;</li>
-	 * <li>Returns <code>false</code> if a time-out occurred and the command was <em>not</em> executed.
-	 * If the time-out is zero, wait indefinitely.</li>
-	 * </ul>
+	 * Suspend the current thread until the specified command is executed
+	 * or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if
+	 * the command was executed in the allotted time;
+	 * return <code>false</code> if a time-out occurred and the command was
+	 * <em>not</em> executed.
+	 * If the time-out is zero, wait indefinitely.
 	 * <p>
-	 * The command itself must be executed <em>after</em> any other commands previously passed to the
-	 * command executor (at least when passed from clients executing on the same thread).
-	 *
+	 * The command itself must be executed <em>after</em> any other commands
+	 * previously passed to the command executor (at least when passed
+	 * from clients executing on the same thread).
 	 * @see #execute(Command)
 	 */
 	boolean waitToExecute(Command command, long timeout) throws InterruptedException;
 
+
 	/**
-	 * Singleton implementation of the command executor interface that simply executes the command
-	 * without any sort of enhancement.
+	 * Singleton implementation of the command executor interface
+	 * that simply executes the command without any sort of enhancement.
 	 */
-	final class Default implements ExtendedCommandExecutor, Serializable {
+	final class Default
+		implements ExtendedCommandExecutor, Serializable
+	{
 		public static final ExtendedCommandExecutor INSTANCE = new Default();
-		private static final long serialVersionUID = 1L;
+		public static ExtendedCommandExecutor instance() {
+			return INSTANCE;
+		}
 		// ensure single instance
 		private Default() {
 			super();
 		}
-		public static ExtendedCommandExecutor instance() {
-			return INSTANCE;
-		}
 		@Override
 		public void execute(Command command) {
 			command.execute();
 		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
 		@Override
 		public void waitToExecute(Command command) {
 			command.execute();
@@ -90,33 +83,37 @@
 			command.execute();
 			return true;
 		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
 	}
 
+
 	/**
-	 * Singleton implementation of the command executor interface that ignores any commands.
+	 * Singleton implementation of the command executor interface
+	 * that ignores any commands.
 	 */
-	final class Inactive implements ExtendedCommandExecutor, Serializable {
+	final class Inactive
+		implements ExtendedCommandExecutor, Serializable
+	{
 		public static final ExtendedCommandExecutor INSTANCE = new Inactive();
-		private static final long serialVersionUID = 1L;
+		public static ExtendedCommandExecutor instance() {
+			return INSTANCE;
+		}
 		// ensure single instance
 		private Inactive() {
 			super();
 		}
-		public static ExtendedCommandExecutor instance() {
-			return INSTANCE;
-		}
 		@Override
 		public void execute(Command command) {
 			// do nothing
 		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
 		@Override
 		public void waitToExecute(Command command) {
 			// do nothing
@@ -126,5 +123,14 @@
 			// do nothing
 			return true;
 		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleCommand.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleCommand.java
index f471b2d..5466e9d 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleCommand.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleCommand.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,55 +14,57 @@
 package org.eclipse.persistence.tools.utility.command;
 
 import java.io.Serializable;
-
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
- * Simple interface for implementing the GOF Command design pattern and allows for the command to
- * throw an {@link InterruptedException}.
+ * Simple interface for implementing the GOF Command design pattern
+ * and allows for the command to throw an {@link InterruptedException}.
  * <p>
- * 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.
+ * 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.
  *
- * @see org.eclipse.persistence.tools.utility.command.Command
- * @version 2.5
+ * @see org.eclipse.jpt.common.utility.command.Command
  */
 public interface InterruptibleCommand {
 
 	/**
-	 * Executes the command. The semantics of the command is determined by the contract between the
-	 * client and server.
+	 * Execute the command. The semantics of the command
+	 * is determined by the contract between the client and server.
 	 */
 	void execute() throws InterruptedException;
 
+
 	/**
 	 * Singleton implementation of the interruptible command interface that
 	 * will throw an interrupted exception when executed.
 	 */
-	final class Interrupted implements InterruptibleCommand, Serializable {
+	final class Interrupted
+		implements InterruptibleCommand, Serializable
+	{
 		public static final InterruptibleCommand INSTANCE = new Interrupted();
-		private static final long serialVersionUID = 1L;
+		public static InterruptibleCommand instance() {
+			return INSTANCE;
+		}
 		// ensure single instance
 		private Interrupted() {
 			super();
 		}
-		public static InterruptibleCommand instance() {
-			return INSTANCE;
-		}
 		// throw an exception
 		@Override
 		public void execute() throws InterruptedException {
 			throw new InterruptedException();
 		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
 		private Object readResolve() {
 			// replace this object with the singleton
 			return INSTANCE;
 		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleCommandAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleCommandAdapter.java
new file mode 100644
index 0000000..7dbde25
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleCommandAdapter.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.command;
+
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Convenience command that does nothing.
+ */
+public class InterruptibleCommandAdapter
+	implements InterruptibleCommand
+{
+	@Override
+	public void execute() throws InterruptedException {
+		// NOP
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleCommandExecutor.java
index f8056bc..b634068 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleCommandExecutor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,21 +14,21 @@
 package org.eclipse.persistence.tools.utility.command;
 
 import java.io.Serializable;
-
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
- * This interface allows clients to control how an interruptible command is executed. This is useful
- * when the server provides the command but the client provides the context (e.g. the client would
- * like to dispatch the command to the UI thread).
+ * This interface allows clients to control how an interruptible command is executed.
+ * This is useful when the server provides the command but the client provides
+ * the context (e.g. the client would like to dispatch the command to the UI
+ * thread).
  * <p>
- * 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.
+ * 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.
  *
- * @see org.eclipse.persistence.tools.utility.command.CommandExecutor
- * @version 2.5
+ * @see org.eclipse.jpt.common.utility.command.CommandExecutor
  */
 public interface InterruptibleCommandExecutor {
 
@@ -37,31 +37,34 @@
 	 */
 	void execute(InterruptibleCommand command) throws InterruptedException;
 
+
 	/**
-	 * Singleton implementation of the interruptible command executor interface that simply executes
-	 * the command without any sort of enhancement.
+	 * Singleton implementation of the interruptible command executor interface
+	 * that simply executes the command without any sort of enhancement.
 	 */
-	final class Default implements InterruptibleCommandExecutor, Serializable {
+	final class Default
+		implements InterruptibleCommandExecutor, Serializable
+	{
 		public static final InterruptibleCommandExecutor INSTANCE = new Default();
-		private static final long serialVersionUID = 1L;
+		public static InterruptibleCommandExecutor instance() {
+			return INSTANCE;
+		}
 		// ensure single instance
 		private Default() {
 			super();
 		}
-		public static InterruptibleCommandExecutor instance() {
-			return INSTANCE;
-		}
 		@Override
 		public void execute(InterruptibleCommand command) throws InterruptedException {
 			command.execute();
 		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
 		private Object readResolve() {
 			// replace this object with the singleton
 			return INSTANCE;
 		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleCommandWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleCommandWrapper.java
new file mode 100644
index 0000000..6aad458
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleCommandWrapper.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.command;
+
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Command wrapper that can have its wrapped command changed,
+ * allowing a client to change a previously-supplied command's
+ * behavior mid-stream.
+ *
+ * @see #setCommand(InterruptibleCommand)
+ */
+public class InterruptibleCommandWrapper
+	implements InterruptibleCommand
+{
+	protected volatile InterruptibleCommand command;
+
+	public InterruptibleCommandWrapper(InterruptibleCommand command) {
+		super();
+		if (command == null) {
+			throw new NullPointerException();
+		}
+		this.command = command;
+	}
+
+	@Override
+	public void execute() throws InterruptedException {
+		this.command.execute();
+	}
+
+	public void setCommand(InterruptibleCommand command) {
+		if (command == null) {
+			throw new NullPointerException();
+		}
+		this.command = command;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.command);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleParameterizedCommand.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleParameterizedCommand.java
new file mode 100644
index 0000000..9eba71b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleParameterizedCommand.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.command;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Simple interface for implementing a command that takes a single argument
+ * and allows for the command to throw an {@link InterruptedException}.
+ * <p>
+ * 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.
+ *
+ * @see org.eclipse.jpt.common.utility.command.ParameterizedCommand
+ *
+ * @parm <T> the type of the object passed to the command
+ */
+public interface InterruptibleParameterizedCommand <T> {
+
+	/**
+	 * Execute the command. The semantics of the command
+	 * is determined by the contract between the client and server.
+	 */
+	void execute(T argument) throws InterruptedException;
+
+
+	/**
+	 * Singleton implementation of the interruptible parameterized command
+	 * interface that will throw an interrupted exception when executed.
+	 */
+	final class Interrupted<S>
+		implements InterruptibleParameterizedCommand<S>, Serializable
+	{
+		@SuppressWarnings("rawtypes")
+		public static final InterruptibleParameterizedCommand INSTANCE = new Interrupted();
+		@SuppressWarnings("unchecked")
+		public static <R> InterruptibleParameterizedCommand<R> instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Interrupted() {
+			super();
+		}
+		// throw an exception
+		@Override
+		public void execute(S argument) throws InterruptedException {
+			throw new InterruptedException();
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleParameterizedCommandAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleParameterizedCommandAdapter.java
new file mode 100644
index 0000000..985dac0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleParameterizedCommandAdapter.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.command;
+
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Convenience command that does nothing.
+ */
+public class InterruptibleParameterizedCommandAdapter<E>
+	implements InterruptibleParameterizedCommand<E>
+{
+	@Override
+	public void execute(E argument) throws InterruptedException {
+		// NOP
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleParameterizedCommandWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleParameterizedCommandWrapper.java
new file mode 100644
index 0000000..4a0d8de
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/InterruptibleParameterizedCommandWrapper.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.command;
+
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Command wrapper that can have its wrapped command changed,
+ * allowing a client to change a previously-supplied command's
+ * behavior mid-stream.
+ *
+ * @parm <T> the type of the object passed to the command
+ * @see #setCommand(InterruptibleParameterizedCommand)
+ */
+public class InterruptibleParameterizedCommandWrapper<T>
+	implements InterruptibleParameterizedCommand<T>
+{
+	protected volatile InterruptibleParameterizedCommand<T> command;
+
+	public InterruptibleParameterizedCommandWrapper(InterruptibleParameterizedCommand<T> command) {
+		super();
+		if (command == null) {
+			throw new NullPointerException();
+		}
+		this.command = command;
+	}
+
+	@Override
+	public void execute(T argument) throws InterruptedException {
+		this.command.execute(argument);
+	}
+
+	public void setCommand(InterruptibleParameterizedCommand<T> command) {
+		if (command == null) {
+			throw new NullPointerException();
+		}
+		this.command = command;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.command);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/NotifyingRepeatingCommand.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/NotifyingRepeatingCommand.java
index 42b14f3..a840753 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/NotifyingRepeatingCommand.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/NotifyingRepeatingCommand.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -15,84 +15,97 @@
 
 import java.io.Serializable;
 import java.util.EventListener;
-
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
- * Extend the repeating command to support listeners that are notified when an execution "cycle" is
- * complete; i.e. the command has, for the moment, handled every execution request and quiesced.
- * This notification is <em>not</em> guaranteed to occur with <em>every</em> execution "cycle";
- * since other, unrelated, executions can be triggered concurrently, causing the "cycle" to continue.
+ * Extend the repeating command to support listeners that are notified
+ * when an execution "cycle" is complete; i.e. the command has,
+ * for the moment, handled every execution request and quiesced.
+ * This notification is <em>not</em> guaranteed to occur with <em>every</em>
+ * execution "cycle"; since other, unrelated, executions can be triggered
+ * concurrently, causing the "cycle" to continue.
  * <p>
- * 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.
+ * 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 NotifyingRepeatingCommand extends RepeatingCommand {
-
+public interface NotifyingRepeatingCommand
+	extends RepeatingCommand
+{
 	/**
-	 * Adds the specified listener.
+	 * Add the specified listener.
 	 */
 	void addListener(Listener listener);
 
 	/**
-	 * Removes the specified listener.
+	 * Remove the specified listener.
 	 */
 	void removeListener(Listener listener);
 
-	/**
-	 * Interface implemented by listeners to be notified whenever the command has quiesced.
-	 */
-	public interface Listener extends EventListener {
 
+	// ********** listener **********
+
+	/**
+	 * Interface implemented by listeners to be notified whenever the
+	 * command has quiesced.
+	 */
+	public interface Listener
+		extends EventListener
+	{
 		/**
 		 * The specified command has quiesced.
 		 */
 		void executionQuiesced(Command command);
 	}
 
+
+	// ********** null singleton **********
+
 	/**
 	 * Singleton implementation of the notifying repeating command interface
 	 * that will do nothing when executed.
 	 */
-	final class Null implements NotifyingRepeatingCommand, Serializable {
+	final class Null
+		implements NotifyingRepeatingCommand, Serializable
+	{
 		public static final NotifyingRepeatingCommand INSTANCE = new Null();
-		private static final long serialVersionUID = 1L;
+		public static NotifyingRepeatingCommand instance() {
+			return INSTANCE;
+		}
 		// ensure single instance
 		private Null() {
 			super();
 		}
-		public static NotifyingRepeatingCommand instance() {
-			return INSTANCE;
-		}
 		@Override
-		public void addListener(Listener listener) {
+		public void start() {
 			// do nothing
 		}
 		@Override
 		public void execute() {
 			// do nothing
 		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public void removeListener(Listener listener) {
-			// do nothing
-		}
-		@Override
-		public void start() {
-			// do nothing
-		}
 		@Override
 		public void stop() {
 			// do nothing
 		}
 		@Override
+		public void addListener(Listener listener) {
+			// do nothing
+		}
+		@Override
+		public void removeListener(Listener listener) {
+			// do nothing
+		}
+		@Override
 		public String toString() {
-			return StringTools.buildSingletonToString(this);
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
 		}
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/NotifyingRepeatingCommandWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/NotifyingRepeatingCommandWrapper.java
index 3960d1a..4fdd2b9 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/NotifyingRepeatingCommandWrapper.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/NotifyingRepeatingCommandWrapper.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -38,6 +38,7 @@
 {
 	private final ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
 
+
 	// ********** construction **********
 
 	/**
@@ -97,4 +98,4 @@
 			}
 		}
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ParameterizedCommand.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ParameterizedCommand.java
new file mode 100644
index 0000000..d053680
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ParameterizedCommand.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.command;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Simple interface for implementing a command that takes a single argument.
+ * <p>
+ * 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.
+ *
+ * @parm <T> the type of the object passed to the command
+ */
+public interface ParameterizedCommand<T>
+	extends InterruptibleParameterizedCommand<T>
+{
+	/**
+	 * Execute the command. The semantics of the command
+	 * is determined by the contract between the client and server.
+	 */
+	@Override
+	void execute(T argument);
+
+
+	/**
+	 * Singleton implementation of the command interface that will do nothing
+	 * when executed.
+	 */
+	final class Null<S>
+		implements ParameterizedCommand<S>, Serializable
+	{
+		@SuppressWarnings("rawtypes")
+		public static final ParameterizedCommand INSTANCE = new Null();
+		@SuppressWarnings("unchecked")
+		public static <R> ParameterizedCommand<R> instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Null() {
+			super();
+		}
+		@Override
+		public void execute(S argument) {
+			// do nothing
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+
+	/**
+	 * Singleton implementation of the command interface that will throw an
+	 * exception when executed.
+	 */
+	final class Disabled<S>
+		implements ParameterizedCommand<S>, Serializable
+	{
+		@SuppressWarnings("rawtypes")
+		public static final ParameterizedCommand INSTANCE = new Disabled();
+		@SuppressWarnings("unchecked")
+		public static <R> ParameterizedCommand<R> instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Disabled() {
+			super();
+		}
+		// throw an exception
+		@Override
+		public void execute(S argument) {
+			throw new UnsupportedOperationException();
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ParameterizedCommandAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ParameterizedCommandAdapter.java
new file mode 100644
index 0000000..123a9dd
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ParameterizedCommandAdapter.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.command;
+
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Convenience command that does nothing.
+ */
+public class ParameterizedCommandAdapter<E>
+	implements ParameterizedCommand<E>
+{
+	@Override
+	public void execute(E argument) {
+		// NOP
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ParameterizedCommandWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ParameterizedCommandWrapper.java
new file mode 100644
index 0000000..72ace2c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ParameterizedCommandWrapper.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.command;
+
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Command wrapper that can have its wrapped command changed,
+ * allowing a client to change a previously-supplied command's
+ * behavior mid-stream.
+ *
+ * @parm <T> the type of the object passed to the command
+ * @see #setCommand(ParameterizedCommand)
+ */
+public class ParameterizedCommandWrapper<T>
+	implements ParameterizedCommand<T>
+{
+	protected volatile ParameterizedCommand<T> command;
+
+	public ParameterizedCommandWrapper(ParameterizedCommand<T> command) {
+		super();
+		if (command == null) {
+			throw new NullPointerException();
+		}
+		this.command = command;
+	}
+
+	@Override
+	public void execute(T argument) {
+		this.command.execute(argument);
+	}
+
+	public void setCommand(ParameterizedCommand<T> command) {
+		if (command == null) {
+			throw new NullPointerException();
+		}
+		this.command = command;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.command);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/QueueingCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/QueueingCommandExecutor.java
index 162b9c5..4beb7f6 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/QueueingCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/QueueingCommandExecutor.java
@@ -1,19 +1,18 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-
 /**
  * @see AbstractQueueingCommandExecutor
  */
@@ -31,4 +30,4 @@
 	public QueueingCommandExecutor(StatefulCommandExecutor commandExecutor) {
 		super(commandExecutor);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/QueueingExtendedCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/QueueingExtendedCommandExecutor.java
index 726c0cd..0ed1b55 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/QueueingExtendedCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/QueueingExtendedCommandExecutor.java
@@ -1,24 +1,23 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-
 /**
  * Calls to {@link #waitToExecute(Command)} will suspend the current thread
  * until the command executor is {@link #start() started} and any previously-
  * dispatched commands have executed.
- * 
+ *
  * @see AbstractQueueingCommandExecutor
  */
 public class QueueingExtendedCommandExecutor
@@ -83,4 +82,4 @@
 			syncCommand.release();
 		}
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RepeatingCommand.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RepeatingCommand.java
index 1894c75..f50fc13 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RepeatingCommand.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RepeatingCommand.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,67 +14,74 @@
 package org.eclipse.persistence.tools.utility.command;
 
 import java.io.Serializable;
-
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
- * This command will execute repeatedly the minimum number of times. The assumption is the command's
- * effects are cumulative(?); i.e. the cumulative result of multiple executions of the command is no
- * different than the result of a single execution of the command. Once the command is executing,
- * any further requests to execute simply trigger a re-execution of the command once it has finished
- * its current execution.
+ * This command will execute repeatedly the minimum
+ * number of times. The assumption is the command's effects are
+ * cumulative(?); i.e. the cumulative result of multiple executions of the
+ * command is no different than the result of a single execution of the command.
+ * Once the command is executing, any further requests to execute simply trigger
+ * a re-execution of the command once it has finished its current execution.
  * <p>
- * 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.
+ * 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 RepeatingCommand extends Command {
-
+public interface RepeatingCommand
+	extends Command
+{
 	/**
-	 * Starts the command, allowing it to begin executing with the next call to {@link #execute()}.
+	 * Start the command, allowing it to begin executing with the next call to
+	 * {@link #execute()}.
 	 * @exception IllegalStateException when the command is not stopped
 	 */
 	void start();
 
 	/**
-	 * Stops the command; ignore further calls to {@link #execute()}.
+	 * Stop the command; ignore further calls to {@link #execute()}.
 	 * @exception IllegalStateException when the command executor is not started
 	 */
 	void stop() throws InterruptedException;
 
+
 	/**
-	 * Singleton implementation of the repeating command interface that will do nothing when executed.
+	 * Singleton implementation of the repeating command interface that will do
+	 * nothing when executed.
 	 */
-	final class Null implements RepeatingCommand, Serializable {
+	final class Null
+		implements RepeatingCommand, Serializable
+	{
 		public static final RepeatingCommand INSTANCE = new Null();
-		private static final long serialVersionUID = 1L;
+		public static RepeatingCommand instance() {
+			return INSTANCE;
+		}
 		// ensure single instance
 		private Null() {
 			super();
 		}
-		public static RepeatingCommand instance() {
-			return INSTANCE;
+		@Override
+		public void start() {
+			// do nothing
 		}
 		@Override
 		public void execute() {
 			// do nothing
 		}
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-		@Override
-		public void start() {
-			// do nothing
-		}
 		@Override
 		public void stop() {
 			// do nothing
 		}
 		@Override
 		public String toString() {
-			return StringTools.buildSingletonToString(this);
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
 		}
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RepeatingCommandState.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RepeatingCommandState.java
index 130e4dd..e8b45ad 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RepeatingCommandState.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RepeatingCommandState.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -13,15 +13,14 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.SynchronizedObject;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.reference.SynchronizedObject;
 
 /**
  * Provide the state machine to support minimal repeat command executions.
  */
 @SuppressWarnings("nls")
 public class RepeatingCommandState {
-
 	/**
 	 * The current state.
 	 */
@@ -53,6 +52,7 @@
 		this.state = new SynchronizedObject<State>(State.STOPPED, this);
 	}
 
+
 	/**
 	 * Set the {@link #state} to {@link State#READY READY}.
 	 * @exception IllegalStateException if the command wrapper is not
@@ -68,14 +68,15 @@
 			case EXECUTING:
 			case REPEAT:
 			case STOPPING:
+			default:
 				throw this.buildISE();
 		}
 	}
 
 	/**
 	 * A client has requested an execution.
-	 * Returns whether we are ready to begin a new execution "cycle".
-	 * Returns <code>false</code>;
+	 * Return whether we are ready to begin a new execution "cycle".
+	 * If an execution is already under way, return <code>false</code>;
 	 * but set the {@link #state} to {@link State#REPEAT REPEAT}
 	 * so another execution will occur once the current
 	 * execution is complete.
@@ -106,8 +107,9 @@
 			case STOPPING:
 				// no further executions are allowed
 				return false;
+			default:
+				throw this.buildISE();
 		}
-		throw this.buildISE();
 	}
 
 	/**
@@ -135,14 +137,14 @@
 			case EXECUTING:
 			case REPEAT:
 			case STOPPING:
+			default:
 				throw this.buildISE();
 		}
-		throw this.buildISE();
 	}
 
 	/**
 	 * The current execution has finished.
-	 * Returns whether we should begin another execution because a call to
+	 * Return whether we should begin another execution because a call to
 	 * execute occurred <em>during</em> the just-completed execution.
 	 */
 	public synchronized boolean isRepeat() {
@@ -152,7 +154,7 @@
 			case PRE_EXECUTION:
 				throw this.buildISE();
 			case EXECUTING:
-				// * Returns to READY
+				// execution has finished and there are no outstanding requests for another; return to READY
 				this.state.setValue(State.READY);
 				return false;
 			case REPEAT:
@@ -164,12 +166,13 @@
 				// mark the "stop" complete and perform no more executions
 				this.state.setValue(State.STOPPED);
 				return false;
+			default:
+				throw this.buildISE();
 		}
-		throw this.buildISE();
 	}
 
 	/**
-	 * Returns whether the execution "cycle" is "quiesced" (i.e. there are no
+	 * Return whether the execution "cycle" is "quiesced" (i.e. there are no
 	 * outstanding execution requests).
 	 */
 	public boolean isQuiesced() {
@@ -196,6 +199,7 @@
 				break;
 			case STOPPED:
 			case STOPPING:
+			default:
 				throw this.buildISE();
 		}
 	}
@@ -218,11 +222,8 @@
 		return new IllegalStateException("state: " + this.state);
 	}
 
-	/**
-	 * {@inheritDoc}
-	 */
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.state);
+		return ObjectTools.toString(this, this.state);
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RepeatingCommandWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RepeatingCommandWrapper.java
index d4111cb..3616901 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RepeatingCommandWrapper.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RepeatingCommandWrapper.java
@@ -1,20 +1,22 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
+import java.util.ArrayList;
 import org.eclipse.persistence.tools.utility.ExceptionHandler;
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.StackTrace;
 
 /**
  * Wrap a repeating {@link Command}.
@@ -58,6 +60,16 @@
 	 */
 	final RepeatingCommandState state;
 
+	/**
+	 * List of stack traces for each (repeating) invocation of the command,
+	 * starting with the initial invocation. The list is cleared with each
+	 * initial invocation of the command.
+	 */
+	private final ArrayList<StackTrace> stackTraces = DEBUG ? new ArrayList<StackTrace>() : null;
+	// see RepeatingCommandWrapperTests.testDEBUG()
+	private static final boolean DEBUG = false;
+
+
 	// ********** construction **********
 
 	/**
@@ -108,14 +120,25 @@
 	 * It is possible to come back here if the wrapped command recurses
 	 * to the client and triggers another execution.
 	 */
-	// pretty sure no need for this method to be 'synchronized'
 	@Override
-	public void execute() {
+	public synchronized void execute() {
 		if (this.state.isReadyToStartExecutionCycle()) {
-			this.startCommandExecutor.execute(this.startCommand);
+			if (DEBUG) {
+				this.stackTraces.clear();
+				this.stackTraces.add(new StackTrace());
+			}
+			this.executeStartCommand();
+		} else {
+			if (DEBUG) {
+				this.stackTraces.add(new StackTrace());
+			}
 		}
 	}
 
+	/* private protected */ void executeStartCommand() {
+		this.startCommandExecutor.execute(this.startCommand);
+	}
+
 	@Override
 	public void stop() throws InterruptedException {
 		this.state.stop();
@@ -134,7 +157,7 @@
 		}
 		@Override
 		public String toString() {
-			return StringTools.buildToStringFor(this, RepeatingCommandWrapper.this.command);
+			return ObjectTools.toString(this, RepeatingCommandWrapper.this.command);
 		}
 	}
 
@@ -169,6 +192,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.command);
+		return ObjectTools.toString(this, this.command);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RunnableCommand.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RunnableCommand.java
index fee4cb1..a38e7bd 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RunnableCommand.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/RunnableCommand.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -13,13 +13,13 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-
 /**
  * Wrap a {@link Runnable} so it can be used as a {@link Command}.
  */
 @SuppressWarnings("nls")
-public class RunnableCommand implements Command {
-
+public class RunnableCommand
+	implements Command
+{
 	protected final Runnable runnable;
 
 	public RunnableCommand(Runnable runnable) {
@@ -30,19 +30,13 @@
 		this.runnable = runnable;
 	}
 
-	/**
-	 * {@inheritDoc}
-	 */
 	@Override
 	public void execute() {
 		this.runnable.run();
 	}
 
-	/**
-	 * {@inheritDoc}
-	 */
 	@Override
 	public String toString() {
 		return "Command[" + this.runnable +']';
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SafeCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SafeCommandExecutor.java
index 97df12a..a680e12 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SafeCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SafeCommandExecutor.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -44,4 +44,4 @@
 	public SafeCommandExecutor(CommandExecutor commandExecutor, ExceptionHandler exceptionHandler) {
 		super(commandExecutor, exceptionHandler);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SafeExtendedCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SafeExtendedCommandExecutor.java
index a827b74..871cf8e 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SafeExtendedCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SafeExtendedCommandExecutor.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -50,7 +50,7 @@
 	public void waitToExecute(Command command) throws InterruptedException {
 		try {
 			this.commandExecutor.waitToExecute(command);
-		} catch (RuntimeException ex) {
+		} catch (Throwable ex) {
 			this.exceptionHandler.handleException(ex);
 		}
 	}
@@ -59,9 +59,9 @@
 	public boolean waitToExecute(Command command, long timeout) throws InterruptedException {
 		try {
 			return this.commandExecutor.waitToExecute(command, timeout);
-		} catch (RuntimeException ex) {
+		} catch (Throwable ex) {
 			this.exceptionHandler.handleException(ex);
 			return true;  // hmmm... seems like we get here only if the command executed
 		}
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SimpleStatefulCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SimpleStatefulCommandExecutor.java
index 39417c3..fd6cb80 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SimpleStatefulCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SimpleStatefulCommandExecutor.java
@@ -1,24 +1,23 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-
 /**
- * Straightforward implementation of {@link StatefulCommandExecutor}
+ * Straightforward implementation of {@link org.eclipse.jpt.common.utility.command.StatefulCommandExecutor}
  * that executes commands immediately by default. This executor can
  * also be used to adapt simple {@link CommandExecutor}s to the
- * {@link StatefulCommandExecutor} interface, providing support for
+ * {@link org.eclipse.jpt.common.utility.command.StatefulCommandExecutor} interface, providing support for
  * lifecycle state.
  */
 public class SimpleStatefulCommandExecutor
@@ -31,4 +30,4 @@
 	public SimpleStatefulCommandExecutor(CommandExecutor commandExecutor) {
 		super(commandExecutor);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SimpleStatefulExtendedCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SimpleStatefulExtendedCommandExecutor.java
index ce502a9..b61edc5 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SimpleStatefulExtendedCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SimpleStatefulExtendedCommandExecutor.java
@@ -1,23 +1,24 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-
 /**
  * Straightforward implementation of {@link StatefulExtendedCommandExecutor}
  * that executes commands immediately by default. This executor can
- * also be used to adapt simple {@link CommandExecutor}s to the
+ * also be used to adapt simple
+ * {@link org.eclipse.jpt.common.utility.command.CommandExecutor CommandExecutor}s
+ * to the
  * {@link StatefulExtendedCommandExecutor} interface, providing support for
  * lifecycle state. Any calls to {@link #waitToExecute(Command)} suspend the
  * calling thread until the command executor is {@link #start() started}.
@@ -63,4 +64,4 @@
 		}
 		return false;
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SingleUseQueueingCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SingleUseQueueingCommandExecutor.java
index 4257ac1..8a20db2 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SingleUseQueueingCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SingleUseQueueingCommandExecutor.java
@@ -1,19 +1,18 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-
 /**
  * @see AbstractSingleUseQueueingCommandExecutor
  */
@@ -31,4 +30,4 @@
 	public SingleUseQueueingCommandExecutor(StatefulCommandExecutor commandExecutor) {
 		super(commandExecutor);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SingleUseQueueingExtendedCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SingleUseQueueingExtendedCommandExecutor.java
index cece86c..8de2c4b 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SingleUseQueueingExtendedCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SingleUseQueueingExtendedCommandExecutor.java
@@ -1,19 +1,18 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-
 /**
  * Calls to {@link #waitToExecute(Command)} will suspend the current thread
  * until the command executor is {@link #start() started} and any previously-
@@ -22,7 +21,7 @@
  * <strong>NB:</strong> Calls to {@link #waitToExecute(Command)} will suspend
  * the current thread <em>indefinitely</em> if the command executor is
  * {@link #stop() stopped}.
- * 
+ *
  * @see AbstractSingleUseQueueingCommandExecutor
  */
 public class SingleUseQueueingExtendedCommandExecutor
@@ -78,4 +77,4 @@
 			syncCommand.release();
 		}
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/StatefulCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/StatefulCommandExecutor.java
index d1fc18a..aff8690 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/StatefulCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/StatefulCommandExecutor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -16,25 +16,23 @@
 /**
  * Add the ability to start and stop the command executor.
  * <p>
- * 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.
- *
- * @version 2.5
+ * 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 StatefulCommandExecutor extends CommandExecutor {
-
+public interface StatefulCommandExecutor
+	extends CommandExecutor
+{
 	/**
-	 * Starts the command executor.
-	 *
+	 * Start the command executor.
 	 * @exception IllegalStateException when the command executor is not stopped
 	 */
 	void start();
 
 	/**
-	 * Stops the command executor.
-	 *
+	 * Stop the command executor.
 	 * @exception IllegalStateException when the command executor is not started
 	 */
 	void stop() throws InterruptedException;
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/StatefulExtendedCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/StatefulExtendedCommandExecutor.java
index 47f3d90..ce16ef9 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/StatefulExtendedCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/StatefulExtendedCommandExecutor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -16,15 +16,14 @@
 /**
  * Add the ability to start and stop the command executor.
  * <p>
- * 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.
- *
- * @version 2.5
+ * 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 StatefulExtendedCommandExecutor extends StatefulCommandExecutor,
-                                                         ExtendedCommandExecutor {
-
+public interface StatefulExtendedCommandExecutor
+	extends StatefulCommandExecutor, ExtendedCommandExecutor
+{
 	// combine interfaces
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SynchronizingCommand.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SynchronizingCommand.java
index 80e083b..2f2aff9 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SynchronizingCommand.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/SynchronizingCommand.java
@@ -1,20 +1,20 @@
 /*******************************************************************************
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.SynchronizedBoolean;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.reference.SynchronizedBoolean;
 
 /**
  * A <em>synchronizing</em> command can be used to coordinate the execution of
@@ -24,7 +24,7 @@
  * "secondary" thread).
  * <p>
  * Typically, Thread A dispatches {@Command commands} to a
- * {@link org.eclipse.persistence.tools.utility.command.CommandExecutor command
+ * {@link org.eclipse.jpt.common.utility.command.CommandExecutor command
  * executor}) that executes the {@Command commands} asynchronously on Thread B.
  * A <em>synchronizing</em> command allows Thread A to
  * dispatch a <em>synchronizing</em> command to Thread B and suspend until
@@ -62,6 +62,7 @@
 	private volatile boolean expired = false;  // guarded by #flag
 	private final Command command;
 
+
 	/**
 	 * Construct a <em>synchronizing</em> command that does <em>not</em> execute
 	 * a {@link #command} on the "secondary" {@link Thread thread} (Thread B),
@@ -88,12 +89,12 @@
 
 	/**
 	 * Typically called by a
-	 * {@link org.eclipse.persistence.tools.utility.command.CommandExecutor command
+	 * {@link org.eclipse.jpt.common.utility.command.CommandExecutor command
 	 * executor} executing Thread B.
 	 * <p>
 	 * The "synchronizing" command has reached the front of the command queue
 	 * and is executing on Thread B.
-	 * Returns control to the Thread A.
+	 * Execute the wrapped command and return control to the Thread A.
 	 * Suspend Thread B until Thread A resets the flag.
 	 * <p>
 	 * If the "synchronizing" command is executed (synchronously) on the same
@@ -161,6 +162,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.flag);
+		return ObjectTools.toString(this, this.flag);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ThreadLocalCommand.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ThreadLocalCommand.java
index 8530849..ade6207 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ThreadLocalCommand.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ThreadLocalCommand.java
@@ -1,19 +1,18 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-
 /**
  * This implementation of the Command interface allows the client to
  * specify a different Command for each thread.
@@ -62,10 +61,10 @@
 	}
 
 	/**
-	 * Returns the string representation of the current thread's command.
+	 * Return the string representation of the current thread's command.
 	 */
 	@Override
 	public String toString() {
 		return this.get().toString();
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ThreadLocalCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ThreadLocalCommandExecutor.java
index 0746ec1..157cd11 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ThreadLocalCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ThreadLocalCommandExecutor.java
@@ -1,19 +1,18 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-
 /**
  * @see AbstractThreadLocalCommandExecutor
  */
@@ -30,4 +29,4 @@
 	public ThreadLocalCommandExecutor(CommandExecutor defaultCommandExecutor) {
 		super(defaultCommandExecutor);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ThreadLocalExtendedCommandExecutor.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ThreadLocalExtendedCommandExecutor.java
index 7dcb2d2..4976ce2 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ThreadLocalExtendedCommandExecutor.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/command/ThreadLocalExtendedCommandExecutor.java
@@ -1,19 +1,18 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.command;
 
-
 /**
  * @see AbstractThreadLocalCommandExecutor
  */
@@ -41,4 +40,4 @@
 	public boolean waitToExecute(Command command, long timeout) throws InterruptedException {
 		return this.getThreadLocalCommandExecutor().waitToExecute(command, timeout);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumeration/EmptyEnumeration.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumeration/EmptyEnumeration.java
new file mode 100644
index 0000000..6167dab
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumeration/EmptyEnumeration.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.enumeration;
+
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+/**
+ * An <code>EmptyEnumeration</code> is just that.
+ *
+ * @param <E> the type of elements returned by the enumeration
+ */
+public final class EmptyEnumeration<E>
+	implements Enumeration<E>, Serializable
+{
+	// singleton
+	@SuppressWarnings("rawtypes")
+	private static final EmptyEnumeration INSTANCE = new EmptyEnumeration();
+
+	/**
+	 * Return the singleton.
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> Enumeration<T> instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure single instance.
+	 */
+	private EmptyEnumeration() {
+		super();
+	}
+
+	@Override
+	public boolean hasMoreElements() {
+		return false;
+	}
+
+	@Override
+	public E nextElement() {
+		throw new NoSuchElementException();
+	}
+
+	@Override
+	public String toString() {
+		return this.getClass().getSimpleName();
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the singleton
+		return INSTANCE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumeration/EnumerationTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumeration/EnumerationTools.java
new file mode 100644
index 0000000..1d5d429
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumeration/EnumerationTools.java
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.enumeration;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Vector;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.EnumerationIterator;
+
+/**
+ * {@link Enumeration} utility methods.
+ * @see org.eclipse.jpt.common.utility.internal.ArrayTools
+ * @see CollectionTools
+ * @see org.eclipse.jpt.common.utility.internal.iterable.IterableTools
+ * @see org.eclipse.jpt.common.utility.internal.iterator.IteratorTools
+ * @see ListTools
+ */
+public final class EnumerationTools {
+	/**
+	 * Return whether the specified enumeration contains the
+	 * specified element.
+	 */
+	public static boolean contains(Enumeration<?> enumeration, Object value) {
+		if (value == null) {
+			while (enumeration.hasMoreElements()) {
+				if (enumeration.nextElement() == null) {
+					return true;
+				}
+			}
+		} else {
+			while (enumeration.hasMoreElements()) {
+				if (value.equals(enumeration.nextElement())) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Return whether the specified enumeration contains all of the
+	 * elements in the specified collection.
+	 */
+	public static boolean containsAll(Enumeration<?> enumeration, Collection<?> collection) {
+		return CollectionTools.set(iterator(enumeration)).containsAll(collection);
+	}
+
+	/**
+	 * Return whether the specified enumeration contains all of the
+	 * elements in the specified collection.
+	 * The specified enumeration size is a performance hint.
+	 */
+	public static boolean containsAll(Enumeration<?> enumeration, int enumerationSize, Collection<?> collection) {
+		return CollectionTools.set(iterator(enumeration), enumerationSize).containsAll(collection);
+	}
+
+	/**
+	 * Return whether the specified enumeration contains all of the
+	 * elements in the specified iterable.
+	 */
+	public static boolean containsAll(Enumeration<?> enumeration, Iterable<?> iterable) {
+		return CollectionTools.containsAll(CollectionTools.set(iterator(enumeration)), iterable);
+	}
+
+	/**
+	 * Return whether the specified enumeration contains all of the
+	 * elements in the specified iterable.
+	 * The specified enumeration size is a performance hint.
+	 */
+	public static boolean containsAll(Enumeration<?> enumeration, int enumerationSize, Iterable<?> iterable) {
+		return CollectionTools.containsAll(CollectionTools.set(iterator(enumeration), enumerationSize), iterable);
+	}
+
+	/**
+	 * Return whether the specified enumeration 1 contains all of the
+	 * elements in the specified enumeration 2.
+	 */
+	public static boolean containsAll(Enumeration<?> enumeration1, Enumeration<?> enumeration2) {
+		return CollectionTools.containsAll(CollectionTools.set(iterator(enumeration1)), iterator(enumeration2));
+	}
+
+	/**
+	 * Return whether the specified enumeration 1 contains all of the
+	 * elements in the specified enumeration 2.
+	 * The specified iterator 1 size is a performance hint.
+	 */
+	public static boolean containsAll(Enumeration<?> enumeration1, int enumeration1Size, Enumeration<?> enumeration2) {
+		return CollectionTools.containsAll(CollectionTools.set(iterator(enumeration1), enumeration1Size), iterator(enumeration2));
+	}
+
+	/**
+	 * Return whether the specified enumeration contains all of the
+	 * elements in the specified array.
+	 */
+	public static boolean containsAll(Enumeration<?> enumeration, Object... array) {
+		return CollectionTools.containsAll(CollectionTools.set(iterator(enumeration)), array);
+	}
+
+	/**
+	 * Return whether the specified enumeration contains all of the
+	 * elements in the specified array.
+	 * The specified enumeration size is a performance hint.
+	 */
+	public static boolean containsAll(Enumeration<?> enumeration, int enumerationSize, Object... array) {
+		return CollectionTools.containsAll(CollectionTools.set(iterator(enumeration), enumerationSize), array);
+	}
+
+	/**
+	 * Return whether the specified enumerations do not return the same elements
+	 * in the same order.
+	 */
+	public static boolean elementsAreDifferent(Enumeration<?> enumeration1, Enumeration<?> enumeration2) {
+		return ! elementsAreEqual(enumeration1, enumeration2);
+	}
+
+	/**
+	 * Return whether the specified enumerations return equal elements
+	 * in the same order.
+	 */
+	public static boolean elementsAreEqual(Enumeration<?> enumeration1, Enumeration<?> enumeration2) {
+		while (enumeration1.hasMoreElements() && enumeration2.hasMoreElements()) {
+			if (ObjectTools.notEquals(enumeration1.nextElement(), enumeration2.nextElement())) {
+				return false;
+			}
+		}
+		return ! (enumeration1.hasMoreElements() || enumeration2.hasMoreElements());
+	}
+
+	/**
+	 * Return whether the specified enumerations return the same elements.
+	 */
+	public static boolean elementsAreIdentical(Enumeration<?> enumeration1, Enumeration<?> enumeration2) {
+		while (enumeration1.hasMoreElements() && enumeration2.hasMoreElements()) {
+			if (enumeration1.nextElement() != enumeration2.nextElement()) {
+				return false;
+			}
+		}
+		return ! (enumeration1.hasMoreElements() || enumeration2.hasMoreElements());
+	}
+
+	/**
+	 * Return whether the specified enumerations do <em>not</em> return the same
+	 * elements.
+	 */
+	public static boolean elementsAreNotIdentical(Enumeration<?> enumeration1, Enumeration<?> enumeration2) {
+		return ! elementsAreIdentical(enumeration1, enumeration2);
+	}
+
+	/**
+	 * Return an empty enumeration.
+	 */
+	public static <E> Enumeration<E> emptyEnumeration() {
+		return EmptyEnumeration.instance();
+	}
+
+	/**
+	 * Adapt the specified iterator to the {@link Enumeration} interface.
+	 */
+	public static <E> Enumeration<E> enumeration(Iterator<E> iterator) {
+		return new IteratorEnumeration<E>(iterator);
+	}
+
+	/**
+	 * Return the element corresponding to the specified index
+	 * in the specified enumeration.
+	 */
+	public static <E> E get(Enumeration<? extends E> enumeration, int index) {
+		int i = 0;
+		while (enumeration.hasMoreElements()) {
+			E next = enumeration.nextElement();
+			if (i++ == index) {
+				return next;
+			}
+		}
+		throw new IndexOutOfBoundsException(String.valueOf(index) + ':' + String.valueOf(i));
+	}
+
+	/**
+	 * Return a hash code corresponding to the elements in the specified iterator.
+	 */
+	public static int hashCode(Enumeration<?> enumeration) {
+		int hash = 1;
+		while (enumeration.hasMoreElements()) {
+			Object next = enumeration.nextElement();
+			hash = 31 * hash + ((next == null) ? 0 : next.hashCode());
+		}
+		return hash;
+	}
+
+	/**
+	 * Return the index of the first occurrence of the
+	 * specified element in the specified enumeration;
+	 * return -1 if there is no such element.
+	 */
+	public static int indexOf(Enumeration<?> enumeration, Object value) {
+		if (value == null) {
+			for (int i = 0; enumeration.hasMoreElements(); i++) {
+				if (enumeration.nextElement() == null) {
+					return i;
+				}
+			}
+		} else {
+			for (int i = 0; enumeration.hasMoreElements(); i++) {
+				if (value.equals(enumeration.nextElement())) {
+					return i;
+				}
+			}
+		}
+		return -1;
+	}
+
+	/**
+	 * Return the index of the last occurrence of the
+	 * specified element in the specified enumeration;
+	 * return -1 if there is no such element.
+	 */
+	public static int lastIndexOf(Enumeration<?> enumeration, Object value) {
+		int last = -1;
+		if (value == null) {
+			for (int i = 0; enumeration.hasMoreElements(); i++) {
+				if (enumeration.nextElement() == null) {
+					last = i;
+				}
+			}
+		} else {
+			for (int i = 0; enumeration.hasMoreElements(); i++) {
+				if (value.equals(enumeration.nextElement())) {
+					last = i;
+				}
+			}
+		}
+		return last;
+	}
+
+	/**
+	 * Return the specified enumeration's last element.
+	 * @exception java.util.NoSuchElementException enumeration is empty.
+	 */
+	public static <E> E last(Enumeration<E> enumeration) {
+		E last;
+		do {
+			last = enumeration.nextElement();
+		} while (enumeration.hasMoreElements());
+		return last;
+	}
+
+	/**
+	 * Return the number of elements returned by the specified enumeration.
+	 */
+	public static int size(Enumeration<?> enumeration) {
+		int size = 0;
+		while (enumeration.hasMoreElements()) {
+			enumeration.nextElement();
+			size++;
+		}
+		return size;
+	}
+
+	/**
+	 * Return whether the specified enumeration is empty
+	 * (Shortcuts the enumeration rather than calculating the entire size)
+	 */
+	public static boolean isEmpty(Enumeration<?> enumeration) {
+		return ! enumeration.hasMoreElements();
+	}
+
+	/**
+	 * Return the enumeration after it has been "sorted".
+	 */
+	public static <E extends Comparable<? super E>> Enumeration<E> sort(Enumeration<? extends E> enumeration) {
+		return sort(enumeration, null);
+	}
+
+	/**
+	 * Return the enumeration after it has been "sorted".
+	 * The specified enumeration size is a performance hint.
+	 */
+	public static <E extends Comparable<? super E>> Enumeration<E> sort(Enumeration<? extends E> enumeration, int enumerationSize) {
+		return sort(enumeration, null, enumerationSize);
+	}
+
+	/**
+	 * Return the enumeration after it has been "sorted".
+	 */
+	public static <E> Enumeration<E> sort(Enumeration<? extends E> enumeration, Comparator<? super E> comparator) {
+		return ((Vector<E>) ListTools.sort(CollectionTools.vector(iterator(enumeration)), comparator)).elements();
+	}
+
+	/**
+	 * Return the enumeration after it has been "sorted".
+	 * The specified enumeration size is a performance hint.
+	 */
+	public static <E> Enumeration<E> sort(Enumeration<? extends E> enumeration, Comparator<? super E> comparator, int enumerationSize) {
+		return ((Vector<E>) ListTools.sort(CollectionTools.vector(iterator(enumeration), enumerationSize), comparator)).elements();
+	}
+
+	/**
+	 * Return an iterator corresponding to the specified enumeration.
+	 */
+	public static <E> Iterator<E> iterator(Enumeration<? extends E> enumeration) {
+		return new EnumerationIterator<E>(enumeration);
+	}
+
+
+	// ********** constructor **********
+
+	/**
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private EnumerationTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumeration/IteratorEnumeration.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumeration/IteratorEnumeration.java
new file mode 100644
index 0000000..11faf2c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumeration/IteratorEnumeration.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.enumeration;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * An <code>IteratorEnumeration</code> wraps an
+ * {@link Iterator} so that it can be treated like an
+ * {@link Enumeration}.
+ * Hopefully we don't have much need for this....
+ *
+ * @param <E> the type of elements returned by the enumeration
+ */
+public class IteratorEnumeration<E>
+	implements Enumeration<E>
+{
+	private final Iterator<? extends E> iterator;
+
+	/**
+	 * Construct an enumeration that wraps the specified iterable.
+	 */
+	public IteratorEnumeration(Iterable<? extends E> iterable) {
+		this(iterable.iterator());
+	}
+
+	/**
+	 * Construct an enumeration that wraps the specified iterator.
+	 */
+	public IteratorEnumeration(Iterator<? extends E> iterator) {
+		super();
+		if (iterator == null) {
+			throw new NullPointerException();
+		}
+		this.iterator = iterator;
+	}
+
+	@Override
+	public boolean hasMoreElements() {
+		return this.iterator.hasNext();
+	}
+
+	@Override
+	public E nextElement() {
+		return this.iterator.next();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.iterator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumerations/EmptyEnumeration.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumerations/EmptyEnumeration.java
deleted file mode 100644
index 3093302..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumerations/EmptyEnumeration.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.enumerations;
-
-import java.io.Serializable;
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
-
-/**
- * An <code>EmptyEnumeration</code> is just that.
- * 
- * @param <E> the type of elements returned by the enumeration
- */
-public final class EmptyEnumeration<E>
-	implements Enumeration<E>, Serializable
-{
-
-	// singleton
-	@SuppressWarnings("rawtypes")
-	private static final EmptyEnumeration INSTANCE = new EmptyEnumeration();
-
-	/**
-	 * Returns the singleton.
-	 */
-	@SuppressWarnings("unchecked")
-	public static <T> Enumeration<T> instance() {
-		return INSTANCE;
-	}
-
-	/**
-	 * Ensure single instance.
-	 */
-	private EmptyEnumeration() {
-		super();
-	}
-
-	@Override
-	public boolean hasMoreElements() {
-		return false;
-	}
-
-	@Override
-	public E nextElement() {
-		throw new NoSuchElementException();
-	}
-
-	@Override
-	public String toString() {
-		return this.getClass().getSimpleName();
-	}
-
-	private static final long serialVersionUID = 1L;
-	private Object readResolve() {
-		// replace this object with the singleton
-		return INSTANCE;
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumerations/IteratorEnumeration.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumerations/IteratorEnumeration.java
deleted file mode 100644
index 6c66ae0..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/enumerations/IteratorEnumeration.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.enumerations;
-
-import java.util.Enumeration;
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * An <code>IteratorEnumeration</code> wraps an
- * {@link Iterator} so that it can be treated like an
- * {@link Enumeration}.
- * Hopefully we don't have much need for this....
- *
- * @param <E> the type of elements returned by the enumeration
- */
-public class IteratorEnumeration<E>
-	implements Enumeration<E>
-{
-	private final Iterator<? extends E> iterator;
-
-	/**
-	 * Construct an enumeration that wraps the specified iterable.
-	 */
-	public IteratorEnumeration(Iterable<? extends E> iterable) {
-		this(iterable.iterator());
-	}
-
-	/**
-	 * Construct an enumeration that wraps the specified iterator.
-	 */
-	public IteratorEnumeration(Iterator<? extends E> iterator) {
-		super();
-		this.iterator = iterator;
-	}
-
-	@Override
-	public boolean hasMoreElements() {
-		return this.iterator.hasNext();
-	}
-
-	@Override
-	public E nextElement() {
-		return this.iterator.next();
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterator);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/ANDFilter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/ANDFilter.java
new file mode 100644
index 0000000..79415a0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/ANDFilter.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.filter;
+
+/**
+ * This compound filter will "accept" any object that is accepted by
+ * <em>all</em> the wrapped filters. If there are <em>no</em> wrapped
+ * filters, this filter will always return <code>true</code>.
+ * If there are wrapped filters, this filter will
+ * exhibit "short-circuit" behavior; i.e. if any wrapped filter "rejects"
+ * the operand, no following wrapped filters will be evaluated.
+ *
+ * @param <T> the type of objects to be filtered
+ */
+@SuppressWarnings("nls")
+public class ANDFilter<T>
+	extends CompoundFilter<T>
+{
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Construct a filter that will "accept" any object that is accept by
+	 * <em>all</em> the specified wrapped filters.
+	 */
+	public ANDFilter(Filter<T>... filters) {
+		super(filters);
+	}
+
+	@Override
+	public boolean accept(T o) {
+		for (Filter<T> filter : this.filters) {
+			if ( ! filter.accept(o)) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	@Override
+	protected String operatorString() {
+		return "AND";
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/CompoundFilter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/CompoundFilter.java
new file mode 100644
index 0000000..841c0f4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/CompoundFilter.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.filter;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+
+/**
+ * This filter provides a simple framework for combining the behavior
+ * of multiple filters.
+ *
+ * @param <T> the type of objects to be filtered
+ */
+public abstract class CompoundFilter<T>
+	implements Filter<T>, Cloneable, Serializable
+{
+	protected Filter<T>[] filters;
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Construct a compound filter for the specified list of filters.
+	 */
+	protected CompoundFilter(Filter<T>... filters) {
+		super();
+		if (filters == null) {
+			throw new NullPointerException();
+		}
+		this.filters = filters;
+	}
+
+	/**
+	 * Return the filters.
+	 */
+	public Filter<T>[] getFilters() {
+		return this.filters;
+	}
+
+	@Override
+	public Object clone() {
+		try {
+			return super.clone();
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if ( ! (o instanceof CompoundFilter)) {
+			return false;
+		}
+		@SuppressWarnings("unchecked")
+		CompoundFilter<T> other = (CompoundFilter<T>) o;
+		return Arrays.equals(this.filters, other.filters);
+	}
+
+	@Override
+	public int hashCode() {
+		return Arrays.hashCode(this.filters);
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		StringBuilderTools.appendHashCodeToString(sb, this);
+		sb.append('(');
+		for (Filter<T> filter : this.filters) {
+			sb.append(filter);
+			sb.append(' ');
+			sb.append(this.operatorString());
+			sb.append(' ');
+		}
+		if (this.filters.length > 0) {
+			sb.setLength(sb.length() - this.operatorString().length() - 2);
+		}
+		sb.append(')');
+		return sb.toString();
+	}
+
+	/**
+	 * Return a string representation of the compound filter's operator.
+	 * Used by {@link #toString()}.
+	 */
+	protected abstract String operatorString();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/Filter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/Filter.java
new file mode 100644
index 0000000..1de9f21
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/Filter.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.filter;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Used by various "pluggable" classes to filter objects.
+ * <p>
+ * 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.
+ *
+ * @param <T> the type of objects to be filtered
+ */
+public interface Filter<T> {
+
+	/**
+	 * Return whether the specified object is "accepted" by the
+	 * filter. The semantics of "accept" is determined by the
+	 * contract between the client and the server.
+	 */
+	boolean accept(T o);
+
+
+	/**
+	 * Convenience filter implementation that accepts everything
+	 * and produces a helpful {@link #toString()}.
+	 */
+	class Adapter<S>
+		implements Filter<S>
+	{
+		@Override
+		public boolean accept(S o) {
+			return true;
+		}
+
+		@Override
+		public String toString() {
+			return ObjectTools.toString(this);
+		}
+	}
+
+
+	/**
+	 * Singleton implementation of the filter interface that accepts all the
+	 * objects (i.e. it does no filtering).
+	 */
+	final class Transparent<S>
+		implements Filter<S>, Serializable
+	{
+		@SuppressWarnings("rawtypes")
+		public static final Filter INSTANCE = new Transparent();
+		@SuppressWarnings("unchecked")
+		public static <R> Filter<R> instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Transparent() {
+			super();
+		}
+		// nothing is filtered - everything is accepted
+		@Override
+		public boolean accept(S o) {
+			return true;
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+
+	/**
+	 * Singleton implementation of the filter interface that accepts none of the
+	 * objects (i.e. it filters out all the objects).
+	 */
+	final class Opaque<S>
+		implements Filter<S>, Serializable
+	{
+		@SuppressWarnings("rawtypes")
+		public static final Filter INSTANCE = new Opaque();
+		@SuppressWarnings("unchecked")
+		public static <R> Filter<R> instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Opaque() {
+			super();
+		}
+		// everything is filtered - nothing is accepted
+		@Override
+		public boolean accept(S o) {
+			return false;
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+
+	/**
+	 * Singleton implementation of the filter interface that throws an exception
+	 * if called.
+	 */
+	final class Disabled<S>
+		implements Filter<S>, Serializable
+	{
+		@SuppressWarnings("rawtypes")
+		public static final Filter INSTANCE = new Disabled();
+		@SuppressWarnings("unchecked")
+		public static <R> Filter<R> instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Disabled() {
+			super();
+		}
+		// throw an exception
+		@Override
+		public boolean accept(S o) {
+			throw new UnsupportedOperationException();
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/FilterAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/FilterAdapter.java
new file mode 100644
index 0000000..6032d16
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/FilterAdapter.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 20012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.filter;
+
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Convenience filter that "accepts" every object.
+ *
+ * @param <T> the type of objects to be filtered
+ */
+public class FilterAdapter<T>
+	implements Filter<T>
+{
+	@Override
+	public boolean accept(T o) {
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/FilterWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/FilterWrapper.java
new file mode 100644
index 0000000..def264e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/FilterWrapper.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.filter;
+
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Filter wrapper that can have its wrapped filter changed,
+ * allowing a client to change a previously-supplied filter's
+ * behavior mid-stream.
+ *
+ * @param <T> the type of objects to be filtered
+ * @see #setFilter(Filter)
+ */
+public class FilterWrapper<T>
+	implements Filter<T>
+{
+	protected volatile Filter<T> filter;
+
+	public FilterWrapper(Filter<T> filter) {
+		super();
+		if (filter == null) {
+			throw new NullPointerException();
+		}
+		this.filter = filter;
+	}
+
+	@Override
+	public boolean accept(T o) {
+		return this.filter.accept(o);
+	}
+
+	public void setFilter(Filter<T> filter) {
+		if (filter == null) {
+			throw new NullPointerException();
+		}
+		this.filter = filter;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.filter);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/NOTFilter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/NOTFilter.java
new file mode 100644
index 0000000..8add70d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/NOTFilter.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.filter;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * This filter will "accept" any object that is NOT accepted by
+ * the wrapped filter.
+ *
+ * @param <T> the type of objects to be filtered
+ */
+public class NOTFilter<T>
+	implements Filter<T>, Cloneable, Serializable
+{
+	protected final Filter<T> filter;
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Construct a filter that will "accept" any object that is NOT accepted
+	 * by the specified wrapped filter.
+	 */
+	public NOTFilter(Filter<T> filter) {
+		super();
+		if (filter == null) {
+			throw new NullPointerException();
+		}
+		this.filter = filter;
+	}
+
+	@Override
+	public boolean accept(T o) {
+		return ! this.filter.accept(o);
+	}
+
+	public Filter<T> getFilter() {
+		return this.filter;
+	}
+
+	@Override
+	public Object clone() {
+		try {
+			return super.clone();
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if ( ! (o instanceof NOTFilter)) {
+			return false;
+		}
+		@SuppressWarnings("unchecked")
+		NOTFilter<T> other = (NOTFilter<T>) o;
+		return this.filter.equals(other.filter);
+	}
+
+	@Override
+	public int hashCode() {
+		return this.filter.hashCode();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.filter);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/NotNullFilter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/NotNullFilter.java
new file mode 100644
index 0000000..6141730
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/NotNullFilter.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.filter;
+
+import java.io.Serializable;
+
+/**
+ * This filter accepts only non-null objects.
+ *
+ * @param <T> the type of objects to be filtered
+ */
+public final class NotNullFilter<T>
+	implements Filter<T>, Serializable
+{
+	@SuppressWarnings("rawtypes")
+	public static final Filter INSTANCE = new NotNullFilter();
+
+	@SuppressWarnings("unchecked")
+	public static <R> Filter<R> instance() {
+		return INSTANCE;
+	}
+
+	// ensure single instance
+	private NotNullFilter() {
+		super();
+	}
+
+	// accept only non-null objects
+	@Override
+	public boolean accept(T o) {
+		return o != null;
+	}
+
+	@Override
+	public String toString() {
+		return this.getClass().getSimpleName();
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the singleton
+		return INSTANCE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/ORFilter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/ORFilter.java
new file mode 100644
index 0000000..94f149d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/ORFilter.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.filter;
+
+/**
+ * This compound filter will "accept" any object that is accepted by
+ * <em>any</em> one of the wrapped filters. If there are <em>no</em> wrapped
+ * filters, this filter will always return <code>false</code>.
+ * If there are wrapped filters, this filter will
+ * exhibit "short-circuit" behavior; i.e. if any wrapped filter "accepts"
+ * the operand, no following wrapped filters will be evaluated.
+ *
+ * @param <T> the type of objects to be filtered
+ */
+@SuppressWarnings("nls")
+public class ORFilter<T>
+	extends CompoundFilter<T>
+{
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Construct a filter that will "accept" any object that is accept by
+	 * <em>any</em> one of the specified wrapped filters.
+	 */
+	public ORFilter(Filter<T>... filters) {
+		super(filters);
+	}
+
+	@Override
+	public boolean accept(T o) {
+		for (Filter<T> filter : this.filters) {
+			if (filter.accept(o)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	@Override
+	protected String operatorString() {
+		return "OR";
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/SimpleFilter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/SimpleFilter.java
new file mode 100644
index 0000000..936e5d0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/SimpleFilter.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.filter;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Simple, abstract implementation of <code>Filter</code>
+ * that holds on to a criterion object that can be used in the
+ * {@link #accept(Object) accept} or {@link #reject(Object) reject}
+ * methods. Subclasses can override either of these methods,
+ * depending on which is easier to implement. Note that at least
+ * one of these methods <em>must</em> be overridden or
+ * an infinite loop will occur. If both of them are overridden,
+ * only the {@link #accept(Object) accept} method will be used.
+ * <p>
+ * This class simplifies the implementation of straightforward inner classes.
+ * Here is an example of a filter that can be used by a
+ * {@link org.eclipse.jpt.common.utility.internal.iterable.FilteringIterable
+ * FilteringIterable} to return only those strings
+ * in the nested iterable that start with <code>"prefix"</code>:
+ * <pre>
+ * Filter<String> filter = new SimpleFilter<String, String>("prefix") {
+ *     public boolean accept(String string) {
+ *         return string.startsWith(this.criterion);
+ *     }
+ * };
+ * </pre>
+ *
+ * @param <T> the type of objects to be filtered
+ * @param <C> the type of the filter's criterion
+ */
+public abstract class SimpleFilter<T, C>
+	implements Filter<T>, Cloneable, Serializable
+{
+	protected final C criterion;
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Construct a simple filter with a <code>null</code> criterion.
+	 */
+	protected SimpleFilter() {
+		this(null);
+	}
+
+	/**
+	 * More useful constructor. The specified criterion can
+	 * be used by a subclass to "accept" or "reject" objects.
+	 */
+	protected SimpleFilter(C criterion) {
+		super();
+		this.criterion = criterion;
+	}
+
+	/**
+	 * Return whether the the specified object should be "rejected".
+	 * The semantics of "rejected" is determined by the subclass.
+	 */
+	protected boolean reject(T o) {
+		return ! this.accept(o);
+	}
+
+	/**
+	 * Return whether the the specified object should be "accepted".
+	 * The semantics of "accepted" is determined by the subclass.
+	 */
+	@Override
+	public boolean accept(T o) {
+		return ! this.reject(o);
+	}
+
+	/**
+	 * Return the filter's criterion.
+	 */
+	public C getCriterion() {
+		return this.criterion;
+	}
+
+	@Override
+	public SimpleFilter<T, C> clone() {
+		try {
+			@SuppressWarnings("unchecked")
+			SimpleFilter<T, C> clone = (SimpleFilter<T, C>) super.clone();
+			return clone;
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if ( ! (o instanceof SimpleFilter<?, ?>)) {
+			return false;
+		}
+		SimpleFilter<?, ?> other = (SimpleFilter<?, ?>) o;
+		return ObjectTools.equals(this.criterion, other.criterion);
+	}
+
+	@Override
+	public int hashCode() {
+		return (this.criterion == null) ? 0 : this.criterion.hashCode();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.criterion);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/XORFilter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/XORFilter.java
new file mode 100644
index 0000000..ba44f51
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/filter/XORFilter.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.filter;
+
+/**
+ * This compound filter will "accept" any object that is accepted by either of
+ * the wrapped filters, but not both. Both filters will always be evaluated.
+ *
+ * @param <T> the type of objects to be filtered
+ */
+@SuppressWarnings("nls")
+public class XORFilter<T>
+	extends CompoundFilter<T>
+{
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Construct a filter that will "accept" any object that is accept by either
+	 * of the specified wrapped filters, but not by both.
+	 */
+	@SuppressWarnings("unchecked")
+	public XORFilter(Filter<T> filter1, Filter<T> filter2) {
+		super(filter1, filter2);
+		if ((filter1 == null) || (filter2 == null)) {
+			throw new NullPointerException();
+		}
+	}
+
+	@Override
+	public boolean accept(T o) {
+		return this.filters[0].accept(o) ^ this.filters[1].accept(o);
+	}
+
+	@Override
+	protected String operatorString() {
+		return "XOR";
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/CompositeOutputStream.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/CompositeOutputStream.java
new file mode 100644
index 0000000..7d13f71
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/CompositeOutputStream.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * A composite output stream forwards the data written to it
+ * to multiple streams.
+ */
+public class CompositeOutputStream
+	extends OutputStream
+{
+	private OutputStream[] streams;
+
+
+	/**
+	 * Construct a "tee" output stream that writes to the
+	 * specified streams.
+	 */
+	public CompositeOutputStream(OutputStream... streams) {
+		super();
+		if (streams == null) {
+			throw new NullPointerException();
+		}
+		this.streams = streams;
+	}
+
+	@Override
+	public synchronized void write(int i) throws IOException {
+		for (OutputStream stream : this.streams) {
+			stream.write(i);
+		}
+	}
+
+	@Override
+	public synchronized void write(byte[] bytes) throws IOException {
+		for (OutputStream stream : this.streams) {
+			stream.write(bytes);
+		}
+	}
+
+	@Override
+	public synchronized void write(byte[] bytes, int off, int len) throws IOException {
+		for (OutputStream stream : this.streams) {
+			stream.write(bytes, off, len);
+		}
+	}
+
+	@Override
+	public synchronized void flush() throws IOException {
+		for (OutputStream stream : this.streams) {
+			stream.flush();
+		}
+	}
+
+	@Override
+	public synchronized void close() throws IOException {
+		for (OutputStream stream : this.streams) {
+			stream.close();
+		}
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, Arrays.toString(this.streams));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/CompositeWriter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/CompositeWriter.java
new file mode 100644
index 0000000..f87e6ef
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/CompositeWriter.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Arrays;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * A composite writer forwards the character data written to it
+ * to multiple streams.
+ */
+public class CompositeWriter
+	extends Writer
+{
+	private Writer[] writers;
+
+
+	/**
+	 * Construct a "tee" writer that writes to the specified writers.
+	 */
+	public CompositeWriter(Writer... writers) {
+		super();
+		if (writers == null) {
+			throw new NullPointerException();
+		}
+		this.writers = writers;
+	}
+
+	/**
+	 * Construct a "tee" writer that writes to the specified writers and
+	 * locks on the specified object.
+	 */
+	public CompositeWriter(Object lock, Writer... writers) {
+		super(lock);
+		if (writers == null) {
+			throw new NullPointerException();
+		}
+		this.writers = writers;
+	}
+
+	@Override
+	public void write(int c) throws IOException {
+		for (Writer writer : this.writers) {
+			writer.write(c);
+		}
+	}
+
+	@Override
+	public void write(char[] cbuf) throws IOException {
+		for (Writer writer : this.writers) {
+			writer.write(cbuf);
+		}
+	}
+
+	@Override
+	public void write(char[] cbuf, int off, int len) throws IOException {
+		for (Writer writer : this.writers) {
+			writer.write(cbuf, off, len);
+		}
+	}
+
+	@Override
+	public void write(String str) throws IOException {
+		for (Writer writer : this.writers) {
+			writer.write(str);
+		}
+	}
+
+	@Override
+	public void write(String str, int off, int len) throws IOException {
+		for (Writer writer : this.writers) {
+			writer.write(str, off, len);
+		}
+	}
+
+	@Override
+	public void flush() throws IOException {
+		for (Writer writer : this.writers) {
+			writer.flush();
+		}
+	}
+
+	@Override
+	public void close() throws IOException {
+		for (Writer writer : this.writers) {
+			writer.close();
+		}
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, Arrays.toString(this.writers));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/FileTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/FileTools.java
new file mode 100644
index 0000000..357dcc6
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/FileTools.java
@@ -0,0 +1,997 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.SystemTools;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.iterable.FilteringIterable;
+import org.eclipse.persistence.tools.utility.iterator.ArrayIterator;
+import org.eclipse.persistence.tools.utility.iterator.FilteringIterator;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+import org.eclipse.persistence.tools.utility.transformer.TransformerAdapter;
+import org.eclipse.persistence.tools.utility.transformer.XMLStringEncoder;
+
+/**
+ * {@link File} utility methods:<ul>
+ * <li>delete entire trees of directories and files
+ * <li>build iterators on entire trees of directories and files
+ * <li>build a temporary directory
+ * <li>"canonize" files
+ * </ul>
+ */
+@SuppressWarnings("nls")
+public final class FileTools {
+
+	public static final String USER_HOME_DIRECTORY_NAME = System.getProperty("user.home");
+
+	public static final String USER_TEMPORARY_DIRECTORY_NAME = System.getProperty("java.io.tmpdir");
+
+	public static String DEFAULT_TEMPORARY_DIRECTORY_NAME = "tmpdir";
+
+	public static final String CURRENT_WORKING_DIRECTORY_NAME = System.getProperty("user.dir");
+
+    /** A list of some invalid file name characters:<ul>
+     * <li><code>:</code> - Windows drive indicator; MacOS filename separator
+     * <li><code>*</code> - Windows wildcard character
+     * <li><code>|</code> - Windows redirection character
+     * <li><code>&</code> - escape character
+     * <li><code>/</code> - Windows command option tag; Unix/Linux filename separator
+     * <li><code>\</code> - Windows filename separator; Unix/Linux escape character
+     * <li><code>;</code> - ???
+     * <li><code>?</code> - Windows wildcard character
+     * <li><code>[</code> - ???
+     * <li><code>]</code> - ???
+     * <li><code>=</code> - ???
+     * <li><code>+</code> - ???
+     * <li><code>&lt;</code> - Windows redirection character
+     * <li><code>></code> - Windows redirection character
+     * <li><code>"</code> - Windows filename delimiter
+     * <li><code>,</code> - ???
+     * </ul>
+     */
+	public static final char[] INVALID_FILENAME_CHARACTERS = { ':', '*', '|', '&', '/', '\\', ';', '?', '[', ']', '=', '+', '<', '>', '"', ',' };
+
+	/** This transformer will convert strings into valid file names. */
+	public static final Transformer<String, String> FILE_NAME_ENCODER = new XMLStringEncoder(INVALID_FILENAME_CHARACTERS);
+
+	/** Windows files that are redirected to devices etc. */
+	private static final String[] WINDOWS_RESERVED_FILE_NAMES = {
+		"con",
+		"aux",
+		"com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9",
+		"lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9",
+		"prn",
+		"nul"
+	};
+
+	/** The default length of a shortened file name. */
+	public static final int MAXIMUM_SHORTENED_FILE_NAME_LENGTH = 60;
+
+
+	// ********** deleting directories **********
+
+	/**
+	 * Delete the specified directory and all of its contents.
+	 * <em>USE WITH CARE.</em>
+	 */
+	public static void deleteDirectory(String directoryName) {
+		deleteDirectory(new File(directoryName));
+	}
+
+	/**
+	 * Delete the specified directory and all of its contents.
+	 * <em>USE WITH CARE.</em>
+	 */
+	public static void deleteDirectory(File directory) {
+		deleteDirectoryContents(directory);
+		if ( ! directory.delete()) {
+			throw new RuntimeException("unable to delete directory: " + directory.getAbsolutePath());
+		}
+	}
+
+	/**
+	 * Delete the contents of the specified directory
+	 * (but not the directory itself).
+	 * <em>USE WITH CARE.</em>
+	 */
+	public static void deleteDirectoryContents(String directoryName) {
+		deleteDirectoryContents(new File(directoryName));
+	}
+
+	/**
+	 * Delete the contents of the specified directory
+	 * (but not the directory itself).
+	 * <em>USE WITH CARE.</em>
+	 */
+	public static void deleteDirectoryContents(File directory) {
+		for (File file : directory.listFiles()) {
+			if (file.isDirectory()) {
+				deleteDirectory(file);	// recurse
+			} else {
+				if ( ! file.delete()) {
+					throw new RuntimeException("unable to delete file: " + file.getAbsolutePath());
+				}
+			}
+		}
+	}
+
+
+	// ********** copying files **********
+
+	/**
+	 * Copies the content of the source file to the destination file.
+	 */
+	@SuppressWarnings("resource") // false positive?
+	public static void copyToFile(File sourceFile, File destinationFile)
+		throws IOException
+	{
+		FileChannel sourceChannel = null;
+		FileChannel destinationChannel = null;
+		try {
+			sourceChannel = new FileInputStream(sourceFile).getChannel();
+			destinationChannel = new FileOutputStream(destinationFile).getChannel();
+			destinationChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
+		} finally {
+			try {
+				if (sourceChannel != null) {
+					sourceChannel.close();
+				}
+			} finally {
+				if (destinationChannel != null) {
+					destinationChannel.close();
+				}
+			}
+		}
+	}
+
+	/**
+	 * Copies the content of the source file to a file by
+	 * the same name in the destination directory.
+	 */
+	public static void copyToDirectory(File sourceFile, File destinationDirectory)
+		throws IOException
+	{
+		File destinationFile = new File(destinationDirectory, sourceFile.getName());
+		if ( ! destinationFile.exists() && ! destinationFile.createNewFile()) {
+			throw new RuntimeException("File.createNewFile() failed: " + destinationFile);
+		}
+		copyToFile(sourceFile, destinationFile);
+	}
+
+
+	// ********** files and directories **********
+
+	/**
+	 * Return all the normal files in the specified directory,
+	 * skipping subdirectories.
+	 * @see File#isFile()
+	 */
+	public static Iterator<File> files(String directoryName) {
+		return files(new File(directoryName));
+	}
+
+	/**
+	 * Return all the normal files in the specified directory,
+	 * skipping subdirectories.
+	 * @see File#isFile()
+	 */
+	public static Iterator<File> files(File directory) {
+		return new FilteringIterator<File>(new ArrayIterator<File>(directory.listFiles()), NORMAL_FILE_FILTER);
+	}
+
+	/**
+	 * @see File#isFile()
+	 */
+	public static final Filter<File> NORMAL_FILE_FILTER = new NormalFileFilter();
+	/* CU private */ static class NormalFileFilter
+		extends Filter.Adapter<File>
+	{
+		@Override
+		public boolean accept(File file) {
+			return file.isFile();
+		}
+	}
+
+	/**
+	 * Return all the subdirectories in the specified directory.
+	 * @see File#isDirectory()
+	 */
+	public static Iterator<File> directories(String directoryName) {
+		return directories(new File(directoryName));
+	}
+
+	/**
+	 * Return all the subdirectories in the specified directory.
+	 * @see File#isDirectory()
+	 */
+	public static Iterator<File> directories(File directory) {
+		return new FilteringIterator<File>(new ArrayIterator<File>(directory.listFiles()), DIRECTORY_FILTER);
+	}
+
+	/**
+	 * @see File#isDirectory()
+	 */
+	public static final Filter<File> DIRECTORY_FILTER = new DirectoryFilter();
+	/* CU private */ static class DirectoryFilter
+		extends Filter.Adapter<File>
+	{
+		@Override
+		public boolean accept(File file) {
+			return file.isDirectory();
+		}
+	}
+
+	/**
+	 * Return all the normal files in the specified directory,
+	 * recursing into subdirectories but skipping the subdirectories themselves.
+	 * @see File#isFile()
+	 */
+	public static Iterator<File> allFiles(String directoryName) {
+		return allFiles(new File(directoryName));
+	}
+
+	/**
+	 * Return all the normal files in the specified directory,
+	 * recursing into subdirectories but skipping the subdirectories themselves.
+	 * @see File#isFile()
+	 */
+	public static Iterator<File> allFiles(File directory) {
+		ArrayList<File> files = new ArrayList<File>(10000);
+		addAllFilesTo(directory, files);
+		return files.iterator();
+	}
+
+	/**
+	 * <strong>NB:</strong> Looping offers much better performance than a true
+	 * recursion when dealing with large directory trees.
+	 */
+	private static void addAllFilesTo(File directory, ArrayList<File> files) {
+		for (File file : directory.listFiles()) {
+			if (file.isFile()) {
+				files.add(file);
+			} else if (file.isDirectory()) {
+				addAllFilesTo(file, files); // recurse
+			}
+		}
+	}
+
+	/**
+	 * Return all the directories in the specified directory,
+	 * recursing into subdirectories.
+	 * @see File#isDirectory()
+	 */
+	public static Iterator<File> allDirectories(String directoryName) {
+		return allDirectories(new File(directoryName));
+	}
+
+	/**
+	 * Return all the directories in the specified directory,
+	 * recursing into subdirectories.
+	 * @see File#isDirectory()
+	 */
+	public static Iterator<File> allDirectories(File directory) {
+		ArrayList<File> files = new ArrayList<File>(10000);
+		addAllDirectoriesTo(directory, files);
+		return files.iterator();
+	}
+
+	/**
+	 * <strong>NB:</strong> Looping offers much better performance than a true
+	 * recursion when dealing with large directory trees.
+	 */
+	private static void addAllDirectoriesTo(File directory, ArrayList<File> directories) {
+		for (File file : directory.listFiles()) {
+			if (file.isDirectory()) {
+				directories.add(file);
+				addAllDirectoriesTo(file, directories); // recurse
+			}
+		}
+	}
+
+
+	// ********** short file name manipulation **********
+
+	/**
+	 * Strip the extension from the specified file name
+	 * and return the result. If the file name has no
+	 * extension, it is returned unchanged
+	 */
+	public static String stripExtension(String fileName) {
+		int index = fileName.lastIndexOf('.');
+		return (index == -1) ? fileName : fileName.substring(0, index);
+	}
+
+	/**
+	 * Strip the extension from the specified file's name
+	 * and return the result. If the file's name has no
+	 * extension, it is returned unchanged
+	 */
+	public static String stripExtension(File file) {
+		return stripExtension(file.getPath());
+	}
+
+	/**
+	 * Return the extension, including the dot, of the specified file name.
+	 * If the file name has no extension, return an empty string.
+	 */
+	public static String extension(String fileName) {
+		int index = fileName.lastIndexOf('.');
+		return (index == -1) ? StringTools.EMPTY_STRING : fileName.substring(index);
+	}
+
+	/**
+	 * Return the extension, including the dot, of the specified file's name.
+	 * If the file's name has no extension, return an empty string.
+	 */
+	public static String extension(File file) {
+		return extension(file.getPath());
+	}
+
+
+	// ********** temporary directories **********
+
+	/**
+	 * Build and return an empty temporary directory with the specified
+	 * name. If the directory already exists, it will be cleared out.
+	 * This directory will be a subdirectory of the Java temporary directory,
+	 * as indicated by the System property <code>"java.io.tmpdir"</code>.
+	 * @see #DEFAULT_TEMPORARY_DIRECTORY_NAME
+	 */
+	public static File emptyTemporaryDirectory(String name) {
+		File dir = new File(userTemporaryDirectory(), name);
+		if (dir.exists()) {
+			deleteDirectoryContents(dir);
+		} else {
+			mkdirs(dir);
+		}
+		return dir;
+	}
+
+	private static void mkdirs(File dir) {
+		if ( ! dir.mkdirs()) {
+			throw new RuntimeException("File.mkdirs() failed: " + dir);
+		}
+	}
+
+	/**
+	 * Build and return an empty temporary directory with a
+	 * name of <code>"tmpdir"</code>. If the directory already exists, it will be cleared out.
+	 * This directory will be a subdirectory of the Java temporary directory,
+	 * as indicated by the System property <code>"java.io.tmpdir"</code>.
+	 * @see #DEFAULT_TEMPORARY_DIRECTORY_NAME
+	 */
+	public static File emptyTemporaryDirectory() {
+		return emptyTemporaryDirectory(DEFAULT_TEMPORARY_DIRECTORY_NAME);
+	}
+
+	/**
+	 * Build and return a temporary directory with the specified
+	 * name. If the directory already exists, it will be left unchanged;
+	 * if it does not already exist, it will be created.
+	 * This directory will be a subdirectory of the Java temporary directory,
+	 * as indicated by the System property <code>"java.io.tmpdir"</code>.
+	 * @see #DEFAULT_TEMPORARY_DIRECTORY_NAME
+	 */
+	public static File temporaryDirectory(String name) {
+		File dir = new File(userTemporaryDirectory(), name);
+		if ( ! dir.exists()) {
+			mkdirs(dir);
+		}
+		return dir;
+	}
+
+	/**
+	 * Build and return a temporary directory with a name of
+	 * <code>"tmpdir"</code>. If the directory already exists, it will be left unchanged;
+	 * if it does not already exist, it will be created.
+	 * This directory will be a subdirectory of the Java temporary directory,
+	 * as indicated by the System property <code>"java.io.tmpdir"</code>.
+	 * @see #DEFAULT_TEMPORARY_DIRECTORY_NAME
+	 */
+	public static File temporaryDirectory() {
+		return temporaryDirectory(DEFAULT_TEMPORARY_DIRECTORY_NAME);
+	}
+
+	/**
+	 * Build and return a <em>new</em> temporary directory with the specified
+	 * prefix. The prefix will be appended with a number that
+	 * is incremented, starting with 1, until a non-pre-existing directory
+	 * is found and successfully created. This directory will be a
+	 * subdirectory of the Java temporary directory, as indicated by
+	 * the System property <code>"java.io.tmpdir"</code>.
+	 * @see #DEFAULT_TEMPORARY_DIRECTORY_NAME
+	 */
+	public static File newTemporaryDirectory(String prefix) {
+		if ( ! prefix.endsWith(".")) { //$NON-NLS-1$
+			prefix = prefix + '.';
+		}
+		File dir;
+		int i = 0;
+		do {
+			i++;
+			dir = new File(userTemporaryDirectory(), prefix + i);
+		} while ( ! dir.mkdirs());
+		return dir;
+	}
+
+	/**
+	 * Build and return a *new* temporary directory with a
+	 * prefix of "tmpdir". This prefix will be appended with a number that
+	 * is incremented, starting with 1, until a non-pre-existing directory
+	 * is found and successfully created. This directory will be a
+	 * subdirectory of the Java temporary directory, as indicated by
+	 * the System property "java.io.tmpdir".
+	 */
+	public static File newTemporaryDirectory() {
+		return newTemporaryDirectory(DEFAULT_TEMPORARY_DIRECTORY_NAME);
+	}
+
+
+	// ********** resource files **********
+
+	/**
+	 * Build and return a file for the specified resource.
+	 * The resource name must be fully-qualified, i.e. it cannot be relative
+	 * to the package name/directory.
+	 * <p>
+	 * <strong>NB:</strong> There is a bug in jdk1.4.x the prevents us from getting
+	 * a resource that has spaces (or other special characters) in
+	 * its name.... (Java bug 4466485)
+	 */
+	public static File resourceFile(String resourceName) throws URISyntaxException {
+		if ( ! resourceName.startsWith("/")) { //$NON-NLS-1$
+			throw new IllegalArgumentException(resourceName);
+		}
+		return resourceFile(resourceName, FileTools.class);
+	}
+
+	/**
+	 * Build and return a file for the specified resource.
+	 * <p>
+	 * <strong>NB:</strong> There is a bug in jdk1.4.x the prevents us from getting
+	 * a resource that has spaces (or other special characters) in
+	 * its name.... (Java bug 4466485)
+	 */
+	public static File resourceFile(String resourceName, Class<?> javaClass) throws URISyntaxException {
+		URL url = javaClass.getResource(resourceName);
+		return buildFile(url);
+	}
+
+	/**
+	 * Build and return a file for the specified URL.
+	 * <p>
+	 * <strong>NB:</strong> There is a bug in jdk1.4.x the prevents us from getting
+	 * a resource that has spaces (or other special characters) in
+	 * its name.... (Java bug 4466485)
+	 */
+	public static File buildFile(URL url) throws URISyntaxException {
+		return buildFile(url.getFile());
+	}
+
+	/**
+	 * Build and return a file for the specified file name.
+	 * <p>
+	 * <strong>NB:</strong> There is a bug in jdk1.4.x the prevents us from getting
+	 * a resource that has spaces (or other special characters) in
+	 * its name.... (Java bug 4466485)
+	 */
+	public static File buildFile(String fileName) throws URISyntaxException {
+		URI uri = new URI(fileName);
+		File file = new File(uri.getPath());
+		return file;
+	}
+
+
+	// ********** "canonical" files **********
+
+	/**
+	 * Convert the specified file into a "canonical" file.
+	 * If getting the file's "canonical" form fails, return the file's
+	 * "absolute" form.
+	 * @see File#getCanonicalFile()
+	 */
+	public static File canonicalFile(File file) {
+		try {
+			return file.getCanonicalFile();
+		} catch (IOException ioexception) {
+			// settle for the absolute file
+			return file.getAbsoluteFile();
+		}
+	}
+
+	public static Transformer<File, File> CANONICAL_FILE_TRANSFORMER = new CanonicalFileTransformer();
+	/* CU private */ static class CanonicalFileTransformer
+		extends TransformerAdapter<File, File>
+	{
+		@Override
+		public File transform(File file) {
+			return canonicalFile(file);
+		}
+	}
+
+	/**
+	 * Convert the specified file name into a "canonical" file name.
+	 */
+	public static String canonicalFileName(String fileName) {
+		return canonicalFile(new File(fileName)).getAbsolutePath();
+	}
+
+	public static Transformer<String, String> CANONICAL_FILE_NAME_TRANSFORMER = new CanonicalFileNameTransformer();
+	/* CU private */ static class CanonicalFileNameTransformer
+		extends TransformerAdapter<String, String>
+	{
+		@Override
+		public String transform(String fileName) {
+			return canonicalFileName(fileName);
+		}
+	}
+
+
+	// ********** file name validation **********
+
+	/**
+	 * Return whether the specified file name is invalid.
+	 * @see #INVALID_FILENAME_CHARACTERS
+	 */
+	public static boolean fileNameIsInvalid(String filename) {
+		return ! fileNameIsValid(filename);
+	}
+
+	/**
+	 * Return whether the specified file name is valid.
+	 * @see #INVALID_FILENAME_CHARACTERS
+	 */
+	public static boolean fileNameIsValid(String filename) {
+		int len = filename.length();
+		for (int i = 0; i < len; i++) {
+			char filenameChar = filename.charAt(i);
+			if (ArrayTools.contains(INVALID_FILENAME_CHARACTERS, filenameChar)) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Convert the illegal characters in the specified file name to
+	 * the specified character and return the result.
+	 * @see #INVALID_FILENAME_CHARACTERS
+	 */
+	public static String convertToValidFileName(String filename, char replacementChar) {
+		int len = filename.length();
+		StringBuilder sb = new StringBuilder(len);
+		for (int i = 0; i < len; i++) {
+			char filenameChar = filename.charAt(i);
+			if (ArrayTools.contains(INVALID_FILENAME_CHARACTERS, filenameChar)) {
+				sb.append(replacementChar);
+			} else {
+				sb.append(filenameChar);
+			}
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Convert the illegal characters in the specified file name to
+	 * periods (<code>'.'</code>) and return the result.
+	 */
+	public static String convertToValidFileName(String filename) {
+		return convertToValidFileName(filename, '.');
+	}
+
+	/**
+	 * Return whether the specified file name is "reserved"
+	 * (i.e. it cannot be used for "user" files). Windows reserves
+	 * a number of file names (e.g. CON, AUX, PRN).
+	 * @see #WINDOWS_RESERVED_FILE_NAMES
+	 */
+	public static boolean fileNameIsReserved(String fileName) {
+		// Unix/Linux does not have any "reserved" file names (I think...)
+		return SystemTools.osIsWindows() && ArrayTools.contains(WINDOWS_RESERVED_FILE_NAMES, fileName.toLowerCase());
+	}
+
+	/**
+	 * Return whether the specified file contains any "reserved"
+	 * components.
+	 * Windows reserves a number of file names (e.g. CON, AUX, PRN);
+	 * and these file names cannot be used for either the names of
+	 * files or directories.
+	 * @see #WINDOWS_RESERVED_FILE_NAMES
+	 */
+	public static boolean fileHasAnyReservedComponents(File file) {
+		File temp = file;
+		while (temp != null) {
+			if (fileNameIsReserved(temp.getName())) {
+				return true;
+			}
+			temp = temp.getParentFile();
+		}
+		return false;
+	}
+
+
+	// ********** shortened file names **********
+
+	/**
+	 * Return a shorter version of the absolute file name for the specified file.
+	 * The shorter version will not be longer than the maximum length.
+	 * The first directory (usually the drive letter) and the file name or the
+	 * last directory will always be added to the generated string regardless of
+	 * the maximum length allowed.
+	 */
+	public static String shortenFileName(URL url) {
+		return shortenFileName(url, MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
+	}
+
+	/**
+	 * Return a shorter version of the absolute file name for the specified file.
+	 * The shorter version will not be longer than the maximum length.
+	 * The first directory (usually the drive letter) and the file name or the
+	 * last directory will always be added to the generated string regardless of
+	 * the maximum length allowed.
+	 */
+	public static String shortenFileName(URL url, int maxLength) {
+		File file;
+		try {
+			file = buildFile(url);
+		} catch (URISyntaxException e) {
+			file = new File(url.getFile());
+		}
+		return shortenFileName(file, maxLength);
+	}
+
+	/**
+	 * Return a shorter version of the absolute file name for the specified file.
+	 * The shorter version will not be longer than the maximum length.
+	 * The first directory (usually the drive letter) and the file name or the
+	 * last directory will always be added to the generated string regardless of
+	 * the maximum length allowed.
+	 */
+	public static String shortenFileName(File file) {
+		return shortenFileName(file, MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
+	}
+
+	/**
+	 * Return a shorter version of the absolute file name for the specified file.
+	 * The shorter version will not be longer than the maximum length.
+	 * The first directory (usually the drive letter) and the file name or the
+	 * last directory will always be added to the generated string regardless of
+	 * the maximum length allowed.
+	 */
+	public static String shortenFileName(File file, int maxLength) {
+		String absoluteFileName = canonicalFile(file).getAbsolutePath();
+		if (absoluteFileName.length() <= maxLength) {
+			// no need to shorten
+			return absoluteFileName;
+		}
+
+		// break down the path into its components
+		String fs = File.separator;
+		String[] paths = absoluteFileName.split('\\' + fs);
+
+		if (paths.length <= 1) {
+			// e.g. "C:\"
+			return paths[0];
+		}
+
+		if (paths.length == 2) {
+			// e.g. "C:\MyReallyLongFileName.ext" or "C:\MyReallyLongDirectoryName"
+			// return the complete file name since this is a minimum requirement,
+			// regardless of the maximum length allowed
+			return absoluteFileName;
+		}
+
+		StringBuilder sb = new StringBuilder();
+		sb.append(paths[0]);		// always add the first directory, which is usually the drive letter
+
+		// Keep the index of insertion into the string buffer
+		int insertIndex = sb.length();
+
+		sb.append(fs);
+		sb.append(paths[paths.length - 1]);		// append the file name or the last directory
+
+		maxLength -= 4;                      // -4 for "/..."
+
+		int currentLength = sb.length() - 4; // -4 for "/..."
+		int leftIndex = 1;                   //  1 to skip the root directory
+		int rightIndex = paths.length - 2;   // -1 for the file name or the last directory
+
+		boolean canAddFromLeft = true;
+		boolean canAddFromRight = true;
+
+		// Add each directory, the insertion is going in both direction: left and
+		// right, once a side can't be added, the other side is still continuing
+		// until both can't add anymore
+		while (true) {
+			if (!canAddFromLeft && !canAddFromRight)
+				break;
+
+			if (canAddFromRight) {
+				String rightDirectory = paths[rightIndex];
+				int rightLength = rightDirectory.length();
+
+				// Add the directory on the right side of the loop
+				if (currentLength + rightLength + 1 <= maxLength) {
+					sb.insert(insertIndex,     fs);
+					sb.insert(insertIndex + 1, rightDirectory);
+
+					currentLength += rightLength + 1;
+					rightIndex--;
+
+					// The right side is now overlapping the left side, that means
+					// we can't add from the right side anymore
+					if (leftIndex >= rightIndex) {
+						canAddFromRight = false;
+					}
+				} else {
+					canAddFromRight = false;
+				}
+			}
+
+			if (canAddFromLeft) {
+				String leftDirectory = paths[leftIndex];
+				int leftLength = leftDirectory.length();
+
+				// Add the directory on the left side of the loop
+				if (currentLength + leftLength + 1 <= maxLength) {
+					sb.insert(insertIndex,     fs);
+					sb.insert(insertIndex + 1, leftDirectory);
+
+					insertIndex += leftLength + 1;
+					currentLength += leftLength + 1;
+					leftIndex++;
+
+					// The left side is now overlapping the right side, that means
+					// we can't add from the left side anymore
+					if (leftIndex >= rightIndex) {
+						canAddFromLeft = false;
+					}
+				} else {
+					canAddFromLeft = false;
+				}
+			}
+		}
+
+		if (leftIndex <= rightIndex) {
+			sb.insert(insertIndex, fs);
+			sb.insert(insertIndex + 1, "...");
+		}
+
+		return sb.toString();
+	}
+
+
+	// ********** system properties **********
+
+	/**
+	 * Return a file representing the user's home directory.
+	 */
+	public static File userHomeDirectory() {
+		return new File(USER_HOME_DIRECTORY_NAME);
+	}
+
+	/**
+	 * Return a file representing the user's temporary directory.
+	 */
+	public static File userTemporaryDirectory() {
+		return new File(USER_TEMPORARY_DIRECTORY_NAME);
+	}
+
+	/**
+	 * Return a file representing the current working directory.
+	 */
+	public static File currentWorkingDirectory() {
+		return new File(CURRENT_WORKING_DIRECTORY_NAME);
+	}
+
+
+	// ********** miscellaneous **********
+
+	/**
+	 * Return only the files that fit the specified filter.
+	 */
+	public static Iterable<File> filter(Iterable<File> files, FileFilter fileFilter) {
+		return new FilteringIterable<File>(files, new FileFilterFilterAdapter(fileFilter));
+	}
+
+	/**
+	 * Return only the files that fit the specified filter.
+	 */
+	public static Iterator<File> filter(Iterator<File> files, FileFilter fileFilter) {
+		return new FilteringIterator<File>(files, new FileFilterFilterAdapter(fileFilter));
+	}
+
+	/**
+	 * Adapt a {@link FileFilter} to the {@link Filter} interface.
+	 */
+	public static class FileFilterFilterAdapter
+		extends Filter.Adapter<File>
+	{
+		private final FileFilter fileFilter;
+		public FileFilterFilterAdapter(FileFilter fileFilter) {
+			super();
+			this.fileFilter = fileFilter;
+		}
+		@Override
+		public boolean accept(File file) {
+			return this.fileFilter.accept(file);
+		}
+	}
+
+	/**
+	 * Return a file that is a re-specification of the specified
+	 * file, relative to the specified directory.<ul>
+	 * <li>Linux/Unix/Mac:<br>
+	 *     <code>convertToRelativeFile(/foo/bar/baz.java, /foo) => bar/baz.java</code>
+	 * <li>Windows:<br>
+	 *     <code>convertToRelativeFile(C:\foo\bar\baz.java, C:\foo) => bar/baz.java</code>
+	 * </ul>
+	 * The file can be either a file or a directory; the directory
+	 * <em>should</em> be a directory.
+	 * If the file is already relative or it cannot be made relative
+	 * to the directory, it will be returned unchanged.
+	 * <p>
+	 * <strong>NB:</strong> This method has been tested on Windows and Linux,
+	 * but not Mac (but the Mac is Unix-based these days, so
+	 * it shouldn't be a problem...).
+	 */
+	public static File convertToRelativeFile(final File file, final File dir) {
+		// check whether the file is already relative
+		if ( ! file.isAbsolute()) {
+			return file;		// return unchanged
+		}
+
+		File cFile = canonicalFile(file);
+		File cDir = canonicalFile(dir);
+
+		// the two are the same directory
+		if (cFile.equals(cDir)) {
+			return new File(".");
+		}
+
+		File[] filePathFiles = pathFiles(cFile);
+		File[] dirPathFiles = pathFiles(cDir);
+
+		// Windows only (?): the roots are different - e.g. D:\ vs. C:\
+		if ( ! dirPathFiles[0].equals(filePathFiles[0])) {
+			return file;		// return unchanged
+		}
+
+		// at this point we know the root is the same, now find how much is in common
+		int i = 0;		// this will point at the first miscompare
+		while ((i < dirPathFiles.length) && (i < filePathFiles.length)) {
+			if (dirPathFiles[i].equals(filePathFiles[i])) {
+				i++;
+			} else {
+				break;
+			}
+		}
+		// save our current position
+		int firstMismatch = i;
+
+		// check whether the file is ABOVE the directory: ../..
+		if (firstMismatch == filePathFiles.length) {
+			return relativeParentFile(dirPathFiles.length - firstMismatch);
+		}
+
+		// build a new file from the path beyond the matching portions
+		File diff = new File(filePathFiles[i].getName());
+		while (++i < filePathFiles.length) {
+			diff = new File(diff, filePathFiles[i].getName());
+		}
+
+		// check whether the file is BELOW the directory: subdir1/subdir2/file.ext
+		if (firstMismatch == dirPathFiles.length) {
+			return diff;
+		}
+
+		// the file must be a PEER of the directory: ../../subdir1/subdir2/file.ext
+		return new File(relativeParentFile(dirPathFiles.length - firstMismatch), diff.getPath());
+	}
+
+	/**
+	 * Return a file that is a re-specification of the specified
+	 * file, relative to the current working directory.
+	 * @see #convertToRelativeFile(File, File)
+	 */
+	public static File convertToRelativeFile(final File file) {
+		return convertToRelativeFile(file, currentWorkingDirectory());
+	}
+
+	/**
+	 * Return an array of files representing the path to the specified
+	 * file. For example:<br>
+	 * <code>
+	 *     C:/foo/bar/baz.txt => { C:/, C:/foo, C:/foo/bar, C:/foo/bar/baz.txt }
+	 * </code>
+	 */
+	private static File[] pathFiles(File file) {
+		List<File> path = new ArrayList<File>();
+		for (File f = file; f != null; f = f.getParentFile()) {
+			path.add(f);
+		}
+		Collections.reverse(path);
+		return path.toArray(new File[path.size()]);
+	}
+
+	/**
+	 * Return a file with the specified (non-zero) number of relative
+	 * file names, e.g. <code>relativeParentFile(3) => ../../..</code>.
+	 */
+	private static File relativeParentFile(int len) {
+		if (len <= 0) {
+			throw new IllegalArgumentException("length must be greater than zero: " + len);
+		}
+		File result = new File("..");
+		for (int i = len - 1; i-- > 0; ) {
+			result = new File(result, "..");
+		}
+		return result;
+	}
+
+	/**
+	 * Return a file that is a re-specification of the specified
+	 * file, absolute to the specified directory.<ul>
+	 * <li>Linux/Unix/Mac:<br>
+	 *     <code>convertToAbsoluteFile(bar/baz.java, /foo) => /foo/bar/baz.java</code>
+	 * <li>Windows:<br>
+	 *     <code>convertToAbsoluteFile(bar/baz.java, C:\foo) => C:\foo\bar\baz.java</code>
+	 * </ul>
+	 * The file can be either a file or a directory; the directory
+	 * <em>should</em> be a directory.
+	 * If the file is already absolute, it will be returned unchanged.
+	 * <p>
+	 * <strong>NB:</strong> This method has been tested on Windows and Linux,
+	 * but not Mac (but the Mac is Unix-based these days, so
+	 * it shouldn't be a problem...).
+	 */
+	public static File convertToAbsoluteFile(final File file, final File dir) {
+		return (file.isAbsolute()) ? file : canonicalFile(new File(dir, file.getPath()));
+	}
+
+	/**
+	 * Return a file that is a re-specification of the specified
+	 * file, absolute to the current working directory.
+	 * @see #convertToAbsoluteFile(File, File)
+	 */
+	public static File convertToAbsoluteFile(final File file) {
+		return convertToAbsoluteFile(file, currentWorkingDirectory());
+	}
+
+
+	// ********** constructor **********
+
+	/**
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private FileTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/IndentingPrintWriter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/IndentingPrintWriter.java
new file mode 100644
index 0000000..33f6aef
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/IndentingPrintWriter.java
@@ -0,0 +1,221 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.io.PrintWriter;
+import java.io.Writer;
+import org.eclipse.persistence.tools.utility.StringTools;
+
+/**
+ * Extend {@link PrintWriter} to automatically indent new lines and
+ * support using a line separator other than the current system default
+ * (i.e. the string returned from a call to
+ * <code>System.getProperty("line.separator")</code>).
+ * <p>
+ * 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.
+ */
+@SuppressWarnings("nls")
+public class IndentingPrintWriter
+	extends PrintWriter
+{
+	private final String indent;
+	private volatile int indentLevel;
+    private final String lineSeparator;
+	private volatile boolean needsIndent = true;
+
+
+	public static String DEFAULT_INDENT = "\t";
+
+
+	/**
+	 * Construct a writer that indents with tabs and uses the current system
+	 * default line separator.
+	 */
+	public IndentingPrintWriter(Writer out) {
+		this(out, DEFAULT_INDENT, StringTools.CR);
+	}
+
+	/**
+	 * Construct a writer that indents with the specified string and uses the
+	 * current system default line separator.
+	 */
+	public IndentingPrintWriter(Writer out, String indent) {
+		this(out, indent, 0, StringTools.CR);
+	}
+
+	/**
+	 * Construct a writer that indents with the specified string and uses the
+	 * specified line separator.
+	 */
+	public IndentingPrintWriter(Writer out, String indent, String lineSeparator) {
+		this(out, indent, 0, lineSeparator);
+	}
+
+	/**
+	 * Construct a writer that indents with the specified string,
+	 * begins with the specified indent level, and uses the
+	 * current system default line separator.
+	 */
+	public IndentingPrintWriter(Writer out, String indent, int initialIndentLevel) {
+		this(out, indent, initialIndentLevel, StringTools.CR);
+	}
+
+	/**
+	 * Construct a writer that indents with the specified string,
+	 * begins with the specified indent level, and uses the
+	 * specified line separator.
+	 */
+	public IndentingPrintWriter(Writer out, String indent, int initialIndentLevel, String lineSeparator) {
+		super(out);
+		if ((indent == null) || (lineSeparator == null)) {
+			throw new NullPointerException();
+		}
+		this.indent = indent;
+		this.indentLevel = initialIndentLevel;
+		this.lineSeparator = lineSeparator;
+	}
+
+	/**
+	 */
+	@Override
+	public void println() {
+		try {
+			synchronized (this.lock) {
+				this.println_();
+			}
+		} catch (InterruptedIOException ex) {
+			Thread.currentThread().interrupt();
+		} catch (IOException ex) {
+			this.setError();
+		}
+	}
+
+	/**
+	 * Print the appropriate line separator and
+	 * set flag so following line is indented.
+	 * Pre-condition: synchronized
+	 */
+	private void println_() throws IOException {
+		if (this.out == null) {
+			throw new IOException("Stream closed");
+		}
+		this.out.write(this.lineSeparator);
+		this.needsIndent = true;
+	}
+
+	/**
+	 * Print the appropriate indent.
+	 * Pre-condition: synchronized
+	 */
+	private void printIndent() {
+		if (this.needsIndent) {
+			this.needsIndent = false;
+			for (int i = this.indentLevel; i-- > 0; ) {
+				this.print(this.indent);
+			}
+		}
+	}
+
+	/**
+	 * Write a portion of an array of characters.
+	 */
+	@Override
+	public void write(char buf[], int off, int len) {
+		synchronized (this.lock) {
+			this.printIndent();
+			super.write(buf, off, len);
+		}
+	}
+
+	/**
+	 * Write a single character.
+	 */
+	@Override
+	public void write(int c) {
+		synchronized (this.lock) {
+			this.printIndent();
+			super.write(c);
+		}
+	}
+
+	/**
+	 * Write a portion of a string.
+	 */
+	@Override
+	public void write(String s, int off, int len) {
+		synchronized (this.lock) {
+			this.printIndent();
+			super.write(s, off, len);
+		}
+	}
+
+	/**
+	 * Bump the indent level.
+	 */
+	public void indent() {
+		this.incrementIndentLevel();
+	}
+
+	/**
+	 * Decrement the indent level.
+	 */
+	public void undent() {
+		this.decrementIndentLevel();
+	}
+
+	/**
+	 * Bump the indent level.
+	 */
+	public void incrementIndentLevel() {
+		synchronized (this.lock) {
+			this.indentLevel++;
+		}
+	}
+
+	/**
+	 * Decrement the indent level.
+	 */
+	public void decrementIndentLevel() {
+		synchronized (this.lock) {
+			this.indentLevel--;
+		}
+	}
+
+	/**
+	 * Return the current indent level.
+	 */
+	public int getIndentLevel() {
+		synchronized (this.lock) {
+			return this.indentLevel;
+		}
+	}
+
+	/**
+	 * Allow the indent level to be set directly.
+	 * Return the previous indent level.
+	 */
+	public int setIndentLevel(int indentLevel) {
+		synchronized (this.lock) {
+			int old = this.indentLevel;
+			this.indentLevel = indentLevel;
+			return old;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/InvalidInputStream.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/InvalidInputStream.java
new file mode 100644
index 0000000..b9939db
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/InvalidInputStream.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.InputStream;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * This input stream will throw an exception
+ * any time it is read from. Marking or closing the stream
+ * will <em>not</em> trigger an exception.
+ */
+public final class InvalidInputStream
+	extends InputStream
+{
+	// singleton
+	private static InputStream INSTANCE = new InvalidInputStream();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static synchronized InputStream instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private InvalidInputStream() {
+		super();
+	}
+
+	@Override
+	public int read() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.singletonToString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/InvalidOutputStream.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/InvalidOutputStream.java
new file mode 100644
index 0000000..0ec238e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/InvalidOutputStream.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.OutputStream;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * This output stream will throw an exception
+ * any time it is written to. Flushing or closing the stream
+ * will <em>not</em> trigger an exception.
+ */
+public final class InvalidOutputStream
+	extends OutputStream
+{
+	// singleton
+	private static OutputStream INSTANCE = new InvalidOutputStream();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static synchronized OutputStream instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private InvalidOutputStream() {
+		super();
+	}
+
+	@Override
+	public void write(int b) {
+		// we don't throw an IOException because that is swallowed by PrintStream
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.singletonToString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/InvalidReader.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/InvalidReader.java
new file mode 100644
index 0000000..1675097
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/InvalidReader.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.IOException;
+import java.io.Reader;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * This reader will throw an exception
+ * any time it is read from. Closing the reader
+ * will <em>not</em> trigger an exception.
+ */
+public final class InvalidReader
+	extends Reader
+{
+	// singleton
+	private static Reader INSTANCE = new InvalidReader();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static synchronized Reader instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private InvalidReader() {
+		super();
+	}
+
+	@Override
+	public int read(char[] cbuf, int off, int len) throws IOException {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void close() throws IOException {
+		// do nothing
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.singletonToString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/InvalidWriter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/InvalidWriter.java
new file mode 100644
index 0000000..39eef11
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/InvalidWriter.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.IOException;
+import java.io.Writer;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * This writer will throw an exception
+ * any time it is written to. Flushing or closing the writer
+ * will <em>not</em> trigger an exception.
+ */
+public final class InvalidWriter
+	extends Writer
+{
+	// singleton
+	private static Writer INSTANCE = new InvalidWriter();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static synchronized Writer instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private InvalidWriter() {
+		super();
+	}
+
+	@Override
+	public void write(char[] cbuf, int off, int len) throws IOException {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void flush() throws IOException {
+		// do nothing
+	}
+
+	@Override
+	public void close() throws IOException {
+		// do nothing
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.singletonToString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/NullInputStream.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/NullInputStream.java
new file mode 100644
index 0000000..857a093
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/NullInputStream.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * This is an input stream that does nothing.
+ * It returns nothing.
+ * Performance should be pretty good....
+ */
+public final class NullInputStream
+	extends InputStream
+{
+	// singleton
+	private static InputStream INSTANCE = new NullInputStream();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static synchronized InputStream instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private NullInputStream() {
+		super();
+	}
+
+	@Override
+	public int read() throws IOException {
+		return -1;
+	}
+
+	@Override
+	public int read(byte[] b) throws IOException {
+		return -1;
+	}
+
+	@Override
+	public int read(byte[] b, int off, int len) throws IOException {
+		return -1;
+	}
+
+	@Override
+	public long skip(long n) throws IOException {
+		return 0;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.singletonToString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/NullOutputStream.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/NullOutputStream.java
new file mode 100644
index 0000000..2f06175
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/NullOutputStream.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * This is an output stream that does nothing.
+ * Everything is thrown into the "bit bucket".
+ * Performance should be pretty good....
+ */
+public final class NullOutputStream
+	extends OutputStream
+{
+	// singleton
+	private static OutputStream INSTANCE = new NullOutputStream();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static synchronized OutputStream instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private NullOutputStream() {
+		super();
+	}
+
+	@Override
+	public void write(int b) throws IOException {
+		// do nothing
+	}
+
+	@Override
+	public void write(byte[] b) throws IOException {
+		// do nothing
+	}
+
+	@Override
+	public void write(byte[] b, int off, int len) throws IOException {
+		// do nothing
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.singletonToString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/NullReader.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/NullReader.java
new file mode 100644
index 0000000..8193869
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/NullReader.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.Reader;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * This is a reader that does nothing.
+ * It returns nothing.
+ * Performance should be pretty good....
+ */
+public final class NullReader
+	extends Reader
+{
+	// singleton
+	private static Reader INSTANCE = new NullReader();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static synchronized Reader instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private NullReader() {
+		super();
+	}
+
+	@Override
+	public void close() {
+		// do nothing
+	}
+
+	@Override
+	public int read() {
+		return -1;
+	}
+
+	@Override
+	public int read(char[] cbuf) {
+		return -1;
+	}
+
+	@Override
+	public int read(char[] cbuf, int off, int len) {
+		return -1;
+	}
+
+	@Override
+	public long skip(long n) {
+		return 0;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.singletonToString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/NullWriter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/NullWriter.java
new file mode 100644
index 0000000..93a9b51
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/NullWriter.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.Writer;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * This is a writer that does nothing.
+ * Everything is thrown into the "bit bucket".
+ * Performance should be pretty good....
+ */
+public final class NullWriter
+	extends Writer
+{
+	// singleton
+	private static Writer INSTANCE = new NullWriter();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static synchronized Writer instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private NullWriter() {
+		super();
+	}
+
+	@Override
+	public void write(char[] cbuf, int off, int len) {
+		// do nothing
+	}
+
+	@Override
+	public void flush() {
+		// do nothing
+	}
+
+	@Override
+	public void close() {
+		// do nothing
+	}
+
+	@Override
+	public void write(char[] cbuf) {
+		// do nothing
+	}
+
+	@Override
+	public void write(int c) {
+		// do nothing
+	}
+
+	@Override
+	public void write(String str, int off, int len) {
+		// do nothing
+	}
+
+	@Override
+	public void write(String str) {
+		// do nothing
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.singletonToString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/Pipe.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/Pipe.java
new file mode 100644
index 0000000..3c232c3
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/Pipe.java
@@ -0,0 +1,424 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Improved implementation of the JDK's piped streams. This pipe allows
+ * multiple threads to write and read the pipe and does not poll the pipe
+ * and does not kill the pipe if a thread writing to it dies.
+ */
+@SuppressWarnings("nls")
+public class Pipe {
+
+	private final int bufferSize;
+	private final byte[] buffer;
+	private final long timeout;
+
+	private final InputStream in = new InputStreamAdapter();
+	private final OutputStream out = new OutputStreamAdapter();
+
+	private boolean readLap = false;
+	private int readIndex = 0;
+
+	private boolean writeLap = false;
+	private int writeIndex = 0;
+
+	private boolean inputStreamClosed = false;
+	private boolean outputStreamClosed = false;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a pipe with the default buffer size (2048) and time-out
+	 * value (zero, which means no time-out).
+	 */
+	public Pipe() {
+		this(2048);
+	}
+
+	/**
+	 * Construct a pipe with the specified buffer size and the default
+	 * time-out value (zero, which means no time-out).
+	 */
+	public Pipe(int bufferSize) {
+		this(bufferSize, 0L);
+	}
+
+	/**
+	 * Construct a pipe with the specified buffer size and
+	 * time-out value. A time-out value of zero will cause reads to
+	 * block indefinitely.
+	 */
+	public Pipe(int bufferSize, long timeout) {
+		super();
+		this.bufferSize = bufferSize;
+		this.buffer = new byte[bufferSize];
+		this.timeout = timeout;
+	}
+
+
+	// ********** accessors **********
+
+	/**
+	 * Return the input stream half of the pipe.
+	 * This stream will return the data written to
+	 * the output stream half of the pipe.
+	 */
+	public InputStream getInputStream() {
+		return this.in;
+	}
+
+	/**
+	 * Return the output stream half of the pipe.
+	 * Data written to this stream will be returned
+	 * by the input stream half of the pipe.
+	 */
+	public OutputStream getOutputStream() {
+		return this.out;
+	}
+
+
+	// ********** reading **********
+
+	/**
+	 * Return the number of bytes currently available for reading
+	 * from the input stream.
+	 */
+	synchronized int available() {
+		if (this.inputStreamClosed) {
+			return 0;
+		}
+		return this.bytesInPipe();
+	}
+
+	/**
+	 * Return the number of bytes currently available for reading
+	 * from the input stream.
+	 */
+	private int bytesInPipe() {
+		int diff = this.writeIndex - this.readIndex;
+		if (diff == 0) {
+			// the write is either at the same position or a complete lap ahead
+			return (this.writeLap == this.readLap) ? 0 : this.bufferSize;
+		}
+		return (diff > 0) ? diff : diff + this.bufferSize;
+	}
+
+	/**
+	 * Read a byte from the pipe. This method will block
+	 * until either a byte is available or a time-out occurs.
+	 * If a time-out occurs, throw an InterruptedIOException.
+	 */
+	synchronized int read() throws IOException {
+		if (this.inputStreamClosed) {
+			throw new IOException("Pipe closed");
+		}
+		// wait for a byte to become available
+		long stop = System.currentTimeMillis() + this.timeout;
+		long remaining = this.timeout;
+		while (this.bytesInPipe() == 0) {
+			if (this.outputStreamClosed) {
+				return -1; // if the pipe is empty and the output stream is closed, we are done
+			}
+			try {
+				this.wait(remaining);
+			} catch (InterruptedException ex) {
+				throw new InterruptedIOException();
+			}
+			if (this.timeout > 0L) {
+				remaining = stop - System.currentTimeMillis();
+				if (remaining <= 0L) {
+					throw new InterruptedIOException(); // a time-out occurred
+				}
+			}
+			if (this.inputStreamClosed) {
+				throw new IOException("Pipe closed"); // the pipe might've been closed while we were waiting //$NON-NLS-1$
+			}
+		}
+		// a byte is available and the input stream is still open
+		byte b = this.buffer[this.readIndex];
+		this.readIndex++;
+		if (this.readIndex == this.bufferSize) {
+			this.readLap = ! this.readLap;
+			this.readIndex = 0;
+		}
+
+		// notify any waiting writers that there is free space in the pipe
+		this.notifyAll();
+
+		return b & 0xFF;
+	}
+
+	/**
+	 * Read the specified number of bytes from the pipe and
+	 * into the specified byte array at the specified offset.
+	 * Return the actual number of bytes read.
+	 * This method will block until either a byte is available
+	 * or a time-out occurs. If a time-out occurs, throw an
+	 * InterruptedIOException.
+	 */
+	synchronized int read(byte[] b, int off, int len) throws IOException {
+		if (this.inputStreamClosed) {
+			throw new IOException("Pipe closed");
+		}
+		// wait for a byte to become available
+		long stop = System.currentTimeMillis() + this.timeout;
+		long remaining = this.timeout;
+		int bytesInPipe = this.bytesInPipe();
+		while (bytesInPipe == 0) {
+			if (this.outputStreamClosed) {
+				return -1; // if the pipe is empty and the output stream is closed, we are done
+			}
+			try {
+				this.wait(remaining);
+			} catch (InterruptedException ex) {
+				throw new InterruptedIOException();
+			}
+			if (this.timeout > 0L) {
+				remaining = stop - System.currentTimeMillis();
+				if (remaining <= 0L) {
+					throw new InterruptedIOException(); // a time-out occurred
+				}
+			}
+			if (this.inputStreamClosed) {
+				throw new IOException("Pipe closed"); // the pipe might've been closed while we were waiting //$NON-NLS-1$
+			}
+			bytesInPipe = this.bytesInPipe();
+		}
+		// some bytes are available and the input stream is still open
+		int bytesRead = (len > bytesInPipe) ? bytesInPipe : len;
+		int copyLength1 = this.bufferSize - this.readIndex;
+		if (copyLength1 > bytesRead) {
+			copyLength1 = bytesRead;
+		}
+		System.arraycopy(this.buffer, this.readIndex, b, off, copyLength1);
+		this.readIndex += copyLength1;
+		if (this.readIndex == this.bufferSize) {
+			this.readLap = ! this.readLap;
+			this.readIndex = 0;
+		}
+
+		int copyLength2 = bytesRead - copyLength1;
+		if (copyLength2 > 0) {
+			System.arraycopy(this.buffer, 0, b, off + copyLength1, copyLength2);
+			this.readIndex += copyLength2;
+		}
+
+		// notify any waiting writers that there is free space in the pipe
+		this.notifyAll();
+
+		return bytesRead;
+	}
+
+	/**
+	 * Close the input stream half of the pipe. This will effectively
+	 * close the output stream half of the pipe also, preventing any
+	 * further data from being written to the pipe.
+	 */
+	synchronized void closeInputStream() {
+		if (this.inputStreamClosed) {
+			throw new IllegalStateException("InputStream already closed");
+		}
+		this.inputStreamClosed = true;
+		this.outputStreamClosed = true;
+		this.notifyAll();
+	}
+
+
+	// ********** writing **********
+
+	/**
+	 * Return the number of bytes currently available in the buffer
+	 * for writing.
+	 */
+	private int freeSpace() {
+		int diff = this.readIndex - this.writeIndex;
+		if (diff == 0) {
+			// the write is either at the same position or a complete lap ahead
+			return (this.writeLap == this.readLap) ? this.bufferSize : 0;
+		}
+		return (diff > 0) ? diff : diff + this.bufferSize;
+	}
+
+	/**
+	 * Write the specified byte to the pipe. This method will block
+	 * indefinitely if the pipe is full.
+	 */
+	synchronized void write(int b) throws IOException {
+		if (this.outputStreamClosed) {
+			throw new IOException("Pipe closed");
+		}
+		// wait for some free space
+		while (this.freeSpace() == 0) {
+			try {
+				this.wait();
+			} catch (InterruptedException ex) {
+				throw new InterruptedIOException();
+			}
+			if (this.outputStreamClosed) {
+				throw new IOException("Pipe closed"); // the pipe might've been closed while we were waiting //$NON-NLS-1$
+			}
+		}
+		// free space is available and the output stream is still open
+		this.buffer[this.writeIndex] = (byte) b;
+		this.writeIndex++;
+		if (this.writeIndex == this.bufferSize) {
+			this.writeLap = ! this.writeLap;
+			this.writeIndex = 0;
+		}
+
+		this.notifyAll();
+	}
+
+	/**
+	 * Write the specified bytes to the pipe. This method will block
+	 * indefinitely if the pipe is full.
+	 */
+	synchronized void write(byte[] b, int off, int len) throws IOException {
+		if (this.outputStreamClosed) {
+			throw new IOException("Pipe closed");
+		}
+		while (len > 0) {
+			// wait for some free space
+			int freeSpace = this.freeSpace();
+			while (freeSpace == 0) {
+				try {
+					this.wait();
+				} catch (InterruptedException ex) {
+					throw new InterruptedIOException();
+				}
+				if (this.outputStreamClosed) {
+					throw new IOException("Pipe closed"); // the pipe might've been closed while we were waiting //$NON-NLS-1$
+				}
+				freeSpace = this.freeSpace();
+			}
+			// free space is available and the output stream is still open;
+			// calculate how many bytes we can put in the buffer this pass
+			int tempLength = (len > freeSpace) ? freeSpace : len;
+
+			int copyLength1 = this.bufferSize - this.writeIndex;
+			if (copyLength1 > tempLength) {
+				copyLength1 = tempLength;
+			}
+			System.arraycopy(b, off, this.buffer, this.writeIndex, copyLength1);
+			this.writeIndex += copyLength1;
+			if (this.writeIndex == this.bufferSize) {
+				this.writeLap = ! this.writeLap;
+				this.writeIndex = 0;
+			}
+
+			int copyLength2 = tempLength - copyLength1;
+			if (copyLength2 > 0) {
+				System.arraycopy(b, off + copyLength1, this.buffer, 0, copyLength2);
+				this.writeIndex += copyLength2;
+			}
+			// move to the next chunk of bytes
+			off += tempLength;
+			len -= tempLength;
+
+			// notify any waiting readers that there is data to be read from the pipe
+			this.notifyAll();
+		}
+	}
+
+	/**
+	 * Close the output stream half of the pipe. Although no more data
+	 * can be written to the pipe after this method is called, the input
+	 * stream half of the pipe can remain open and will return the data
+	 * still remaining in the buffer.
+	 */
+	synchronized void closeOutputStream() {
+		if (this.outputStreamClosed) {
+			throw new IllegalStateException("OutputStream already closed");
+		}
+		this.outputStreamClosed = true;
+		this.notifyAll();
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this);
+	}
+
+
+	// ********** inner classes **********
+
+	/**
+	 * Adapt the pipe to the {@link InputStream} specification.
+	 */
+	private class InputStreamAdapter
+		extends InputStream
+	{
+		InputStreamAdapter() {
+			super();
+		}
+
+		@Override
+		public int available() throws IOException {
+			return Pipe.this.available();
+		}
+
+		@Override
+		public int read() throws IOException {
+			return Pipe.this.read();
+		}
+
+		@Override
+		public int read(byte[] b, int off, int len) throws IOException {
+			return Pipe.this.read(b, off, len);
+		}
+
+		@Override
+		public void close() throws IOException {
+			Pipe.this.closeInputStream();
+		}
+	}
+
+
+	/**
+	 * Adapt the pipe to the {@link OutputStream} specification.
+	 */
+	private class OutputStreamAdapter
+		extends OutputStream
+	{
+		OutputStreamAdapter() {
+			super();
+		}
+
+		@Override
+		public void write(int b) throws IOException {
+			Pipe.this.write(b);
+		}
+
+		@Override
+		public void write(byte[] b, int off, int len) throws IOException {
+			Pipe.this.write(b, off, len);
+		}
+
+		@Override
+		public void close() throws IOException {
+			Pipe.this.closeOutputStream();
+		}
+	}
+}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/StringBufferWriter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/StringBufferWriter.java
new file mode 100644
index 0000000..aa0244b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/StringBufferWriter.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.Writer;
+
+/**
+ * Silly Sun. Why {@link java.io.StringWriter} does not allow us to pass in a
+ * {@link StringBuffer} is beyond me....
+ *
+ * @see java.io.StringWriter
+ */
+public class StringBufferWriter
+	extends Writer
+{
+	private StringBuffer sb;
+
+	/**
+	 * Construct a writer on the specified string buffer.
+	 */
+	public StringBufferWriter(StringBuffer sb) {
+		super();
+		if (sb == null) {
+			throw new NullPointerException();
+		}
+		this.sb = sb;
+		this.lock = sb;
+	}
+
+	/**
+	 * Construct a writer on a string buffer with the specified initial size.
+	 */
+	public StringBufferWriter(int initialSize) {
+		this(new StringBuffer(initialSize));
+	}
+
+	/**
+	 * Construct a writer on a string buffer.
+	 */
+	public StringBufferWriter() {
+		this(new StringBuffer());
+	}
+
+	@Override
+	public void write(int c) {
+		this.sb.append((char) c);
+	}
+
+	@Override
+	public void write(char cbuf[], int off, int len) {
+		if (len != 0) {
+			this.sb.append(cbuf, off, len);
+		}
+	}
+
+	@Override
+	public void write(String str) {
+		this.sb.append(str);
+	}
+
+	@Override
+	public void write(String str, int off, int len)  {
+		this.sb.append(str, off, off + len);
+	}
+
+	public StringBuffer getBuffer() {
+		return this.sb;
+	}
+
+	@Override
+	public void flush() {
+		// do nothing
+	}
+
+	@Override
+	public void close() {
+		// do nothing
+	}
+
+	@Override
+	public String toString() {
+		return this.sb.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/StringBuilderWriter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/StringBuilderWriter.java
new file mode 100644
index 0000000..c2d18dc
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/StringBuilderWriter.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.Writer;
+
+/**
+ * Silly Sun. Why {@link java.io.StringWriter} does not allow us to pass in a
+ * {@link StringBuilder} is beyond me....
+ *
+ * @see java.io.StringWriter
+ */
+public class StringBuilderWriter
+	extends Writer
+{
+	private StringBuilder sb;
+
+	/**
+	 * Construct a writer on the specified string builder.
+	 */
+	public StringBuilderWriter(StringBuilder sb) {
+		super();
+		if (sb == null) {
+			throw new NullPointerException();
+		}
+		this.sb = sb;
+		this.lock = sb;
+	}
+
+	/**
+	 * Construct a writer on the specified string builder.
+	 */
+	public StringBuilderWriter(int initialSize) {
+		this(new StringBuilder(initialSize));
+	}
+
+	/**
+	 * Construct a writer on the specified string builder.
+	 */
+	public StringBuilderWriter() {
+		this(new StringBuilder());
+	}
+
+	@Override
+	public void write(int c) {
+		this.sb.append((char) c);
+	}
+
+	@Override
+	public void write(char cbuf[], int off, int len) {
+		if (len != 0) {
+			this.sb.append(cbuf, off, len);
+		}
+	}
+
+	@Override
+	public void write(String str) {
+		this.sb.append(str);
+	}
+
+	@Override
+	public void write(String str, int off, int len)  {
+		this.sb.append(str, off, off + len);
+	}
+
+	public StringBuilder getBuilder() {
+		return this.sb;
+	}
+
+	@Override
+	public void flush() {
+		// do nothing
+	}
+
+	@Override
+	public void close() {
+		// do nothing
+	}
+
+	@Override
+	public String toString() {
+		return this.sb.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/WriterTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/WriterTools.java
new file mode 100644
index 0000000..679590c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/io/WriterTools.java
@@ -0,0 +1,1871 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.io;
+
+import java.io.IOException;
+import java.io.Writer;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.CharArrayTools;
+import org.eclipse.persistence.tools.utility.CharacterTools;
+import org.eclipse.persistence.tools.utility.StringTools;
+
+/**
+ * {@link Writer} utility methods.
+ *
+ * @see StringTools
+ */
+@SuppressWarnings("nls")
+public final class WriterTools {
+
+	// ********** padding/truncating/centering **********
+
+	/**
+	 * Center the specified string in the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with spaces at
+	 * each end.
+	 */
+	public static void center(Writer writer, String string, int length) throws IOException {
+		center(writer, string, length, ' ');
+	}
+
+	/**
+	 * @see #center(Writer, String, int)
+	 */
+	public static void center(Writer writer, char[] string, int length) throws IOException {
+		center(writer, string, length, ' ');
+	}
+
+	/**
+	 * Center the specified string in the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at each end.
+	 */
+	public static void center(Writer writer, String string, int length, char c) throws IOException {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length();
+		if (stringLength == length) {
+			writer.write(string);
+		} else if (stringLength > length) {
+			int begin = (stringLength - length) >> 1; // take fewer characters off the front
+			writer.write(string, begin, length);
+		} else {
+			int begin = (length - stringLength) >> 1; // add fewer characters to the front
+			fill(writer, begin, c);
+			writer.append(string);
+			fill(writer, length - (begin + stringLength), c);
+		}
+	}
+
+	/**
+	 * @see #center(Writer, String, int, char)
+	 */
+	public static void center(Writer writer, char[] string, int length, char c) throws IOException {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length;
+		if (stringLength == length) {
+			writer.write(string);
+		} else if (stringLength > length) {
+			int begin = (stringLength - length) >> 1; // take fewer characters off the front
+			writer.write(string, begin, length);
+		} else {
+			int begin = (length - stringLength) >> 1; // add fewer characters to the front
+			fill(writer, begin, c);
+			writer.write(string);
+			fill(writer, length - (begin + stringLength), c);
+		}
+	}
+
+	/**
+	 * Pad the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with spaces
+	 * at the end.
+	 */
+	public static void pad(Writer writer, String string, int length) throws IOException {
+		pad(writer, string, length, ' ');
+	}
+
+	/**
+	 * @see #pad(Writer, String, int)
+	 */
+	public static void pad(Writer writer, char[] string, int length) throws IOException {
+		pad(writer, string, length, ' ');
+	}
+
+	/**
+	 * Pad the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at the end.
+	 */
+	public static void pad(Writer writer, String string, int length, char c) throws IOException {
+		int stringLength = string.length();
+		if (stringLength > length) {
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
+		}
+		if (stringLength == length) {
+			writer.write(string);
+		} else {
+			pad_(writer, string, length, c);
+		}
+	}
+
+	/**
+	 * @see #pad(Writer, String, int, char)
+	 */
+	public static void pad(Writer writer, char[] string, int length, char c) throws IOException {
+		int stringLength = string.length;
+		if (stringLength > length) {
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
+		}
+		if (stringLength == length) {
+			writer.write(string);
+		} else {
+			pad_(writer, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * Pad or truncate the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with spaces at
+	 * the end.
+	 */
+	public static void fit(Writer writer, String string, int length) throws IOException {
+		fit(writer, string, length, ' ');
+	}
+
+	/**
+	 * @see #fit(Writer, String, int)
+	 */
+	public static void fit(Writer writer, char[] string, int length) throws IOException {
+		fit(writer, string, length, ' ');
+	}
+
+	/**
+	 * Pad or truncate the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, truncate it.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at the end.
+	 */
+	public static void fit(Writer writer, String string, int length, char c) throws IOException {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length();
+		if (stringLength == length) {
+			writer.write(string);
+		} else if (stringLength > length) {
+			writer.write(string, 0, length);
+		} else {
+			pad_(writer, string, length, c);
+		}
+	}
+
+	/**
+	 * @see #fit(Writer, String, int, char)
+	 */
+	public static void fit(Writer writer, char[] string, int length, char c) throws IOException {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length;
+		if (stringLength == length) {
+			writer.write(string);
+		} else if (stringLength > length) {
+			writer.write(string, 0, length);
+		} else {
+			pad_(writer, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * Pad the specified string without validating the parms.
+	 */
+	private static void pad_(Writer writer, String string, int length, char c) throws IOException {
+		writer.write(string);
+		fill(writer, string, length, c);
+	}
+
+	/**
+	 * Add enough characters to the specified writer to compensate for
+	 * the difference between the specified string and specified length.
+	 */
+	private static void fill(Writer writer, String string, int length, char c) throws IOException {
+		fill(writer, string.length(), length, c);
+	}
+
+	/**
+	 * Pad the specified string without validating the parms.
+	 */
+	private static void pad_(Writer writer, char[] string, int stringLength, int length, char c) throws IOException {
+		writer.write(string);
+		fill(writer, stringLength, length, c);
+	}
+
+	/**
+	 * Add enough characters to the specified writer to compensate for
+	 * the difference between the specified string and specified length.
+	 */
+	private static void fill(Writer writer, int stringLength, int length, char c) throws IOException {
+		fill(writer, length - stringLength, c);
+	}
+
+	/**
+	 * Add the specified length of characters to the specified writer.
+	 */
+	private static void fill(Writer writer, int length, char c) throws IOException {
+		writer.write(ArrayTools.fill(new char[length], c));
+	}
+
+	/**
+	 * Pad the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with zeros
+	 * at the front.
+	 */
+	public static void zeroPad(Writer writer, String string, int length) throws IOException {
+		frontPad(writer, string, length, '0');
+	}
+
+	/**
+	 * @see #zeroPad(Writer, String, int)
+	 */
+	public static void zeroPad(Writer writer, char[] string, int length) throws IOException {
+		frontPad(writer, string, length, '0');
+	}
+
+	/**
+	 * Pad the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, throw an
+	 * {@link IllegalArgumentException}.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at the front.
+	 */
+	public static void frontPad(Writer writer, String string, int length, char c) throws IOException {
+		int stringLength = string.length();
+		if (stringLength > length) {
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
+		}
+		if (stringLength == length) {
+			writer.write(string);
+		} else {
+			frontPad_(writer, string, length, c);
+		}
+	}
+
+	/**
+	 * @see #frontPad(Writer, String, int, char)
+	 */
+	public static void frontPad(Writer writer, char[] string, int length, char c) throws IOException {
+		int stringLength = string.length;
+		if (stringLength > length) {
+			throw new IllegalArgumentException("String is too long: " + stringLength + " > " + length);
+		}
+		if (stringLength == length) {
+			writer.write(string);
+		} else {
+			frontPad_(writer, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * Pad or truncate the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, append only the last
+	 * part of the string.
+	 * If the string is shorter than the specified length, pad it with zeros
+	 * at the front.
+	 */
+	public static void zeroFit(Writer writer, String string, int length) throws IOException {
+		frontFit(writer, string, length, '0');
+	}
+
+	/**
+	 * @see #zeroFit(Writer, String, int)
+	 */
+	public static void zeroFit(Writer writer, char[] string, int length) throws IOException {
+		frontFit(writer, string, length, '0');
+	}
+
+	/**
+	 * Pad or truncate the specified string to the specified length.
+	 * If the string is already the specified length, append it unchanged.
+	 * If the string is longer than the specified length, append only the last
+	 * part of the string.
+	 * If the string is shorter than the specified length, pad it with the
+	 * specified character at the front.
+	 */
+	public static void frontFit(Writer writer, String string, int length, char c) throws IOException {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length();
+		if (stringLength == length) {
+			writer.write(string);
+		} else if (stringLength > length) {
+			writer.write(string, stringLength - length, length);
+		} else {
+			frontPad_(writer, string, length, c);
+		}
+	}
+
+	/**
+	 * @see #frontFit(Writer, String, int, char)
+	 */
+	public static void frontFit(Writer writer, char[] string, int length, char c) throws IOException {
+		if (length == 0) {
+			return;
+		}
+		int stringLength = string.length;
+		if (stringLength == length) {
+			writer.write(string);
+		} else if (stringLength > length) {
+			writer.write(string, stringLength - length, length);
+		} else {
+			frontPad_(writer, string, stringLength, length, c);
+		}
+	}
+
+	/**
+	 * Pad the specified string without validating the parms.
+	 */
+	private static void frontPad_(Writer writer, String string, int length, char c) throws IOException {
+		fill(writer, string, length, c);
+		writer.write(string);
+	}
+
+	/**
+	 * Pad the specified string without validating the parms.
+	 */
+	private static void frontPad_(Writer writer, char[] string, int stringLength, int length, char c) throws IOException {
+		fill(writer, stringLength, length, c);
+		writer.write(string);
+	}
+
+
+	// ********** separating **********
+
+	/**
+	 * Separate the segments of the specified string with the specified
+	 * separator:<p>
+	 * <code>
+	 * separate("012345", '-', 2) => "01-23-45"
+	 * </code>
+	 */
+	public static void separate(Writer writer, String string, char separator, int segmentSize) throws IOException {
+		if (segmentSize <= 0) {
+			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
+		}
+		int stringLength = string.length();
+		if (stringLength <= segmentSize) {
+			writer.write(string);
+		} else {
+			separate(writer, string, separator, segmentSize, stringLength);
+		}
+	}
+
+	/**
+	 * Pre-conditions: string is longer than segment size; segment size is positive
+	 */
+	private static void separate(Writer writer, String string, char separator, int segmentSize, int stringLength) throws IOException {
+		int segCount = 0;
+		for (int i = 0; i < stringLength; i++) {
+			char c = string.charAt(i);
+			if (segCount == segmentSize) {
+				writer.write(separator);
+				segCount = 0;
+			}
+			segCount++;
+			writer.write(c);
+		}
+	}
+
+	/**
+	 * @see #separate(Writer, String, char, int)
+	 */
+	public static void separate(Writer writer, char[] string, char separator, int segmentSize) throws IOException {
+		if (segmentSize <= 0) {
+			throw new IllegalArgumentException("segment size must be positive: " + segmentSize);
+		}
+		int stringLength = string.length;
+		if (stringLength <= segmentSize) {
+			writer.write(string);
+		} else {
+			separate(writer, string, separator, segmentSize, stringLength);
+		}
+	}
+
+	/**
+	 * Pre-conditions: string is longer than segment size; segment size is positive
+	 */
+	private static void separate(Writer writer, char[] string, char separator, int segmentSize, int stringLength) throws IOException {
+		int segCount = 0;
+		for (int i = 0; i < stringLength; i++) {
+			char c = string[i];
+			if (segCount == segmentSize) {
+				writer.write(separator);
+				segCount = 0;
+			}
+			segCount++;
+			writer.write(c);
+		}
+	}
+
+
+	// ********** delimiting/quoting **********
+
+	/**
+	 * Delimit the specified string with double quotes.
+	 * Escape any occurrences of a double quote in the string with another
+	 * double quote.
+	 */
+	public static void quote(Writer writer, String string) throws IOException {
+		delimit(writer, string, CharacterTools.QUOTE);
+	}
+
+	/**
+	 * @see #quote(Writer, String)
+	 */
+	public static void quote(Writer writer, char[] string) throws IOException {
+		delimit(writer, string, CharacterTools.QUOTE);
+	}
+
+	/**
+	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
+	 * the delimiter at the front and back of the resulting string.
+	 * Escape any occurrences of the delimiter in the string with another delimiter.
+	 */
+	public static void delimit(Writer writer, String string, char delimiter) throws IOException {
+		writer.write(delimiter);
+		int stringLength = string.length();
+		for (int i = 0; i < stringLength; i++) {
+			char c = string.charAt(i);
+			if (c == delimiter) {
+				writer.write(c);
+			}
+			writer.write(c);
+		}
+		writer.write(delimiter);
+	}
+
+	/**
+	 * @see #delimit(Writer, String, char)
+	 */
+	public static void delimit(Writer writer, char[] string, char delimiter) throws IOException {
+		writer.write(delimiter);
+		for (char c : string) {
+			if (c == delimiter) {
+				writer.write(c);
+			}
+			writer.write(c);
+		}
+		writer.write(delimiter);
+	}
+
+	/**
+	 * Delimit the specified string with the specified delimiter; i.e. put a copy of
+	 * the delimiter at the front and back of the resulting string.
+	 * Escape any occurrences of a single-character delimiter in the string with
+	 * another delimiter.
+	 */
+	public static void delimit(Writer writer, String string, String delimiter) throws IOException {
+		int delimiterLength = delimiter.length();
+		switch (delimiterLength) {
+			case 0:
+				writer.write(string);
+				break;
+			case 1:
+				delimit(writer, string, delimiter.charAt(0));
+				break;
+			default:
+				delimit(writer, string, delimiter, delimiterLength);
+				break;
+		}
+	}
+
+	/**
+	 * No parm check
+	 */
+	private static void delimit(Writer writer, String string, String delimiter, int delimiterLength) throws IOException {
+		writer.write(delimiter, 0, delimiterLength);
+		writer.write(string);
+		writer.write(delimiter, 0, delimiterLength);
+	}
+
+	/**
+	 * @see #delimit(Writer, String, String)
+	 */
+	public static void delimit(Writer writer, char[] string, char[] delimiter) throws IOException {
+		int delimiterLength = delimiter.length;
+		switch (delimiterLength) {
+			case 0:
+				writer.write(string);
+				break;
+			case 1:
+				delimit(writer, string, delimiter[0]);
+				break;
+			default:
+				delimit(writer, string, delimiter, delimiterLength);
+				break;
+		}
+	}
+
+	/**
+	 * No parm check
+	 */
+	private static void delimit(Writer writer, char[] string, char[] delimiter, int delimiterLength) throws IOException {
+		writer.write(delimiter, 0, delimiterLength);
+		writer.write(string);
+		writer.write(delimiter, 0, delimiterLength);
+	}
+
+
+	// ********** undelimiting **********
+
+	/**
+	 * Remove the delimiters from the specified string, removing any escape
+	 * characters. Throw an {@link IllegalArgumentException} if the string is
+	 * too short to undelimit (i.e. length < 2).
+	 */
+	public static void undelimit(Writer writer, String string) throws IOException {
+		int stringLength = string.length();
+		int resultLength = stringLength - 2;
+		if (resultLength < 0) {
+			throw new IllegalArgumentException("invalid string: \"" + string + '"');
+		}
+		if (resultLength == 0) {
+			return;
+		}
+		undelimit_(writer, string, stringLength);
+	}
+
+	/**
+	 * pre-condition: string is at least 3 characters long
+	 */
+	private static void undelimit_(Writer writer, String string, int stringLength) throws IOException {
+		char delimiter = string.charAt(0);  // the first char is the delimiter
+		char c = delimiter;
+		char next = string.charAt(1);
+		int i = 1;
+		int last = stringLength - 1;
+		do {
+			c = next;
+			writer.write(c);
+			i++;
+			next = string.charAt(i);
+			if (c == delimiter) {
+				if ((next != delimiter) || (i == last)) {
+					// an embedded delimiter must be followed by another delimiter
+					return;
+				}
+				i++;
+				next = string.charAt(i);
+			}
+		} while (i != last);
+	}
+
+	/**
+	 * @see #undelimit(Writer, String)
+	 */
+	public static void undelimit(Writer writer, char[] string) throws IOException {
+		int stringLength = string.length;
+		int resultLength = stringLength - 2;
+		if (resultLength < 0) {
+			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
+		}
+		if (resultLength == 0) {
+			return;
+		}
+		undelimit_(writer, string, stringLength);
+	}
+
+	/**
+	 * pre-condition: string is at least 3 characters long
+	 */
+	private static void undelimit_(Writer writer, char[] string, int stringLength) throws IOException {
+		char delimiter = string[0];  // the first char is the delimiter
+		char c = delimiter;
+		char next = string[1];
+		int i = 1;
+		int last = stringLength - 1;
+		do {
+			c = next;
+			writer.write(c);
+			i++;
+			next = string[i];
+			if (c == delimiter) {
+				if ((next != delimiter) || (i == last)) {
+					// an embedded delimiter must be followed by another delimiter
+					return;
+				}
+				i++;
+				next = string[i];
+			}
+		} while (i != last);
+	}
+
+	/**
+	 * Remove the first and last count characters from the specified string.
+	 * If the string is too short to be undelimited, throw an
+	 * {@link IllegalArgumentException}.
+	 * Use this method to undelimit strings that do not escape embedded
+	 * delimiters.
+	 */
+	public static void undelimit(Writer writer, String string, int count) throws IOException {
+		if (count == 0) {
+			writer.write(string);
+			return;
+		}
+		int resultLength = string.length() - (2 * count);
+		if (resultLength < 0) {
+			throw new IllegalArgumentException("invalid string: \"" + string + '"');
+		}
+		if (resultLength == 0) {
+			return;
+		}
+		writer.write(string, count, resultLength);
+	}
+
+	/**
+	 * @see #undelimit(Writer, String, int)
+	 */
+	public static void undelimit(Writer writer, char[] string, int count) throws IOException {
+		if (count == 0) {
+			writer.write(string);
+			return;
+		}
+		int resultLength = string.length - (2 * count);
+		if (resultLength < 0) {
+			throw new IllegalArgumentException("invalid string: \"" + new String(string) + '"');
+		}
+		if (resultLength == 0) {
+			return;
+		}
+		writer.write(string, count, resultLength);
+	}
+
+
+	// ********** removing characters **********
+
+	/**
+	 * Remove the first occurrence of the specified character
+	 * from the specified string and print the result on the specified stream.
+	 */
+	public static void removeFirstOccurrence(Writer writer, String string, char c) throws IOException {
+		int index = string.indexOf(c);
+		if (index == -1) {
+			writer.write(string);
+		} else {
+			removeCharAtIndex(writer, string, index);
+		}
+	}
+
+	private static void removeCharAtIndex(Writer writer, String string, int index) throws IOException {
+		int last = string.length() - 1;
+		if (index == 0) {
+			// character found at the front of string
+			writer.write(string, 1, last);
+		} else {
+			writer.write(string, 0, index);
+			if (index != last) {
+				// character is not the end of the string
+				writer.write(string, index + 1, last - index);
+			}
+		}
+	}
+
+	/**
+	 * @see #removeFirstOccurrence(Writer, String, char)
+	 */
+	public static void removeFirstOccurrence(Writer writer, char[] string, char c) throws IOException {
+		int index = ArrayTools.indexOf(string, c);
+		if (index == -1) {
+			writer.write(string);
+		} else {
+			removeCharAtIndex(writer, string, index);
+		}
+	}
+
+	private static void removeCharAtIndex(Writer writer, char[] string, int index) throws IOException {
+		int last = string.length - 1;
+		if (index == 0) {
+			// character found at the front of string
+			writer.write(string, 1, last);
+		} else if (index == last) {
+			// character found at the end of string
+			writer.write(string, 0, last);
+		} else {
+			// character found somewhere in the middle of the string
+			writer.write(string, 0, index);
+			writer.write(string, index + 1, last - index);
+		}
+	}
+
+	/**
+	 * Remove all occurrences of the specified character
+	 * from the specified string and write the result to the specified stream.
+	 */
+	public static void removeAllOccurrences(Writer writer, String string, char c) throws IOException {
+		int first = string.indexOf(c);
+		if (first == -1) {
+			writer.write(string);
+		} else {
+			removeAllOccurrences(writer, string, c, first);
+		}
+	}
+
+	/**
+	 * The index of the first matching character is passed in.
+	 */
+	private static void removeAllOccurrences(Writer writer, String string, char c, int first) throws IOException {
+		writer.write(string, 0, first);
+		int stringLength = string.length();
+		for (int i = first; i < stringLength; i++) {
+			char d = string.charAt(i);
+			if (d != c) {
+				writer.write(d);
+			}
+		}
+	}
+
+	/**
+	 * @see #removeAllOccurrences(Writer, String, char)
+	 */
+	public static void removeAllOccurrences(Writer writer, char[] string, char c) throws IOException {
+		int first = ArrayTools.indexOf(string, c);
+		if (first == -1) {
+			writer.write(string);
+		} else {
+			removeAllOccurrences(writer, string, c, first);
+		}
+	}
+
+	/**
+	 * The index of the first matching character is passed in.
+	 */
+	private static void removeAllOccurrences(Writer writer, char[] string, char c, int first) throws IOException {
+		writer.write(string, 0, first);
+		int stringLength = string.length;
+		for (int i = first; i < stringLength; i++) {
+			char d = string[i];
+			if (d != c) {
+				writer.write(d);
+			}
+		}
+	}
+
+	/**
+	 * Remove all the spaces
+	 * from the specified string and write the result to the specified stream.
+	 */
+	public static void removeAllSpaces(Writer writer, String string) throws IOException {
+		removeAllOccurrences(writer, string, ' ');
+	}
+
+	/**
+	 * @see #removeAllSpaces(Writer, String)
+	 */
+	public static void removeAllSpaces(Writer writer, char[] string) throws IOException {
+		removeAllOccurrences(writer, string, ' ');
+	}
+
+	/**
+	 * Remove all the whitespace
+	 * from the specified string and append the result to the
+	 * specified stream.
+	 */
+	public static void removeAllWhitespace(Writer writer, String string) throws IOException {
+		int first = StringTools.indexOfWhitespace(string);
+		if (first == -1) {
+			writer.write(string);
+		} else {
+			removeAllWhitespace(writer, string, first);
+		}
+	}
+
+	/**
+	 * The index of the first whitespace character is passed in.
+	 */
+	private static void removeAllWhitespace(Writer writer, String string, int first) throws IOException {
+		writer.write(string, 0, first);
+		int stringLength = string.length();
+		for (int i = first; i < stringLength; i++) {
+			char c = string.charAt(i);
+			if ( ! Character.isWhitespace(c)) {
+				writer.write(c);
+			}
+		}
+	}
+
+	/**
+	 * @see #removeAllWhitespace(Writer, String)
+	 */
+	public static void removeAllWhitespace(Writer writer, char[] string) throws IOException {
+		int first = CharArrayTools.indexOfWhitespace(string);
+		if (first == -1) {
+			writer.write(string);
+		} else {
+			removeAllWhitespace(writer, string, first);
+		}
+	}
+
+	/**
+	 * The index of the first whitespace character is passed in.
+	 */
+	private static void removeAllWhitespace(Writer writer, char[] string, int first) throws IOException {
+		writer.write(string, 0, first);
+		int stringLength = string.length;
+		for (int i = first; i < stringLength; i++) {
+			char c = string[i];
+			if ( ! Character.isWhitespace(c)) {
+				writer.write(c);
+			}
+		}
+	}
+
+	/**
+	 * Compress the whitespace
+	 * in the specified string and append the result to the
+	 * specified stream.
+	 * The whitespace is compressed by replacing any occurrence of one or more
+	 * whitespace characters with a single space.
+	 */
+	public static void compressWhitespace(Writer writer, String string) throws IOException {
+		int first = StringTools.indexOfWhitespace(string);
+		if (first == -1) {
+			writer.write(string);
+		} else {
+			compressWhitespace(writer, string, first);
+		}
+	}
+
+	/**
+	 * The index of the first whitespace character is passed in.
+	 */
+	private static void compressWhitespace(Writer writer, String string, int first) throws IOException {
+		writer.write(string, 0, first);
+		int stringLength = string.length();
+		int i = first;
+		char c = string.charAt(i);
+		main: while (true) {
+			// replace first whitespace character with a space...
+			writer.write(' ');
+			// ...and skip subsequent whitespace characters
+			while (true) {
+				i++;
+				if (i >= stringLength) {
+					break main;
+				}
+				c = string.charAt(i);
+				if ( ! Character.isWhitespace(c)) {
+					break;
+				}
+			}
+			while (true) {
+				writer.write(c);
+				i++;
+				if (i >= stringLength) {
+					break main;
+				}
+				c = string.charAt(i);
+				if (Character.isWhitespace(c)) {
+					break;
+				}
+			}
+		}
+	}
+
+	/**
+	 * @see #compressWhitespace(Writer, String)
+	 */
+	public static void compressWhitespace(Writer writer, char[] string) throws IOException {
+		int first = CharArrayTools.indexOfWhitespace(string);
+		if (first == -1) {
+			writer.write(string);
+		} else {
+			compressWhitespace(writer, string, first);
+		}
+	}
+
+	/**
+	 * The index of the first whitespace character is passed in.
+	 */
+	private static void compressWhitespace(Writer writer, char[] string, int first) throws IOException {
+		writer.write(string, 0, first);
+		int stringLength = string.length;
+		int i = first;
+		char c = string[i];
+		main: while (true) {
+			// replace first whitespace character with a space...
+			writer.write(' ');
+			// ...and skip subsequent whitespace characters
+			while (true) {
+				i++;
+				if (i >= stringLength) {
+					break main;
+				}
+				c = string[i];
+				if ( ! Character.isWhitespace(c)) {
+					break;
+				}
+			}
+			while (true) {
+				writer.write(c);
+				i++;
+				if (i >= stringLength) {
+					break main;
+				}
+				c = string[i];
+				if (Character.isWhitespace(c)) {
+					break;
+				}
+			}
+		}
+	}
+
+
+	// ********** capitalization **********
+
+	/**
+	 * Append the specified string to the specified stream
+	 * with its first letter capitalized.
+	 */
+	public static void capitalize(Writer writer, String string) throws IOException {
+		if (string.length() == 0) {
+			return;
+		}
+		if (Character.isUpperCase(string.charAt(0))) {
+			writer.write(string);
+		} else {
+			capitalize_(writer, string);
+		}
+	}
+
+	/**
+	 * no zero-length check or upper case check
+	 */
+	private static void capitalize_(Writer writer, String string) throws IOException {
+		writer.write(Character.toUpperCase(string.charAt(0)));
+		writer.write(string, 1, string.length() - 1);
+	}
+
+	/**
+	 * @see #capitalize(Writer, String)
+	 */
+	public static void capitalize(Writer writer, char[] string) throws IOException {
+		if (string.length == 0) {
+			return;
+		}
+		if (Character.isUpperCase(string[0])) {
+			writer.write(string);
+		} else {
+			capitalize_(writer, string);
+		}
+	}
+
+	/**
+	 * no zero-length check or upper case check
+	 */
+	private static void capitalize_(Writer writer, char[] string) throws IOException {
+		writer.write(Character.toUpperCase(string[0]));
+		writer.write(string, 1, string.length - 1);
+	}
+
+	/**
+	 * Append the specified string to the specified stream
+	 * with its first letter converted to lower case.
+	 * (Unless both the first and second letters are upper case,
+	 * in which case the string is returned unchanged.)
+	 */
+	public static void uncapitalize(Writer writer, String string) throws IOException {
+		int stringLength = string.length();
+		if (StringTools.needNotBeUncapitalized(string, stringLength)) {
+			writer.write(string);
+		} else {
+			uncapitalize(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * no zero-length check or upper case check
+	 */
+	private static void uncapitalize(Writer writer, String string, int stringLength) throws IOException {
+		writer.write(Character.toLowerCase(string.charAt(0)));
+		writer.write(string, 1, stringLength - 1);
+	}
+
+	/**
+	 * @see #uncapitalize(Writer, String)
+	 */
+	public static void uncapitalize(Writer writer, char[] string) throws IOException {
+		int stringLength = string.length;
+		if (CharArrayTools.needNotBeUncapitalized(string, stringLength)) {
+			writer.write(string);
+		} else {
+			uncapitalize(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * no zero-length check or upper case check
+	 */
+	private static void uncapitalize(Writer writer, char[] string, int stringLength) throws IOException {
+		writer.write(Character.toLowerCase(string[0]));
+		writer.write(string, 1, stringLength - 1);
+	}
+
+
+	// ********** convert byte array to hex string **********
+
+	/**
+	 * Convert the specified byte array to the corresponding string of
+	 * hexadecimal characters.
+	 * @see org.eclipse.jpt.common.utility.internal.ByteArrayTools#convertToHexString(byte[])
+	 */
+	public static void convertToHexString(Writer writer, byte[] bytes) throws IOException {
+		int bytesLength = bytes.length;
+		if (bytesLength != 0) {
+			convertToHexString(writer, bytes, bytesLength);
+		}
+	}
+
+	/**
+	 * Pre-condition: the byte array is not empty
+	 */
+	private static void convertToHexString(Writer writer, byte[] bytes, int bytesLength) throws IOException {
+		char[] digits = CharacterTools.DIGITS;
+		for (int i = 0; i < bytesLength; i++) {
+			int b = bytes[i] & 0xFF; // clear any sign bits
+			writer.write(digits[b >> 4]); // first nibble
+			writer.write(digits[b & 0xF]); // second nibble
+		}
+	}
+
+
+	// ********** convert camel case to all caps **********
+
+	/**
+	 * Convert the specified "camel case" string to an "all caps" string:
+	 * <p>
+	 * <code>
+	 * "largeProject" -> "LARGE_PROJECT"
+	 * </code>
+	 */
+	public static void convertCamelCaseToAllCaps(Writer writer, String camelCaseString) throws IOException {
+		int stringLength = camelCaseString.length();
+		if (stringLength != 0) {
+			convertCamelCaseToAllCaps_(writer, camelCaseString, stringLength);
+		}
+	}
+
+	/**
+	 * Pre-condition: the string is not empty
+	 */
+	private static void convertCamelCaseToAllCaps_(Writer writer, String camelCaseString, int stringLength) throws IOException {
+		char prev = 0;	// assume 0 is not a valid char
+		char c = 0;
+		char next = camelCaseString.charAt(0);
+		for (int i = 1; i <= stringLength; i++) {	// NB: start at 1 and end at stringLength!
+			c = next;
+			next = ((i == stringLength) ? 0 : camelCaseString.charAt(i));
+			if (StringTools.camelCaseWordBreak(prev, c, next)) {
+				writer.write('_');
+			}
+			writer.write(Character.toUpperCase(c));
+			prev = c;
+		}
+	}
+
+	/**
+	 * @see #convertCamelCaseToAllCaps(Writer, String)
+	 */
+	public static void convertCamelCaseToAllCaps(Writer writer, char[] camelCaseString) throws IOException {
+		int stringLength = camelCaseString.length;
+		if (stringLength != 0) {
+			convertCamelCaseToAllCaps_(writer, camelCaseString, stringLength);
+		}
+	}
+
+	/**
+	 * Pre-condition: the string is not empty
+	 */
+	private static void convertCamelCaseToAllCaps_(Writer writer, char[] camelCaseString, int stringLength) throws IOException {
+		char prev = 0;	// assume 0 is not a valid char
+		char c = 0;
+		char next = camelCaseString[0];
+		for (int i = 1; i <= stringLength; i++) {	// NB: start at 1 and end at stringLength!
+			c = next;
+			next = ((i == stringLength) ? 0 : camelCaseString[i]);
+			if (StringTools.camelCaseWordBreak(prev, c, next)) {
+				writer.write('_');
+			}
+			writer.write(Character.toUpperCase(c));
+			prev = c;
+		}
+	}
+
+	/**
+	 * Convert the specified "camel case" string to an "all caps" string:
+	 * <p>
+	 * <code>
+	 * "largeProject" -> "LARGE_PROJECT"
+	 * </code>
+	 * <p>
+	 * Limit the resulting string to the specified maximum length.
+	 */
+	public static void convertCamelCaseToAllCaps(Writer writer, String camelCaseString, int maxLength) throws IOException {
+		if (maxLength != 0) {
+			int stringLength = camelCaseString.length();
+			if (stringLength != 0) {
+				convertCamelCaseToAllCaps(writer, camelCaseString, maxLength, stringLength);
+			}
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	private static void convertCamelCaseToAllCaps(Writer writer, String camelCaseString, int maxLength, int stringLength) throws IOException {
+		char prev = 0;	// assume 0 is not a valid char
+		char c = 0;
+		char next = camelCaseString.charAt(0);
+		int writerLength = 0;
+		for (int i = 1; i <= stringLength; i++) {	// NB: start at 1 and end at stringLength!
+			c = next;
+			next = ((i == stringLength) ? 0 : camelCaseString.charAt(i));
+			if (StringTools.camelCaseWordBreak(prev, c, next)) {
+				writer.write('_');
+				if (++writerLength == maxLength) {
+					return;
+				}
+			}
+			writer.write(Character.toUpperCase(c));
+			if (++writerLength == maxLength) {
+				return;
+			}
+			prev = c;
+		}
+	}
+
+	/**
+	 * @see #convertCamelCaseToAllCaps(Writer, String, int)
+	 */
+	public static void convertCamelCaseToAllCaps(Writer writer, char[] camelCaseString, int maxLength) throws IOException {
+		if (maxLength != 0) {
+			int stringLength = camelCaseString.length;
+			if (stringLength != 0) {
+				convertCamelCaseToAllCaps(writer, camelCaseString, maxLength, stringLength);
+			}
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	private static void convertCamelCaseToAllCaps(Writer writer, char[] camelCaseString, int maxLength, int stringLength) throws IOException {
+		char prev = 0;	// assume 0 is not a valid char
+		char c = 0;
+		char next = camelCaseString[0];
+		int writerLength = 0;
+		for (int i = 1; i <= stringLength; i++) {	// NB: start at 1 and end at stringLength!
+			c = next;
+			next = ((i == stringLength) ? 0 : camelCaseString[i]);
+			if (StringTools.camelCaseWordBreak(prev, c, next)) {
+				writer.write('_');
+				if (++writerLength == maxLength) {
+					return;
+				}
+			}
+			writer.write(Character.toUpperCase(c));
+			if (++writerLength == maxLength) {
+				return;
+			}
+			prev = c;
+		}
+	}
+
+
+	// ********** convert all caps to camel case **********
+
+	/**
+	 * Convert the specified "all caps" string to a "camel case" string:
+	 * <p>
+	 * <code>
+	 * "LARGE_PROJECT" -> "LargeProject"
+	 * </code>
+	 * <p>
+	 * Capitalize the first letter.
+	 */
+	public static void convertAllCapsToCamelCase(Writer writer, String allCapsString) throws IOException {
+		convertAllCapsToCamelCase(writer, allCapsString, true);
+	}
+
+	/**
+	 * @see #convertAllCapsToCamelCase(Writer, String)
+	 */
+	public static void convertAllCapsToCamelCase(Writer writer, char[] allCapsString) throws IOException {
+		convertAllCapsToCamelCase(writer, allCapsString, true);
+	}
+
+	/**
+	 * Convert the specified "all caps" string to a "camel case" string:
+	 * <p>
+	 * <code>
+	 * "LARGE_PROJECT" -> "largeProject"
+	 * </code>
+	 * <p>
+	 * Optionally capitalize the first letter.
+	 */
+	public static void convertAllCapsToCamelCase(Writer writer, String allCapsString, boolean capitalizeFirstLetter) throws IOException {
+		int stringLength = allCapsString.length();
+		if (stringLength != 0) {
+			convertAllCapsToCamelCase(writer, allCapsString, capitalizeFirstLetter, stringLength);
+		}
+	}
+
+	private static void convertAllCapsToCamelCase(Writer writer, String allCapsString, boolean capitalizeFirstLetter, int stringLength) throws IOException {
+		char prev = 0;
+		char c = 0;
+		boolean first = true;
+		for (int i = 0; i < stringLength; i++) {
+			prev = c;
+			c = allCapsString.charAt(i);
+			if (c == '_') {
+				continue;
+			}
+			if (first) {
+				first = false;
+				writer.write(capitalizeFirstLetter ? Character.toUpperCase(c) : Character.toLowerCase(c));
+			} else {
+				writer.write((prev == '_') ? Character.toUpperCase(c) : Character.toLowerCase(c));
+			}
+		}
+	}
+
+	/**
+	 * @see #convertAllCapsToCamelCase(Writer, String, boolean)
+	 */
+	public static void convertAllCapsToCamelCase(Writer writer, char[] allCapsString, boolean capitalizeFirstLetter) throws IOException {
+		int stringLength = allCapsString.length;
+		if (stringLength != 0) {
+			convertAllCapsToCamelCase(writer, allCapsString, capitalizeFirstLetter, stringLength);
+		}
+	}
+
+	private static void convertAllCapsToCamelCase(Writer writer, char[] allCapsString, boolean capitalizeFirstLetter, int stringLength) throws IOException {
+		char prev = 0;
+		char c = 0;
+		boolean first = true;
+		for (int i = 0; i < stringLength; i++) {
+			prev = c;
+			c = allCapsString[i];
+			if (c == '_') {
+				continue;
+			}
+			if (first) {
+				first = false;
+				writer.write(capitalizeFirstLetter ? Character.toUpperCase(c) : Character.toLowerCase(c));
+			} else {
+				writer.write((prev == '_') ? Character.toUpperCase(c) : Character.toLowerCase(c));
+			}
+		}
+	}
+
+
+	// ********** convert to Java string literal **********
+
+	/**
+	 * Convert the specified string to a Java string literal, with the
+	 * appropriate escaped characters.
+	 */
+	public static void convertToJavaStringLiteral(Writer writer, String string) throws IOException {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			writer.write(StringTools.EMPTY_JAVA_STRING_LITERAL);
+		} else {
+			convertToJavaStringLiteral(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	private static void convertToJavaStringLiteral(Writer writer, String string, int stringLength) throws IOException {
+		writer.write(CharacterTools.QUOTE);
+		for (int i = 0; i < stringLength; i++) {
+			convertToJavaStringLiteral(writer, string.charAt(i));
+		}
+		writer.write(CharacterTools.QUOTE);
+	}
+
+	/**
+	 * Convert the specified string to the contents of a Java string literal,
+	 * with the appropriate escaped characters.
+	 */
+	public static void convertToJavaStringLiteralContent(Writer writer, String string) throws IOException {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			convertToJavaStringLiteralContent(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	private static void convertToJavaStringLiteralContent(Writer writer, String string, int stringLength) throws IOException {
+		for (int i = 0; i < stringLength; i++) {
+			convertToJavaStringLiteral(writer, string.charAt(i));
+		}
+	}
+
+	/**
+	 * @see #convertToJavaStringLiteral(Writer, String)
+	 */
+	public static void convertToJavaStringLiteral(Writer writer, char[] string) throws IOException {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			writer.write(StringTools.EMPTY_JAVA_STRING_LITERAL);
+		} else {
+			convertToJavaStringLiteral(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	private static void convertToJavaStringLiteral(Writer writer, char[] string, int stringLength) throws IOException {
+		writer.write(CharacterTools.QUOTE);
+		convertToJavaStringLiteralContent(writer, string, stringLength);
+		writer.write(CharacterTools.QUOTE);
+	}
+
+	/**
+	 * @see #convertToJavaStringLiteralContent(Writer, String)
+	 */
+	public static void convertToJavaStringLiteralContent(Writer writer, char[] string) throws IOException {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			convertToJavaStringLiteralContent(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * The length of the string is passed in.
+	 */
+	private static void convertToJavaStringLiteralContent(Writer writer, char[] string, int stringLength) throws IOException {
+		for (int i = 0; i < stringLength; i++) {
+			convertToJavaStringLiteral(writer, string[i]);
+		}
+	}
+
+	private static void convertToJavaStringLiteral(Writer writer, char c) throws IOException {
+		switch (c) {
+			case '\b':  // backspace
+				writer.write("\\b");
+				break;
+			case '\t':  // horizontal tab
+				writer.write("\\t");
+				break;
+			case '\n':  // line-feed LF
+				writer.write("\\n");
+				break;
+			case '\f':  // form-feed FF
+				writer.write("\\f");
+				break;
+			case '\r':  // carriage-return CR
+				writer.write("\\r");
+				break;
+			case '"':  // double-quote
+				writer.write("\\\"");
+				break;
+//			case '\'':  // single-quote
+//				writer.write("\\'");
+//				break;
+			case '\\':  // backslash
+				writer.write("\\\\");
+				break;
+			default:
+				writer.write(c);
+				break;
+		}
+	}
+
+
+	// ********** convert to XML **********
+
+	/**
+	 * Convert the specified string to an XML attribute value, escaping the
+	 * appropriate characters. Delimit with quotes (<code>"</code>) unless
+	 * there are <em>embedded</em> quotes (<em>and</em> no embedded
+	 * apostrophes); in which case, delimit with apostrophes (<code>'</code>).
+	 */
+	public static void convertToXmlAttributeValue(Writer writer, String string) throws IOException {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			writer.write(StringTools.EMPTY_XML_ATTRIBUTE_VALUE);
+		} else {
+			convertToXmlAttributeValue(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToXmlAttributeValue(Writer writer, String string, int stringLength) throws IOException {
+		int index = string.indexOf(CharacterTools.QUOTE);
+		if (index == -1) {
+			// no embedded quotes - use quote delimiters
+			convertToDoubleQuotedXmlAttributeValue(writer, string, stringLength);
+		} else {
+			index = string.indexOf(CharacterTools.APOSTROPHE);
+			if (index == -1) {
+				// embedded quotes but no embedded apostrophes - use apostrophe delimiters
+				convertToSingleQuotedXmlAttributeValue(writer, string, stringLength);
+			} else {
+				// embedded quotes *and* embedded apostrophes - use quote delimiters
+				convertToDoubleQuotedXmlAttributeValue(writer, string, stringLength);
+			}
+		}
+	}
+
+	private static void convertToDoubleQuotedXmlAttributeValue(Writer writer, String string, int stringLength) throws IOException {
+		writer.write(CharacterTools.QUOTE);
+		convertToDoubleQuotedXmlAttributeValueContent(writer, string, stringLength);
+		writer.write(CharacterTools.QUOTE);
+	}
+
+	private static void convertToSingleQuotedXmlAttributeValue(Writer writer, String string, int stringLength) throws IOException {
+		writer.write(CharacterTools.APOSTROPHE);
+		convertToSingleQuotedXmlAttributeValueContent(writer, string, stringLength);
+		writer.write(CharacterTools.APOSTROPHE);
+	}
+
+	/**
+	 * Convert the specified string to a double-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * double quotes).
+	 * @see #convertToXmlAttributeValue(Writer, String)
+	 */
+	public static void convertToDoubleQuotedXmlAttributeValue(Writer writer, String string) throws IOException {
+		convertToDoubleQuotedXmlAttributeValue(writer, string, string.length());
+	}
+
+	/**
+	 * Convert the specified string to the contents of a double-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * double quotes).
+	 * @see #convertToXmlAttributeValue(Writer, String)
+	 */
+	public static void convertToDoubleQuotedXmlAttributeValueContent(Writer writer, String string) throws IOException {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			convertToDoubleQuotedXmlAttributeValueContent(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToDoubleQuotedXmlAttributeValueContent(Writer writer, String string, int stringLength) throws IOException {
+		for (int i = 0; i < stringLength; i++) {
+			convertToDoubleQuotedXmlAttributeValue(writer, string.charAt(i));
+		}
+	}
+
+	/**
+	 * Convert the specified string to a single-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * single quotes).
+	 * @see #convertToXmlAttributeValue(Writer, String)
+	 */
+	public static void convertToSingleQuotedXmlAttributeValue(Writer writer, String string) throws IOException {
+		convertToSingleQuotedXmlAttributeValue(writer, string, string.length());
+	}
+
+	/**
+	 * Convert the specified string to the contents of a single-quoted XML
+	 * attribute value, escaping the appropriate characters (i.e. the embedded
+	 * single quotes).
+	 * @see #convertToXmlAttributeValue(Writer, String)
+	 */
+	public static void convertToSingleQuotedXmlAttributeValueContent(Writer writer, String string) throws IOException {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			convertToSingleQuotedXmlAttributeValueContent(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToSingleQuotedXmlAttributeValueContent(Writer writer, String string, int stringLength) throws IOException {
+		for (int i = 0; i < stringLength; i++) {
+			convertToSingleQuotedXmlAttributeValueContent(writer, string.charAt(i));
+		}
+	}
+
+	/**
+	 * @see #convertToXmlAttributeValue(Writer, String)
+	 */
+	public static void convertToXmlAttributeValue(Writer writer, char[] string) throws IOException {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			writer.write(StringTools.EMPTY_XML_ATTRIBUTE_VALUE);
+		} else {
+			convertToXmlAttributeValue(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToXmlAttributeValue(Writer writer, char[] string, int stringLength) throws IOException {
+		int index = ArrayTools.indexOf(string, CharacterTools.QUOTE);
+		if (index == -1) {
+			// no embedded quotes - use quote delimiters
+			convertToDoubleQuotedXmlAttributeValue(writer, string, stringLength);
+		} else {
+			index = ArrayTools.indexOf(string, CharacterTools.APOSTROPHE);
+			if (index == -1) {
+				// embedded quotes but no embedded apostrophes - use apostrophe delimiters
+				convertToSingleQuotedXmlAttributeValue(writer, string, stringLength);
+			} else {
+				// embedded quotes *and* embedded apostrophes - use quote delimiters
+				convertToDoubleQuotedXmlAttributeValue(writer, string, stringLength);
+			}
+		}
+	}
+
+	private static void convertToDoubleQuotedXmlAttributeValue(Writer writer, char[] string, int stringLength) throws IOException {
+		writer.write(CharacterTools.QUOTE);
+		convertToDoubleQuotedXmlAttributeValueContent(writer, string, stringLength);
+		writer.write(CharacterTools.QUOTE);
+	}
+
+	private static void convertToSingleQuotedXmlAttributeValue(Writer writer, char[] string, int stringLength) throws IOException {
+		writer.write(CharacterTools.APOSTROPHE);
+		convertToSingleQuotedXmlAttributeValueContent(writer, string, stringLength);
+		writer.write(CharacterTools.APOSTROPHE);
+	}
+
+	/**
+	 * @see #convertToDoubleQuotedXmlAttributeValue(Writer, String)
+	 * @see #convertToXmlAttributeValue(Writer, char[])
+	 */
+	public static void convertToDoubleQuotedXmlAttributeValue(Writer writer, char[] string) throws IOException {
+		convertToDoubleQuotedXmlAttributeValue(writer, string, string.length);
+	}
+
+	/**
+	 * @see #convertToDoubleQuotedXmlAttributeValueContent(Writer, String)
+	 * @see #convertToXmlAttributeValue(Writer, char[])
+	 */
+	public static void convertToDoubleQuotedXmlAttributeValueContent(Writer writer, char[] string) throws IOException {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			convertToDoubleQuotedXmlAttributeValueContent(writer, string, stringLength);
+		}
+	}
+
+	private static void convertToDoubleQuotedXmlAttributeValueContent(Writer writer, char[] string, int stringLength) throws IOException {
+		for (int i = 0; i < stringLength; i++) {
+			convertToDoubleQuotedXmlAttributeValue(writer, string[i]);
+		}
+	}
+
+	/**
+	 * @see #convertToSingleQuotedXmlAttributeValue(Writer, String)
+	 * @see #convertToXmlAttributeValue(Writer, char[])
+	 */
+	public static void convertToSingleQuotedXmlAttributeValue(Writer writer, char[] string) throws IOException {
+		convertToSingleQuotedXmlAttributeValue(writer, string, string.length);
+	}
+
+	/**
+	 * @see #convertToSingleQuotedXmlAttributeValueContent(Writer, String)
+	 * @see #convertToXmlAttributeValue(Writer, char[])
+	 */
+	public static void convertToSingleQuotedXmlAttributeValueContent(Writer writer, char[] string) throws IOException {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			convertToSingleQuotedXmlAttributeValueContent(writer, string, stringLength);
+		}
+	}
+
+	private static void convertToSingleQuotedXmlAttributeValueContent(Writer writer, char[] string, int stringLength) throws IOException {
+		for (int i = 0; i < stringLength; i++) {
+			convertToSingleQuotedXmlAttributeValueContent(writer, string[i]);
+		}
+	}
+
+	/**
+	 * String is delimited with quotes - escape embedded quotes.
+	 * @see <a href="http://www.w3.org/TR/xml/#syntax">XML Spec</a>
+	 */
+	private static void convertToDoubleQuotedXmlAttributeValue(Writer writer, char c) throws IOException {
+		switch (c) {
+			case '"':  // double-quote
+				writer.write(StringTools.XML_QUOTE);
+				break;
+			case '&':  // ampersand
+				writer.write(StringTools.XML_AMP);
+				break;
+			case '<':  // less than
+				writer.write(StringTools.XML_LT);
+				break;
+			default:
+				writer.write(c);
+				break;
+		}
+	}
+
+	/**
+	 * String is delimited with apostrophes - escape embedded apostrophes.
+	 * @see <a href="http://www.w3.org/TR/xml/#syntax">XML Spec</a>
+	 */
+	private static void convertToSingleQuotedXmlAttributeValueContent(Writer writer, char c) throws IOException {
+		switch (c) {
+			case '\'':  // apostrophe
+				writer.write(StringTools.XML_APOS);
+				break;
+			case '&':  // ampersand
+				writer.write(StringTools.XML_AMP);
+				break;
+			case '<':  // less than
+				writer.write(StringTools.XML_LT);
+				break;
+			default:
+				writer.write(c);
+				break;
+		}
+	}
+
+	/**
+	 * Convert the specified string to an XML element text, escaping the
+	 * appropriate characters.
+	 * @see #convertToXmlElementCDATA(Writer, String)
+	 */
+	public static void convertToXmlElementText(Writer writer, String string) throws IOException {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			convertToXmlElementText(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToXmlElementText(Writer writer, String string, int stringLength) throws IOException {
+		for (int i = 0; i < stringLength; i++) {
+			convertToXmlElementText(writer, string.charAt(i));
+		}
+	}
+
+	/**
+	 * @see #convertToXmlElementText(Writer, String)
+	 */
+	public static void convertToXmlElementText(Writer writer, char[] string) throws IOException {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			convertToXmlElementText(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToXmlElementText(Writer writer, char[] string, int stringLength) throws IOException {
+		for (int i = 0; i < stringLength; i++) {
+			convertToXmlElementText(writer, string[i]);
+		}
+	}
+
+	/**
+	 * @see <a href="http://www.w3.org/TR/xml/#syntax">XML Spec</a>
+	 */
+	private static void convertToXmlElementText(Writer writer, char c) throws IOException {
+		switch (c) {
+			case '&':  // ampersand
+				writer.write(StringTools.XML_AMP);
+				break;
+			case '<':  // less than
+				writer.write(StringTools.XML_LT);
+				break;
+			default:
+				writer.write(c);
+				break;
+		}
+	}
+
+	/**
+	 * Convert the specified string to an XML element CDATA, escaping the
+	 * appropriate characters.
+	 * @see #convertToXmlElementText(Writer, String)
+	 */
+	public static void convertToXmlElementCDATA(Writer writer, String string) throws IOException {
+		int stringLength = string.length();
+		if (stringLength == 0) {
+			writer.write(StringTools.EMPTY_XML_ELEMENT_CDATA);
+		} else {
+			convertToXmlElementCDATA(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToXmlElementCDATA(Writer writer, String string, int stringLength) throws IOException {
+		writer.write(StringTools.XML_ELEMENT_CDATA_START);
+		convertToXmlElementCDATAContent(writer, string, stringLength);
+		writer.write(StringTools.XML_ELEMENT_CDATA_END);
+	}
+
+	/**
+	 * Convert the specified string to the contents of an XML element CDATA,
+	 * escaping the appropriate characters.
+	 * @see #convertToXmlElementCDATA(Writer, String)
+	 * @see #convertToXmlElementText(Writer, String)
+	 */
+	public static void convertToXmlElementCDATAContent(Writer writer, String string) throws IOException {
+		int stringLength = string.length();
+		if (stringLength != 0) {
+			convertToXmlElementCDATAContent(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 * @see <a href="http://www.w3.org/TR/xml/#sec-cdata-sect">XML Spec</a>
+	 */
+	private static void convertToXmlElementCDATAContent(Writer writer, String string, int stringLength) throws IOException {
+		for (int i = 0; i < stringLength; i++) {
+			char c = string.charAt(i);
+			writer.write(c);
+			// "]]>" -> "]]&gt;"
+			if (c != ']') {
+				continue;
+			}
+			if (++i >= stringLength) {
+				break;
+			}
+			c = string.charAt(i);
+			writer.write(c);
+			if (c != ']') {
+				continue;
+			}
+			if (++i >= stringLength) {
+				break;
+			}
+			c = string.charAt(i);
+			if (c == '>') {
+				writer.write(StringTools.XML_GT);
+			} else {
+				writer.write(c);
+			}
+		}
+	}
+
+	/**
+	 * @see #convertToXmlElementCDATA(Writer, String)
+	 */
+	public static void convertToXmlElementCDATA(Writer writer, char[] string) throws IOException {
+		int stringLength = string.length;
+		if (stringLength == 0) {
+			writer.write(StringTools.EMPTY_XML_ELEMENT_CDATA);
+		} else {
+			convertToXmlElementCDATA(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 */
+	private static void convertToXmlElementCDATA(Writer writer, char[] string, int stringLength) throws IOException {
+		writer.write(StringTools.XML_ELEMENT_CDATA_START);
+		convertToXmlElementCDATAContent(writer, string, stringLength);
+		writer.write(StringTools.XML_ELEMENT_CDATA_END);
+	}
+
+	/**
+	 * @see #convertToXmlElementCDATAContent(Writer, String)
+	 * @see #convertToXmlElementCDATA(Writer, char[])
+	 */
+	public static void convertToXmlElementCDATAContent(Writer writer, char[] string) throws IOException {
+		int stringLength = string.length;
+		if (stringLength != 0) {
+			convertToXmlElementCDATAContent(writer, string, stringLength);
+		}
+	}
+
+	/**
+	 * The (non-zero) length of the string is passed in.
+	 * @see <a href="http://www.w3.org/TR/xml/#sec-cdata-sect">XML Spec</a>
+	 */
+	private static void convertToXmlElementCDATAContent(Writer writer, char[] string, int stringLength) throws IOException {
+		for (int i = 0; i < stringLength; i++) {
+			char c = string[i];
+			writer.write(c);
+			// "]]>" -> "]]&gt;"
+			if (c != ']') {
+				continue;
+			}
+			if (++i >= stringLength) {
+				break;
+			}
+			c = string[i];
+			writer.write(c);
+			if (c != ']') {
+				continue;
+			}
+			if (++i >= stringLength) {
+				break;
+			}
+			c = string[i];
+			if (c == '>') {
+				writer.write(StringTools.XML_GT);
+			} else {
+				writer.write(c);
+			}
+		}
+	}
+
+
+	// ********** constructor **********
+
+	/*
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private WriterTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/AbstractSimultaneousIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/AbstractSimultaneousIterable.java
new file mode 100644
index 0000000..bd61165
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/AbstractSimultaneousIterable.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+public abstract class AbstractSimultaneousIterable<E, I extends Iterable<E>> {
+
+	final Iterable<? extends I> iterables;
+	final int iterablesSize;  // hint
+
+
+	/**
+	 * Construct a "simultaneous" iterable for the specified iterables.
+	 */
+	protected <T extends I> AbstractSimultaneousIterable(T... iterables) {
+		this(new ArrayIterable<T>(iterables), iterables.length);
+	}
+
+	/**
+	 * Construct a "multiple" iterable for the specified iterables.
+	 */
+	protected <T extends I> AbstractSimultaneousIterable(Iterable<T> iterables) {
+		this(iterables, -1);
+	}
+
+	/**
+	 * Construct a "multiple" iterable for the specified iterables.
+	 * Use the specified size as a performance hint.
+	 */
+	protected <T extends I> AbstractSimultaneousIterable(Iterable<T> iterables, int iterablesSize) {
+		super();
+		if (iterables == null) {
+			throw new NullPointerException();
+		}
+		this.iterables = iterables;
+		this.iterablesSize = iterablesSize;
+	}
+
+	<T extends Iterator<E>> ArrayList<T> buildList() {
+		return (this.iterablesSize < 0) ? new ArrayList<T>() : new ArrayList<T>(this.iterablesSize);
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.iterables);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ArrayIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ArrayIterable.java
new file mode 100644
index 0000000..54c4a25
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ArrayIterable.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.iterator.ArrayIterator;
+
+/**
+ * An <code>ArrayIterable</code> provides an {@link Iterable}
+ * for an array of objects of type <code>E</code>.
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ *
+ * @see ArrayIterator
+ * @see ArrayListIterable
+ */
+@SuppressWarnings("nls")
+public class ArrayIterable<E>
+	implements Iterable<E>
+{
+	final E[] array;
+	final int start;
+	final int end;
+
+	/**
+	 * Construct an iterable for the specified array.
+	 */
+	public ArrayIterable(E... array) {
+		this(array, 0);
+	}
+
+	/**
+	 * Construct an iterable for the specified array,
+	 * starting at the specified start index and continuing for
+	 * the rest of the array.
+	 */
+	public ArrayIterable(E[] array, int start) {
+		this(array, start, array.length);
+	}
+
+	/**
+	 * Construct an iterable for the specified array,
+	 * starting at the specified start index, inclusive, and continuing to
+	 * the specified end index, exclusive.
+	 */
+	public ArrayIterable(E[] array, int start, int end) {
+		super();
+		if ((start < 0) || (start > array.length)) {
+			throw new IllegalArgumentException("start: " + start);
+		}
+		if ((end < start) || (end > array.length)) {
+			throw new IllegalArgumentException("end: " + end);
+		}
+		this.array = array;
+		this.start = start;
+		this.end = end;
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return new ArrayIterator<E>(this.array, this.start, this.end);
+	}
+
+	@Override
+	public String toString() {
+		return Arrays.toString(this.array);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ArrayListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ArrayListIterable.java
new file mode 100644
index 0000000..67b8f1b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ArrayListIterable.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.ArrayListIterator;
+
+/**
+ * An <code>ArrayListIterable</code> provides a {@link ListIterable}
+ * for an array of objects of type <code>E</code>.
+ *
+ * @param <E> the type of elements returned by the list iterable's list iterator
+ *
+ * @see ArrayIterable
+ * @see ArrayListIterator
+ */
+public class ArrayListIterable<E>
+	extends ArrayIterable<E>
+	implements ListIterable<E>
+{
+	/**
+	 * Construct a list iterable for the specified array.
+	 */
+	public ArrayListIterable(E... array) {
+		this(array, 0);
+	}
+
+	/**
+	 * Construct a list iterable for the specified array,
+	 * starting at the specified start index and continuing for
+	 * the rest of the array.
+	 */
+	public ArrayListIterable(E[] array, int start) {
+		this(array, start, array.length);
+	}
+
+	/**
+	 * Construct a list iterable for the specified array,
+	 * starting at the specified start index, inclusive, and continuing to
+	 * the specified end index, exclusive.
+	 */
+	public ArrayListIterable(E[] array, int start, int end) {
+		super(array, start, end);
+	}
+
+	@Override
+	public ListIterator<E> iterator() {
+		return new ArrayListIterator<E>(this.array, this.start, this.end);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ChainIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ChainIterable.java
new file mode 100644
index 0000000..6a00bb6
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ChainIterable.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.ChainIterator;
+
+/**
+ * A <code>ChainIterable</code> provides a pluggable {@link Iterable}
+ * that loops over a chain of arbitrarily linked objects. The chain
+ * should be null-terminated (i.e. a call to the {@link #nextLink(Object)}
+ * method should return <code>null</code> when it is passed the last
+ * link of the chain).
+ * To use, supply a starting link and supply a
+ * {@link org.eclipse.jpt.common.utility.internal.iterator.ChainIterator.Linker}
+ * or subclass <code>ChainIterable</code> and override the
+ * {@link #nextLink(Object)} method.
+ * The starting link will be the first object returned by the iterable's iterator.
+ * If the starting link is <code>null</code>, the iterable will be empty.
+ * Note this iterable does not support <code>null</code> elements.
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ *
+ * @see ChainIterator
+ */
+@SuppressWarnings("nls")
+public class ChainIterable<E>
+	implements Iterable<E>
+{
+	private final E startLink;
+	private final ChainIterator.Linker<E> linker;
+
+
+	/**
+	 * Construct an iterable with the specified starting link
+	 * and a default linker that calls back to the iterable.
+	 * Use this constructor if you want to override the
+	 * {@link #nextLink(Object)} method instead of building a
+	 * {@link org.eclipse.jpt.common.utility.internal.iterator.ChainIterator.Linker}.
+	 */
+	public ChainIterable(E startLink) {
+		super();
+		this.startLink = startLink;
+		this.linker = this.buildDefaultLinker();
+	}
+
+	/**
+	 * Construct an iterator with the specified starting link
+	 * and linker.
+	 */
+	public ChainIterable(E startLink, ChainIterator.Linker<E> linker) {
+		super();
+		if (linker == null) {
+			throw new NullPointerException();
+		}
+		this.startLink = startLink;
+		this.linker = linker;
+	}
+
+	protected ChainIterator.Linker<E> buildDefaultLinker() {
+		return new DefaultLinker();
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return new ChainIterator<E>(this.startLink, this.linker);
+	}
+
+	/**
+	 * Return the next link in the chain; null if there are no more links.
+	 * <p>
+	 * This method can be overridden by a subclass as an alternative to
+	 * building a {@link org.eclipse.jpt.common.utility.internal.iterator.ChainIterator.Linker}.
+	 */
+	protected E nextLink(@SuppressWarnings("unused") E currentLink) {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+	@Override
+	public String toString() {
+		return ListTools.list(this).toString();
+	}
+
+
+	//********** default linker **********
+
+	protected class DefaultLinker implements ChainIterator.Linker<E> {
+		@Override
+		public E nextLink(E currentLink) {
+			return ChainIterable.this.nextLink(currentLink);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/CloneIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/CloneIterable.java
new file mode 100644
index 0000000..2964ed9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/CloneIterable.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import org.eclipse.persistence.tools.utility.iterator.CloneIterator;
+
+/**
+ * Pull together remover state and behavior for subclasses.
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ *
+ * @see SnapshotCloneIterable
+ * @see LiveCloneIterable
+ */
+@SuppressWarnings("nls")
+public abstract class CloneIterable<E>
+	implements Iterable<E>
+{
+	final CloneIterator.Remover<E> remover;
+
+
+	// ********** constructors **********
+
+	protected CloneIterable() {
+		super();
+		this.remover = this.buildDefaultRemover();
+	}
+
+	protected CloneIterable(CloneIterator.Remover<E> remover) {
+		super();
+		if (remover == null) {
+			throw new NullPointerException();
+		}
+		this.remover = remover;
+	}
+
+	CloneIterator.Remover<E> buildDefaultRemover() {
+		return new DefaultRemover();
+	}
+
+
+	// ********** default removal **********
+
+	/**
+	 * Remove the specified element from the original collection.
+	 * <p>
+	 * This method can be overridden by a subclass as an
+	 * alternative to building a
+	 * {@link org.eclipse.jpt.common.utility.internal.iterator.CloneIterator.Remover}.
+	 */
+	protected void remove(@SuppressWarnings("unused") E element) {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+
+	//********** default mutator **********
+
+	class DefaultRemover implements CloneIterator.Remover<E> {
+		@Override
+		public void remove(E element) {
+			CloneIterable.this.remove(element);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/CloneListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/CloneListIterable.java
new file mode 100644
index 0000000..44d0a08
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/CloneListIterable.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import org.eclipse.persistence.tools.utility.iterator.CloneListIterator;
+
+/**
+ * Pull together mutator state and behavior for subclasses.
+ *
+ * @param <E> the type of elements returned by the list iterable's list iterator
+ *
+ * @see SnapshotCloneListIterable
+ * @see LiveCloneListIterable
+ */
+@SuppressWarnings("nls")
+public abstract class CloneListIterable<E>
+	implements ListIterable<E>
+{
+	final CloneListIterator.Mutator<E> mutator;
+
+
+	// ********** constructors **********
+
+	protected CloneListIterable() {
+		super();
+		this.mutator = this.buildDefaultMutator();
+	}
+
+	protected CloneListIterable(CloneListIterator.Mutator<E> mutator) {
+		super();
+		if (mutator == null) {
+			throw new NullPointerException();
+		}
+		this.mutator = mutator;
+	}
+
+	CloneListIterator.Mutator<E> buildDefaultMutator() {
+		return new DefaultMutator();
+	}
+
+
+	// ********** default mutations **********
+
+	/**
+	 * At the specified index, add the specified element to the original list.
+	 * <p>
+	 * This method can be overridden by a subclass as an
+	 * alternative to building a {@link org.eclipse.jpt.common.utility.internal.iterator.CloneListIterator.Mutator}.
+	 */
+	protected void add(@SuppressWarnings("unused") int index, @SuppressWarnings("unused") E element) {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+	/**
+	 * Remove the element at the specified index from the original list.
+	 * <p>
+	 * This method can be overridden by a subclass as an
+	 * alternative to building a {@link org.eclipse.jpt.common.utility.internal.iterator.CloneListIterator.Mutator}.
+	 */
+	protected void remove(@SuppressWarnings("unused") int index) {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+	/**
+	 * At the specified index, set the specified element in the original list.
+	 * <p>
+	 * This method can be overridden by a subclass as an
+	 * alternative to building a {@link org.eclipse.jpt.common.utility.internal.iterator.CloneListIterator.Mutator}.
+	 */
+	protected void set(@SuppressWarnings("unused") int index, @SuppressWarnings("unused") E element) {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+
+	//********** default mutator **********
+
+	class DefaultMutator implements CloneListIterator.Mutator<E> {
+		@Override
+		public void add(int index, E element) {
+			CloneListIterable.this.add(index, element);
+		}
+		@Override
+		public void remove(int index) {
+			CloneListIterable.this.remove(index);
+		}
+		@Override
+		public void set(int index, E element) {
+			CloneListIterable.this.set(index, element);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/CompositeIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/CompositeIterable.java
new file mode 100644
index 0000000..c067929
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/CompositeIterable.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.CompositeIterator;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
+
+/**
+ * A <code>CompositeIterable</code> wraps an {@link Iterable}
+ * of {@link Iterable}s and makes them appear to be a single
+ * {@link Iterable}.
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ *
+ * @see CompositeIterator
+ * @see CompositeListIterable
+ */
+public class CompositeIterable<E>
+	implements Iterable<E>
+{
+	private final Iterable<? extends Iterable<? extends E>> iterables;
+
+
+	/**
+	 * Construct an iterable with the specified collection of iterables.
+	 */
+	public CompositeIterable(Iterable<? extends Iterable<? extends E>> iterables) {
+		super();
+		if (iterables == null) {
+			throw new NullPointerException();
+		}
+		this.iterables = iterables;
+	}
+
+	/**
+	 * Construct an iterable with the specified object prepended
+	 * to the specified iterable.
+	 */
+	@SuppressWarnings("unchecked")
+	public CompositeIterable(E object, Iterable<? extends E> iterable) {
+		this(new SingleElementIterable<E>(object), iterable);
+	}
+
+	/**
+	 * Construct an iterable with the specified object appended
+	 * to the specified iterable.
+	 */
+	@SuppressWarnings("unchecked")
+	public CompositeIterable(Iterable<? extends E> iterable, E object) {
+		this(iterable, new SingleElementIterable<E>(object));
+	}
+
+	/**
+	 * Construct an iterable with the specified iterables.
+	 */
+	public CompositeIterable(Iterable<? extends E>... iterables) {
+		this(new ArrayIterable<Iterable<? extends E>>(iterables));
+	}
+
+	/**
+	 * combined iterators
+	 */
+	@Override
+	public Iterator<E> iterator() {
+		return new CompositeIterator<E>(this.iterators());
+	}
+
+	/**
+	 * iterator of iterators
+	 */
+	protected Iterator<? extends Iterator<? extends E>> iterators() {
+		return new TransformationIterator<Iterable<? extends E>, Iterator<? extends E>>(this.iterables()) {
+			@Override
+			protected Iterator<? extends E> transform(Iterable<? extends E> next) {
+				return next.iterator();
+			}
+		};
+	}
+
+	/**
+	 * iterator of iterables
+	 */
+	protected Iterator<? extends Iterable<? extends E>> iterables() {
+		return this.iterables.iterator();
+	}
+
+	@Override
+	public String toString() {
+		return ListTools.list(this).toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/CompositeListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/CompositeListIterable.java
new file mode 100644
index 0000000..c98ec10
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/CompositeListIterable.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.CompositeListIterator;
+import org.eclipse.persistence.tools.utility.iterator.TransformationListIterator;
+
+/**
+ * A <code>CompositeListIterable</code> wraps a {@link ListIterable}
+ * of {@link ListIterable}s and makes them appear to be a single
+ * {@link ListIterable}.
+ *
+ * @param <E> the type of elements returned by the list iterable's list iterator
+ *
+ * @see CompositeListIterator
+ * @see CompositeIterable
+ * @see ReadOnlyCompositeListIterable
+ */
+public class CompositeListIterable<E>
+	implements ListIterable<E>
+{
+	private final ListIterable<? extends ListIterable<E>> iterables;
+
+
+	/**
+	 * Construct a list iterable on the elements in the specified list of lists.
+	 */
+	public <L extends List<E>> CompositeListIterable(List<L> lists) {
+		this(new TransformationListIterable<L, ListIterable<E>>(lists) {
+				@Override
+				protected ListIterable<E> transform(L list) {
+					return new ListListIterable<E>(list);
+				}
+			});
+	}
+
+	/**
+	 * Construct a list iterable with the specified list of list iterables.
+	 */
+	public CompositeListIterable(ListIterable<? extends ListIterable<E>> iterables) {
+		super();
+		if (iterables == null) {
+			throw new NullPointerException();
+		}
+		this.iterables = iterables;
+	}
+
+	/**
+	 * Construct a list iterable with the specified object prepended
+	 * to the specified list.
+	 */
+	public CompositeListIterable(E object, List<E> list) {
+		this(object, new ListListIterable<E>(list));
+	}
+
+	/**
+	 * Construct a list iterable with the specified object prepended
+	 * to the specified list iterable.
+	 */
+	@SuppressWarnings("unchecked")
+	public CompositeListIterable(E object, ListIterable<E> iterable) {
+		this(new SingleElementListIterable<E>(object), iterable);
+	}
+
+	/**
+	 * Construct a list iterable with the specified object appended
+	 * to the specified list.
+	 */
+	public CompositeListIterable(List<E> list, E object) {
+		this(new ListListIterable<E>(list), object);
+	}
+
+	/**
+	 * Construct a list iterable with the specified object appended
+	 * to the specified list iterable.
+	 */
+	@SuppressWarnings("unchecked")
+	public CompositeListIterable(ListIterable<E> iterable, E object) {
+		this(iterable, new SingleElementListIterable<E>(object));
+	}
+
+	/**
+	 * Construct a list iterable with the specified list iterables.
+	 */
+	public CompositeListIterable(ListIterable<E>... iterables) {
+		this(new ArrayListIterable<ListIterable<E>>(iterables));
+	}
+
+	/**
+	 * Construct a list iterable with the specified lists.
+	 */
+	public CompositeListIterable(List<E>... lists) {
+		this(new TransformationListIterable<List<E>, ListIterable<E>>(new ArrayListIterable<List<E>>(lists)) {
+			@Override
+			protected ListIterable<E> transform(List<E> list) {
+				return new ListListIterable<E>(list);
+			}
+		});
+	}
+
+	/**
+	 * combined list iterators
+	 */
+	@Override
+	public ListIterator<E> iterator() {
+		return new CompositeListIterator<E>(this.iterators());
+	}
+
+	/**
+	 * list iterator of list iterators
+	 */
+	protected ListIterator<? extends ListIterator<E>> iterators() {
+		return new TransformationListIterator<ListIterable<E>, ListIterator<E>>(this.iterables()) {
+			@Override
+			protected ListIterator<E> transform(ListIterable<E> next) {
+				return next.iterator();
+			}
+		};
+	}
+
+	/**
+	 * list iterator of list iterables
+	 */
+	protected ListIterator<? extends ListIterable<E>> iterables() {
+		return this.iterables.iterator();
+	}
+
+	@Override
+	public String toString() {
+		return ListTools.list(this).toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/EmptyIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/EmptyIterable.java
new file mode 100644
index 0000000..810053f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/EmptyIterable.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+
+/**
+ * An <code>EmptyIterable</code> is just that.
+ * Maybe just a touch better-performing than {@link java.util.Collections#EMPTY_SET}
+ * since we don't create a new {@link Iterator} every time {@link #iterator()} is called.
+ * (Not sure why they do that....)
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ *
+ * @see EmptyIterator
+ * @see EmptyListIterable
+ */
+@SuppressWarnings("nls")
+public final class EmptyIterable<E>
+	implements Iterable<E>, Serializable
+{
+	// singleton
+	@SuppressWarnings("rawtypes")
+	private static final Iterable INSTANCE = new EmptyIterable();
+
+	/**
+	 * Return the singleton.
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> Iterable<T> instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure single instance.
+	 */
+	private EmptyIterable() {
+		super();
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return EmptyIterator.instance();
+	}
+
+	@Override
+	public String toString() {
+		return "[]";
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the singleton
+		return INSTANCE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/EmptyListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/EmptyListIterable.java
new file mode 100644
index 0000000..3c5eac9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/EmptyListIterable.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.io.Serializable;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.EmptyListIterator;
+
+/**
+ * An <code>EmptyListIterable</code> is just that.
+ * Maybe just a touch better-performing than {@link java.util.Collections#EMPTY_LIST}
+ * since we don't create a new {@link java.util.Iterator} every time
+ * {@link #iterator()} is called. (Not sure why they do that....)
+ *
+ * @param <E> the type of elements returned by the list iterable's list iterator
+ *
+ * @see EmptyListIterator
+ * @see EmptyIterable
+ */
+@SuppressWarnings("nls")
+public final class EmptyListIterable<E>
+	implements ListIterable<E>, Serializable
+{
+	// singleton
+	@SuppressWarnings("rawtypes")
+	private static final ListIterable INSTANCE = new EmptyListIterable();
+
+	/**
+	 * Return the singleton.
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> ListIterable<T> instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure single instance.
+	 */
+	private EmptyListIterable() {
+		super();
+	}
+
+	@Override
+	public ListIterator<E> iterator() {
+		return EmptyListIterator.instance();
+	}
+
+	@Override
+	public String toString() {
+		return "[]";
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the singleton
+		return INSTANCE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/FilteringIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/FilteringIterable.java
new file mode 100644
index 0000000..3dc1591
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/FilteringIterable.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.iterator.FilteringIterator;
+
+/**
+ * A <code>FilteringIterable</code> wraps another {@link Iterable}
+ * and uses a {@link Filter} to determine which elements in the
+ * nested iterable are to be returned by the iterable's iterator.
+ * <p>
+ * As an alternative to building a {@link Filter}, a subclass
+ * of <code>FilteringIterable</code> can override the
+ * {@link #accept(Object)} method.
+ *
+ * @param <E> the type of elements to be filtered
+ *
+ * @see FilteringIterator
+ */
+@SuppressWarnings("nls")
+public class FilteringIterable<E>
+	implements Iterable<E>
+{
+	private final Iterable<? extends E> iterable;
+	private final Filter<E> filter;
+
+
+	/**
+	 * Construct an iterable with the specified nested
+	 * iterable and a default filter that calls back to the iterable.
+	 * Use this constructor if you want to override the
+	 * {@link #accept(Object)} method instead of building
+	 * a {@link Filter}.
+	 */
+	public FilteringIterable(Iterable<? extends E> iterable) {
+		super();
+		this.iterable = iterable;
+		this.filter = this.buildDefaultFilter();
+	}
+
+	/**
+	 * Construct an iterable with the specified nested
+	 * iterable and filter.
+	 */
+	public FilteringIterable(Iterable<? extends E> iterable, Filter<E> filter) {
+		super();
+		if ((iterable == null) || (filter == null)) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+		this.filter = filter;
+	}
+
+	protected Filter<E> buildDefaultFilter() {
+		return new DefaultFilter();
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return new FilteringIterator<E>(this.iterable.iterator(), this.filter);
+	}
+
+	/**
+	 * Return whether the iterable's iterator
+	 * should return the specified next element from a call to the
+	 * {@link Iterator#next()} method.
+	 * <p>
+	 * This method can be overridden by a subclass as an
+	 * alternative to building a {@link Filter}.
+	 */
+	protected boolean accept(@SuppressWarnings("unused") E o) {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+	@Override
+	public String toString() {
+		return ListTools.list(this).toString();
+	}
+
+
+	//********** default filter **********
+
+	protected class DefaultFilter implements Filter<E> {
+		@Override
+		public boolean accept(E o) {
+			return FilteringIterable.this.accept(o);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/GraphIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/GraphIterable.java
new file mode 100644
index 0000000..2d54dda
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/GraphIterable.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.GraphIterator;
+
+/**
+ * A <code>GraphIterable</code> is similar to a {@link TreeIterable}
+ * except that it cannot be assumed that all nodes assume a strict tree
+ * structure. For instance, in a tree, a node cannot be a descendent of
+ * itself, but a graph may have a cyclical structure.
+ *
+ * A <code>GraphIterable</code> simplifies the traversal of a
+ * graph of objects, where the objects' protocol(s) provides
+ * a method for getting the next collection of nodes in the graph,
+ * (or <em>neighbors</em>), but does not provide a method for
+ * getting <em>all</em> of the nodes in the graph.
+ * (e.g. a neighbor can return his neighbors, and those neighbors
+ * can return their neighbors, which might also include the original
+ * neighbor, but you only want to visit the original neighbor once.)
+ * <p>
+ * If a neighbor has already been visited (determined by using
+ * {@link #equals(Object)}), that neighbor is not visited again,
+ * nor are the neighbors of that object.
+ * <p>
+ * It is up to the user of this class to ensure a <em>complete</em> graph.
+ * <p>
+ * To use, supply:<ul>
+ * <li> either the initial node of the graph or an {@link Iterable}
+ * of the initial collection of graph nodes
+ * <li> a {@link org.eclipse.jpt.common.utility.internal.iterator.GraphIterator.MisterRogers} that tells who the neighbors are
+ * of each node
+ * (alternatively, subclass <code>GraphIterable</code>
+ * and override the {@link #neighbors(Object)} method)
+ * </ul>
+ * The {@link Iterator#remove()} operation is not supported. This behavior, if
+ * desired, must be implemented by the user of this class.
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ *
+ * @see GraphIterator
+ */
+@SuppressWarnings("nls")
+public class GraphIterable<E>
+	implements Iterable<E>
+{
+	private final Iterable<? extends E> roots;
+	private final GraphIterator.MisterRogers<E> misterRogers;
+
+
+	/**
+	 * Construct an iterable containing the nodes of a graph with the specified root
+	 * and a default Mr. Rogers that calls back to the iterable.
+	 * Use this constructor if you want to override the
+	 * {@link #neighbors(Object)} method instead of building
+	 * a {@link org.eclipse.jpt.common.utility.internal.iterator.GraphIterator.MisterRogers}.
+	 */
+	public GraphIterable(E root) {
+		this(new SingleElementIterable<E>(root));
+	}
+
+	/**
+	 * Construct an iterable containing the nodes of a graph
+	 * with the specified root and Mr. Rogers.
+	 */
+	public GraphIterable(E root, GraphIterator.MisterRogers<E> misterRogers) {
+		this(new SingleElementIterable<E>(root), misterRogers);
+	}
+
+	/**
+	 * Construct an iterable containing the nodes of a graph
+	 * with the specified collection of roots
+	 * and a default Mr. Rogers that calls back to the iterable.
+	 * Use this constructor if you want to override the
+	 * {@link #neighbors(Object)} method instead of building
+	 * a {@link org.eclipse.jpt.common.utility.internal.iterator.GraphIterator.MisterRogers}.
+	 */
+	public GraphIterable(E... roots) {
+		this(Arrays.asList(roots));
+	}
+
+	/**
+	 * Construct an iterable containing the nodes of a graph
+	 * with the specified roots and Mr. Rogers.
+	 */
+	public GraphIterable(E[] roots, GraphIterator.MisterRogers<E> misterRogers) {
+		this(Arrays.asList(roots), misterRogers);
+	}
+
+	/**
+	 * Construct an iterable containing the nodes of a graph
+	 * with the specified collection of roots
+	 * and a default Mr. Rogers that calls back to the iterable.
+	 * Use this constructor if you want to override the
+	 * {@link #neighbors(Object)} method instead of building
+	 * a {@link org.eclipse.jpt.common.utility.internal.iterator.GraphIterator.MisterRogers}.
+	 */
+	public GraphIterable(Iterable<? extends E> roots) {
+		super();
+		if (roots == null) {
+			throw new NullPointerException();
+		}
+		this.roots = roots;
+		this.misterRogers = this.buildDefaultMisterRogers();
+	}
+
+	/**
+	 * Construct an iterable containing the nodes of a graph
+	 * with the specified roots and Mr. Rogers.
+	 */
+	public GraphIterable(Iterable<? extends E> roots, GraphIterator.MisterRogers<E> misterRogers) {
+		super();
+		if ((roots == null) || (misterRogers == null)) {
+			throw new NullPointerException();
+		}
+		this.roots = roots;
+		this.misterRogers = misterRogers;
+	}
+
+	protected GraphIterator.MisterRogers<E> buildDefaultMisterRogers() {
+		return new DefaultMisterRogers();
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return new GraphIterator<E>(this.roots, this.misterRogers);
+	}
+
+	/**
+	 * Return the immediate neighbors of the specified object.
+	 * <p>
+	 * This method can be overridden by a subclass as an
+	 * alternative to building a {@link org.eclipse.jpt.common.utility.internal.iterator.GraphIterator.MisterRogers}.
+	 */
+	protected Iterator<? extends E> neighbors(@SuppressWarnings("unused") E next) {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+	@Override
+	public String toString() {
+		return ListTools.list(this).toString();
+	}
+
+
+	//********** default Mr. Rogers **********
+
+	protected class DefaultMisterRogers implements GraphIterator.MisterRogers<E> {
+		@Override
+		public Iterator<? extends E> neighbors(E node) {
+			return GraphIterable.this.neighbors(node);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/IterableTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/IterableTools.java
new file mode 100644
index 0000000..880abbd
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/IterableTools.java
@@ -0,0 +1,1034 @@
+/*******************************************************************************

+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.iterable;

+

+import java.util.ArrayList;

+import java.util.Arrays;

+import java.util.Collection;

+import java.util.Comparator;

+import java.util.Iterator;

+import java.util.List;

+import org.eclipse.persistence.tools.utility.collection.CollectionTools;

+import org.eclipse.persistence.tools.utility.collection.HashBag;

+import org.eclipse.persistence.tools.utility.collection.ListTools;

+import org.eclipse.persistence.tools.utility.collection.Queue;

+import org.eclipse.persistence.tools.utility.collection.Stack;

+import org.eclipse.persistence.tools.utility.command.InterruptibleParameterizedCommand;

+import org.eclipse.persistence.tools.utility.command.ParameterizedCommand;

+import org.eclipse.persistence.tools.utility.filter.Filter;

+import org.eclipse.persistence.tools.utility.iterator.ChainIterator;

+import org.eclipse.persistence.tools.utility.iterator.CloneIterator;

+import org.eclipse.persistence.tools.utility.iterator.CloneListIterator;

+import org.eclipse.persistence.tools.utility.iterator.GraphIterator;

+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;

+import org.eclipse.persistence.tools.utility.transformer.Transformer;

+

+/**

+ * {@link Iterable} utility methods.

+ * @see org.eclipse.jpt.common.utility.internal.ArrayTools

+ * @see CollectionTools

+ * @see IteratorTools

+ * @see ListTools

+ */

+public final class IterableTools {

+	/**

+	 * Return a bag corresponding to the specified iterable.

+	 */

+	public static <E> HashBag<E> bag(Iterable<? extends E> iterable) {

+		return CollectionTools.bag(iterable);

+	}

+

+	/**

+	 * Return a bag corresponding to the specified iterable.

+	 * The specified iterable size is a performance hint.

+	 */

+	public static <E> HashBag<E> bag(Iterable<? extends E> iterable, int iterableSize) {

+		return CollectionTools.bag(iterable, iterableSize);

+	}

+

+	/**

+	 * Return a collection corresponding to the specified iterable.

+	 */

+	public static <E> HashBag<E> collection(Iterable<? extends E> iterable) {

+		return CollectionTools.collection(iterable);

+	}

+

+	/**

+	 * Return a collection corresponding to the specified iterable.

+	 * The specified iterable size is a performance hint.

+	 */

+	public static <E> HashBag<E> collection(Iterable<? extends E> iterable, int iterableSize) {

+		return CollectionTools.collection(iterable, iterableSize);

+	}

+

+	/**

+	 * Return whether the specified iterable contains the

+	 * specified element.

+	 */

+	public static boolean contains(Iterable<?> iterable, Object value) {

+		return IteratorTools.contains(iterable.iterator(), value);

+	}

+

+	/**

+	 * Return whether the specified iterable contains all of the

+	 * elements in the specified collection.

+	 */

+	public static boolean containsAll(Iterable<?> iterable, Collection<?> collection) {

+		return IteratorTools.containsAll(iterable.iterator(), collection);

+	}

+

+

+	/**

+	 * Return whether the specified iterable contains all of the

+	 * elements in the specified collection.

+	 * The specified iterable size is a performance hint.

+	 */

+	public static boolean containsAll(Iterable<?> iterable, int iterableSize, Collection<?> collection) {

+		return IteratorTools.containsAll(iterable.iterator(), iterableSize, collection);

+	}

+

+

+	/**

+	 * Return whether the specified iterable 1 contains all of the

+	 * elements in the specified iterable 2.

+	 */

+	public static boolean containsAll(Iterable<?> iterable1, Iterable<?> iterable2) {

+		return IteratorTools.containsAll(iterable1.iterator(), iterable2);

+	}

+

+

+	/**

+	 * Return whether the specified iterable 1 contains all of the

+	 * elements in the specified iterable 2.

+	 * The specified iterable 1 size is a performance hint.

+	 */

+	public static boolean containsAll(Iterable<?> iterable1, int iterable1Size, Iterable<?> iterable2) {

+		return IteratorTools.containsAll(iterable1.iterator(), iterable1Size, iterable2);

+	}

+

+

+	/**

+	 * Return whether the specified iterable contains all of the

+	 * elements in the specified iterator.

+	 */

+	public static boolean containsAll(Iterable<?> iterable, Iterator<?> iterator) {

+		return IteratorTools.containsAll(iterable.iterator(), iterator);

+	}

+

+

+	/**

+	 * Return whether the specified iterable contains all of the

+	 * elements in the specified iterator.

+	 * The specified iterable size is a performance hint.

+	 */

+	public static boolean containsAll(Iterable<?> iterable, int iterableSize, Iterator<?> iterator) {

+		return IteratorTools.containsAll(iterable.iterator(), iterableSize, iterator);

+	}

+

+

+	/**

+	 * Return whether the specified iterable contains all of the

+	 * elements in the specified array.

+	 */

+	public static boolean containsAll(Iterable<?> iterable, Object... array) {

+		return IteratorTools.containsAll(iterable.iterator(), array);

+	}

+

+

+	/**

+	 * Return whether the specified iterable contains all of the

+	 * elements in the specified array.

+	 * The specified iterable size is a performance hint.

+	 */

+	public static boolean containsAll(Iterable<?> iterable, int iterableSize, Object... array) {

+		return IteratorTools.containsAll(iterable.iterator(), iterableSize, array);

+	}

+

+	/**

+	 * Return whether the specified iterables do not return the same elements

+	 * in the same order.

+	 */

+	public static boolean elementsAreDifferent(Iterable<?> iterable1, Iterable<?> iterable2) {

+		return IteratorTools.elementsAreDifferent(iterable1.iterator(), iterable2.iterator());

+	}

+

+

+	/**

+	 * Return whether the specified iterables return equal elements

+	 * in the same order.

+	 */

+	public static boolean elementsAreEqual(Iterable<?> iterable1, Iterable<?> iterable2) {

+		return IteratorTools.elementsAreEqual(iterable1.iterator(), iterable2.iterator());

+	}

+

+

+	/**

+	 * Return whether the specified iterables return the same elements.

+	 */

+	public static boolean elementsAreIdentical(Iterable<?> iterable1, Iterable<?> iterable2) {

+		return IteratorTools.elementsAreIdentical(iterable1.iterator(), iterable2.iterator());

+	}

+

+

+	/**

+	 * Return whether the specified iterables do <em>not</em> return the same

+	 * elements.

+	 */

+	public static boolean elementsAreNotIdentical(Iterable<?> iterable1, Iterable<?> iterable2) {

+		return IteratorTools.elementsAreNotIdentical(iterable1.iterator(), iterable2.iterator());

+	}

+

+	/**

+	 * Execute the specified command for each element in the specified iterable.

+	 */

+	public static <E> void execute(Iterable<? extends E> iterable, ParameterizedCommand<E> command) {

+		IteratorTools.execute(iterable.iterator(), command);

+	}

+

+	/**

+	 * Execute the specified command for each element in the specified iterable.

+	 */

+	public static <E> void execute(Iterable<? extends E> iterable, InterruptibleParameterizedCommand<E> command) throws InterruptedException {

+		IteratorTools.execute(iterable.iterator(), command);

+	}

+

+	/**

+	 * Return the element corresponding to the specified index

+	 * in the specified iterable.

+	 */

+	public static <E> E get(Iterable<? extends E> iterable, int index) {

+		return IteratorTools.get(iterable.iterator(), index);

+	}

+

+	/**

+	 * Return a hash code corresponding to the elements in the specified iterable.

+	 */

+	public static int hashCode(Iterable<?> iterable) {

+		return (iterable == null) ? 0 : IteratorTools.hashCode(iterable.iterator());

+	}

+

+	/**

+	 * Return the index of the first occurrence of the

+	 * specified element in the specified iterable;

+	 * return -1 if there is no such element.

+	 */

+	public static int indexOf(Iterable<?> iterable, Object value) {

+		return IteratorTools.indexOf(iterable.iterator(), value);

+	}

+

+	/**

+	 * Return whether the specified iterable is empty

+	 * (Shortcuts the iterator rather than calculating the entire size)

+	 */

+	public static boolean isEmpty(Iterable<?> iterable) {

+		return IteratorTools.isEmpty(iterable.iterator());

+	}

+

+	/**

+	 * Return the specified iterable's last element.

+	 * @exception java.util.NoSuchElementException iterable is empty.

+	 */

+	public static <E> E last(Iterable<E> iterable) {

+		return IteratorTools.last(iterable.iterator());

+	}

+

+	/**

+	 * Return the index of the last occurrence of the

+	 * specified element in the specified iterable;

+	 * return -1 if there is no such element.

+	 */

+	public static int lastIndexOf(Iterable<?> iterable, Object value) {

+		return IteratorTools.lastIndexOf(iterable.iterator(), value);

+	}

+

+	/**

+	 * Return a list corresponding to the specified iterable.

+	 */

+	public static <E> ArrayList<E> list(Iterable<? extends E> iterable) {

+		return ListTools.list(iterable);

+	}

+

+	/**

+	 * Return a list corresponding to the specified iterable.

+	 * The specified iterable size is a performance hint.

+	 */

+	public static <E> ArrayList<E> list(Iterable<? extends E> iterable, int iterableSize) {

+		return ListTools.list(iterable, iterableSize);

+	}

+

+	/**

+	 * Return the number of elements returned by the specified iterable.

+	 */

+	public static int size(Iterable<?> iterable) {

+		return IteratorTools.size(iterable.iterator());

+	}

+

+	/**

+	 * Return an iterable containing the sorted elements of the specified iterable.

+	 */

+	public static <E extends Comparable<? super E>> Iterable<E> sort(Iterable<E> iterable) {

+		return sort(iterable, null);

+	}

+

+	/**

+	 * Return an iterable containing the sorted elements of the specified iterable.

+	 * The specified iterable size is a performance hint.

+	 */

+	public static <E extends Comparable<? super E>> Iterable<E> sort(Iterable<E> iterable, int iterableSize) {

+		return sort(iterable, null, iterableSize);

+	}

+

+	/**

+	 * Return an iterable containing the sorted elements of the specified iterable.

+	 */

+	public static <E> Iterable<E> sort(Iterable<E> iterable, Comparator<? super E> comparator) {

+		return ListTools.sort(ListTools.list(iterable), comparator);

+	}

+

+	/**

+	 * Return an iterable containing the sorted elements of the specified iterable.

+	 * The specified iterable size is a performance hint.

+	 */

+	public static <E> Iterable<E> sort(Iterable<E> iterable, Comparator<? super E> comparator, int iterableSize) {

+		return ListTools.sort(ListTools.list(iterable, iterableSize), comparator);

+	}

+

+	/**

+	 * Convert the specified iterable into an array.

+	 * @see Collection#toArray()

+	 */

+	public static Object[] toArray(Iterable<?> iterable) {

+		return list(iterable).toArray();

+	}

+

+	/**

+	 * Convert the specified iterable into an array.

+	 * The specified iterable size is a performance hint.

+	 * @see Collection#toArray()

+	 */

+	public static Object[] toArray(Iterable<?> iterable, int iterableSize) {

+		return list(iterable, iterableSize).toArray();

+	}

+

+	/**

+	 * Convert the specified iterable into an array.

+	 * @see Collection#toArray(Object[])

+	 */

+	public static <E> E[] toArray(Iterable<? extends E> iterable, E[] array) {

+		return list(iterable).toArray(array);

+	}

+

+	/**

+	 * Convert the specified iterable into an array.

+	 * The specified iterable size is a performance hint.

+	 * @see Collection#toArray(Object[])

+	 */

+	public static <E> E[] toArray(Iterable<? extends E> iterable, int iterableSize, E[] array) {

+		return list(iterable, iterableSize).toArray(array);

+	}

+

+

+	// ********** factory methods **********

+

+	/**

+	 * Return a chain iterable that starts with the specified element and uses

+	 * the specified {@link org.eclipse.jpt.common.utility.internal.iterator.ChainIterator.Linker linker}.

+	 * @see ChainIterable

+	 */

+	public static <E> ChainIterable<E> chainIterable(E startLink, ChainIterator.Linker<E> linker) {

+		return new ChainIterable<E>(startLink, linker);

+	}

+

+	/**

+	 * Return an iterable that returns the specified object followed by the

+	 * elements in the specified iterable.

+	 * @see CompositeIterable

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> CompositeIterable<E> compositeIterable(E object, Iterable<? extends E> iterable) {

+		return compositeIterable(new Iterable[] { singletonIterable(object), iterable });

+	}

+

+	/**

+	 * Return an iterable that returns the

+	 * elements in the specified iterable followed by the specified object.

+	 * @see CompositeIterable

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> CompositeIterable<E> compositeIterable(Iterable<? extends E> iterable, E object) {

+		return compositeIterable(new Iterable[] { iterable, singletonIterable(object) });

+	}

+

+	/**

+	 * Return an iterable that returns the

+	 * elements in the specified iterables.

+	 * @see CompositeIterable

+	 */

+	public static <E> CompositeIterable<E> compositeIterable(Iterable<? extends E>... iterables) {

+		return compositeIterable(Arrays.asList(iterables));

+	}

+

+	/**

+	 * Return an iterable that returns the

+	 * elements in the specified iterables.

+	 * @see CompositeIterable

+	 */

+	public static <E> CompositeIterable<E> compositeIterable(Iterable<? extends Iterable<? extends E>> iterables) {

+		return new CompositeIterable<E>(iterables);

+	}

+

+	/**

+	 * Return an iterable on the children of the specified parents.

+	 * Use the specified transformer to transform each parent into its children.

+	 * @see CompositeIterable

+	 */

+	public static <P, E> CompositeIterable<E> compositeIterable(Iterable<? extends P> parents, Transformer<P, Iterable<? extends E>> childrenTransformer) {

+		return compositeIterable(transform(parents, childrenTransformer));

+	}

+

+	/**

+	 * Return a list iterable that returns the specified object followed by the

+	 * elements in the specified list.

+	 * @see CompositeListIterable

+	 */

+	public static <E> CompositeListIterable<E> compositeListIterable(E object, List<E> list) {

+		return compositeListIterable(object, listIterable(list));

+	}

+

+	/**

+	 * Return a list iterable that returns the specified object followed by the

+	 * elements in the specified iterable.

+	 * @see CompositeListIterable

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> CompositeListIterable<E> compositeListIterable(E object, ListIterable<E> iterable) {

+		return compositeListIterable(new ListIterable[] { singletonListIterable(object), iterable });

+	}

+

+	/**

+	 * Return a list iterable that returns the elements in the specified list

+	 * followed by the specified object.

+	 * @see CompositeListIterable

+	 */

+	public static <E> CompositeListIterable<E> compositeListIterable(List<E> list, E object) {

+		return compositeListIterable(listIterable(list), object);

+	}

+

+	/**

+	 * Return a list iterable that returns the

+	 * elements in the specified lists.

+	 * @see CompositeListIterable

+	 */

+	public static <E> CompositeListIterable<E> compositeListIterable(List<E>... lists) {

+		return compositeListIterable(Arrays.asList(lists));

+	}

+

+	/**

+	 * Return a list iterable that returns the

+	 * elements in the specified lists.

+	 * @see CompositeListIterable

+	 */

+	public static <E> CompositeListIterable<E> compositeListIterable(List<? extends List<E>> lists) {

+		Transformer<List<E>, ListIterable<E>> transformer = listListIterableTransformer();

+		return compositeListIterable(transform(listIterable(lists), transformer));

+	}

+

+	/**

+	 * Return a list iterable that returns the

+	 * elements in the specified iterables.

+	 * @see CompositeListIterable

+	 */

+	public static <E> CompositeListIterable<E> compositeListIterable(ListIterable<? extends ListIterable<E>> iterables) {

+		return new CompositeListIterable<E>(iterables);

+	}

+

+	/**

+	 * Return a list iterable on the children of the specified parents.

+	 * Use the specified transformer to transform each parent into its children.

+	 * @see CompositeListIterable

+	 */

+	public static <P, E> CompositeListIterable<E> compositeListIterable(ListIterable<? extends P> parents, Transformer<P, ListIterable<E>> childrenTransformer) {

+		return compositeListIterable(transform(parents, childrenTransformer));

+	}

+

+	/**

+	 * Return a list iterable that returns the

+	 * elements in the specified iterable followed by the specified object.

+	 * @see CompositeListIterable

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> CompositeListIterable<E> compositeListIterable(ListIterable<E> iterable, E object) {

+		return compositeListIterable(new ListIterable[] { iterable, singletonListIterable(object) });

+	}

+

+	/**

+	 * Return a list iterable that returns the

+	 * elements in the specified iterables.

+	 * @see CompositeListIterable

+	 */

+	public static <E> CompositeListIterable<E> compositeListIterable(ListIterable<E>... iterables) {

+		return compositeListIterable(listIterable(iterables));

+	}

+

+	/**

+	 * Return an empty iterable.

+	 */

+	public static <E> Iterable<E> emptyIterable() {

+		return EmptyIterable.instance();

+	}

+

+	/**

+	 * Return an empty list iterable.

+	 */

+	public static <E> ListIterable<E> emptyListIterable() {

+		return EmptyListIterable.instance();

+	}

+

+	/**

+	 * Return an iterable that will use the specified filter to filter the

+	 * elements in the specified iterable.

+	 * @see FilteringIterable

+	 */

+	public static <E> FilteringIterable<E> filter(Iterable<? extends E> iterable, Filter<E> filter) {

+		return new FilteringIterable<E>(iterable, filter);

+	}

+

+	/**

+	 * Return an iterable that will return the specified root element followed

+	 * by its children etc. as determined by the specified Mr. Rogers.

+	 * @see GraphIterable

+	 */

+	public static <E> GraphIterable<E> graphIterable(E root, GraphIterator.MisterRogers<E> misterRogers) {

+		return new GraphIterable<E>(root, misterRogers);

+	}

+

+	/**

+	 * Return an iterable that will return the specified root elements followed

+	 * by their children etc. as determined by the specified Mr. Rogers.

+	 * @see GraphIterable

+	 */

+	public static <E> GraphIterable<E> graphIterable(E[] roots, GraphIterator.MisterRogers<E> misterRogers) {

+		return new GraphIterable<E>(roots, misterRogers);

+	}

+

+	/**

+	 * Return an iterable that will return the specified root elements followed

+	 * by their children etc. as determined by the specified Mr. Rogers.

+	 * @see GraphIterable

+	 */

+	public static <E> GraphIterable<E> graphIterable(Iterable<E> roots, GraphIterator.MisterRogers<E> misterRogers) {

+		return new GraphIterable<E>(roots, misterRogers);

+	}

+

+	/**

+	 * Return an iterable on the elements in the specified array.

+	 */

+	public static <E> ArrayIterable<E> iterable(E... array) {

+		return iterable(array, 0);

+	}

+

+	/**

+	 * Return an iterable on the elements in the specified array

+	 * starting at the specified position in the array.

+	 */

+	public static <E> ArrayIterable<E> iterable(E[] array, int start) {

+		return iterable(array, start, array.length);

+	}

+

+	/**

+	 * Return an iterable on the elements in the specified array

+	 * starting at the specified start index, inclusive, and continuing to

+	 * the specified end index, exclusive.

+	 */

+	public static <E> ArrayIterable<E> iterable(E[] array, int start, int end) {

+		return new ArrayIterable<E>(array, start, end);

+	}

+

+	/**

+	 * Return an iterable on the specified queue.

+	 * @see Queue

+	 */

+	public static <E> QueueIterable<E> iterable(Queue<E> queue) {

+		return new QueueIterable<E>(queue);

+	}

+

+	/**

+	 * Return an iterable on the specified stack.

+	 * @see Stack

+	 */

+	public static <E> StackIterable<E> iterable(Stack<E> stack) {

+		return new StackIterable<E>(stack);

+	}

+

+	/**

+	 * Return an iterable that converts the specified iterable's element type.

+	 * @see LateralIterableWrapper

+	 */

+	public static <E1, E2> LateralIterableWrapper<E1, E2> lateralIterable(Iterable<E1> iterable) {

+		return new LateralIterableWrapper<E1, E2>(iterable);

+	}

+

+	/**

+	 * Return a list iterable that converts the specified list iterable's element type.

+	 * @see LateralIterableWrapper

+	 */

+	public static <E1, E2> LateralListIterableWrapper<E1, E2> lateralIterable(ListIterable<E1> iterable) {

+		return new LateralListIterableWrapper<E1, E2>(iterable);

+	}

+

+	/**

+	 * Return a list iterable for the specified array.

+	 */

+	public static <E> ArrayListIterable<E> listIterable(E... array) {

+		return listIterable(array, 0);

+	}

+

+	/**

+	 * Return a list iterable for the specified array

+	 * starting at the specified position in the array.

+	 */

+	public static <E> ArrayListIterable<E> listIterable(E[] array, int start) {

+		return listIterable(array, start, array.length);

+	}

+

+	/**

+	 * Return a list iterable for the specified array

+	 * starting at the specified start index, inclusive, and continuing to

+	 * the specified end index, exclusive.

+	 */

+	public static <E> ArrayListIterable<E> listIterable(E[] array, int start, int end) {

+		return new ArrayListIterable<E>(array, start, end);

+	}

+

+	/**

+	 * Return a list iterable for the specified list.

+	 */

+	public static <E> ListListIterable<E> listIterable(List<E> list) {

+		return new ListListIterable<E>(list);

+	}

+

+	/**

+	 * Return a transformer that transforms a {@link List} into a

+	 * {@link ListIterable}.

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> Transformer<List<E>, ListIterable<E>> listListIterableTransformer() {

+		return LIST_LIST_ITERABLE_TRANSFORMER;

+	}

+

+	/**

+	 * A transformer that transforms a {@link List} into a

+	 * {@link ListIterable}.

+	 */

+	@SuppressWarnings("rawtypes")

+	public static final Transformer LIST_LIST_ITERABLE_TRANSFORMER = new ListListIterableTransformer();

+	/* CU private */ static class ListListIterableTransformer<E>

+		implements Transformer<List<E>, ListIterable<E>>

+	{

+		@Override

+		public ListIterable<E> transform(List<E> list) {

+			return listIterable(list);

+		}

+	}

+

+	/**

+	 * Return a transformer that transforms a {@link List} into a

+	 * read-only {@link ListIterable}.

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> Transformer<List<? extends E>, ListIterable<? extends E>> readOnlyListListIterableTransformer() {

+		return READ_ONLY_LIST_LIST_ITERABLE_TRANSFORMER;

+	}

+

+	/**

+	 * A transformer that transforms a {@link List} into a

+	 * read-only {@link ListIterable}.

+	 */

+	@SuppressWarnings("rawtypes")

+	public static final Transformer READ_ONLY_LIST_LIST_ITERABLE_TRANSFORMER = new ReadOnlyListListIterableTransformer();

+	/* CU private */ static class ReadOnlyListListIterableTransformer<E>

+		implements Transformer<List<? extends E>, ListIterable<? extends E>>

+	{

+		@Override

+		public ListIterable<? extends E> transform(List<? extends E> list) {

+			return listIterable(list);

+		}

+	}

+

+	/**

+	 * Return an iterable that clones the specified collection before returning

+	 * elements.

+	 * @see LiveCloneIterable

+	 */

+	public static <E> LiveCloneIterable<E> liveCloneIterable(Collection<? extends E> collection) {

+		return new LiveCloneIterable<E>(collection);

+	}

+

+	/**

+	 * Return an iterable that clones the specified collection before returning

+	 * elements and uses the specified {@link org.eclipse.jpt.common.utility.internal.iterator.CloneIterator.Remover remover}.

+	 * @see LiveCloneIterable

+	 */

+	public static <E> LiveCloneIterable<E> liveCloneIterable(Collection<? extends E> collection, CloneIterator.Remover<E> remover) {

+		return new LiveCloneIterable<E>(collection, remover);

+	}

+

+	/**

+	 * Return a list iterable that clones the specified collection before returning

+	 * elements.

+	 * @see LiveCloneListIterable

+	 */

+	public static <E> LiveCloneListIterable<E> liveCloneListIterable(List<? extends E> list) {

+		return new LiveCloneListIterable<E>(list);

+	}

+

+	/**

+	 * Return a list iterable that clones the specified collection before returning

+	 * elements and uses the specified {@link org.eclipse.jpt.common.utility.internal.iterator.CloneListIterator.Mutator mutator}.

+	 * @see LiveCloneListIterable

+	 */

+	public static <E> LiveCloneListIterable<E> liveCloneListIterable(List<? extends E> list, CloneListIterator.Mutator<E> mutator) {

+		return new LiveCloneListIterable<E>(list, mutator);

+	}

+

+	/**

+	 * Construct an iterable that wraps the specified iterable and returns a

+	 * {@link org.eclipse.jpt.common.utility.internal.iterator.PeekableIterator}.

+	 * @see PeekableIterable

+	 */

+	public static <E> PeekableIterable<E> peekableIterable(Iterable<? extends E> iterable) {

+		return new PeekableIterable<E>(iterable);

+	}

+

+	/**

+	 * Return a list iterable that returns the specified object followed by the

+	 * elements in the specified list.

+	 * @see ReadOnlyCompositeListIterable

+	 */

+	public static <E, T extends E> ReadOnlyCompositeListIterable<E> readOnlyCompositeListIterable(E object, List<T> list) {

+		return readOnlyCompositeListIterable(object, listIterable(list));

+	}

+

+	/**

+	 * Return a list iterable that returns the specified object followed by the

+	 * elements in the specified iterable.

+	 * @see ReadOnlyCompositeListIterable

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> ReadOnlyCompositeListIterable<E> readOnlyCompositeListIterable(E object, ListIterable<? extends E> iterable) {

+		return readOnlyCompositeListIterable(new ListIterable[] { singletonListIterable(object), iterable });

+	}

+

+	/**

+	 * Return a list iterable that returns the elements in the specified list

+	 * followed by the specified object.

+	 * @see ReadOnlyCompositeListIterable

+	 */

+	public static <E> ReadOnlyCompositeListIterable<E> readOnlyCompositeListIterable(List<E> list, E object) {

+		return readOnlyCompositeListIterable(listIterable(list), object);

+	}

+

+	/**

+	 * Return a list iterable that returns the

+	 * elements in the specified lists.

+	 * @see ReadOnlyCompositeListIterable

+	 */

+	public static <E> ReadOnlyCompositeListIterable<E> readOnlyCompositeListIterable(List<E>... lists) {

+		return readOnlyCompositeListIterable(Arrays.asList(lists));

+	}

+

+	/**

+	 * Return a list iterable that returns the

+	 * elements in the specified lists.

+	 * @see ReadOnlyCompositeListIterable

+	 */

+	public static <E> ReadOnlyCompositeListIterable<E> readOnlyCompositeListIterable(List<? extends List<? extends E>> lists) {

+		Transformer<List<? extends E>, ListIterable<? extends E>> transformer = readOnlyListListIterableTransformer();

+		return readOnlyCompositeListIterable(transform(listIterable(lists), transformer));

+	}

+

+	/**

+	 * Return a list iterable that returns the

+	 * elements in the specified iterables.

+	 * @see ReadOnlyCompositeListIterable

+	 */

+	public static <E> ReadOnlyCompositeListIterable<E> readOnlyCompositeListIterable(ListIterable<? extends ListIterable<? extends E>> iterables) {

+		return new ReadOnlyCompositeListIterable<E>(iterables);

+	}

+

+	/**

+	 * Return a list iterable on the children of the specified parents.

+	 * Use the specified transformer to transform each parent into its children.

+	 * @see ReadOnlyCompositeListIterable

+	 */

+	public static <P, E> ReadOnlyCompositeListIterable<E> readOnlyCompositeListIterable(ListIterable<? extends P> parents, Transformer<P, ListIterable<? extends E>> childrenTransformer) {

+		return readOnlyCompositeListIterable(transform(parents, childrenTransformer));

+	}

+

+	/**

+	 * Return a list iterable that returns the

+	 * elements in the specified iterable followed by the specified object.

+	 * @see ReadOnlyCompositeListIterable

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> ReadOnlyCompositeListIterable<E> readOnlyCompositeListIterable(ListIterable<? extends E> iterable, E object) {

+		return readOnlyCompositeListIterable(new ListIterable[] { iterable, singletonListIterable(object) });

+	}

+

+	/**

+	 * Return a list iterable that returns the

+	 * elements in the specified iterables.

+	 * @see ReadOnlyCompositeListIterable

+	 */

+	public static <E> ReadOnlyCompositeListIterable<E> readOnlyCompositeListIterable(ListIterable<? extends E>... iterables) {

+		return readOnlyCompositeListIterable(listIterable(iterables));

+	}

+

+	/**

+	 * Convert the specified iterable to read-only.

+	 * @see ReadOnlyIterable

+	 */

+	public static <E> ReadOnlyIterable<E> readOnlyIterable(Iterable<? extends E> iterable) {

+		return new ReadOnlyIterable<E>(iterable);

+	}

+

+	/**

+	 * Convert the specified iterable to read-only.

+	 * @see ReadOnlyListIterable

+	 */

+	public static <E> ReadOnlyListIterable<E> readOnlyListIterable(ListIterable<? extends E> iterable) {

+		return new ReadOnlyListIterable<E>(iterable);

+	}

+

+	/**

+	 * Return an iterable that provides simultaneous processing of the elements

+	 * in the specified iterables.

+	 * @see SimultaneousIterable

+	 */

+	public static <E, I extends Iterable<E>> SimultaneousIterable<E> simultaneousIterable(I... iterables) {

+		return new SimultaneousIterable<E>(iterables);

+	}

+

+	/**

+	 * Return an iterable that provides simultaneous processing of the elements

+	 * in the specified iterables.

+	 * @see SimultaneousIterable

+	 */

+	public static <E, I extends Iterable<E>> SimultaneousIterable<E> simultaneousIterable(Iterable<I> iterables) {

+		return new SimultaneousIterable<E>(iterables);

+	}

+

+	/**

+	 * Return an iterable that provides simultaneous processing of the elements

+	 * in the specified iterables.

+	 * @see SimultaneousIterable

+	 */

+	public static <E, I extends Iterable<E>> SimultaneousIterable<E> simultaneousIterable(Iterable<I> iterables, int iterablesSize) {

+		return new SimultaneousIterable<E>(iterables, iterablesSize);

+	}

+

+	/**

+	 * Return a list iterable that provides simultaneous processing of the elements

+	 * in the specified iterables.

+	 * @see SimultaneousListIterable

+	 */

+	public static <E, I extends ListIterable<E>> SimultaneousListIterable<E> simultaneousListIterable(I... iterables) {

+		return new SimultaneousListIterable<E>(iterables);

+	}

+

+	/**

+	 * Return a list iterable that provides simultaneous processing of the elements

+	 * in the specified iterables.

+	 * @see SimultaneousListIterable

+	 */

+	public static <E, I extends ListIterable<E>> SimultaneousListIterable<E> simultaneousListIterable(Iterable<I> iterables) {

+		return new SimultaneousListIterable<E>(iterables);

+	}

+

+	/**

+	 * Return a list iterable that provides simultaneous processing of the elements

+	 * in the specified iterables.

+	 * @see SimultaneousListIterable

+	 */

+	public static <E, I extends ListIterable<E>> SimultaneousListIterable<E> simultaneousListIterable(Iterable<I> iterables, int iterablesSize) {

+		return new SimultaneousListIterable<E>(iterables, iterablesSize);

+	}

+

+	/**

+	 * Return an iterable that returns only the single,

+	 * specified object.

+	 * @see SingleElementIterable

+	 */

+	public static <E> SingleElementIterable<E> singletonIterable(E value) {

+		return new SingleElementIterable<E>(value);

+	}

+

+	/**

+	 * Return a list iterable that returns only the single,

+	 * specified object.

+	 * @see SingleElementListIterable

+	 */

+	public static <E> SingleElementListIterable<E> singletonListIterable(E value) {

+		return new SingleElementListIterable<E>(value);

+	}

+

+	/**

+	 * Return an iterable that clones the specified collection before returning

+	 * elements.

+	 * @see SnapshotCloneIterable

+	 */

+	public static <E> SnapshotCloneIterable<E> snapshotCloneIterable(Collection<? extends E> collection) {

+		return new SnapshotCloneIterable<E>(collection);

+	}

+

+	/**

+	 * Return an iterable that clones the specified collection before returning

+	 * elements and uses the specified {@link org.eclipse.jpt.common.utility.internal.iterator.CloneIterator.Remover remover}.

+	 * @see LiveCloneIterable

+	 */

+	public static <E> SnapshotCloneIterable<E> snapshotCloneIterable(Collection<? extends E> collection, CloneIterator.Remover<E> remover) {

+		return new SnapshotCloneIterable<E>(collection, remover);

+	}

+

+	/**

+	 * Return a list iterable that clones the specified collection before returning

+	 * elements.

+	 * @see SnapshotCloneListIterable

+	 */

+	public static <E> SnapshotCloneListIterable<E> snapshotCloneIterable(List<? extends E> list) {

+		return new SnapshotCloneListIterable<E>(list);

+	}

+

+	/**

+	 * Return a list iterable that clones the specified collection before returning

+	 * elements and uses the specified {@link org.eclipse.jpt.common.utility.internal.iterator.CloneListIterator.Mutator mutator}.

+	 * @see SnapshotCloneListIterable

+	 */

+	public static <E> SnapshotCloneListIterable<E> snapshotCloneIterable(List<? extends E> list, CloneListIterator.Mutator<E> mutator) {

+		return new SnapshotCloneListIterable<E>(list, mutator);

+	}

+

+	/**

+	 * Return an iterable that converts the specified iterable's element type.

+	 * @see SubIterableWrapper

+	 */

+	public static <E1, E2 extends E1> SubIterableWrapper<E1, E2> subIterable(Iterable<E1> iterable) {

+		return new SubIterableWrapper<E1, E2>(iterable);

+	}

+

+	/**

+	 * Return an iterable that converts the specified list's element type.

+	 * @see SubListIterableWrapper

+	 */

+	public static <E1, E2 extends E1> SubListIterableWrapper<E1, E2> subListIterable(List<E1> list) {

+		return new SubListIterableWrapper<E1, E2>(list);

+	}

+

+	/**

+	 * Return an iterable that converts the specified iterable's element type.

+	 * @see SubListIterableWrapper

+	 */

+	public static <E1, E2 extends E1> SubListIterableWrapper<E1, E2> subListIterable(ListIterable<E1> iterable) {

+		return new SubListIterableWrapper<E1, E2>(iterable);

+	}

+

+	/**

+	 * Return an iterable that converts the specified iterable's element type.

+	 * @see SuperIterableWrapper

+	 */

+	public static <E> SuperIterableWrapper<E> superIterable(Iterable<? extends E> iterable) {

+		return new SuperIterableWrapper<E>(iterable);

+	}

+

+	/**

+	 * Return an iterable that converts the specified list's element type.

+	 * @see SuperListIterableWrapper

+	 */

+	public static <E> SuperListIterableWrapper<E> superListIterable(List<? extends E> list) {

+		return new SuperListIterableWrapper<E>(list);

+	}

+

+	/**

+	 * Return an iterable that converts the specified iterable's element type.

+	 * @see SuperListIterableWrapper

+	 */

+	public static <E> SuperListIterableWrapper<E> superListIterable(ListIterable<? extends E> iterable) {

+		return new SuperListIterableWrapper<E>(iterable);

+	}

+

+	/**

+	 * Return an iterable that will use the specified transformer to transform the

+	 * elements in the specified iterable.

+	 * @see TransformationIterable

+	 */

+	public static <E1, E2> TransformationIterable<E1, E2> transform(Iterable<? extends E1> iterable, Transformer<E1, ? extends E2> transformer) {

+		return new TransformationIterable<E1, E2>(iterable, transformer);

+	}

+

+	/**

+	 * Return an iterable that will use the specified transformer to transform the

+	 * elements in the specified list.

+	 * @see TransformationListIterable

+	 */

+	public static <E1, E2, T extends E1> TransformationListIterable<E1, E2> transformationListIterable(List<T> list, Transformer<E1, ? extends E2> transformer) {

+		return new TransformationListIterable<E1, E2>(list, transformer);

+	}

+

+	/**

+	 * Return an iterable that will use the specified transformer to transform the

+	 * elements in the specified iterable.

+	 * @see TransformationListIterable

+	 */

+	public static <E1, E2> TransformationListIterable<E1, E2> transform(ListIterable<? extends E1> iterable, Transformer<E1, ? extends E2> transformer) {

+		return new TransformationListIterable<E1, E2>(iterable, transformer);

+	}

+

+	/**

+	 * Construct an iterable that returns the nodes of a tree

+	 * with the specified root and transformer.

+	 * @see TreeIterable

+	 */

+	public static <E> TreeIterable<E> treeIterable(E root, Transformer<E, Iterator<? extends E>> transformer) {

+		return treeIterable(new SingleElementIterable<E>(root), transformer);

+	}

+

+	/**

+	 * Construct an iterable that returns the nodes of a tree

+	 * with the specified roots and transformer.

+	 * @see TreeIterable

+	 */

+	public static <E> TreeIterable<E> treeIterable(E[] roots, Transformer<E, Iterator<? extends E>> transformer) {

+		return treeIterable(new ArrayIterable<E>(roots), transformer);

+	}

+

+	/**

+	 * Construct an iterable that returns the nodes of a tree

+	 * with the specified roots and transformer.

+	 * @see TreeIterable

+	 */

+	public static <E> TreeIterable<E> treeIterable(Iterable<? extends E> roots, Transformer<E, Iterator<? extends E>> transformer) {

+		return new TreeIterable<E>(roots, transformer);

+	}

+

+

+	// ********** constructor **********

+

+	/**

+	 * Suppress default constructor, ensuring non-instantiability.

+	 */

+	private IterableTools() {

+		super();

+		throw new UnsupportedOperationException();

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/IterableWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/IterableWrapper.java
new file mode 100644
index 0000000..eeb0e3a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/IterableWrapper.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Iterable wrapper that can have its wrapped iterable changed,
+ * allowing a client to change a previously-supplied iterable's
+ * behavior mid-stream.
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ * @see #setIterable(Iterable)
+ */
+public class IterableWrapper<E>
+	implements Iterable<E>
+{
+	protected volatile Iterable<E> iterable;
+
+	public IterableWrapper(Iterable<E> iterable) {
+		super();
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return this.iterable.iterator();
+	}
+
+	public void setIterable(Iterable<E> iterable) {
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.iterable);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/LateralIterableWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/LateralIterableWrapper.java
new file mode 100644
index 0000000..a4457f6
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/LateralIterableWrapper.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.iterator.LateralIteratorWrapper;
+
+/**
+ * Wrap an iterable of elements of type <code>E1</code>, converting it into an
+ * iterable of elements of type <code>E2</code>. <em>Assume</em> the wrapped
+ * iterable contains only elements of type <code>E2</code>. The result is a
+ * {@link ClassCastException} if this assumption is false.
+ *
+ * @param <E1> input: the type of elements contained by the wrapped iterable
+ * @param <E2> output: the type of elements returned by the iterable's iterators
+ *
+ * @see LateralIteratorWrapper
+ * @see SubIterableWrapper
+ */
+public class LateralIterableWrapper<E1, E2>
+	implements Iterable<E2>
+{
+	private final Iterable<E1> iterable;
+
+
+	public LateralIterableWrapper(Iterable<E1> iterable) {
+		super();
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+	}
+
+	@Override
+	public Iterator<E2> iterator() {
+		return new LateralIteratorWrapper<E1, E2>(this.iterable.iterator());
+	}
+
+	@Override
+	public String toString() {
+		return this.iterable.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/LateralListIterableWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/LateralListIterableWrapper.java
new file mode 100644
index 0000000..14a8adc
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/LateralListIterableWrapper.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.LateralListIteratorWrapper;
+
+/**
+ * Wrap a list iterable of elements of type <code>E1</code>, converting it into
+ * a list iterable of elements of type <code>E2</code>. <em>Assume</em> the
+ * wrapped iterable contains only elements of type <code>E2</code>.
+ * The result is a {@link ClassCastException} if this assumption is false.
+ *
+ * @param <E1> input: the type of elements contained by the wrapped list iterable
+ * @param <E2> output: the type of elements returned by the iterable's list iterators
+ *
+ * @see LateralListIteratorWrapper
+ * @see SubListIterableWrapper
+ */
+public class LateralListIterableWrapper<E1, E2>
+	implements ListIterable<E2>
+{
+	private final ListIterable<E1> iterable;
+
+
+	public LateralListIterableWrapper(List<E1> list) {
+		this(new ListListIterable<E1>(list));
+	}
+
+	public LateralListIterableWrapper(ListIterable<E1> iterable) {
+		super();
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+	}
+
+	@Override
+	public ListIterator<E2> iterator() {
+		return new LateralListIteratorWrapper<E1, E2>(this.iterable.iterator());
+	}
+
+	@Override
+	public String toString() {
+		return this.iterable.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ListIterable.java
new file mode 100644
index 0000000..f307569
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ListIterable.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.ListIterator;
+
+/**
+ * A <code>ListIterable</code> simply extends {@link Iterable}
+ * to return a {@link ListIterator} of type <code>E</code>.
+ * <p>
+ * 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.
+ *
+ * @param <E> the type of elements returned by the iterable's iterators
+ */
+public interface ListIterable<E>
+	extends Iterable<E>
+{
+	/**
+	 * Return a list iterator over a set of elements of type E.
+	 */
+	@Override
+	ListIterator<E> iterator();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ListIterableAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ListIterableAdapter.java
new file mode 100644
index 0000000..95ba58d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ListIterableAdapter.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterator.EmptyListIterator;
+
+/**
+ * Convenience list iterable that returns an empty iterator.
+ */
+public class ListIterableAdapter<E>
+	implements ListIterable<E>
+{
+	@Override
+	public ListIterator<E> iterator() {
+		return EmptyListIterator.instance();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ListIterableWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ListIterableWrapper.java
new file mode 100644
index 0000000..49b18ee
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ListIterableWrapper.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * List iterable wrapper that can have its wrapped list iterable changed,
+ * allowing a client to change a previously-supplied iterable's
+ * behavior mid-stream.
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ * @see #setIterable(ListIterable)
+ */
+public class ListIterableWrapper<E>
+	implements ListIterable<E>
+{
+	protected volatile ListIterable<E> iterable;
+
+	public ListIterableWrapper(ListIterable<E> iterable) {
+		super();
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+	}
+
+	@Override
+	public ListIterator<E> iterator() {
+		return this.iterable.iterator();
+	}
+
+	public void setIterable(ListIterable<E> iterable) {
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.iterable);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ListListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ListListIterable.java
new file mode 100644
index 0000000..7942797
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ListListIterable.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * A <code>ListListIterable</code> adapts a {@link List}
+ * to the {@link ListIterable} interface.
+ *
+ * @param <E> the type of elements returned by the iterable's iterators
+ */
+public class ListListIterable<E>
+	implements ListIterable<E>
+{
+	private final List<E> list;
+
+	public ListListIterable(List<E> list) {
+		super();
+		if (list == null) {
+			throw new NullPointerException();
+		}
+		this.list = list;
+	}
+
+	@Override
+	public ListIterator<E> iterator() {
+		return this.list.listIterator();
+	}
+
+	@Override
+	public String toString() {
+		return this.list.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/LiveCloneIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/LiveCloneIterable.java
new file mode 100644
index 0000000..da7da35
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/LiveCloneIterable.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Collection;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.iterator.CloneIterator;
+
+/**
+ * A <code>LiveCloneIterable</code> returns an iterator on a current copy of a
+ * collection, allowing for concurrent access to the original collection. A
+ * copy of the collection is created every time {@link #iterator()} is
+ * called. As a result, the contents of the collection can be different with
+ * each call to {@link #iterator()} (i.e. it is "live").
+ * <p>
+ * The original collection passed to the <code>LiveCloneIterable</code>'s
+ * constructor should be thread-safe (e.g. {@link java.util.Vector});
+ * otherwise you run the risk of a corrupted collection.
+ * <p>
+ * By default, the iterator returned by a <code>LiveCloneIterable</code> does not
+ * support the {@link Iterator#remove()} operation; this is because it does not
+ * have access to the original collection. But if the <code>LiveCloneIterable</code>
+ * is supplied with an {@link org.eclipse.jpt.common.utility.internal.iterator.CloneIterator.Remover} it will delegate the
+ * {@link Iterator#remove()} operation to the <code>Remover</code>.
+ * Alternatively, a subclass can override the iterable's {@link #remove(Object)}
+ * method.
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ *
+ * @see CloneIterator
+ * @see SnapshotCloneIterable
+ * @see LiveCloneListIterable
+ */
+public class LiveCloneIterable<E>
+	extends CloneIterable<E>
+{
+	private final Collection<? extends E> collection;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a "live" iterable for the specified collection.
+	 * The {@link Iterator#remove()} operation will not be supported
+	 * by the iterator returned by {@link #iterator()}
+	 * unless a subclass overrides the iterable's {@link #remove(Object)}
+	 * method.
+	 */
+	public LiveCloneIterable(Collection<? extends E> collection) {
+		super();
+		if (collection == null) {
+			throw new NullPointerException();
+		}
+		this.collection = collection;
+	}
+
+	/**
+	 * Construct a "live" iterable for the specified collection.
+	 * The specified remover will be used by any generated iterators to
+	 * remove objects from the original collection.
+	 */
+	public LiveCloneIterable(Collection<? extends E> collection, CloneIterator.Remover<E> remover) {
+		super(remover);
+		if (collection == null) {
+			throw new NullPointerException();
+		}
+		this.collection = collection;
+	}
+
+
+	// ********** Iterable implementation **********
+
+	@Override
+	public Iterator<E> iterator() {
+		return new CloneIterator<E>(this.collection, this.remover);
+	}
+
+	@Override
+	public String toString() {
+		return this.collection.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/LiveCloneListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/LiveCloneListIterable.java
new file mode 100644
index 0000000..079afe0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/LiveCloneListIterable.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.CloneListIterator;
+
+/**
+ * A <code>LiveCloneListIterable</code> returns a list iterator on a current
+ * copy of a list, allowing for concurrent access to the original list. A
+ * copy of the list is created every time {@link #iterator()} is
+ * called. As a result, the contents of the list can be different with
+ * each call to {@link #iterator()} (i.e. it is "live").
+ * <p>
+ * The original list passed to the <code>LiveCloneListIterable</code>'s
+ * constructor should be thread-safe (e.g. {@link java.util.Vector});
+ * otherwise you run the risk of a corrupted list.
+ * <p>
+ * By default, the list iterator returned by a <code>LiveCloneListIterable</code>
+ * does not support the modify operations; this is because it does not
+ * have access to the original list. But if the <code>LiveCloneListIterable</code>
+ * is supplied with an {@link org.eclipse.jpt.common.utility.internal.iterator.CloneListIterator.Mutator} it will delegate the
+ * modify operations to the <code>Mutator</code>.
+ * Alternatively, a subclass can override the list iterable's mutation
+ * methods.
+ *
+ * @param <E> the type of elements returned by the list iterable's list iterator
+ *
+ * @see CloneListIterator
+ * @see SnapshotCloneListIterable
+ * @see LiveCloneIterable
+ */
+public class LiveCloneListIterable<E>
+	extends CloneListIterable<E>
+{
+	private final List<? extends E> list;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a "live" list iterable for the specified list.
+	 * The {@link ListIterator} mutation operations will not be supported
+	 * by the list iterator returned by {@link #iterator()}
+	 * unless a subclass overrides the iterable's mutation
+	 * methods.
+	 */
+	public LiveCloneListIterable(List<? extends E> list) {
+		super();
+		if (list == null) {
+			throw new NullPointerException();
+		}
+		this.list = list;
+	}
+
+	/**
+	 * Construct a "live" list iterable for the specified list.
+	 * The specified mutator will be used by any generated list iterators to
+	 * modify the original list.
+	 */
+	public LiveCloneListIterable(List<? extends E> list, CloneListIterator.Mutator<E> mutator) {
+		super(mutator);
+		if (list == null) {
+			throw new NullPointerException();
+		}
+		this.list = list;
+	}
+
+
+	// ********** ListIterable implementation **********
+
+	@Override
+	public ListIterator<E> iterator() {
+		return new CloneListIterator<E>(this.list, this.mutator);
+	}
+
+	@Override
+	public String toString() {
+		return this.list.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/PeekableIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/PeekableIterable.java
new file mode 100644
index 0000000..7cfa624
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/PeekableIterable.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import org.eclipse.persistence.tools.utility.iterator.PeekableIterator;
+
+/**
+ * A <code>PeekableIterable</code> wraps another {@link Iterable}
+ * and returns an {@link PeekableIterator} that allows a
+ * {@link PeekableIterator#peek() peek} at the next element to be
+ * returned by {@link java.util.Iterator#next()}.
+ * <p>
+ * One, possibly undesirable, side-effect of using this iterator is that
+ * the nested iterator's <code>next()</code> method will be invoked
+ * <em>before</em> the peekable iterator's {@link java.util.Iterator#next()}
+ * method is invoked. This is because the "next" element must be
+ * pre-loaded for the {@link PeekableIterator#peek()} method.
+ * This also prevents a peekable iterator from supporting the optional
+ * {@link java.util.Iterator#remove()} method.
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ *
+ * @see PeekableIterator
+ */
+public class PeekableIterable<E>
+	implements Iterable<E>
+{
+	private final Iterable<? extends E> iterable;
+
+	/**
+	 * Construct a peekable iterable that wraps the specified
+	 * iterable.
+	 */
+	public PeekableIterable(Iterable<? extends E> iterable) {
+		super();
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+	}
+
+	@Override
+	public PeekableIterator<E> iterator() {
+		return new PeekableIterator<E>(this.iterable);
+	}
+
+	@Override
+	public String toString() {
+		return this.iterable.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/QueueIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/QueueIterable.java
new file mode 100644
index 0000000..98b0612
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/QueueIterable.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.collection.Queue;
+import org.eclipse.persistence.tools.utility.iterator.QueueIterator;
+
+/**
+ * A <code>QueueIterable</code> provides an {@link Iterable}
+ * for a {@link Queue} of objects of type <code>E</code>. The queue's elements
+ * are {@link Queue#dequeue() dequeue}d" as the iterable's iterator returns
+ * them with calls to {@link Iterator#next()}.
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ *
+ * @see Queue
+ * @see QueueIterator
+ */
+public class QueueIterable<E>
+	implements Iterable<E>
+{
+	private final Queue<E> queue;
+
+	/**
+	 * Construct an iterable for the specified queue.
+	 */
+	public QueueIterable(Queue<E> queue) {
+		super();
+		if (queue == null) {
+			throw new NullPointerException();
+		}
+		this.queue = queue;
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return new QueueIterator<E>(this.queue);
+	}
+
+	@Override
+	public String toString() {
+		return this.queue.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ReadOnlyCompositeListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ReadOnlyCompositeListIterable.java
new file mode 100644
index 0000000..c993da6
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ReadOnlyCompositeListIterable.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.iterator.TransformationListIterator;
+
+/**
+ * A <code>ReadOnlyCompositeListIterable</code> wraps a {@link ListIterable}
+ * of {@link ListIterable}s and makes them appear to be a single
+ * read-only {@link ListIterable}. A read-only composite list
+ * iterable is more flexible than a normal composite list iterable when it
+ * comes to the element types of the nested list iterables.
+ *
+ * @param <E> the type of elements returned by the list iterable's list iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterator.ReadOnlyCompositeListIterator
+ * @see CompositeListIterable
+ */
+public class ReadOnlyCompositeListIterable<E>
+	implements ListIterable<E>
+{
+	private final ListIterable<? extends ListIterable<? extends E>> iterables;
+
+
+	/**
+	 * Construct a list iterable with the specified list of list iterables.
+	 */
+	public ReadOnlyCompositeListIterable(ListIterable<? extends ListIterable<? extends E>> iterables) {
+		super();
+		if (iterables == null) {
+			throw new NullPointerException();
+		}
+		this.iterables = iterables;
+	}
+
+	/**
+	 * Construct a list iterable with the specified object prepended
+	 * to the specified list iterable.
+	 */
+	@SuppressWarnings("unchecked")
+	public ReadOnlyCompositeListIterable(E object, ListIterable<? extends E> iterable) {
+		this(new SingleElementListIterable<E>(object), iterable);
+	}
+
+	/**
+	 * Construct a list iterable with the specified object appended
+	 * to the specified list iterable.
+	 */
+	@SuppressWarnings("unchecked")
+	public ReadOnlyCompositeListIterable(ListIterable<? extends E> iterable, E object) {
+		this(iterable, new SingleElementListIterable<E>(object));
+	}
+
+	/**
+	 * Construct a list iterable with the specified list iterables.
+	 */
+	public ReadOnlyCompositeListIterable(ListIterable<? extends E>... iterables) {
+		this(new ArrayListIterable<ListIterable<? extends E>>(iterables));
+	}
+
+	/**
+	 * combined list iterators
+	 */
+	@Override
+	public ListIterator<E> iterator() {
+		return IteratorTools.readOnlyCompositeListIterator(this.iterators());
+	}
+
+	/**
+	 * list iterator of list iterators
+	 */
+	protected ListIterator<? extends ListIterator<? extends E>> iterators() {
+		return new TransformationListIterator<ListIterable<? extends E>, ListIterator<? extends E>>(this.iterables()) {
+			@Override
+			protected ListIterator<? extends E> transform(ListIterable<? extends E> next) {
+				return next.iterator();
+			}
+		};
+	}
+
+	/**
+	 * list iterator of list iterables
+	 */
+	protected ListIterator<? extends ListIterable<? extends E>> iterables() {
+		return this.iterables.iterator();
+	}
+
+	@Override
+	public String toString() {
+		return ListTools.list(this).toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ReadOnlyIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ReadOnlyIterable.java
new file mode 100644
index 0000000..55927a6
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ReadOnlyIterable.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyIterator;
+
+/**
+ * A <code>ReadOnlyIterable</code> wraps another {@link Iterable}
+ * and returns a read-only {@link Iterator}.
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ *
+ * @see ReadOnlyIterator
+ * @see ReadOnlyListIterable
+ */
+public class ReadOnlyIterable<E>
+	implements Iterable<E>
+{
+	private final Iterable<? extends E> iterable;
+
+
+	/**
+	 * Construct an iterable the returns a read-only iterator on the elements
+	 * in the specified iterable.
+	 */
+	public ReadOnlyIterable(Iterable<? extends E> iterable) {
+		super();
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return new ReadOnlyIterator<E>(this.iterable);
+	}
+
+	@Override
+	public String toString() {
+		return this.iterable.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ReadOnlyListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ReadOnlyListIterable.java
new file mode 100644
index 0000000..133560c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/ReadOnlyListIterable.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyListIterator;
+
+/**
+ * A <code>ReadOnlyListIterable</code> wraps another {@link ListIterable}
+ * and returns a read-only {@link ListIterator}.
+ *
+ * @param <E> the type of elements returned by the list iterable's list iterator
+ *
+ * @see ReadOnlyListIterator
+ * @see ReadOnlyIterable
+ */
+public class ReadOnlyListIterable<E>
+	implements ListIterable<E>
+{
+	private final ListIterable<? extends E> listIterable;
+
+
+	/**
+	 * Construct a list iterable the returns a read-only list iterator on the elements
+	 * in the specified list iterable.
+	 */
+	public ReadOnlyListIterable(ListIterable<? extends E> iterable) {
+		super();
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		this.listIterable = iterable;
+	}
+
+	@Override
+	public ListIterator<E> iterator() {
+		return new ReadOnlyListIterator<E>(this.listIterable);
+	}
+
+	@Override
+	public String toString() {
+		return this.listIterable.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SimultaneousIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SimultaneousIterable.java
new file mode 100644
index 0000000..c2d0544
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SimultaneousIterable.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.persistence.tools.utility.iterator.SimultaneousIterator;
+
+/**
+ * A <code>SimultaneousIterable</code> returns an {@link Iterator} that supports
+ * the simultaneous processing of a set of {@link Iterable}s
+ * of objects of type <code>E</code>.
+ *
+ * @param <E> the type of elements returned by the nested iterators
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterator.SimultaneousIterator
+ */
+public class SimultaneousIterable<E>
+	extends AbstractSimultaneousIterable<E, Iterable<E>>
+	implements Iterable<List<E>>
+{
+	/**
+	 * Construct a "simultaneous" iterator for the specified iterators.
+	 */
+	public <I extends Iterable<E>> SimultaneousIterable(I... iterables) {
+		super(iterables);
+	}
+
+	/**
+	 * Construct a "multiple" iterator for the specified iterators.
+	 */
+	public <I extends Iterable<E>> SimultaneousIterable(Iterable<I> iterables) {
+		super(iterables);
+	}
+
+	/**
+	 * Construct a "multiple" iterator for the specified iterators.
+	 * Use the specified size as a performance hint.
+	 */
+	public <I extends Iterable<E>> SimultaneousIterable(Iterable<I> iterables, int iterablesSize) {
+		super(iterables, iterablesSize);
+	}
+
+	@Override
+	public Iterator<List<E>> iterator() {
+		ArrayList<Iterator<E>> iterators = this.buildList();
+		for (Iterable<E> iterable : this.iterables) {
+			iterators.add(iterable.iterator());
+		}
+		return new SimultaneousIterator<E>(iterators, iterators.size());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SimultaneousListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SimultaneousListIterable.java
new file mode 100644
index 0000000..5886ab4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SimultaneousListIterable.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.SimultaneousListIterator;
+
+/**
+ * A <code>SimultaneousListIterable</code> returns a {@link ListIterator} that supports
+ * the simultaneous processing of a set of {@link ListIterable}s
+ * of objects of type <code>E</code>.
+ *
+ * @param <E> the type of elements returned by the nested list iterators
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterator.SimultaneousListIterator
+ */
+public class SimultaneousListIterable<E>
+	extends AbstractSimultaneousIterable<E, ListIterable<E>>
+	implements ListIterable<List<E>>
+{
+	/**
+	 * Construct a "simultaneous" iterator for the specified iterators.
+	 */
+	public <I extends ListIterable<E>> SimultaneousListIterable(I... iterables) {
+		super(iterables);
+	}
+
+	/**
+	 * Construct a "multiple" iterator for the specified iterators.
+	 */
+	public <I extends ListIterable<E>> SimultaneousListIterable(Iterable<I> iterables) {
+		super(iterables);
+	}
+
+	/**
+	 * Construct a "multiple" iterator for the specified iterators.
+	 * Use the specified size as a performance hint.
+	 */
+	public <I extends ListIterable<E>> SimultaneousListIterable(Iterable<I> iterables, int iterablesSize) {
+		super(iterables, iterablesSize);
+	}
+
+	@Override
+	public ListIterator<List<E>> iterator() {
+		ArrayList<ListIterator<E>> iterators = this.buildList();
+		for (ListIterable<E> iterable : this.iterables) {
+			iterators.add(iterable.iterator());
+		}
+		return new SimultaneousListIterator<E>(iterators, iterators.size());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SingleElementIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SingleElementIterable.java
new file mode 100644
index 0000000..9050617
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SingleElementIterable.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.iterator.SingleElementIterator;
+
+/**
+ * A <code>SingleElementIterable</code> returns an {@link Iterator}
+ * that holds a single element
+ * and returns it with the first call to {@link Iterator#next()}, at
+ * which point it will return <code>false</code> to any subsequent
+ * call to {@link Iterator#hasNext()}.
+ * <p>
+ * A <code>SingleElementIterable</code> is equivalent to the
+ * {@link Iterable} returned by:
+ * 	{@link java.util.Collections#singleton(Object)}.
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ *
+ * @see SingleElementIterator
+ * @see SingleElementListIterable
+ */
+@SuppressWarnings("nls")
+public class SingleElementIterable<E>
+	implements Iterable<E>
+{
+	private final E element;
+
+	/**
+	 * Construct an iterable that contains only the specified element.
+	 */
+	public SingleElementIterable(E element) {
+		super();
+		this.element = element;
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return new SingleElementIterator<E>(this.element);
+	}
+
+	@Override
+	public String toString() {
+		return "[" + this.element + "]";
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SingleElementListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SingleElementListIterable.java
new file mode 100644
index 0000000..1922a6c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SingleElementListIterable.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.SingleElementListIterator;
+
+/**
+ * A <code>SingleElementListIterable</code> returns a {@link ListIterator}
+ * that holds a single element
+ * and returns it with the first call to {@link ListIterator#next()}, at
+ * which point it will return <code>false</code> to any subsequent
+ * call to {@link ListIterator#hasNext()}. Likewise, it will return <code>false</code>
+ * to a call to {@link ListIterator#hasPrevious()} until a call to {@link ListIterator#next()},
+ * at which point a call to {@link ListIterator#previous()} will return the
+ * single element.
+ * <p>
+ * A <code>SingleElementListIterable</code> is equivalent to the
+ * {@link Iterable} returned by:
+ * 	{@link java.util.Collections#singletonList(Object)}.
+ *
+ * @param <E> the type of elements returned by the list iterable's list iterator
+ *
+ * @see SingleElementListIterator
+ * @see SingleElementIterable
+ */
+@SuppressWarnings("nls")
+public class SingleElementListIterable<E>
+	implements ListIterable<E>
+{
+	private final E element;
+
+	/**
+	 * Construct a list iterable that contains only the specified element.
+	 */
+	public SingleElementListIterable(E element) {
+		super();
+		this.element = element;
+	}
+
+	@Override
+	public ListIterator<E> iterator() {
+		return new SingleElementListIterator<E>(this.element);
+	}
+
+	@Override
+	public String toString() {
+		return "[" + this.element + "]";
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SnapshotCloneIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SnapshotCloneIterable.java
new file mode 100644
index 0000000..82e1a2f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SnapshotCloneIterable.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.iterator.CloneIterator;
+
+/**
+ * A <code>SnapshotCloneIterable</code> returns an iterator on a "snapshot" of a
+ * collection, allowing for concurrent access to the original collection. A
+ * copy of the collection is created when the iterable is constructed.
+ * As a result, the contents of the collection will be the same with
+ * every call to {@link #iterator()}.
+ * <p>
+ * The original collection passed to the <code>SnapshotCloneIterable</code>'s
+ * constructor should be thread-safe (e.g. {@link java.util.Vector});
+ * otherwise you run the risk of a corrupted collection.
+ * <p>
+ * By default, the iterator returned by a <code>SnapshotCloneIterable</code> does not
+ * support the {@link Iterator#remove()} operation; this is because it does not
+ * have access to the original collection. But if the <code>SnapshotCloneIterable</code>
+ * is supplied with a {@link org.eclipse.jpt.common.utility.internal.iterator.CloneIterator.Remover} it will delegate the
+ * {@link Iterator#remove()} operation to the <code>Remover</code>.
+ * Alternatively, a subclass can override the iterable's {@link #remove(Object)}
+ * method.
+ * <p>
+ * This iterable is useful for multiple passes over a collection that should not
+ * be changed (e.g. by another thread) between passes.
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ *
+ * @see CloneIterator
+ * @see LiveCloneIterable
+ * @see SnapshotCloneListIterable
+ */
+public class SnapshotCloneIterable<E>
+	extends CloneIterable<E>
+{
+	private final Object[] array;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a "snapshot" iterable for the specified collection.
+	 * The {@link Iterator#remove()} operation will not be supported
+	 * by the iterator returned by {@link #iterator()}
+	 * unless a subclass overrides the iterable's {@link #remove(Object)}
+	 * method.
+	 */
+	public SnapshotCloneIterable(Collection<? extends E> collection) {
+		super();
+		this.array = collection.toArray();
+	}
+
+	/**
+	 * Construct a "snapshot" iterable for the specified collection.
+	 * The specified remover will be used by any generated iterators to
+	 * remove objects from the original collection.
+	 */
+	public SnapshotCloneIterable(Collection<? extends E> collection, CloneIterator.Remover<E> remover) {
+		super(remover);
+		this.array = collection.toArray();
+	}
+
+
+	// ********** Iterable implementation **********
+
+	@Override
+	public Iterator<E> iterator() {
+		return new LocalCloneIterator<E>(this.remover, this.array);
+	}
+
+	@Override
+	public String toString() {
+		return Arrays.toString(this.array);
+	}
+
+
+	// ********** clone iterator **********
+
+	/**
+	 * provide access to "internal" constructor
+	 */
+	protected static class LocalCloneIterator<E> extends CloneIterator<E> {
+		protected LocalCloneIterator(Remover<E> remover, Object[] array) {
+			super(remover, array);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SnapshotCloneListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SnapshotCloneListIterable.java
new file mode 100644
index 0000000..c7b4e8a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SnapshotCloneListIterable.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.CloneListIterator;
+
+/**
+ * A <code>SnapshotCloneListIterable</code> returns a list iterator on a
+ * "snapshot" of a list, allowing for concurrent access to the original list.
+ * A copy of the list is created when the list iterable is constructed.
+ * As a result, the contents of the list will be the same with
+ * every call to {@link #iterator()}, even if the original list is modified via
+ * the list iterator's mutation methods.
+ * <p>
+ * The original list passed to the <code>SnapshotCloneListIterable</code>'s
+ * constructor should be thread-safe (e.g. {@link java.util.Vector});
+ * otherwise you run the risk of a corrupted list.
+ * <p>
+ * By default, the list iterator returned by a <code>SnapshotCloneListIterable</code> does not
+ * support the {@link ListIterator} mutation operations; this is because it does not
+ * have access to the original list. But if the <code>SnapshotCloneListIterable</code>
+ * is supplied with a {@link org.eclipse.jpt.common.utility.internal.iterator.CloneListIterator.Mutator} it will delegate the
+ * {@link ListIterator} mutation operations to the <code>Mutator</code>.
+ * Alternatively, a subclass can override the list iterable's mutation
+ * methods.
+ * <p>
+ * This list iterable is useful for multiple passes over a list that should not
+ * be changed (e.g. by another thread) between passes.
+ *
+ * @param <E> the type of elements returned by the list iterable's list iterator
+ *
+ * @see CloneListIterator
+ * @see LiveCloneListIterable
+ * @see SnapshotCloneIterable
+ */
+public class SnapshotCloneListIterable<E>
+	extends CloneListIterable<E>
+{
+	private final Object[] array;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a "snapshot" list iterable for the specified list.
+	 * The {@link ListIterator} modify operations will not be supported
+	 * by the list iterator returned by {@link #iterator()}
+	 * unless a subclass overrides the list iterable's modify
+	 * method.
+	 */
+	public SnapshotCloneListIterable(List<? extends E> list) {
+		super();
+		this.array = list.toArray();
+	}
+
+	/**
+	 * Construct a "snapshot" list iterable for the specified list.
+	 * The specified mutator will be used by any generated list iterators to
+	 * modify the original list.
+	 */
+	public SnapshotCloneListIterable(List<? extends E> list, CloneListIterator.Mutator<E> mutator) {
+		super(mutator);
+		this.array = list.toArray();
+	}
+
+
+	// ********** ListIterable implementation **********
+
+	@Override
+	public ListIterator<E> iterator() {
+		return new LocalCloneListIterator<E>(this.mutator, this.array);
+	}
+
+	@Override
+	public String toString() {
+		return Arrays.toString(this.array);
+	}
+
+
+	// ********** clone iterator **********
+
+	/**
+	 * provide access to "internal" constructor
+	 */
+	protected static class LocalCloneListIterator<E> extends CloneListIterator<E> {
+		protected LocalCloneListIterator(Mutator<E> mutator, Object[] array) {
+			super(mutator, array);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/StackIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/StackIterable.java
new file mode 100644
index 0000000..471457e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/StackIterable.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.collection.Stack;
+import org.eclipse.persistence.tools.utility.iterator.StackIterator;
+
+/**
+ * A <code>StackIterable</code> provides an {@link Iterable}
+ * for a {@link Stack} of objects of type <code>E</code>. The stack's elements
+ * are {@link Stack#pop() "popped"} as the iterable's iterator returns
+ * them with calls to {@link Iterator#next()}.
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ *
+ * @see Stack
+ * @see StackIterator
+ */
+public class StackIterable<E>
+	implements Iterable<E>
+{
+	private final Stack<E> stack;
+
+	/**
+	 * Construct an iterable for the specified stack.
+	 */
+	public StackIterable(Stack<E> stack) {
+		super();
+		if (stack == null) {
+			throw new NullPointerException();
+		}
+		this.stack = stack;
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return new StackIterator<E>(this.stack);
+	}
+
+	@Override
+	public String toString() {
+		return this.stack.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SubIterableWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SubIterableWrapper.java
new file mode 100644
index 0000000..72e26f0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SubIterableWrapper.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.iterator.SubIteratorWrapper;
+
+/**
+ * Wrap an iterable of elements of type <code>E1</code>, converting it into an
+ * iterable of elements of type <code>E2</code>. <em>Assume</em> the wrapped
+ * iterable contains only elements of type <code>E2</code>. The result is a
+ * {@link ClassCastException} if this assumption is false.
+ * <p>
+ * This is like a {@link LateralIterableWrapper} but with more restrictive type
+ * parameters.
+ *
+ * @param <E1> input: the type of elements contained by the wrapped iterable
+ * @param <E2> output: the type of elements returned by the iterable's iterators
+ *
+ * @see SubIteratorWrapper
+ */
+public class SubIterableWrapper<E1, E2 extends E1>
+	implements Iterable<E2>
+{
+	private final Iterable<E1> iterable;
+
+
+	public SubIterableWrapper(Iterable<E1> iterable) {
+		super();
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+	}
+
+	@Override
+	public Iterator<E2> iterator() {
+		return new SubIteratorWrapper<E1, E2>(this.iterable.iterator());
+	}
+
+	@Override
+	public String toString() {
+		return this.iterable.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SubListIterableWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SubListIterableWrapper.java
new file mode 100644
index 0000000..bbe8115
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SubListIterableWrapper.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.SubListIteratorWrapper;
+
+/**
+ * Wrap a list iterable of elements of type <code>E1</code>, converting it into
+ * a list iterable of elements of type <code>E2</code>. <em>Assume</em> the
+ * wrapped iterable contains only elements of type <code>E2</code>.
+ * The result is a {@link ClassCastException} if this assumption is false.
+ * <p>
+ * This is like a {@link LateralListIterableWrapper} but with more restrictive type
+ * parameters.
+ *
+ * @param <E1> input: the type of elements contained by the wrapped list iterable
+ * @param <E2> output: the type of elements returned by the iterable's list iterators
+ *
+ * @see SubListIteratorWrapper
+ */
+public class SubListIterableWrapper<E1, E2 extends E1>
+	implements ListIterable<E2>
+{
+	private final ListIterable<E1> iterable;
+
+
+	public SubListIterableWrapper(List<E1> list) {
+		this(new ListListIterable<E1>(list));
+	}
+
+	public SubListIterableWrapper(ListIterable<E1> iterable) {
+		super();
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+	}
+
+	@Override
+	public ListIterator<E2> iterator() {
+		return new SubListIteratorWrapper<E1, E2>(this.iterable.iterator());
+	}
+
+	@Override
+	public String toString() {
+		return this.iterable.toString();
+	}
+}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SuperIterableWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SuperIterableWrapper.java
new file mode 100644
index 0000000..bd6d684
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SuperIterableWrapper.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Iterator;
+
+/**
+ * Wrap an iterable of elements of any sub-type of <code>E</code>, converting it into an
+ * iterable of elements of type <code>E</code>. This shouldn't be a problem since there
+ * is no way to add invalid elements to the iterable.
+ *
+ * @param <E> the type of elements returned by the iterable's iterators
+ */
+public class SuperIterableWrapper<E>
+	implements Iterable<E>
+{
+	private final Iterable<E> iterable;
+
+
+	@SuppressWarnings("unchecked")
+	public SuperIterableWrapper(Iterable<? extends E> iterable) {
+		super();
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		// this should be a safe cast - the iterator will only ever
+		// return E (or a sub-type) from #next()
+		this.iterable = (Iterable<E>) iterable;
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return this.iterable.iterator();
+	}
+
+	@Override
+	public String toString() {
+		return this.iterable.toString();
+	}
+}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SuperListIterableWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SuperListIterableWrapper.java
new file mode 100644
index 0000000..ced9331
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/SuperListIterableWrapper.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.SuperListIteratorWrapper;
+
+/**
+ * Wrap a list iterable of elements of any sub-type of <code>E</code>,
+ * converting it into a <em>non-writable</em> list iterable of elements
+ * of type <code>E</code>.
+ * This shouldn't be a problem since the resulting list iterable's list
+ * iterator disables the methods that would put invalid elements in the list
+ * iterator's backing list (i.e. {@link SuperListIteratorWrapper#set(Object)}
+ * and {@link SuperListIteratorWrapper#add(Object)}).
+ *
+ * @param <E> the type of elements returned by the iterable's iterators
+ *
+ * @see SuperListIteratorWrapper
+ */
+public class SuperListIterableWrapper<E>
+	implements ListIterable<E>
+{
+	private final ListIterable<? extends E> iterable;
+
+
+	public <T extends E> SuperListIterableWrapper(List<T> list) {
+		this(new ListListIterable<T>(list));
+	}
+
+	public SuperListIterableWrapper(ListIterable<? extends E> iterable) {
+		super();
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+	}
+
+	@Override
+	public ListIterator<E> iterator() {
+		return new SuperListIteratorWrapper<E>(this.iterable.iterator());
+	}
+
+	@Override
+	public String toString() {
+		return this.iterable.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/TransformationIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/TransformationIterable.java
new file mode 100644
index 0000000..f432091
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/TransformationIterable.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.TransformationIterator;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * A <code>TransformationIterable</code> wraps another {@link Iterable}
+ * and transforms its elements for client consumption. To use, supply a
+ * {@link Transformer} or subclass <code>TransformationIterable</code>
+ * and override the {@link #transform(Object)} method.
+ * Objects of type <code>E1</code> are transformed into objects of type <code>E2</code>;
+ * i.e. the iterable's iterator returns objects of type <code>E2</code>.
+ *
+ * @param <E1> input: the type of elements to be transformed
+ * @param <E2> output: the type of elements returned by the iterable's iterator
+ *
+ * @see TransformationIterator
+ * @see TransformationListIterable
+ */
+@SuppressWarnings("nls")
+public class TransformationIterable<E1, E2>
+	implements Iterable<E2>
+{
+	private final Iterable<? extends E1> iterable;
+	private final Transformer<E1, ? extends E2> transformer;
+
+
+	/**
+	 * Construct an iterable with the specified nested iterable
+	 * and a default transformer that calls back to the iterable.
+	 * Use this constructor if you want to override the
+	 * {@link #transform(Object)} method instead of building
+	 * a {@link Transformer}.
+	 */
+	public TransformationIterable(Iterable<? extends E1> iterable) {
+		super();
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+		this.transformer = this.buildDefaultTransformer();
+	}
+
+	/**
+	 * Construct an iterable with the specified nested iterable
+	 * and transformer.
+	 */
+	public TransformationIterable(Iterable<? extends E1> iterable, Transformer<E1, ? extends E2> transformer) {
+		super();
+		if ((iterable == null) || (transformer == null)) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+		this.transformer = transformer;
+	}
+
+	protected Transformer<E1, ? extends E2> buildDefaultTransformer() {
+		return new DefaultTransformer();
+	}
+
+	@Override
+	public Iterator<E2> iterator() {
+		return new TransformationIterator<E1, E2>(this.iterable.iterator(), this.transformer);
+	}
+
+	/**
+	 * Transform the specified object and return the result.
+	 */
+	protected E2 transform(@SuppressWarnings("unused") E1 o) {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+	@Override
+	public String toString() {
+		return ListTools.list(this).toString();
+	}
+
+
+	//********** default transformer **********
+
+	protected class DefaultTransformer implements Transformer<E1, E2> {
+		@Override
+		public E2 transform(E1 o) {
+			return TransformationIterable.this.transform(o);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/TransformationListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/TransformationListIterable.java
new file mode 100644
index 0000000..e0a2e8e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/TransformationListIterable.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.TransformationListIterator;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * A <code>TransformationListIterable</code> wraps another {@link ListIterable}
+ * and transforms its elements for client consumption. To use, supply a
+ * {@link Transformer} or subclass <code>TransformationListIterable</code>
+ * and override the {@link #transform(Object)} method.
+ * Objects of type <code>E1</code> are transformed into objects of type <code>E2</code>;
+ * i.e. the list iterable's list iterator returns objects of type <code>E2</code>.
+ *
+ * @param <E1> input: the type of elements to be transformed
+ * @param <E2> output: the type of elements returned by the iterable's iterator
+ *
+ * @see TransformationListIterator
+ * @see TransformationIterable
+ */
+@SuppressWarnings("nls")
+public class TransformationListIterable<E1, E2>
+	implements ListIterable<E2>
+{
+	private final ListIterable<? extends E1> iterable;
+	private final Transformer<E1, ? extends E2> transformer;
+
+
+	/**
+	 * Construct a list iterable with the specified nested list
+	 * and a default transformer that calls back to the list iterable.
+	 * Use this constructor if you want to override the
+	 * {@link #transform(Object)} method instead of building
+	 * a {@link Transformer}.
+	 */
+	public <T extends E1> TransformationListIterable(List<T> list) {
+		this(new ListListIterable<T>(list));
+	}
+
+	/**
+	 * Construct a list iterable with the specified nested list iterable
+	 * and a default transformer that calls back to the list iterable.
+	 * Use this constructor if you want to override the
+	 * {@link #transform(Object)} method instead of building
+	 * a {@link Transformer}.
+	 */
+	public TransformationListIterable(ListIterable<? extends E1> iterable) {
+		super();
+		if (iterable == null) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+		this.transformer = this.buildDefaultTransformer();
+	}
+
+	/**
+	 * Construct a list iterable with the specified nested list
+	 * and transformer.
+	 */
+	public <T extends E1> TransformationListIterable(List<T> list, Transformer<E1, ? extends E2> transformer) {
+		this(new ListListIterable<T>(list), transformer);
+	}
+
+	/**
+	 * Construct a list iterable with the specified nested list iterable
+	 * and transformer.
+	 */
+	public TransformationListIterable(ListIterable<? extends E1> iterable, Transformer<E1, ? extends E2> transformer) {
+		super();
+		if ((iterable == null) || (transformer == null)) {
+			throw new NullPointerException();
+		}
+		this.iterable = iterable;
+		this.transformer = transformer;
+	}
+
+	protected Transformer<E1, ? extends E2> buildDefaultTransformer() {
+		return new DefaultTransformer();
+	}
+
+	@Override
+	public ListIterator<E2> iterator() {
+		return new TransformationListIterator<E1, E2>(this.iterable.iterator(), this.transformer);
+	}
+
+	/**
+	 * Transform the specified object and return the result.
+	 */
+	protected E2 transform(@SuppressWarnings("unused") E1 o) {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+	@Override
+	public String toString() {
+		return ListTools.list(this).toString();
+	}
+
+
+	//********** default transformer **********
+
+	protected class DefaultTransformer implements Transformer<E1, E2> {
+		@Override
+		public E2 transform(E1 o) {
+			return TransformationListIterable.this.transform(o);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/TreeIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/TreeIterable.java
new file mode 100644
index 0000000..7840a2c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterable/TreeIterable.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterable;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * A <code>TreeIterable</code> simplifies the traversal of a
+ * tree of objects, where the objects' protocol(s) provides
+ * a method for getting the immediate children of the given
+ * node but does not provide a method for getting all the
+ * descendants (children, grandchildren, etc.) of the given node.
+ * <p>
+ * To use, supply:<ul>
+ * <li> either the root element of the tree or, if the tree has
+ * multiple roots, an {@link Iterable} of the set of roots
+ * <li> a {@link Transformer} that delivers the children of each child
+ * </ul>
+ *
+ * @param <E> the type of elements returned by the iterable's iterator
+ *
+ * @see IteratorTools#treeIterator(Iterable, Transformer)
+ */
+public class TreeIterable<E>
+	implements Iterable<E>
+{
+	private final Iterable<? extends E> roots;
+	private final Transformer<E, Iterator<? extends E>> transformer;
+
+
+	/**
+	 * Construct an iterable containing the nodes of a tree with the specified roots
+	 * and midwife.
+	 */
+	public TreeIterable(Iterable<? extends E> roots, Transformer<E, Iterator<? extends E>> transformer) {
+		super();
+		if ((roots == null) || (transformer == null)) {
+			throw new NullPointerException();
+		}
+		this.roots = roots;
+		this.transformer = transformer;
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return IteratorTools.treeIterator(this.roots, this.transformer);
+	}
+
+	@Override
+	public String toString() {
+		return ListTools.list(this).toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ArrayIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ArrayIterable.java
deleted file mode 100644
index adfc3c0..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ArrayIterable.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Arrays;
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
-
-/**
- * An <code>ArrayIterable</code> provides an {@link Iterable}
- * for an array of objects of type <code>E</code>.
- *
- * @param <E> the type of elements returned by the iterable's iterator
- *
- * @see ArrayIterator
- * @see ArrayListIterable
- */
-@SuppressWarnings("nls")
-public class ArrayIterable<E> implements Iterable<E> {
-
-	final E[] array;
-	final int start;
-	final int length;
-
-	/**
-	 * Construct an iterable for the specified array.
-	 */
-	public ArrayIterable(E... array) {
-		this(array, 0, array.length);
-	}
-
-	/**
-	 * Construct an iterable for the specified array,
-	 * starting at the specified start index and continuing for
-	 * the rest of the array.
-	 */
-	public ArrayIterable(E[] array, int start) {
-		this(array, start, array.length - start);
-	}
-
-	/**
-	 * Construct an iterable for the specified array,
-	 * starting at the specified start index and continuing for
-	 * the specified length.
-	 */
-	public ArrayIterable(E[] array, int start, int length) {
-		super();
-		if ((start < 0) || (start > array.length)) {
-			throw new IllegalArgumentException("start: " + start);
-		}
-		if ((length < 0) || (length > array.length - start)) {
-			throw new IllegalArgumentException("length: " + length);
-		}
-		this.array = array;
-		this.start = start;
-		this.length = length;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Iterator<E> iterator() {
-		return new ArrayIterator<E>(this.array, this.start, this.length);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, Arrays.toString(this.array));
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ArrayListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ArrayListIterable.java
deleted file mode 100644
index d3d019d..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ArrayListIterable.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.iterators.ArrayListIterator;
-
-/**
- * An <code>ArrayListIterable</code> provides a {@link ListIterable}
- * for an array of objects of type <code>E</code>.
- *
- * @param <E> the type of elements returned by the list iterable's list iterator
- *
- * @see ArrayIterable
- * @see ArrayListIterator
- */
-public class ArrayListIterable<E>
-	extends ArrayIterable<E>
-	implements ListIterable<E>
-{
-	/**
-	 * Construct a list iterable for the specified array.
-	 */
-	public ArrayListIterable(E... array) {
-		this(array, 0, array.length);
-	}
-
-	/**
-	 * Construct a list iterable for the specified array,
-	 * starting at the specified start index and continuing for
-	 * the rest of the array.
-	 */
-	public ArrayListIterable(E[] array, int start) {
-		this(array, start, array.length - start);
-	}
-
-	/**
-	 * Construct a list iterable for the specified array,
-	 * starting at the specified start index and continuing for
-	 * the specified length.
-	 */
-	public ArrayListIterable(E[] array, int start, int length) {
-		super(array, start, length);
-	}
-
-	@Override
-	public ListIterator<E> iterator() {
-		return new ArrayListIterator<E>(this.array, this.start, this.length);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ChainIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ChainIterable.java
deleted file mode 100644
index 384aa9d..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ChainIterable.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.ChainIterator;
-
-/**
- * A <code>ChainIterable</code> provides a pluggable {@link Iterable}
- * that loops over a chain of arbitrarily linked objects. The chain
- * should be null-terminated (i.e. a call to the {@link #nextLink(Object)}
- * Returns <code>null</code> when it is passed the last
- * link of the chain).
- * To use, supply a starting link and supply a {@link ChainIterator.Linker} or
- * subclass <code>ChainIterable</code> and override the
- * {@link #nextLink(Object)} method.
- * The starting link will be the first object returned by the iterable's iterator.
- * If the starting link is <code>null</code>, the iterable will be empty.
- * Note this iterable does not support <code>null</code> elements.
- *
- * @param <E> the type of elements returned by the iterable's iterator
- *
- * @see ChainIterator
- */
-@SuppressWarnings("nls")
-public class ChainIterable<E>
-	implements Iterable<E>
-{
-	private final E startLink;
-	private final ChainIterator.Linker<E> linker;
-
-	/**
-	 * Construct an iterable with the specified starting link
-	 * and a default linker that calls back to the iterable.
-	 * Use this constructor if you want to override the
-	 * {@link #nextLink(Object)} method instead of building
-	 * a {@link ChainIterator.Linker}.
-	 */
-	public ChainIterable(E startLink) {
-		super();
-		this.startLink = startLink;
-		this.linker = this.buildDefaultLinker();
-	}
-
-	/**
-	 * Construct an iterator with the specified starting link
-	 * and linker.
-	 */
-	public ChainIterable(E startLink, ChainIterator.Linker<E> linker) {
-		super();
-		this.startLink = startLink;
-		this.linker = linker;
-	}
-
-	protected ChainIterator.Linker<E> buildDefaultLinker() {
-		return new DefaultLinker();
-	}
-
-	@Override
-	public Iterator<E> iterator() {
-		return new ChainIterator<E>(this.startLink, this.linker);
-	}
-
-	/**
-	 * Returns the next link in the chain; null if there are no more links.
-	 * <p>
-	 * This method can be overridden by a subclass as an alternative to
-	 * building a {@link ChainIterator.Linker}.
-	 */
-	protected E nextLink(@SuppressWarnings("unused") E currentLink) {
-		throw new RuntimeException("This method was not overridden.");
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.startLink);
-	}
-
-
-	//********** default linker **********
-
-	protected class DefaultLinker implements ChainIterator.Linker<E> {
-		@Override
-		public E nextLink(E currentLink) {
-			return ChainIterable.this.nextLink(currentLink);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/CloneIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/CloneIterable.java
deleted file mode 100644
index e0e5546..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/CloneIterable.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-
-/**
- * Pull together remover state and behavior for subclasses.
- *
- * @param <E> the type of elements returned by the iterable's iterator
- *
- * @see SnapshotCloneIterable
- * @see LiveCloneIterable
- */
-@SuppressWarnings("nls")
-public abstract class CloneIterable<E>
-	implements Iterable<E>
-{
-	final CloneIterator.Remover<E> remover;
-
-	// ********** constructors **********
-
-	protected CloneIterable() {
-		super();
-		this.remover = this.buildDefaultRemover();
-	}
-
-	protected CloneIterable(CloneIterator.Remover<E> remover) {
-		super();
-		this.remover = remover;
-	}
-
-	protected CloneIterator.Remover<E> buildDefaultRemover() {
-		return new DefaultRemover();
-	}
-
-
-	// ********** default removal **********
-
-	/**
-	 * Remove the specified element from the original collection.
-	 * <p>
-	 * This method can be overridden by a subclass as an
-	 * alternative to building a {@link CloneIterator.Remover}.
-	 */
-	protected void remove(@SuppressWarnings("unused") E element) {
-		throw new RuntimeException("This method was not overridden.");
-	}
-
-
-	//********** default mutator **********
-
-	protected class DefaultRemover implements CloneIterator.Remover<E> {
-		@Override
-		public void remove(E element) {
-			CloneIterable.this.remove(element);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/CloneListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/CloneListIterable.java
deleted file mode 100644
index c013b24..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/CloneListIterable.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import org.eclipse.persistence.tools.utility.iterators.CloneListIterator;
-
-/**
- * Pull together mutator state and behavior for subclasses.
- *
- * @param <E> the type of elements returned by the list iterable's list iterator
- *
- * @see SnapshotCloneListIterable
- * @see LiveCloneListIterable
- */
-@SuppressWarnings("nls")
-public abstract class CloneListIterable<E>
-	implements ListIterable<E>
-{
-	final CloneListIterator.Mutator<E> mutator;
-
-	// ********** constructors **********
-
-	protected CloneListIterable() {
-		super();
-		this.mutator = this.buildDefaultMutator();
-	}
-
-	protected CloneListIterable(CloneListIterator.Mutator<E> mutator) {
-		super();
-		this.mutator = mutator;
-	}
-
-	protected CloneListIterator.Mutator<E> buildDefaultMutator() {
-		return new DefaultMutator();
-	}
-
-
-	// ********** default mutations **********
-
-	/**
-	 * At the specified index, add the specified element to the original list.
-	 * <p>
-	 * This method can be overridden by a subclass as an
-	 * alternative to building a {@link CloneListIterator.Mutator}.
-	 */
-	protected void add(@SuppressWarnings("unused") int index, @SuppressWarnings("unused") E element) {
-		throw new RuntimeException("This method was not overridden.");
-	}
-
-	/**
-	 * Remove the element at the specified index from the original list.
-	 * <p>
-	 * This method can be overridden by a subclass as an
-	 * alternative to building a {@link CloneListIterator.Mutator}.
-	 */
-	protected void remove(@SuppressWarnings("unused") int index) {
-		throw new RuntimeException("This method was not overridden.");
-	}
-
-	/**
-	 * At the specified index, set the specified element in the original list.
-	 * <p>
-	 * This method can be overridden by a subclass as an
-	 * alternative to building a {@link CloneListIterator.Mutator}.
-	 */
-	protected void set(@SuppressWarnings("unused") int index, @SuppressWarnings("unused") E element) {
-		throw new RuntimeException("This method was not overridden.");
-	}
-
-
-	//********** default mutator **********
-
-	protected class DefaultMutator implements CloneListIterator.Mutator<E> {
-		@Override
-		public void add(int index, E element) {
-			CloneListIterable.this.add(index, element);
-		}
-		@Override
-		public void remove(int index) {
-			CloneListIterable.this.remove(index);
-		}
-		@Override
-		public void set(int index, E element) {
-			CloneListIterable.this.set(index, element);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/CompositeIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/CompositeIterable.java
deleted file mode 100644
index cb2e763..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/CompositeIterable.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.CompositeIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
-
-/**
- * A <code>CompositeIterable</code> wraps an {@link Iterable}
- * of {@link Iterable}s and makes them appear to be a single
- * {@link Iterable}.
- *
- * @param <E> the type of elements returned by the iterable's iterator
- *
- * @see CompositeIterator
- * @see CompositeListIterable
- */
-public class CompositeIterable<E>
-	implements Iterable<E>
-{
-	private final Iterable<? extends Iterable<? extends E>> iterables;
-
-	/**
-	 * Construct an iterable with the specified collection of iterables.
-	 */
-	public CompositeIterable(Iterable<? extends Iterable<? extends E>> iterables) {
-		super();
-		this.iterables = iterables;
-	}
-
-	/**
-	 * Construct an iterable with the specified object prepended
-	 * to the specified iterable.
-	 */
-	@SuppressWarnings("unchecked")
-	public CompositeIterable(E object, Iterable<? extends E> iterable) {
-		this(new SingleElementIterable<E>(object), iterable);
-	}
-
-	/**
-	 * Construct an iterable with the specified object appended
-	 * to the specified iterable.
-	 */
-	@SuppressWarnings("unchecked")
-	public CompositeIterable(Iterable<? extends E> iterable, E object) {
-		this(iterable, new SingleElementIterable<E>(object));
-	}
-
-	/**
-	 * Construct an iterable with the specified iterables.
-	 */
-	public CompositeIterable(Iterable<? extends E>... iterables) {
-		this(new ArrayIterable<Iterable<? extends E>>(iterables));
-	}
-
-	/**
-	 * combined iterators
-	 */
-	@Override
-	public Iterator<E> iterator() {
-		return new CompositeIterator<E>(this.iterators());
-	}
-
-	/**
-	 * iterator of iterators
-	 */
-	protected Iterator<? extends Iterator<? extends E>> iterators() {
-		return new TransformationIterator<Iterator<? extends E>, Iterable<? extends E>>(this.iterables()) {
-			@Override
-			protected Iterator<? extends E> transform(Iterable<? extends E> next) {
-				return next.iterator();
-			}
-		};
-	}
-
-	/**
-	 * iterator of iterables
-	 */
-	protected Iterator<? extends Iterable<? extends E>> iterables() {
-		return this.iterables.iterator();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterables);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/CompositeListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/CompositeListIterable.java
deleted file mode 100644
index e4285ed..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/CompositeListIterable.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.CompositeListIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationListIterator;
-
-/**
- * A <code>CompositeListIterable</code> wraps a {@link ListIterable}
- * of {@link ListIterable}s and makes them appear to be a single
- * {@link ListIterable}.
- *
- * @param <E> the type of elements returned by the list iterable's list iterator
- *
- * @see CompositeListIterator
- * @see CompositeIterable
- * @see ReadOnlyCompositeListIterable
- */
-public class CompositeListIterable<E>
-	implements ListIterable<E>
-{
-	private final ListIterable<? extends ListIterable<E>> iterables;
-
-	/**
-	 * Construct a list iterable with the specified list of list iterables.
-	 */
-	public CompositeListIterable(List<ListIterable<E>> iterables) {
-		this(new ListListIterable<ListIterable<E>>(iterables));
-	}
-
-	/**
-	 * Construct a list iterable with the specified list of list iterables.
-	 */
-	public CompositeListIterable(ListIterable<? extends ListIterable<E>> iterables) {
-		super();
-		this.iterables = iterables;
-	}
-
-	/**
-	 * Construct a list iterable with the specified object prepended
-	 * to the specified list.
-	 */
-	public CompositeListIterable(E object, List<E> list) {
-		this(object, new ListListIterable<E>(list));
-	}
-
-	/**
-	 * Construct a list iterable with the specified object prepended
-	 * to the specified list iterable.
-	 */
-	@SuppressWarnings("unchecked")
-	public CompositeListIterable(E object, ListIterable<E> iterable) {
-		this(new SingleElementListIterable<E>(object), iterable);
-	}
-
-	/**
-	 * Construct a list iterable with the specified object appended
-	 * to the specified list.
-	 */
-	public CompositeListIterable(List<E> list, E object) {
-		this(new ListListIterable<E>(list), object);
-	}
-
-	/**
-	 * Construct a list iterable with the specified object appended
-	 * to the specified list iterable.
-	 */
-	@SuppressWarnings("unchecked")
-	public CompositeListIterable(ListIterable<E> iterable, E object) {
-		this(iterable, new SingleElementListIterable<E>(object));
-	}
-
-	/**
-	 * Construct a list iterable with the specified list iterables.
-	 */
-	public CompositeListIterable(ListIterable<E>... iterables) {
-		this(new ArrayListIterable<ListIterable<E>>(iterables));
-	}
-
-	/**
-	 * Construct a list iterable with the specified lists.
-	 */
-	public CompositeListIterable(List<E>... lists) {
-		this(new TransformationListIterable<ListIterable<E>, List<E>>(new ArrayListIterable<List<E>>(lists)) {
-			@Override
-			protected ListIterable<E> transform(List<E> list) {
-				return new ListListIterable<E>(list);
-			}
-		});
-	}
-
-	/**
-	 * combined list iterators
-	 */
-	@Override
-	public ListIterator<E> iterator() {
-		return new CompositeListIterator<E>(this.iterators());
-	}
-
-	/**
-	 * list iterator of list iterators
-	 */
-	protected ListIterator<? extends ListIterator<E>> iterators() {
-		return new TransformationListIterator<ListIterator<E>, ListIterable<E>>(this.iterables()) {
-			@Override
-			protected ListIterator<E> transform(ListIterable<E> next) {
-				return next.iterator();
-			}
-		};
-	}
-
-	/**
-	 * list iterator of list iterables
-	 */
-	protected ListIterator<? extends ListIterable<E>> iterables() {
-		return this.iterables.iterator();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterables);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/EmptyIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/EmptyIterable.java
deleted file mode 100644
index 2b3d1c6..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/EmptyIterable.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.io.Serializable;
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.iterators.EmptyIterator;
-
-/**
- * An <code>EmptyIterable</code> is just that.
- * Maybe just a touch better-performing than {@link java.util.Collections#EMPTY_SET}
- * since we don't create a new {@link Iterator} every time {@link #iterator()} is called.
- * (Not sure why they do that....)
- * 
- * @param <E> the type of elements returned by the iterable's iterator
- * 
- * @see EmptyIterator
- * @see EmptyListIterable
- */
-public final class EmptyIterable<E>
-	implements Iterable<E>, Serializable
-{
-	// singleton
-	@SuppressWarnings("rawtypes")
-	private static final Iterable INSTANCE = new EmptyIterable();
-
-	/**
-	 * Returns the singleton.
-	 */
-	@SuppressWarnings("unchecked")
-	public static <T> Iterable<T> instance() {
-		return INSTANCE;
-	}
-
-	/**
-	 * Ensure single instance.
-	 */
-	private EmptyIterable() {
-		super();
-	}
-
-	@Override
-	public Iterator<E> iterator() {
-		return EmptyIterator.instance();
-	}
-
-	@Override
-	public String toString() {
-		return this.getClass().getSimpleName();
-	}
-
-	private static final long serialVersionUID = 1L;
-	private Object readResolve() {
-		// replace this object with the singleton
-		return INSTANCE;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/EmptyListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/EmptyListIterable.java
deleted file mode 100644
index 0c7e416..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/EmptyListIterable.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.io.Serializable;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.iterators.EmptyListIterator;
-
-/**
- * An <code>EmptyListIterable</code> is just that.
- * Maybe just a touch better-performing than {@link java.util.Collections#EMPTY_LIST}
- * since we don't create a new {@link java.util.Iterator} every time
- * {@link #iterator()} is called. (Not sure why they do that....)
- * 
- * @param <E> the type of elements returned by the list iterable's list iterator
- * 
- * @see EmptyListIterator
- * @see EmptyIterable
- */
-public final class EmptyListIterable<E>
-	implements ListIterable<E>, Serializable
-{
-	// singleton
-	@SuppressWarnings("rawtypes")
-	private static final ListIterable INSTANCE = new EmptyListIterable();
-
-	/**
-	 * Returns the singleton.
-	 */
-	@SuppressWarnings("unchecked")
-	public static <T> ListIterable<T> instance() {
-		return INSTANCE;
-	}
-
-	/**
-	 * Ensure single instance.
-	 */
-	private EmptyListIterable() {
-		super();
-	}
-
-	@Override
-	public ListIterator<E> iterator() {
-		return EmptyListIterator.instance();
-	}
-
-	@Override
-	public String toString() {
-		return this.getClass().getSimpleName();
-	}
-
-	private static final long serialVersionUID = 1L;
-	private Object readResolve() {
-		// replace this object with the singleton
-		return INSTANCE;
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/FilteringIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/FilteringIterable.java
deleted file mode 100644
index 82bd700..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/FilteringIterable.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Iterator;
-import org.eclipse.persistence.tools.utility.Filter;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.FilteringIterator;
-
-/**
- * A <code>FilteringIterable</code> wraps another {@link Iterable}
- * and uses a {@link Filter} to determine which elements in the
- * nested iterable are to be returned by the iterable's iterator.
- * <p>
- * As an alternative to building a {@link Filter}, a subclass
- * of <code>FilteringIterable</code> can override the
- * {@link #accept(Object)} method.
- *
- * @param <E> the type of elements to be filtered
- *
- * @see FilteringIterator
- */
-@SuppressWarnings("nls")
-public class FilteringIterable<E>
-	implements Iterable<E>
-{
-	private final Iterable<? extends E> iterable;
-	private final Filter<E> filter;
-
-	/**
-	 * Construct an iterable with the specified nested
-	 * iterable and a default filter that calls back to the iterable.
-	 * Use this constructor if you want to override the
-	 * {@link #accept(Object)} method instead of building
-	 * a {@link Filter}.
-	 */
-	public FilteringIterable(Iterable<? extends E> iterable) {
-		super();
-		this.iterable = iterable;
-		this.filter = this.buildDefaultFilter();
-	}
-
-	/**
-	 * Construct an iterable with the specified nested
-	 * iterable and filter.
-	 */
-	public FilteringIterable(Iterable<? extends E> iterable, Filter<E> filter) {
-		super();
-		this.iterable = iterable;
-		this.filter = filter;
-	}
-
-	protected Filter<E> buildDefaultFilter() {
-		return new DefaultFilter();
-	}
-
-	@Override
-	public Iterator<E> iterator() {
-		return new FilteringIterator<E>(this.iterable.iterator(), this.filter);
-	}
-
-	/**
-	 * Returns whether the iterable's iterator
-	 * Returns the specified next element from a call to the
-	 * {@link Iterator#next()} method.
-	 * <p>
-	 * This method can be overridden by a subclass as an
-	 * alternative to building a {@link Filter}.
-	 */
-	protected boolean accept(@SuppressWarnings("unused") E o) {
-		throw new RuntimeException("This method was not overridden.");
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterable);
-	}
-
-
-	//********** default filter **********
-
-	protected class DefaultFilter implements Filter<E> {
-		@Override
-		public boolean accept(E o) {
-			return FilteringIterable.this.accept(o);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/GraphIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/GraphIterable.java
deleted file mode 100644
index 41820d0..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/GraphIterable.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Arrays;
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.GraphIterator;
-
-/**
- * A <code>GraphIterable</code> is similar to a {@link TreeIterable}
- * except that it cannot be assumed that all nodes assume a strict tree
- * structure. For instance, in a tree, a node cannot be a descendent of
- * itself, but a graph may have a cyclical structure.
- *
- * A <code>GraphIterable</code> simplifies the traversal of a
- * graph of objects, where the objects' protocol(s) provides
- * a method for getting the next collection of nodes in the graph,
- * (or <em>neighbors</em>), but does not provide a method for
- * getting <em>all</em> of the nodes in the graph.
- * Returns his neighbors, and those neighbors
- * Returns their neighbors, which might also include the original
- * neighbor, but you only want to visit the original neighbor once.)
- * <p>
- * If a neighbor has already been visited (determined by using
- * {@link #equals(Object)}), that neighbor is not visited again,
- * nor are the neighbors of that object.
- * <p>
- * It is up to the user of this class to ensure a <em>complete</em> graph.
- * <p>
- * To use, supply:<ul>
- * <li> either the initial node of the graph or an {@link Iterable}
- * of the initial collection of graph nodes
- * <li> a {@link GraphIterator.MisterRogers} that tells who the neighbors are
- * of each node
- * (alternatively, subclass <code>GraphIterable</code>
- * and override the {@link #neighbors(Object)} method)
- * </ul>
- * The {@link Iterator#remove()} operation is not supported. This behavior, if
- * desired, must be implemented by the user of this class.
- *
- * @param <E> the type of elements returned by the iterable's iterator
- *
- * @see GraphIterator
- */
-@SuppressWarnings("nls")
-public class GraphIterable<E>
-	implements Iterable<E>
-{
-	private final Iterable<? extends E> roots;
-	private final GraphIterator.MisterRogers<E> misterRogers;
-
-	/**
-	 * Construct an iterable containing the nodes of a graph with the specified root
-	 * and a default Mr. Rogers that calls back to the iterable.
-	 * Use this constructor if you want to override the
-	 * {@link #neighbors(Object)} method instead of building
-	 * a {@link GraphIterator.MisterRogers}.
-	 */
-	public GraphIterable(E root) {
-		this(new SingleElementIterable<E>(root));
-	}
-
-	/**
-	 * Construct an iterable containing the nodes of a graph
-	 * with the specified root and Mr. Rogers.
-	 */
-	public GraphIterable(E root, GraphIterator.MisterRogers<E> misterRogers) {
-		this(new SingleElementIterable<E>(root), misterRogers);
-	}
-
-	/**
-	 * Construct an iterable containing the nodes of a graph
-	 * with the specified collection of roots
-	 * and a default Mr. Rogers that calls back to the iterable.
-	 * Use this constructor if you want to override the
-	 * {@link #neighbors(Object)} method instead of building
-	 * a {@link GraphIterator.MisterRogers}.
-	 */
-	public GraphIterable(E... roots) {
-		this(Arrays.asList(roots));
-	}
-
-	/**
-	 * Construct an iterable containing the nodes of a graph
-	 * with the specified roots and Mr. Rogers.
-	 */
-	public GraphIterable(E[] roots, GraphIterator.MisterRogers<E> misterRogers) {
-		this(Arrays.asList(roots), misterRogers);
-	}
-
-	/**
-	 * Construct an iterable containing the nodes of a graph
-	 * with the specified collection of roots
-	 * and a default Mr. Rogers that calls back to the iterable.
-	 * Use this constructor if you want to override the
-	 * {@link #neighbors(Object)} method instead of building
-	 * a {@link GraphIterator.MisterRogers}.
-	 */
-	public GraphIterable(Iterable<? extends E> roots) {
-		super();
-		this.roots = roots;
-		this.misterRogers = this.buildDefaultMisterRogers();
-	}
-
-	/**
-	 * Construct an iterable containing the nodes of a graph
-	 * with the specified roots and Mr. Rogers.
-	 */
-	public GraphIterable(Iterable<? extends E> roots, GraphIterator.MisterRogers<E> misterRogers) {
-		super();
-		this.roots = roots;
-		this.misterRogers = misterRogers;
-	}
-
-	protected GraphIterator.MisterRogers<E> buildDefaultMisterRogers() {
-		return new DefaultMisterRogers();
-	}
-
-	@Override
-	public Iterator<E> iterator() {
-		return new GraphIterator<E>(this.roots, this.misterRogers);
-	}
-
-	/**
-	 * Returns the immediate neighbors of the specified object.
-	 * <p>
-	 * This method can be overridden by a subclass as an
-	 * alternative to building a {@link GraphIterator.MisterRogers}.
-	 */
-	protected Iterator<? extends E> neighbors(@SuppressWarnings("unused") E next) {
-		throw new RuntimeException("This method was not overridden.");
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.roots);
-	}
-
-
-	//********** default Mr. Rogers **********
-
-	protected class DefaultMisterRogers implements GraphIterator.MisterRogers<E> {
-		@Override
-		public Iterator<? extends E> neighbors(E node) {
-			return GraphIterable.this.neighbors(node);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/LateralIterableWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/LateralIterableWrapper.java
deleted file mode 100644
index 5bdbc18..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/LateralIterableWrapper.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.LateralIteratorWrapper;
-
-/**
- * Wrap an iterable of elements of type <code>E1</code>, converting it into an
- * iterable of elements of type <code>E2</code>. <em>Assume</em> the wrapped
- * iterable contains only elements of type <code>E2</code>. The result is a
- * {@link ClassCastException} if this assumption is false.
- *
- * @param <E1> input: the type of elements contained by the wrapped iterable
- * @param <E2> output: the type of elements returned by the iterable's iterators
- *
- * @see LateralIteratorWrapper
- * @see SubIterableWrapper
- */
-public class LateralIterableWrapper<E1, E2>
-	implements Iterable<E2>
-{
-	private final Iterable<E1> iterable;
-
-	public LateralIterableWrapper(Iterable<E1> iterable) {
-		super();
-		this.iterable = iterable;
-	}
-
-	@Override
-	public Iterator<E2> iterator() {
-		return new LateralIteratorWrapper<E1, E2>(this.iterable.iterator());
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterable);
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/LateralListIterableWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/LateralListIterableWrapper.java
deleted file mode 100644
index 7fc5419..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/LateralListIterableWrapper.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.LateralListIteratorWrapper;
-
-/**
- * Wrap a list iterable of elements of type <code>E1</code>, converting it into
- * a list iterable of elements of type <code>E2</code>. <em>Assume</em> the
- * wrapped iterable contains only elements of type <code>E2</code>.
- * The result is a {@link ClassCastException} if this assumption is false.
- *
- * @param <E1> input: the type of elements contained by the wrapped list iterable
- * @param <E2> output: the type of elements returned by the iterable's list iterators
- *
- * @see LateralListIteratorWrapper
- * @see SubListIterableWrapper
- */
-public class LateralListIterableWrapper<E1, E2>
-	implements ListIterable<E2>
-{
-	private final ListIterable<E1> iterable;
-
-	public LateralListIterableWrapper(List<E1> list) {
-		this(new ListListIterable<E1>(list));
-	}
-
-	public LateralListIterableWrapper(ListIterable<E1> iterable) {
-		super();
-		this.iterable = iterable;
-	}
-
-	@Override
-	public ListIterator<E2> iterator() {
-		return new LateralListIteratorWrapper<E1, E2>(this.iterable.iterator());
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterable);
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ListIterable.java
deleted file mode 100644
index b2d4282..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ListIterable.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.ListIterator;
-
-/**
- * A <code>ListIterable</code> simply extends {@link Iterable}
- * Returns a {@link ListIterator} of type <code>E</code>.
- *
- * @param <E> the type of elements returned by the iterable's iterators
- */
-public interface ListIterable<E>
-	extends Iterable<E>
-{
-	/**
-	 * Returns a list iterator over a set of elements of type E.
-	 */
-	@Override
-	ListIterator<E> iterator();
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ListListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ListListIterable.java
deleted file mode 100644
index a3dbbfd..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ListListIterable.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.List;
-import java.util.ListIterator;
-
-/**
- * A <code>ListListIterable</code> adapts a {@link List}
- * to the {@link ListIterable} interface.
- *
- * @param <E> the type of elements returned by the iterable's iterators
- */
-public class ListListIterable<E>
-	implements ListIterable<E>
-{
-	private final List<? extends E> list;
-
-	public ListListIterable(List<? extends E> list) {
-		super();
-		this.list = list;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	@SuppressWarnings("unchecked")
-	public ListIterator<E> iterator() {
-		return (ListIterator<E>) this.list.listIterator();
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/LiveCloneIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/LiveCloneIterable.java
deleted file mode 100644
index 6cc83e0..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/LiveCloneIterable.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-
-/**
- * A <code>LiveCloneIterable</code> returns an iterator on a current copy of a
- * collection, allowing for concurrent access to the original collection. A
- * copy of the collection is created every time {@link #iterator()} is
- * called. As a result, the contents of the collection can be different with
- * each call to {@link #iterator()} (i.e. it is "live").
- * <p>
- * The original collection passed to the <code>LiveCloneIterable</code>'s
- * constructor should be thread-safe (e.g. {@link java.util.Vector});
- * otherwise you run the risk of a corrupted collection.
- * <p>
- * By default, the iterator returned by a <code>LiveCloneIterable</code> does not
- * support the {@link Iterator#remove()} operation; this is because it does not
- * have access to the original collection. But if the <code>LiveCloneIterable</code>
- * is supplied with an {@link CloneIterator.Remover} it will delegate the
- * {@link Iterator#remove()} operation to the <code>Remover</code>.
- * Alternatively, a subclass can override the iterable's {@link #remove(Object)}
- * method.
- * 
- * @param <E> the type of elements returned by the iterable's iterator
- * 
- * @see CloneIterator
- * @see SnapshotCloneIterable
- * @see LiveCloneListIterable
- */
-public class LiveCloneIterable<E>
-	extends CloneIterable<E>
-{
-	private final Collection<? extends E> collection;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct a "live" iterable for the specified collection.
-	 * The {@link Iterator#remove()} operation will not be supported
-	 * by the iterator returned by {@link #iterator()}
-	 * unless a subclass overrides the iterable's {@link #remove(Object)}
-	 * method.
-	 */
-	public LiveCloneIterable(Collection<? extends E> collection) {
-		super();
-		this.collection = collection;
-	}
-
-	/**
-	 * Construct a "live" iterable for the specified collection.
-	 * The specified remover will be used by any generated iterators to
-	 * remove objects from the original collection.
-	 */
-	public LiveCloneIterable(Collection<? extends E> collection, CloneIterator.Remover<E> remover) {
-		super(remover);
-		this.collection = collection;
-	}
-
-
-	// ********** Iterable implementation **********
-
-	@Override
-	public Iterator<E> iterator() {
-		return new CloneIterator<E>(this.collection, this.remover);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.collection);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/LiveCloneListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/LiveCloneListIterable.java
deleted file mode 100644
index 87b97ae..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/LiveCloneListIterable.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneListIterator;
-
-/**
- * A <code>LiveCloneListIterable</code> returns a list iterator on a current
- * copy of a list, allowing for concurrent access to the original list. A
- * copy of the list is created every time {@link #iterator()} is
- * called. As a result, the contents of the list can be different with
- * each call to {@link #iterator()} (i.e. it is "live").
- * <p>
- * The original list passed to the <code>LiveCloneListIterable</code>'s
- * constructor should be thread-safe (e.g. {@link java.util.Vector});
- * otherwise you run the risk of a corrupted list.
- * <p>
- * By default, the list iterator returned by a <code>LiveCloneListIterable</code>
- * does not support the modify operations; this is because it does not
- * have access to the original list. But if the <code>LiveCloneListIterable</code>
- * is supplied with an {@link CloneListIterator.Mutator} it will delegate the
- * modify operations to the <code>Mutator</code>.
- * Alternatively, a subclass can override the list iterable's mutation
- * methods.
- * 
- * @param <E> the type of elements returned by the list iterable's list iterator
- * 
- * @see CloneListIterator
- * @see SnapshotCloneListIterable
- * @see LiveCloneIterable
- */
-public class LiveCloneListIterable<E>
-	extends CloneListIterable<E>
-{
-	private final List<? extends E> list;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct a "live" list iterable for the specified list.
-	 * The {@link ListIterator} mutation operations will not be supported
-	 * by the list iterator returned by {@link #iterator()}
-	 * unless a subclass overrides the iterable's mutation
-	 * methods.
-	 */
-	public LiveCloneListIterable(List<? extends E> list) {
-		super();
-		this.list = list;
-	}
-
-	/**
-	 * Construct a "live" list iterable for the specified list.
-	 * The specified mutator will be used by any generated list iterators to
-	 * modify the original list.
-	 */
-	public LiveCloneListIterable(List<? extends E> list, CloneListIterator.Mutator<E> mutator) {
-		super(mutator);
-		this.list = list;
-	}
-
-
-	// ********** ListIterable implementation **********
-
-	@Override
-	public ListIterator<E> iterator() {
-		return new CloneListIterator<E>(this.list, this.mutator);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.list);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/PeekableIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/PeekableIterable.java
deleted file mode 100644
index d53bf51..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/PeekableIterable.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.PeekableIterator;
-
-/**
- * A <code>PeekableIterable</code> wraps another {@link Iterable}
- * and returns an {@link PeekableIterator} that allows a
- * {@link PeekableIterator#peek() peek} at the next element to be 
- * returned by {@link Iterator#next()}.
- * <p>
- * One, possibly undesirable, side-effect of using this iterator is that
- * the nested iterator's <code>next()</code> method will be invoked
- * <em>before</em> the peekable iterator's {@link Iterator#next()}
- * method is invoked. This is because the "next" element must be
- * pre-loaded for the {@link PeekableIterator#peek()} method.
- * This also prevents a peekable iterator from supporting the optional
- * {@link Iterator#remove()} method.
- * 
- * @param <E> the type of elements returned by the iterable's iterator
- * 
- * @see PeekableIterator
- */
-public class PeekableIterable<E>
-	implements Iterable<E>
-{
-	private final Iterable<? extends E> iterable;
-
-	/**
-	 * Construct a peekable iterable that wraps the specified
-	 * iterable.
-	 */
-	public PeekableIterable(Iterable<? extends E> iterable) {
-		super();
-		this.iterable = iterable;
-	}
-
-	@Override
-	public PeekableIterator<E> iterator() {
-		return new PeekableIterator<E>(this.iterable);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterable);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/QueueIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/QueueIterable.java
deleted file mode 100644
index e447a62..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/QueueIterable.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.Queue;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.QueueIterator;
-
-/**
- * A <code>QueueIterable</code> provides an {@link Iterable}
- * for a {@link Queue} of objects of type <code>E</code>. The queue's elements
- * are {@link Queue#dequeue() dequeue}d" as the iterable's iterator returns
- * them with calls to {@link Iterator#next()}.
- * 
- * @param <E> the type of elements returned by the iterable's iterator
- * 
- * @see Queue
- * @see QueueIterator
- */
-public class QueueIterable<E>
-	implements Iterable<E>
-{
-	private final Queue<E> queue;
-
-	/**
-	 * Construct an iterable for the specified queue.
-	 */
-	public QueueIterable(Queue<E> queue) {
-		super();
-		this.queue = queue;
-	}
-
-	@Override
-	public Iterator<E> iterator() {
-		return new QueueIterator<E>(this.queue);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.queue);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ReadOnlyCompositeListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ReadOnlyCompositeListIterable.java
deleted file mode 100644
index 08f5cb7..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ReadOnlyCompositeListIterable.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.ReadOnlyCompositeListIterator;
-import org.eclipse.persistence.tools.utility.iterators.TransformationListIterator;
-
-/**
- * A <code>ReadOnlyCompositeListIterable</code> wraps a {@link ListIterable}
- * of {@link ListIterable}s and makes them appear to be a single
- * read-only {@link ListIterable}. A read-only composite list
- * iterable is more flexible than a normal composite list iterable when it
- * comes to the element types of the nested list iterables.
- *
- * @param <E> the type of elements returned by the list iterable's list iterator
- *
- * @see ReadOnlyCompositeListIterator
- * @see CompositeListIterable
- */
-public class ReadOnlyCompositeListIterable<E>
-	implements ListIterable<E>
-{
-	private final ListIterable<? extends ListIterable<? extends E>> iterables;
-
-	/**
-	 * Construct a list iterable with the specified list of list iterables.
-	 */
-	public ReadOnlyCompositeListIterable(ListIterable<? extends ListIterable<? extends E>> iterables) {
-		super();
-		this.iterables = iterables;
-	}
-
-	/**
-	 * Construct a list iterable with the specified object prepended
-	 * to the specified list iterable.
-	 */
-	@SuppressWarnings("unchecked")
-	public ReadOnlyCompositeListIterable(E object, ListIterable<? extends E> iterable) {
-		this(new SingleElementListIterable<E>(object), iterable);
-	}
-
-	/**
-	 * Construct a list iterable with the specified object appended
-	 * to the specified list iterable.
-	 */
-	@SuppressWarnings("unchecked")
-	public ReadOnlyCompositeListIterable(ListIterable<? extends E> iterable, E object) {
-		this(iterable, new SingleElementListIterable<E>(object));
-	}
-
-	/**
-	 * Construct a list iterable with the specified list iterables.
-	 */
-	public ReadOnlyCompositeListIterable(ListIterable<? extends E>... iterables) {
-		this(new ArrayListIterable<ListIterable<? extends E>>(iterables));
-	}
-
-	/**
-	 * combined list iterators
-	 */
-	@Override
-	public ListIterator<E> iterator() {
-		return new ReadOnlyCompositeListIterator<E>(this.iterators());
-	}
-
-	/**
-	 * list iterator of list iterators
-	 */
-	protected ListIterator<? extends ListIterator<? extends E>> iterators() {
-		return new TransformationListIterator<ListIterator<? extends E>, ListIterable<? extends E>>(this.iterables()) {
-			@Override
-			protected ListIterator<? extends E> transform(ListIterable<? extends E> next) {
-				return next.iterator();
-			}
-		};
-	}
-
-	/**
-	 * list iterator of list iterables
-	 */
-	protected ListIterator<? extends ListIterable<? extends E>> iterables() {
-		return this.iterables.iterator();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterables);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ReadOnlyIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ReadOnlyIterable.java
deleted file mode 100644
index 40bf020..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ReadOnlyIterable.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.ReadOnlyIterator;
-
-/**
- * A <code>ReadOnlyIterable</code> wraps another {@link Iterable}
- * and returns a read-only {@link Iterator}.
- * 
- * @param <E> the type of elements returned by the iterable's iterator
- * 
- * @see ReadOnlyIterator
- * @see ReadOnlyListIterable
- */
-public class ReadOnlyIterable<E>
-	implements Iterable<E>
-{
-	private final Iterable<? extends E> iterable;
-
-	/**
-	 * Construct an iterable the returns a read-only iterator on the elements
-	 * in the specified iterable.
-	 */
-	public ReadOnlyIterable(Iterable<? extends E> iterable) {
-		super();
-		this.iterable = iterable;
-	}
-
-	@Override
-	public Iterator<E> iterator() {
-		return new ReadOnlyIterator<E>(this.iterable);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterable);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ReadOnlyListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ReadOnlyListIterable.java
deleted file mode 100644
index 021d4c7..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/ReadOnlyListIterable.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.ReadOnlyListIterator;
-
-/**
- * A <code>ReadOnlyListIterable</code> wraps another {@link ListIterable}
- * and returns a read-only {@link ListIterator}.
- * 
- * @param <E> the type of elements returned by the list iterable's list iterator
- * 
- * @see ReadOnlyListIterator
- * @see ReadOnlyIterable
- */
-public class ReadOnlyListIterable<E>
-	implements ListIterable<E>
-{
-	private final ListIterable<? extends E> listIterable;
-
-	/**
-	 * Construct a list iterable the returns a read-only list iterator on the elements
-	 * in the specified list iterable.
-	 */
-	public ReadOnlyListIterable(ListIterable<? extends E> iterable) {
-		super();
-		this.listIterable = iterable;
-	}
-
-	@Override
-	public ListIterator<E> iterator() {
-		return new ReadOnlyListIterator<E>(this.listIterable);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.listIterable);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SingleElementIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SingleElementIterable.java
deleted file mode 100644
index d0f31eb..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SingleElementIterable.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.SingleElementIterator;
-
-/**
- * A <code>SingleElementIterable</code> returns an {@link Iterator}
- * that holds a single element
- * and returns it with the first call to {@link Iterator#next()}, at
- * Returns <code>false</code> to any subsequent
- * call to {@link Iterator#hasNext()}.
- * <p>
- * A <code>SingleElementIterable</code> is equivalent to the
- * {@link Iterable} returned by:
- * 	{@link java.util.Collections#singleton(Object)}.
- * 
- * @param <E> the type of elements returned by the iterable's iterator
- * 
- * @see SingleElementIterator
- * @see SingleElementListIterable
- */
-public class SingleElementIterable<E>
-	implements Iterable<E>
-{
-	private final E element;
-
-	/**
-	 * Construct an iterable that contains only the specified element.
-	 */
-	public SingleElementIterable(E element) {
-		super();
-		this.element = element;
-	}
-
-	@Override
-	public Iterator<E> iterator() {
-		return new SingleElementIterator<E>(this.element);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.element);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SingleElementListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SingleElementListIterable.java
deleted file mode 100644
index f8be630..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SingleElementListIterable.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.SingleElementListIterator;
-
-/**
- * A <code>SingleElementListIterable</code> returns a {@link ListIterator}
- * that holds a single element
- * and returns it with the first call to {@link ListIterator#next()}, at
- * Returns <code>false</code> to any subsequent
- * Returns <code>false</code>
- * to a call to {@link ListIterator#hasPrevious()} until a call to {@link ListIterator#next()},
- * Returns the
- * single element.
- * <p>
- * A <code>SingleElementListIterable</code> is equivalent to the
- * {@link Iterable} returned by:
- * 	{@link java.util.Collections#singletonList(Object)}.
- * 
- * @param <E> the type of elements returned by the list iterable's list iterator
- * 
- * @see SingleElementListIterator
- * @see SingleElementIterable
- */
-public class SingleElementListIterable<E>
-	implements ListIterable<E>
-{
-	private final E element;
-
-	/**
-	 * Construct a list iterable that contains only the specified element.
-	 */
-	public SingleElementListIterable(E element) {
-		super();
-		this.element = element;
-	}
-
-	@Override
-	public ListIterator<E> iterator() {
-		return new SingleElementListIterator<E>(this.element);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.element);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SnapshotCloneIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SnapshotCloneIterable.java
deleted file mode 100644
index 028ed57..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SnapshotCloneIterable.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.ArrayTools;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-
-/**
- * A <code>SnapshotCloneIterable</code> returns an iterator on a "snapshot" of a
- * collection, allowing for concurrent access to the original collection. A
- * copy of the collection is created when the iterable is constructed.
- * As a result, the contents of the collection will be the same with
- * every call to {@link #iterator()}.
- * <p>
- * The original collection passed to the <code>SnapshotCloneIterable</code>'s
- * constructor should be thread-safe (e.g. {@link java.util.Vector});
- * otherwise you run the risk of a corrupted collection.
- * <p>
- * By default, the iterator returned by a <code>SnapshotCloneIterable</code> does not
- * support the {@link Iterator#remove()} operation; this is because it does not
- * have access to the original collection. But if the <code>SnapshotCloneIterable</code>
- * is supplied with a {@link CloneIterator.Remover} it will delegate the
- * {@link Iterator#remove()} operation to the <code>Remover</code>.
- * Alternatively, a subclass can override the iterable's {@link #remove(Object)}
- * method.
- * <p>
- * This iterable is useful for multiple passes over a collection that should not
- * be changed (e.g. by another thread) between passes.
- * 
- * @param <E> the type of elements returned by the iterable's iterator
- * 
- * @see CloneIterator
- * @see LiveCloneIterable
- * @see SnapshotCloneListIterable
- */
-public class SnapshotCloneIterable<E>
-	extends CloneIterable<E>
-{
-	private final Object[] array;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct a "snapshot" iterable for the specified iterator.
-	 * The {@link Iterator#remove()} operation will not be supported
-	 * by the iterator returned by {@link #iterator()}
-	 * unless a subclass overrides the iterable's {@link #remove(Object)}
-	 * method.
-	 */
-	public SnapshotCloneIterable(Iterator<? extends E> iterator) {
-		super();
-		this.array = ArrayTools.array(iterator);
-	}
-
-	/**
-	 * Construct a "snapshot" iterable for the specified iterator.
-	 * The specified remover will be used by any generated iterators to
-	 * remove objects from the original collection.
-	 */
-	public SnapshotCloneIterable(Iterator<? extends E> iterator, CloneIterator.Remover<E> remover) {
-		super(remover);
-		this.array = ArrayTools.array(iterator);
-	}
-
-	/**
-	 * Construct a "snapshot" iterable for the specified collection.
-	 * The {@link Iterator#remove()} operation will not be supported
-	 * by the iterator returned by {@link #iterator()}
-	 * unless a subclass overrides the iterable's {@link #remove(Object)}
-	 * method.
-	 */
-	public SnapshotCloneIterable(Collection<? extends E> collection) {
-		super();
-		this.array = collection.toArray();
-	}
-
-	/**
-	 * Construct a "snapshot" iterable for the specified collection.
-	 * The specified remover will be used by any generated iterators to
-	 * remove objects from the original collection.
-	 */
-	public SnapshotCloneIterable(Collection<? extends E> collection, CloneIterator.Remover<E> remover) {
-		super(remover);
-		this.array = collection.toArray();
-	}
-
-
-	// ********** Iterable implementation **********
-
-	@Override
-	public Iterator<E> iterator() {
-		return new LocalCloneIterator<E>(this.remover, this.array);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, Arrays.toString(this.array));
-	}
-
-
-	// ********** clone iterator **********
-
-	/**
-	 * provide access to "internal" constructor
-	 */
-	protected static class LocalCloneIterator<E> extends CloneIterator<E> {
-		protected LocalCloneIterator(Remover<E> remover, Object[] array) {
-			super(remover, array);
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SnapshotCloneListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SnapshotCloneListIterable.java
deleted file mode 100644
index b1dc7ad..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SnapshotCloneListIterable.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneListIterator;
-
-/**
- * A <code>SnapshotCloneListIterable</code> returns a list iterator on a
- * "snapshot" of a list, allowing for concurrent access to the original list.
- * A copy of the list is created when the list iterable is constructed.
- * As a result, the contents of the list will be the same with
- * every call to {@link #iterator()}, even if the original list is modified via
- * the list iterator's mutation methods.
- * <p>
- * The original list passed to the <code>SnapshotCloneListIterable</code>'s
- * constructor should be thread-safe (e.g. {@link java.util.Vector});
- * otherwise you run the risk of a corrupted list.
- * <p>
- * By default, the list iterator returned by a <code>SnapshotCloneListIterable</code> does not
- * support the {@link ListIterator} mutation operations; this is because it does not
- * have access to the original list. But if the <code>SnapshotCloneListIterable</code>
- * is supplied with a {@link CloneListIterator.Mutator} it will delegate the
- * {@link ListIterator} mutation operations to the <code>Mutator</code>.
- * Alternatively, a subclass can override the list iterable's mutation
- * methods.
- * <p>
- * This list iterable is useful for multiple passes over a list that should not
- * be changed (e.g. by another thread) between passes.
- * 
- * @param <E> the type of elements returned by the list iterable's list iterator
- * 
- * @see CloneListIterator
- * @see LiveCloneListIterable
- * @see SnapshotCloneIterable
- */
-public class SnapshotCloneListIterable<E>
-	extends CloneListIterable<E>
-{
-	private final Object[] array;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct a "snapshot" list iterable for the specified list.
-	 * The {@link ListIterator} modify operations will not be supported
-	 * by the list iterator returned by {@link #iterator()}
-	 * unless a subclass overrides the list iterable's modify
-	 * method.
-	 */
-	public SnapshotCloneListIterable(List<? extends E> list) {
-		super();
-		this.array = list.toArray();
-	}
-
-	/**
-	 * Construct a "snapshot" list iterable for the specified list.
-	 * The specified mutator will be used by any generated list iterators to
-	 * modify the original list.
-	 */
-	public SnapshotCloneListIterable(List<? extends E> list, CloneListIterator.Mutator<E> mutator) {
-		super(mutator);
-		this.array = list.toArray();
-	}
-
-
-	// ********** ListIterable implementation **********
-
-	@Override
-	public ListIterator<E> iterator() {
-		return new LocalCloneListIterator<E>(this.mutator, this.array);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, Arrays.toString(this.array));
-	}
-
-
-	// ********** clone iterator **********
-
-	/**
-	 * provide access to "internal" constructor
-	 */
-	protected static class LocalCloneListIterator<E> extends CloneListIterator<E> {
-		protected LocalCloneListIterator(Mutator<E> mutator, Object[] array) {
-			super(mutator, array);
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/StackIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/StackIterable.java
deleted file mode 100644
index 9db4e57..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/StackIterable.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.Stack;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.StackIterator;
-
-/**
- * A <code>StackIterable</code> provides an {@link Iterable}
- * for a {@link Stack} of objects of type <code>E</code>. The stack's elements
- * are {@link Stack#pop() "popped"} as the iterable's iterator returns
- * them with calls to {@link Iterator#next()}.
- * 
- * @param <E> the type of elements returned by the iterable's iterator
- * 
- * @see Stack
- * @see StackIterator
- */
-public class StackIterable<E>
-	implements Iterable<E>
-{
-	private final Stack<E> stack;
-
-	/**
-	 * Construct an iterable for the specified stack.
-	 */
-	public StackIterable(Stack<E> stack) {
-		super();
-		this.stack = stack;
-	}
-
-	@Override
-	public Iterator<E> iterator() {
-		return new StackIterator<E>(this.stack);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.stack);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SubIterableWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SubIterableWrapper.java
deleted file mode 100644
index 9871d5f..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SubIterableWrapper.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.SubIteratorWrapper;
-
-/**
- * Wrap an iterable of elements of type <code>E1</code>, converting it into an
- * iterable of elements of type <code>E2</code>. <em>Assume</em> the wrapped
- * iterable contains only elements of type <code>E2</code>. The result is a
- * {@link ClassCastException} if this assumption is false.
- * <p>
- * This is like a {@link LateralIterableWrapper} but with more restrictive type
- * parameters.
- * 
- * @param <E1> input: the type of elements contained by the wrapped iterable
- * @param <E2> output: the type of elements returned by the iterable's iterators
- * 
- * @see SubIteratorWrapper
- */
-public class SubIterableWrapper<E1, E2 extends E1>
-	implements Iterable<E2>
-{
-	private final Iterable<E1> iterable;
-
-	public SubIterableWrapper(Iterable<E1> iterable) {
-		super();
-		this.iterable = iterable;
-	}
-
-	@Override
-	public Iterator<E2> iterator() {
-		return new SubIteratorWrapper<E1, E2>(this.iterable.iterator());
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterable);
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SubListIterableWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SubListIterableWrapper.java
deleted file mode 100644
index 96617de..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SubListIterableWrapper.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.SubListIteratorWrapper;
-
-/**
- * Wrap a list iterable of elements of type <code>E1</code>, converting it into
- * a list iterable of elements of type <code>E2</code>. <em>Assume</em> the
- * wrapped iterable contains only elements of type <code>E2</code>.
- * The result is a {@link ClassCastException} if this assumption is false.
- * <p>
- * This is like a {@link LateralListIterableWrapper} but with more restrictive type
- * parameters.
- * 
- * @param <E1> input: the type of elements contained by the wrapped list iterable
- * @param <E2> output: the type of elements returned by the iterable's list iterators
- * 
- * @see SubListIteratorWrapper
- */
-public class SubListIterableWrapper<E1, E2 extends E1>
-	implements ListIterable<E2>
-{
-	private final ListIterable<E1> iterable;
-
-	public SubListIterableWrapper(List<E1> list) {
-		this(new ListListIterable<E1>(list));
-	}
-
-	public SubListIterableWrapper(ListIterable<E1> iterable) {
-		super();
-		this.iterable = iterable;
-	}
-
-	@Override
-	public ListIterator<E2> iterator() {
-		return new SubListIteratorWrapper<E1, E2>(this.iterable.iterator());
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterable);
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SuperIterableWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SuperIterableWrapper.java
deleted file mode 100644
index c665546..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SuperIterableWrapper.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * Wrap an iterable of elements of any sub-type of <code>E</code>, converting it into an
- * iterable of elements of type <code>E</code>. This shouldn't be a problem since there
- * is no way to add invalid elements to the iterable.
- * 
- * @param <E> the type of elements returned by the iterable's iterators
- */
-public class SuperIterableWrapper<E>
-	implements Iterable<E>
-{
-	private final Iterable<E> iterable;
-
-	@SuppressWarnings("unchecked")
-	public SuperIterableWrapper(Iterable<? extends E> iterable) {
-		super();
-		// this should be a safe cast - the iterator will only ever
-		// return E (or a sub-type) from #next()
-		this.iterable = (Iterable<E>) iterable;
-	}
-
-	@Override
-	public Iterator<E> iterator() {
-		return this.iterable.iterator();
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterable);
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SuperListIterableWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SuperListIterableWrapper.java
deleted file mode 100644
index 5efd396..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/SuperListIterableWrapper.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.SuperListIteratorWrapper;
-
-/**
- * Wrap a list iterable of elements of any sub-type of <code>E</code>,
- * converting it into a <em>non-writable</em> list iterable of elements
- * of type <code>E</code>.
- * This shouldn't be a problem since the resulting list iterable's list
- * iterator disables the methods that would put invalid elements in the list
- * iterator's backing list (i.e. {@link SuperListIteratorWrapper#set(Object)}
- * and {@link SuperListIteratorWrapper#add(Object)}).
- * 
- * @param <E> the type of elements returned by the iterable's iterators
- * 
- * @see SuperListIteratorWrapper
- */
-public class SuperListIterableWrapper<E>
-	implements ListIterable<E>
-{
-	private final ListIterable<? extends E> iterable;
-
-	public <T extends E> SuperListIterableWrapper(List<T> list) {
-		this(new ListListIterable<T>(list));
-	}
-
-	public SuperListIterableWrapper(ListIterable<? extends E> iterable) {
-		super();
-		this.iterable = iterable;
-	}
-
-	@Override
-	public ListIterator<E> iterator() {
-		return new SuperListIteratorWrapper<E>(this.iterable.iterator());
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterable);
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TransformationFilteringIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TransformationFilteringIterable.java
deleted file mode 100644
index 61b5198..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TransformationFilteringIterable.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Iterator;
-import org.eclipse.persistence.tools.utility.Filter;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.Transformer;
-import org.eclipse.persistence.tools.utility.iterators.TransformationFilteringIterator;
-
-/**
- * A <code>TransformationFilteringIterable</code> wraps another <code>Iterable</code> and uses a
- * {@link Filter} to determine which elements in the nested iterator are to be returned by calls to
- * <code>next()</code>.
- * <p>
- * As an alternative to building a <code>Filter</code>, a subclass can override the
- * <code>accept(E2)</code> method.
- * <p>
- * One, possibly undesirable, side-effect of using this iterator is that the nested iterator's
- * <code>next()</code> method will be invoked <em>before</em> the filtered iterator's <code>next()</code>
- * method is invoked. This is because the "next" element must be checked for whether it is to be
- * accepted before the filtered iterator can determine whether it has a "next" element (i.e. that
- * the <code>hasNext()</code> method should return <code>true</code>). This also prevents a filtered
- * iterator from supporting the optional <code>remove()</code> method.
- *
- * @version 2.5
- */
-@SuppressWarnings("nls")
-public class TransformationFilteringIterable<E1, E2> implements Iterable<E1> {
-
-	/**
-	 * This {@link Filter} determines if an item can be returned or should be filtered out.
-	 */
-	private Filter<? extends E2> filter;
-
-	/**
-	 * The {@link Iterator} wrapped by this one.
-	 */
-	private Iterator<? extends E2> nestedIterator;
-
-	/**
-	 * This {@link Transformer} is used to transform the item before return it.
-	 */
-	private Transformer<E1, ? extends E2> transformer;
-
-	/**
-	 * Creates a new <code>TransformationFilteringIterable</code> with the specified nested {@link
-	 * Iterator} and a filter that simply accepts every object. Use this constructor if you want to
-	 * override the {@link #accept(E2)} method instead of building a {@link Filter}.
-	 *
-	 * @param nestedIterator The {@link Iterator} wrapped by this one
-	 */
-	public TransformationFilteringIterable(Iterator<? extends E2> nestedIterator) {
-		this(nestedIterator, Filter.Disabled.<E2>instance());
-	}
-
-	/**
-	 * Creates a new <code>TransformationFilteringIterable</code> with the specified nested {@link
-	 * Iterator} and {@link BidiTransformer}.
-	 *
-	 * @param nestedIterator The {@link Iterator} wrapped by this one
-	 * @param filter This <code>Filter</code> determines if an item can be returned or should be filtered out
-	 */
-	public TransformationFilteringIterable(Iterator<? extends E2> nestedIterator,
-	                                       Filter<? extends E2> filter) {
-
-		this(nestedIterator, filter, Transformer.Disabled.<E1, E2>instance());
-	}
-
-	/**
-	 * Creates a new <code>TransformationFilteringIterable</code> with the specified nested {@link
-	 * Iterator}, {@link Filter} and {@link BidiTransformer}.
-	 *
-	 * @param nestedIterator The {@link Iterator} wrapped by this one
-	 * @param filter This <code>Filter</code> determines if an item can be returned or should be
-	 * filtered out
-	 * @param transformer This <code>BidiTransformer</code> is used to transform the item before
-	 * return it
-	 */
-	public TransformationFilteringIterable(Iterator<? extends E2> nestedIterator,
-	                                       Filter<? extends E2> filter,
-	                                       Transformer<E1, ? extends E2> transformer) {
-
-		super();
-		this.filter         = filter;
-		this.transformer    = transformer;
-		this.nestedIterator = nestedIterator;
-	}
-
-	/**
-	 * Creates a new <code>TransformationFilteringListIterator</code> with the specified nested
-	 * {@link Iterator} and {@link Transformer}.
-	 *
-	 * @param nestedIterator The {@link Iterator} wrapped by this one
-	 * @param transformer This <code>Transformer</code> is used to transform the item before return it
-	 */
-	public TransformationFilteringIterable(Iterator<? extends E2> nestedIterator,
-	                                       Transformer<E1, ? extends E2> transformer) {
-
-		this(nestedIterator, Filter.Disabled.<E2>instance(), transformer);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Iterator<E1> iterator() {
-		return new TransformationFilteringIterator<E1, E2>(nestedIterator, filter, transformer);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		StringBuilder sb = new StringBuilder();
-		StringTools.appendToStringClassName(sb, getClass());
-		sb.append("(");
-		sb.append(nestedIterator);
-		sb.append(")");
-		return sb.toString();
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TransformationFilteringListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TransformationFilteringListIterable.java
deleted file mode 100644
index 16db3bf..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TransformationFilteringListIterable.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.BidiTransformer;
-import org.eclipse.persistence.tools.utility.Filter;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.TransformationFilteringListIterator;
-
-/**
- * A <code>TransformationFilteringListIterator</code> wraps another {@link ListIterator} and uses
- * a {@link Filter} to determine which elements in the nested iterator are to be returned. The
- * element to return will have been transformed and filtered a second time.
- * <p>
- * As an alternative to building a {@link Filter}, a subclass can override {@link #accept(Object)}.
- * <p>
- * One, possibly undesirable, side-effect of using this iterator is that the nested iterator's
- * {@link ListIterator#next()} method will be invoked <em>before</em> the filtered iterator's
- * {@link ListIterator#next()} method is invoked. This is because the "next" element must be checked
- * for whether it is to be accepted before the filtered iterator can determine whether it has a
- * "next" element (i.e. that the {@link #hasNext()} method should return <code>true</code>). This
- * also prevents a filtered iterator from supporting the optional {@link #remove()} method.
- *
- * @version 2.5
- */
-@SuppressWarnings("nls")
-public class TransformationFilteringListIterable<E1, E2> implements ListIterable<E1> {
-
-	/**
-	 * This {@link Filter} determines if an item can be returned or should be filtered out.
-	 */
-	private Filter<? extends E2> filter;
-
-	/**
-	 * The {@link ListIterator} wrapped by this one.
-	 */
-	private ListIterator<? extends E2> nestedIterator;
-
-	/**
-	 * This {@link Filter} determines if the transformed item can be returned or should be filtered out.
-	 */
-	private Filter<? extends E1> postFilter;
-
-	/**
-	 * This {@link BidiTransformer} is used to transform the item before return it.
-	 */
-	private BidiTransformer<E1, ? extends E2> transformer;
-
-	/**
-	 * Creates a new <code>TransformationFilteringListIterable</code> with the specified nested
-	 * {@link ListIterator} and a filter that simply accepts every object. Use this constructor if
-	 * you want to override the {@link #accept(E2)} method instead of building a {@link Filter}.
-	 *
-	 * @param nestedIterator The {@link ListIterator} wrapped by this one
-	 */
-	public TransformationFilteringListIterable(ListIterator<? extends E2> nestedIterator) {
-		this(nestedIterator, Filter.Disabled.<E2>instance());
-	}
-
-	/**
-	 * Creates a new <code>TransformationFilteringListIterable</code> with the specified nested
-	 * {@link Iterator} and {@link BidiTransformer}.
-	 *
-	 * @param nestedIterator The {@link ListIterator} wrapped by this one
-	 * @param transformer This {@link BidiTransformer} is used to transform the item before return it
-	 */
-	public TransformationFilteringListIterable(ListIterator<? extends E2> nestedIterator,
-	                                           BidiTransformer<E1, ? extends E2> transformer) {
-
-		this(nestedIterator, Filter.Disabled.<E2>instance(), Filter.Disabled.<E1>instance(), transformer);
-	}
-
-	/**
-	 * Creates a new <code>TransformationFilteringListIterable</code> with the specified nested
-	 * {@link Iterator} and {@link Filter}.
-	 *
-	 * @param nestedIterator The {@link ListIterator} wrapped by this one
-	 * @param filter This {@link Filter} determines if an item can be returned or should be filtered out
-	 */
-	public TransformationFilteringListIterable(ListIterator<? extends E2> nestedIterator,
-	                                           Filter<? extends E2> filter) {
-
-		this(nestedIterator, filter, Filter.Disabled.<E1>instance(), BidiTransformer.Disabled.<E1, E2>instance());
-	}
-
-	/**
-	 * Creates a new <code>TransformationFilteringListIterable</code> with the specified nested
-	 * {@link Iterator} and {@link Filter}.
-	 *
-	 * @param nestedIterator The {@link ListIterator} wrapped by this one
-	 * @param postFilter This {@link Filter} determines if the transformed item can be returned or
-	 * should be filtered out
-	 * @param filter This {@link Filter} determines if an item can be returned or should be filtered out
-	 */
-	public TransformationFilteringListIterable(ListIterator<? extends E2> nestedIterator,
-	                                           Filter<? extends E2> filter,
-	                                           Filter<? extends E1> postFilter) {
-
-		this(nestedIterator, filter, postFilter, BidiTransformer.Disabled.<E1, E2>instance());
-	}
-
-	/**
-	 * Creates a new <code>TransformationFilteringListIterator</code> with the specified nested
-	 * {@link ListIterator}, {@link Filter} and {@link BidiTransformer}.
-	 *
-	 * @param nestedIterator The {@link ListIterator} wrapped by this one
-	 * @param filter This {@link Filter} determines if an item can be returned or should be filtered out
-	 * @param postFilter This {@link Filter} determines if the transformed item can be returned or
-	 * should be filtered out
-	 * @param transformer This {@link BidiTransformer} is used to transform the item before return it
-	 */
-	public TransformationFilteringListIterable(ListIterator<? extends E2> nestedIterator,
-	                                           Filter<? extends E2> filter,
-	                                           Filter<? extends E1> postFilter,
-	                                           BidiTransformer<E1, ? extends E2> transformer) {
-
-		super();
-
-		this.filter         = filter;
-		this.postFilter     = postFilter;
-		this.transformer    = transformer;
-		this.nestedIterator = nestedIterator;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public ListIterator<E1> iterator() {
-		return new TransformationFilteringListIterator<E1, E2>(
-			nestedIterator,
-			filter,
-			postFilter,
-			transformer
-		);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		StringBuilder sb = new StringBuilder();
-		StringTools.appendToStringClassName(sb, getClass());
-		sb.append("(");
-		sb.append(nestedIterator);
-		sb.append(")");
-		return sb.toString();
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TransformationIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TransformationIterable.java
deleted file mode 100644
index 2ebfa41..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TransformationIterable.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.Transformer;
-import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
-
-/**
- * A <code>TransformationIterable</code> wraps another {@link Iterable} and transforms its elements
- * for client consumption. To use, supply a {@link Transformer} or subclass <code>TransformationIterable</code>
- * and override the {@link #transform(Object)} method. Objects of type <code>E1</code> are
- * transformed into objects of type <code>E2</code>; i.e. the iterable's iterator returns objects of
- * type <code>E2</code>.
- *
- * @param <E1> input: the type of elements to be transformed
- * @param <E2> output: the type of elements returned by the iterable's iterator
- *
- * @see TransformationIterator
- * @see TransformationListIterable
- *
- * @version 2.5
- */
-@SuppressWarnings("nls")
-public class TransformationIterable<E1, E2> implements Iterable<E1> {
-
-	private final Iterable<? extends E2> iterable;
-	private final Transformer<? extends E1, E2> transformer;
-
-	/**
-	 * Construct an iterable with the specified nested iterable and a default transformer that calls
-	 * back to the iterable. Use this constructor if you want to override the {@link #transform(Object)}
-	 * method instead of building a {@link Transformer}.
-	 */
-	public TransformationIterable(Iterable<? extends E2> iterable) {
-		super();
-		this.iterable = iterable;
-		this.transformer = this.buildDefaultTransformer();
-	}
-
-	/**
-	 * Construct an iterable with the specified nested iterable and transformer.
-	 */
-	public TransformationIterable(Iterable<? extends E2> iterable, Transformer<? extends E1, E2> transformer) {
-		super();
-		this.iterable = iterable;
-		this.transformer = transformer;
-	}
-
-	protected Transformer<? extends E1, E2> buildDefaultTransformer() {
-		return new DefaultTransformer();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Iterator<E1> iterator() {
-		return new TransformationIterator<E1, E2>(this.iterable.iterator(), this.transformer);
-	}
-
-	/**
-	 * Returns the result.
-	 */
-	protected E1 transform(@SuppressWarnings("unused") E2 o) {
-		throw new RuntimeException("This method was not overridden.");
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterable);
-	}
-
-
-	//********** default linker **********
-
-	protected class DefaultTransformer implements Transformer<E1, E2> {
-		@Override
-		public E1 transform(E2 o) {
-			return TransformationIterable.this.transform(o);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TransformationListIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TransformationListIterable.java
deleted file mode 100644
index 83d4617..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TransformationListIterable.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.Transformer;
-import org.eclipse.persistence.tools.utility.iterators.TransformationListIterator;
-
-/**
- * A <code>TransformationListIterable</code> wraps another {@link ListIterable}
- * and transforms its elements for client consumption. To use, supply a
- * {@link Transformer} or subclass <code>TransformationListIterable</code>
- * and override the {@link #transform(Object)} method.
- * Objects of type <code>E1</code> are transformed into objects of type <code>E2</code>;
- * i.e. the list iterable's list iterator returns objects of type <code>E2</code>.
- *
- * @param <E1> input: the type of elements to be transformed
- * @param <E2> output: the type of elements returned by the iterable's iterator
- *
- * @see TransformationListIterator
- * @see TransformationIterable
- */
-@SuppressWarnings("nls")
-public class TransformationListIterable<E1, E2> implements ListIterable<E1> {
-
-	private final ListIterable<? extends E2> iterable;
-	private final Transformer<? extends E1, E2> transformer;
-
-	/**
-	 * Creates a new <code>TransformationListIterable</code> with the specified nested list and a
-	 * default {@link Transformer} that calls back to the list iterable.
-	 * <p/>
-	 * Use this constructor if you want to override the {@link #transform(Object)} method instead of
-	 * building a {@link Transformer}.
-	 */
-	public TransformationListIterable(List<? extends E2> list) {
-		this(new ListListIterable<E2>(list));
-	}
-
-	/**
-	 * Creates a new <code>TransformationListIterable</code> with the specified nested list iterable
-	 * and a default {@link Transformer} that calls back to the list iterable.
-	 * <p/>
-	 * Use this constructor if you want to override the {@link #transform(Object)} method instead of
-	 * building a {@link Transformer}.
-	 */
-	public TransformationListIterable(ListIterable<? extends E2> iterable) {
-		super();
-		this.iterable = iterable;
-		this.transformer = this.buildDefaultTransformer();
-	}
-
-	/**
-	 * Construct a list iterable with the specified nested list
-	 * and transformer.
-	 */
-	public TransformationListIterable(List<? extends E2> list, Transformer<? extends E1, E2> transformer) {
-		this(new ListListIterable<E2>(list), transformer);
-	}
-
-	/**
-	 * Construct a list iterable with the specified nested list iterable
-	 * and transformer.
-	 */
-	public TransformationListIterable(ListIterable<? extends E2> iterable, Transformer<? extends E1, E2> transformer) {
-		super();
-		this.iterable = iterable;
-		this.transformer = transformer;
-	}
-
-	protected Transformer<? extends E1, E2> buildDefaultTransformer() {
-		return new DefaultTransformer();
-	}
-
-	@Override
-	public ListIterator<E1> iterator() {
-		return new TransformationListIterator<E1, E2>(this.iterable.iterator(), this.transformer);
-	}
-
-	/**
-	 * Returns the result.
-	 */
-	protected E1 transform(@SuppressWarnings("unused") E2 o) {
-		throw new RuntimeException("This method was not overridden.");
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterable);
-	}
-
-
-	//********** default linker **********
-
-	protected class DefaultTransformer implements Transformer<E1, E2> {
-		@Override
-		public E1 transform(E2 object) {
-			return TransformationListIterable.this.transform(object);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TreeIterable.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TreeIterable.java
deleted file mode 100644
index ed5b71c..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterables/TreeIterable.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterables;
-
-import java.util.Arrays;
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.TreeIterator;
-
-/**
- * A <code>TreeIterable</code> simplifies the traversal of a
- * tree of objects, where the objects' protocol(s) provides
- * a method for getting the immediate children of the given
- * node but does not provide a method for getting all the
- * descendants (children, grandchildren, etc.) of the given node.
- * <p>
- * To use, supply:<ul>
- * <li> either the root element of the tree or, if the tree has
- * multiple roots, an {@link Iterable} of the set of roots
- * <li> a {@link TreeIterator.Midwife} that delivers the children of each child
- * (alternatively, subclass <code>TreeIterable</code>
- * and override the {@link #children(Object)} method)
- * </ul>
- *
- * @param <E> the type of elements returned by the iterable's iterator
- *
- * @see TreeIterator
- */
-@SuppressWarnings("nls")
-public class TreeIterable<E>
-	implements Iterable<E>
-{
-	private final Iterable<? extends E> roots;
-	private final TreeIterator.Midwife<E> midwife;
-
-	/**
-	 * Construct an iterable containing the nodes of a tree with the specified root
-	 * and a default midwife that calls back to the iterable.
-	 * Use this constructor if you want to override the
-	 * {@link #children(Object)} method instead of building
-	 * a {@link TreeIterator.Midwife}.
-	 */
-	public TreeIterable(E root) {
-		this(new SingleElementIterable<E>(root));
-	}
-
-	/**
-	 * Construct an iterable containing the nodes of a tree with the specified root
-	 * and midwife.
-	 */
-	public TreeIterable(E root, TreeIterator.Midwife<E> midwife) {
-		this(new SingleElementIterable<E>(root), midwife);
-	}
-
-	/**
-	 * Construct an iterable containing the nodes of a tree with the specified roots
-	 * and a default midwife that calls back to the iterable.
-	 * Use this constructor if you want to override the
-	 * {@link #children(Object)} method instead of building
-	 * a {@link TreeIterator.Midwife}.
-	 */
-	public TreeIterable(E... roots) {
-		this(Arrays.asList(roots));
-	}
-
-	/**
-	 * Construct an iterable containing the nodes of a tree with the specified roots
-	 * and midwife.
-	 */
-	public TreeIterable(E[] roots, TreeIterator.Midwife<E> midwife) {
-		this(Arrays.asList(roots), midwife);
-	}
-
-	/**
-	 * Construct an iterable containing the nodes of a tree with the specified roots
-	 * and a default midwife that calls back to the iterable.
-	 * Use this constructor if you want to override the
-	 * {@link #children(Object)} method instead of building
-	 * a {@link TreeIterator.Midwife}.
-	 */
-	public TreeIterable(Iterable<? extends E> roots) {
-		super();
-		this.roots = roots;
-		this.midwife = this.buildDefaultMidwife();
-	}
-
-	/**
-	 * Construct an iterable containing the nodes of a tree with the specified roots
-	 * and midwife.
-	 */
-	public TreeIterable(Iterable<? extends E> roots, TreeIterator.Midwife<E> midwife) {
-		super();
-		this.roots = roots;
-		this.midwife = midwife;
-	}
-
-	protected TreeIterator.Midwife<E> buildDefaultMidwife() {
-		return new DefaultMidwife();
-	}
-
-	@Override
-	public Iterator<E> iterator() {
-		return new TreeIterator<E>(this.roots, this.midwife);
-	}
-
-	/**
-	 * Returns the immediate children of the specified object.
-	 * <p>
-	 * This method can be overridden by a subclass as an
-	 * alternative to building a {@link TreeIterator.Midwife}.
-	 */
-	protected Iterator<? extends E> children(@SuppressWarnings("unused") E next) {
-		throw new RuntimeException("This method was not overridden.");
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.roots);
-	}
-
-
-	//********** default midwife **********
-
-	protected class DefaultMidwife implements TreeIterator.Midwife<E> {
-		@Override
-		public Iterator<? extends E> children(E node) {
-			return TreeIterable.this.children(node);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/AbstractRepeatingElementIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/AbstractRepeatingElementIterator.java
new file mode 100644
index 0000000..c1abc72
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/AbstractRepeatingElementIterator.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * An <code>AbstractRepeatingElementIterator</code> provides an {@link Iterator}
+ * that returns a single element a specific number of times.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.collection.AbstractRepeatingElementList
+ */
+@SuppressWarnings("nls")
+public abstract class AbstractRepeatingElementIterator<E>
+	implements Iterator<E>
+{
+	private final int size;
+	/* private-protected */ int cursor;
+
+	/**
+	 * Construct an iterator for the specified number of elements.
+	 */
+	protected AbstractRepeatingElementIterator(int size) {
+		super();
+		if (size < 0) {
+			throw new IllegalArgumentException("size: " + size);
+		}
+		this.size = size;
+		this.cursor = 0;
+	}
+
+	@Override
+	public boolean hasNext() {
+		return this.cursor != this.size;
+	}
+
+	@Override
+	public E next() {
+		if (this.hasNext()) {
+			this.cursor++;
+			return this.getElement();
+		}
+		throw new NoSuchElementException();
+	}
+
+	protected abstract E getElement();
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.size);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/AbstractRepeatingElementListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/AbstractRepeatingElementListIterator.java
new file mode 100644
index 0000000..51c9f17
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/AbstractRepeatingElementListIterator.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+ * An <code>AbstractRepeatingElementListIterator</code> provides a {@link ListIterator}
+ * that returns a single element a specific number of times.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.collection.AbstractRepeatingElementList
+ */
+public abstract class AbstractRepeatingElementListIterator<E>
+	extends AbstractRepeatingElementIterator<E>
+	implements ListIterator<E>
+{
+	protected AbstractRepeatingElementListIterator(int size) {
+		super(size);
+	}
+
+	@Override
+	public int nextIndex() {
+		return this.cursor;
+	}
+
+	@Override
+	public int previousIndex() {
+		return this.cursor - 1;
+	}
+
+	@Override
+	public boolean hasPrevious() {
+		return this.cursor != 0;
+	}
+
+	@Override
+	public E previous() {
+		if (this.hasPrevious()) {
+			this.cursor--;
+			return this.getElement();
+		}
+		throw new NoSuchElementException();
+	}
+
+	@Override
+	public void add(E e) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void set(E e) {
+		throw new UnsupportedOperationException();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/AbstractSimultaneousIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/AbstractSimultaneousIterator.java
new file mode 100644
index 0000000..3f584dd
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/AbstractSimultaneousIterator.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+
+
+public abstract class AbstractSimultaneousIterator<E, I extends Iterator<E>>
+	implements Iterator<List<E>>
+{
+	/* private- */ protected final Iterable<? extends I> iterators;
+	/* private- */ protected final int iteratorsSize;  // hint
+
+
+	/**
+	 * Construct a "simultaneous" iterator for the specified iterators.
+	 */
+	protected <T extends I> AbstractSimultaneousIterator(T... iterators) {
+		this(new ArrayIterable<I>(iterators), iterators.length);
+	}
+
+	/**
+	 * Construct a "simultaneous" iterator for the specified iterators.
+	 */
+	protected <T extends I> AbstractSimultaneousIterator(Iterable<T> iterators) {
+		this(iterators, -1);
+	}
+
+	/**
+	 * Construct a "simultaneous" iterator for the specified iterators.
+	 * Use the specified size as a performance hint.
+	 */
+	protected <T extends I> AbstractSimultaneousIterator(Iterable<T> iterators, int iteratorsSize) {
+		super();
+		if (iterators == null) {
+			throw new NullPointerException();
+		}
+		this.iterators = iterators;
+		this.iteratorsSize = iteratorsSize;
+	}
+
+	@Override
+	public boolean hasNext() {
+		if (this.iteratorsIsEmpty()) {
+			return false;
+		}
+		for (I iterator : this.iterators) {
+			if ( ! iterator.hasNext()) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	@Override
+	public List<E> next() {
+		if (this.iteratorsIsEmpty()) {
+			throw new NoSuchElementException();
+		}
+		ArrayList<E> result = this.buildList();
+		for (I iterator : this.iterators) {
+			result.add(iterator.next());
+		}
+		return result;
+	}
+
+	/* private- */ protected ArrayList<E> buildList() {
+		return (this.iteratorsSize < 0) ? new ArrayList<E>() : new ArrayList<E>(this.iteratorsSize);
+	}
+
+	@Override
+	public void remove() {
+		if (this.iteratorsIsEmpty()) {
+			throw new IllegalStateException();
+		}
+		for (I iterator : this.iterators) {
+			iterator.remove();
+		}
+	}
+
+	/* private- */ protected boolean iteratorsIsEmpty() {
+		return IterableTools.isEmpty(this.iterators);
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.iterators);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ArrayIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ArrayIterator.java
new file mode 100644
index 0000000..ecf1540
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ArrayIterator.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+
+/**
+ * An <code>ArrayIterator</code> provides an {@link Iterator}
+ * for an array of objects of type <code>E</code>.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.ArrayIterable
+ */
+@SuppressWarnings("nls")
+public class ArrayIterator<E>
+	implements Iterator<E>
+{
+	/* private-protected */ final E[] array;
+	/* private-protected */ int cursor;
+	private final int max;
+
+
+	/**
+	 * Construct an iterator for the specified array.
+	 */
+	public ArrayIterator(E... array) {
+		this(array, 0);
+	}
+
+	/**
+	 * Construct an iterator for the specified array,
+	 * starting at the specified start index and continuing for
+	 * the rest of the array.
+	 */
+	public ArrayIterator(E[] array, int start) {
+		this(array, start, array.length);
+	}
+
+	/**
+	 * Construct an iterator for the specified array,
+	 * starting at the specified start index, inclusive, and continuing to
+	 * the specified end index, exclusive.
+	 */
+	public ArrayIterator(E[] array, int start, int end) {
+		super();
+		if ((start < 0) || (start > array.length)) {
+			throw new IllegalArgumentException("end: " + start);
+		}
+		if ((end < start) || (end > array.length)) {
+			throw new IllegalArgumentException("length: " + end);
+		}
+		this.array = array;
+		this.cursor = start;
+		this.max = end;
+	}
+
+	@Override
+	public boolean hasNext() {
+		return this.cursor != this.max;
+	}
+
+	@Override
+	public E next() {
+		if (this.hasNext()) {
+			return this.array[this.cursor++];
+		}
+		throw new NoSuchElementException();
+	}
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, Arrays.toString(this.array));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ArrayListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ArrayListIterator.java
new file mode 100644
index 0000000..b897c51
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ArrayListIterator.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+ * An <code>ArrayListIterator</code> provides a {@link ListIterator}
+ * for an array of objects.
+ * <p>
+ * The name might be a bit confusing:
+ * This is a {@link ListIterator} for an <code>Array</code>;
+ * <em>not</em> an {@link java.util.Iterator Iterator} for an
+ * {@link java.util.ArrayList ArrayList}.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.ArrayListIterable
+ */
+public class ArrayListIterator<E>
+	extends ArrayIterator<E>
+	implements ListIterator<E>
+{
+	private final int min;
+
+
+	/**
+	 * Construct a list iterator for the specified array.
+	 */
+	public ArrayListIterator(E... array) {
+		this(array, 0);
+	}
+
+	/**
+	 * Construct a list iterator for the specified array,
+	 * starting at the specified start index and continuing for
+	 * the rest of the array.
+	 */
+	public ArrayListIterator(E[] array, int start) {
+		this(array, start, array.length);
+	}
+
+	/**
+	 * Construct a list iterator for the specified array,
+	 * starting at the specified start index, inclusive, and continuing to
+	 * the specified end index, exclusive.
+	 */
+	public ArrayListIterator(E[] array, int start, int end) {
+		super(array, start, end);
+		this.min = start;
+	}
+
+	@Override
+	public int nextIndex() {
+		return this.cursor;
+	}
+
+	@Override
+	public int previousIndex() {
+		return this.cursor - 1;
+	}
+
+	@Override
+	public boolean hasPrevious() {
+		return this.cursor != this.min;
+	}
+
+	@Override
+	public E previous() {
+		if (this.hasPrevious()) {
+			return this.array[--this.cursor];
+		}
+		throw new NoSuchElementException();
+	}
+
+	@Override
+	public void add(E e) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void set(E e) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return super.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ChainIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ChainIterator.java
new file mode 100644
index 0000000..cf93357
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ChainIterator.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * A <code>ChainIterator</code> provides a pluggable {@link Iterator}
+ * that loops over a chain of arbitrarily linked objects. The chain
+ * should be null-terminated (i.e. a call to the {@link #nextLink(Object)}
+ * method should return <code>null</code> when it is passed the last
+ * link of the chain).
+ * To use, supply a starting link and supply a {@link Linker} or
+ * subclass <code>ChainIterator</code> and override the
+ * {@link #nextLink(Object)} method.
+ * The starting link will be the first object returned by the iterator.
+ * If the starting link is <code>null</code>, the iterator will be empty.
+ * Note this iterator does not support <code>null</code> elements.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.ChainIterable
+ */
+public class ChainIterator<E>
+	implements Iterator<E>
+{
+	private E nextLink;
+	private final Linker<E> linker;
+
+
+	/**
+	 * Construct an iterator with the specified starting link
+	 * and a disabled linker.
+	 * Use this constructor if you want to override the
+	 * {@link #nextLink(Object)} method instead of building
+	 * a {@link Linker}.
+	 */
+	public ChainIterator(E startLink) {
+		this(startLink, Linker.Disabled.<E>instance());
+	}
+
+	/**
+	 * Construct an iterator with the specified starting link
+	 * and linker.
+	 */
+	public ChainIterator(E startLink, Linker<E> linker) {
+		super();
+		if (linker == null) {
+			throw new NullPointerException();
+		}
+		this.nextLink = startLink;
+		this.linker = linker;
+	}
+
+	@Override
+	public boolean hasNext() {
+		return this.nextLink != null;
+	}
+
+	@Override
+	public E next() {
+		if (this.nextLink == null) {
+			throw new NoSuchElementException();
+		}
+		E result = this.nextLink;
+		this.nextLink = this.nextLink(this.nextLink);
+		return result;
+	}
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Return the next link in the chain; null if there are no more links.
+	 */
+	protected E nextLink(E currentLink) {
+		return this.linker.nextLink(currentLink);
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.nextLink);
+	}
+
+
+	//********** member interface **********
+
+	/**
+	 * Used by {@link ChainIterator} to link
+	 * the elements in the chain.
+	 */
+	public interface Linker<T> {
+
+		/**
+		 * Return the next link in the chain; null if there are no more links.
+		 */
+		T nextLink(T currentLink);
+
+
+		final class Null<S>
+			implements Linker<S>, Serializable
+		{
+			@SuppressWarnings("rawtypes")
+			public static final Linker INSTANCE = new Null();
+			@SuppressWarnings("unchecked")
+			public static <R> Linker<R> instance() {
+				return INSTANCE;
+			}
+			// ensure single instance
+			private Null() {
+				super();
+			}
+			// simply return null, indicating the chain is ended
+			@Override
+			public S nextLink(S currentLink) {
+				return null;
+			}
+			@Override
+			public String toString() {
+				return ObjectTools.singletonToString(this);
+			}
+			private static final long serialVersionUID = 1L;
+			private Object readResolve() {
+				// replace this object with the singleton
+				return INSTANCE;
+			}
+		}
+
+		final class Disabled<S>
+			implements Linker<S>, Serializable
+		{
+			@SuppressWarnings("rawtypes")
+			public static final Linker INSTANCE = new Disabled();
+			@SuppressWarnings("unchecked")
+			public static <R> Linker<R> instance() {
+				return INSTANCE;
+			}
+			// ensure single instance
+			private Disabled() {
+				super();
+			}
+			// throw an exception
+			@Override
+			public S nextLink(S currentLink) {
+				throw new UnsupportedOperationException();  // ChainIterator.nextLink(Object) was not implemented
+			}
+			@Override
+			public String toString() {
+				return ObjectTools.singletonToString(this);
+			}
+			private static final long serialVersionUID = 1L;
+			private Object readResolve() {
+				// replace this object with the singleton
+				return INSTANCE;
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/CloneIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/CloneIterator.java
new file mode 100644
index 0000000..0825d3d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/CloneIterator.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * A <code>CloneIterator</code> iterates over a copy of a collection,
+ * allowing for concurrent access to the original collection.
+ * <p>
+ * The original collection passed to the <code>CloneIterator</code>'s
+ * constructor should be synchronized (e.g. {@link java.util.Vector});
+ * otherwise you run the risk of a corrupted collection.
+ * <p>
+ * By default, a <code>CloneIterator</code> does not support the
+ * {@link #remove()} operation; this is because it does not have
+ * access to the original collection. But if the <code>CloneIterator</code>
+ * is supplied with an {@link Remover} it will delegate the
+ * {@link #remove()} operation to the {@link Remover}.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.LiveCloneIterable
+ * @see org.eclipse.jpt.common.utility.internal.iterable.SnapshotCloneIterable
+ */
+public class CloneIterator<E>
+	implements Iterator<E>
+{
+	private final Iterator<Object> iterator;
+	private E current;
+	private final Remover<E> remover;
+	private boolean removeAllowed;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an iterator on a copy of the specified collection.
+	 * The {@link #remove()} method will not be supported.
+	 */
+	public CloneIterator(Collection<? extends E> collection) {
+		this(collection, Remover.ReadOnly.<E>instance());
+	}
+
+	/**
+	 * Construct an iterator on a copy of the specified array.
+	 * The {@link #remove()} method will not be supported.
+	 */
+	public CloneIterator(E[] array) {
+		this(array, Remover.ReadOnly.<E>instance());
+	}
+
+	/**
+	 * Construct an iterator on a copy of the specified collection.
+	 * Use the specified remover to remove objects from the
+	 * original collection.
+	 */
+	public CloneIterator(Collection<? extends E> collection, Remover<E> remover) {
+		this(remover, collection.toArray());
+	}
+
+	/**
+	 * Construct an iterator on a copy of the specified array.
+	 * Use the specified remover to remove objects from the
+	 * original array.
+	 */
+	public CloneIterator(E[] array, Remover<E> remover) {
+		this(remover, array.clone());
+	}
+
+	/**
+	 * Internal constructor used by subclasses.
+	 * Swap order of arguments to prevent collision with other constructor.
+	 * The passed in array will *not* be cloned.
+	 */
+	protected CloneIterator(Remover<E> remover, Object... array) {
+		super();
+		if (remover == null) {
+			throw new NullPointerException();
+		}
+		this.iterator = new ArrayIterator<Object>(array);
+		this.current = null;
+		this.remover = remover;
+		this.removeAllowed = false;
+	}
+
+
+	// ********** Iterator implementation **********
+
+	@Override
+	public boolean hasNext() {
+		return this.iterator.hasNext();
+	}
+
+	@Override
+	public E next() {
+		this.current = this.nestedNext();
+		this.removeAllowed = true;
+		return this.current;
+	}
+
+	@Override
+	public void remove() {
+		if ( ! this.removeAllowed) {
+			throw new IllegalStateException();
+		}
+		this.remover.remove(this.current);
+		this.removeAllowed = false;
+	}
+
+
+	// ********** internal methods **********
+
+	/**
+	 * The collection passed in during construction held elements of type <code>E</code>,
+	 * so this cast is not a problem. We need this cast because
+	 * all the elements of the original collection were copied into
+	 * an object array (<code>Object[]</code>).
+	 */
+	@SuppressWarnings("unchecked")
+	protected E nestedNext() {
+		return (E) this.iterator.next();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this);
+	}
+
+
+	//********** member interface **********
+
+	/**
+	 * Used by {@link CloneIterator} to remove
+	 * elements from the original collection; since the iterator
+	 * does not have direct access to the original collection.
+	 */
+	public interface Remover<T> {
+
+		/**
+		 * Remove the specified object from the original collection.
+		 */
+		void remove(T element);
+
+
+		final class ReadOnly<S>
+			implements Remover<S>, Serializable
+		{
+			@SuppressWarnings("rawtypes")
+			public static final Remover INSTANCE = new ReadOnly();
+			@SuppressWarnings("unchecked")
+			public static <R> Remover<R> instance() {
+				return INSTANCE;
+			}
+			// ensure single instance
+			private ReadOnly() {
+				super();
+			}
+			// remove is not supported
+			@Override
+			public void remove(Object element) {
+				throw new UnsupportedOperationException();
+			}
+			@Override
+			public String toString() {
+				return ObjectTools.singletonToString(this);
+			}
+			private static final long serialVersionUID = 1L;
+			private Object readResolve() {
+				// replace this object with the singleton
+				return INSTANCE;
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/CloneListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/CloneListIterator.java
new file mode 100644
index 0000000..3ad613f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/CloneListIterator.java
@@ -0,0 +1,311 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+
+/**
+ * A <code>CloneListIterator</code> iterates over a copy of a list,
+ * allowing for concurrent access to the original list.
+ * <p>
+ * The original list passed to the <code>CloneListIterator</code>'s
+ * constructor should be synchronized; otherwise you run the risk of
+ * a corrupted list (e.g. {@link java.util.Vector}.
+ * <p>
+ * By default, a <code>CloneListIterator</code> does not support the
+ * modification operations; this is because it does not have
+ * access to the original list. But if the <code>CloneListIterator</code>
+ * is supplied with a {@link Mutator} it will delegate the
+ * modification operations to the {@link Mutator}.
+ * Alternatively, a subclass can override the modification methods.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.LiveCloneListIterable
+ * @see org.eclipse.jpt.common.utility.internal.iterable.SnapshotCloneListIterable
+ */
+public class CloneListIterator<E>
+	implements ListIterator<E>
+{
+	private final ListIterator<Object> listIterator;
+	private int cursor;
+	private State state;
+	private final Mutator<E> mutator;
+
+	private enum State {
+		UNKNOWN,
+		PREVIOUS,
+		NEXT
+	}
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a list iterator on a copy of the specified list.
+	 * The modification methods will not be supported,
+	 * unless a subclass overrides them.
+	 */
+	public CloneListIterator(List<? extends E> list) {
+		this(list, Mutator.ReadOnly.<E>instance());
+	}
+
+	/**
+	 * Construct a list iterator on a copy of the specified array.
+	 * The modification methods will not be supported,
+	 * unless a subclass overrides them.
+	 */
+	public CloneListIterator(E[] array) {
+		this(array, Mutator.ReadOnly.<E>instance());
+	}
+
+	/**
+	 * Construct a list iterator on a copy of the specified list.
+	 * Use the specified list mutator to modify the original list.
+	 */
+	public CloneListIterator(List<? extends E> list, Mutator<E> mutator) {
+		this(mutator, list.toArray());
+	}
+
+	/**
+	 * Construct a list iterator on a copy of the specified array.
+	 * Use the specified list mutator to modify the original list.
+	 */
+	public CloneListIterator(E[] array, Mutator<E> mutator) {
+		this(mutator, array.clone());
+	}
+
+	/**
+	 * Internal constructor used by subclasses.
+	 * Swap order of arguments to prevent collision with other constructor.
+	 * The passed in array will *not* be cloned.
+	 */
+	protected CloneListIterator(Mutator<E> mutator, Object... array) {
+		super();
+		if (mutator == null) {
+			throw new NullPointerException();
+		}
+		// build a copy of the list and keep it in sync with original (if the mutator allows changes)
+		// that way the nested list iterator will maintain some of our state
+		this.listIterator = ListTools.list(array).listIterator();
+		this.mutator = mutator;
+		this.cursor = 0;
+		this.state = State.UNKNOWN;
+	}
+
+
+	// ********** ListIterator implementation **********
+
+	@Override
+	public boolean hasNext() {
+		return this.listIterator.hasNext();
+	}
+
+	@Override
+	public E next() {
+		// allow the nested iterator to throw an exception before we modify the index
+		E next = this.nestedNext();
+		this.cursor++;
+		this.state = State.NEXT;
+		return next;
+	}
+
+	@Override
+	public void remove() {
+		// allow the nested iterator to throw an exception before we modify the original list
+		this.listIterator.remove();
+		if (this.state == State.PREVIOUS) {
+			this.remove(this.cursor);
+		} else {
+			this.cursor--;
+			this.remove(this.cursor);
+		}
+	}
+
+	@Override
+	public int nextIndex() {
+		return this.listIterator.nextIndex();
+	}
+
+	@Override
+	public int previousIndex() {
+		return this.listIterator.previousIndex();
+	}
+
+	@Override
+	public boolean hasPrevious() {
+		return this.listIterator.hasPrevious();
+	}
+
+	@Override
+	public E previous() {
+		// allow the nested iterator to throw an exception before we modify the index
+		E previous = this.nestedPrevious();
+		this.cursor--;
+		this.state = State.PREVIOUS;
+		return previous;
+	}
+
+	@Override
+	public void add(E o) {
+		// allow the nested iterator to throw an exception before we modify the original list
+		this.listIterator.add(o);
+		this.add(this.cursor, o);
+		this.cursor++;
+	}
+
+	@Override
+	public void set(E o) {
+		// allow the nested iterator to throw an exception before we modify the original list
+		this.listIterator.set(o);
+		if (this.state == State.PREVIOUS) {
+			this.set(this.cursor, o);
+		} else {
+			this.set(this.cursor - 1, o);
+		}
+	}
+
+
+	// ********** internal methods **********
+
+	/**
+	 * The list passed in during construction held elements of type <code>E</code>,
+	 * so this cast is not a problem. We need this cast because
+	 * all the elements of the original collection were copied into
+	 * an object array (<code>Object[]</code>).
+	 */
+	@SuppressWarnings("unchecked")
+	protected E nestedNext() {
+		return (E) this.listIterator.next();
+	}
+
+	/**
+	 * The list passed in during construction held elements of type <code>E</code>,
+	 * so this cast is not a problem. We need this cast because
+	 * all the elements of the original collection were copied into
+	 * an object array (<code>Object[]</code>).
+	 */
+	@SuppressWarnings("unchecked")
+	protected E nestedPrevious() {
+		return (E) this.listIterator.previous();
+	}
+
+	/**
+	 * Add the specified element to the original list.
+	 * <p>
+	 * This method can be overridden by a subclass as an
+	 * alternative to building a {@link Mutator}.
+	 */
+	protected void add(int index, E o) {
+		this.mutator.add(index, o);
+	}
+
+	/**
+	 * Remove the specified element from the original list.
+	 * <p>
+	 * This method can be overridden by a subclass as an
+	 * alternative to building a {@link Mutator}.
+	 */
+	protected void remove(int index) {
+		this.mutator.remove(index);
+	}
+
+	/**
+	 * Set the specified element in the original list.
+	 * <p>
+	 * This method can be overridden by a subclass as an
+	 * alternative to building a {@link Mutator}.
+	 */
+	protected void set(int index, E o) {
+		this.mutator.set(index, o);
+	}
+
+
+	// ********** overrides **********
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this);
+	}
+
+
+	//********** member interface **********
+
+	/**
+	 * Used by {@link CloneListIterator} to remove
+	 * elements from the original list; since the list iterator
+	 * does not have direct access to the original list.
+	 */
+	public interface Mutator<T> {
+
+		/**
+		 * Add the specified object to the original list.
+		 */
+		void add(int index, T o);
+
+		/**
+		 * Remove the specified object from the original list.
+		 */
+		void remove(int index);
+
+		/**
+		 * Set the specified object in the original list.
+		 */
+		void set(int index, T o);
+
+
+		final class ReadOnly<S>
+			implements Mutator<S>, Serializable
+		{
+			@SuppressWarnings("rawtypes")
+			public static final Mutator INSTANCE = new ReadOnly();
+			@SuppressWarnings("unchecked")
+			public static <R> Mutator<R> instance() {
+				return INSTANCE;
+			}
+			// ensure single instance
+			private ReadOnly() {
+				super();
+			}
+			// add is not supported
+			@Override
+			public void add(int index, Object o) {
+				throw new UnsupportedOperationException();
+			}
+			// remove is not supported
+			@Override
+			public void remove(int index) {
+				throw new UnsupportedOperationException();
+			}
+			// set is not supported
+			@Override
+			public void set(int index, Object o) {
+				throw new UnsupportedOperationException();
+			}
+			@Override
+			public String toString() {
+				return ObjectTools.singletonToString(this);
+			}
+			private static final long serialVersionUID = 1L;
+			private Object readResolve() {
+				// replace this object with the singleton
+				return INSTANCE;
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/CompositeIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/CompositeIterator.java
new file mode 100644
index 0000000..4160bbc
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/CompositeIterator.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
+
+/**
+ * A <code>CompositeIterator</code> wraps a collection
+ * of {@link Iterator}s and makes them appear to be a single
+ * {@link Iterator}.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.CompositeIterable
+ */
+public class CompositeIterator<E>
+	implements Iterator<E>
+{
+	private final Iterator<? extends Iterator<? extends E>> iterators;
+	private Iterator<? extends E> currentIterator;
+	private Iterator<? extends E> lastIteratorToReturnNext;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an iterator that returns all the elements held by the
+	 * specified iterables.
+	 */
+	public CompositeIterator(Iterable<? extends Iterable<? extends E>> iterables) {
+		this(
+			new TransformationIterator<Iterable<? extends E>, Iterator<? extends E>>(iterables.iterator()) {
+				@Override
+				protected Iterator<? extends E> transform(Iterable<? extends E> iterable) {
+					return iterable.iterator();
+				}
+			}
+		);
+	}
+
+	/**
+	 * Construct an iterator with the specified collection of iterators.
+	 */
+	public CompositeIterator(Iterator<? extends Iterator<? extends E>> iterators) {
+		super();
+		if (iterators == null) {
+			throw new NullPointerException();
+		}
+		this.iterators = iterators;
+	}
+
+	/**
+	 * Construct an iterator with the specified object prepended
+	 * to the specified iterable.
+	 */
+	public CompositeIterator(E object, Iterable<? extends E> iterable) {
+		this(object, iterable.iterator());
+	}
+
+	/**
+	 * Construct an iterator with the specified object prepended
+	 * to the specified iterator.
+	 */
+	@SuppressWarnings("unchecked")
+	public CompositeIterator(E object, Iterator<? extends E> iterator) {
+		this(new SingleElementIterator<E>(object), iterator);
+	}
+
+	/**
+	 * Construct an iterator with the specified object appended
+	 * to the specified iterable.
+	 */
+	public CompositeIterator(Iterable<? extends E> iterable, E object) {
+		this(iterable.iterator(), object);
+	}
+
+	/**
+	 * Construct an iterator with the specified object appended
+	 * to the specified iterator.
+	 */
+	@SuppressWarnings("unchecked")
+	public CompositeIterator(Iterator<? extends E> iterator, E object) {
+		this(iterator, new SingleElementIterator<E>(object));
+	}
+
+	/**
+	 * Construct an iterator with the specified iterables.
+	 */
+	public CompositeIterator(Iterable<? extends E>... iterables) {
+		this(new ArrayIterable<Iterable<? extends E>>(iterables));
+	}
+
+	/**
+	 * Construct an iterator with the specified iterators.
+	 */
+	public CompositeIterator(Iterator<? extends E>... iterators) {
+		this(new ArrayIterator<Iterator<? extends E>>(iterators));
+	}
+
+
+	// ********** Iterator implementation **********
+
+	@Override
+	public boolean hasNext() {
+		try {
+			this.loadCurrentIterator();
+		} catch (NoSuchElementException ex) {
+			// this occurs if there are no iterators at all
+			return false;
+		}
+		return this.currentIterator.hasNext();
+	}
+
+	@Override
+	public E next() {
+		this.loadCurrentIterator();
+		E result = this.currentIterator.next();
+
+		// the statement above will throw a NoSuchElementException
+		// if the current iterator is at the end of the line;
+		// so if we get here, we can set 'lastIteratorToReturnNext'
+		this.lastIteratorToReturnNext = this.currentIterator;
+
+		return result;
+	}
+
+	@Override
+	public void remove() {
+		if (this.lastIteratorToReturnNext == null) {
+			// CompositeIterator#next() has never been called
+			throw new IllegalStateException();
+		}
+		this.lastIteratorToReturnNext.remove();
+	}
+
+	/**
+	 * Load {@link #currentIterator} with the first iterator that {@link Iterator#hasNext()}
+	 * or the final iterator if all the elements have already been retrieved.
+	 */
+	private void loadCurrentIterator() {
+		if (this.currentIterator == null) {
+			this.currentIterator = this.iterators.next();
+		}
+		while (( ! this.currentIterator.hasNext()) && this.iterators.hasNext()) {
+			this.currentIterator = this.iterators.next();
+		}
+	}
+
+
+	// ********** overrides **********
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.iterators);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/CompositeListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/CompositeListIterator.java
new file mode 100644
index 0000000..77c8618
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/CompositeListIterator.java
@@ -0,0 +1,284 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
+/**
+ * A <code>CompositeListIterator</code> wraps a list
+ * of {@link ListIterator}s and makes them appear to be a single
+ * {@link ListIterator}.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.CompositeListIterable
+ */
+public class CompositeListIterator<E>
+	implements ListIterator<E>
+{
+	private final ListIterator<? extends ListIterator<E>> iterators;
+	private ListIterator<E> nextIterator;
+	private int nextIndex;
+ 	/**
+ 	 * <code>true</code> if "next" was last returned;
+ 	 * <code>false</code> if "previous" was last returned;
+ 	 * this determines the effect of {@link #remove()} on {@link #nextIndex}
+ 	 */
+	private boolean nextReturned;
+	private ListIterator<E> lastIteratorToReturnElement;
+
+
+	/**
+	 * Construct a list iterator on the elements in the specified list of lists.
+	 */
+	public CompositeListIterator(List<? extends List<E>> lists) {
+		this(
+			new TransformationListIterator<List<E>, ListIterator<E>>(lists.listIterator()) {
+				@Override
+				protected ListIterator<E> transform(List<E> list) {
+					return list.listIterator();
+				}
+			}
+		);
+	}
+
+	/**
+	 * Construct a list iterator on the elements in the specified list of lists.
+	 */
+	public CompositeListIterator(ListIterable<? extends ListIterable<E>> listIterables) {
+		this(
+			new TransformationListIterator<ListIterable<E>, ListIterator<E>>(listIterables.iterator()) {
+				@Override
+				protected ListIterator<E> transform(ListIterable<E> list) {
+					return list.iterator();
+				}
+			}
+		);
+	}
+
+	/**
+	 * Construct a list iterator with the specified list of list iterators.
+	 */
+	public CompositeListIterator(ListIterator<? extends ListIterator<E>> iterators) {
+		super();
+		if (iterators == null) {
+			throw new NullPointerException();
+		}
+		this.iterators = iterators;
+		this.nextIndex = 0;
+		this.nextReturned = false;
+	}
+
+	/**
+	 * Construct a list iterator with the specified object prepended
+	 * to the specified list.
+	 */
+	public CompositeListIterator(E object, List<E> list) {
+		this(object, list.listIterator());
+	}
+
+	/**
+	 * Construct a list iterator with the specified object prepended
+	 * to the specified list.
+	 */
+	public CompositeListIterator(E object, ListIterable<E> listIterable) {
+		this(object, listIterable.iterator());
+	}
+
+	/**
+	 * Construct a list iterator with the specified object prepended
+	 * to the specified iterator.
+	 */
+	@SuppressWarnings("unchecked")
+	public CompositeListIterator(E object, ListIterator<E> iterator) {
+		this(new SingleElementListIterator<E>(object), iterator);
+	}
+
+	/**
+	 * Construct a list iterator with the specified object appended
+	 * to the specified list.
+	 */
+	public CompositeListIterator(List<E> list, E object) {
+		this(list.listIterator(), object);
+	}
+
+	/**
+	 * Construct a list iterator with the specified object appended
+	 * to the specified list.
+	 */
+	public CompositeListIterator(ListIterable<E> listIterable, E object) {
+		this(listIterable.iterator(), object);
+	}
+
+	/**
+	 * Construct a list iterator with the specified object appended
+	 * to the specified iterator.
+	 */
+	@SuppressWarnings("unchecked")
+	public CompositeListIterator(ListIterator<E> iterator, E object) {
+		this(iterator, new SingleElementListIterator<E>(object));
+	}
+
+	/**
+	 * Construct a list iterator with the specified lists.
+	 */
+	public CompositeListIterator(List<E>... lists) {
+		this(Arrays.asList(lists));
+	}
+
+	/**
+	 * Construct a list iterator with the specified lists.
+	 */
+	public CompositeListIterator(ListIterable<E>... listIterables) {
+		this(new ArrayListIterable<ListIterable<E>>(listIterables));
+	}
+
+	/**
+	 * Construct a list iterator with the specified list iterators.
+	 */
+	public CompositeListIterator(ListIterator<E>... iterators) {
+		this(new ArrayListIterator<ListIterator<E>>(iterators));
+	}
+
+	@Override
+	public void add(E o) {
+		this.checkNextIterator();
+		this.nextIterator.add(o);
+		this.nextIndex++;
+	}
+
+	@Override
+	public boolean hasNext() {
+		try {
+			this.loadNextIterator();
+		} catch (NoSuchElementException ex) {
+			// this occurs if there are no iterators at all
+			return false;
+		}
+		return this.nextIterator.hasNext();
+	}
+
+	@Override
+	public boolean hasPrevious() {
+		try {
+			this.loadPreviousIterator();
+		} catch (NoSuchElementException ex) {
+			// this occurs if there are no iterators at all
+			return false;
+		}
+		return this.nextIterator.hasPrevious();
+	}
+
+	@Override
+	public E next() {
+		this.loadNextIterator();
+		E result = this.nextIterator.next();
+
+		// the statement above will throw a NoSuchElementException
+		// if the current iterator is at the end of the line;
+		// so if we get here, we can set the 'lastIteratorToReturnElement'
+		this.lastIteratorToReturnElement = this.nextIterator;
+		this.nextIndex++;
+		this.nextReturned = true;
+
+		return result;
+	}
+
+	@Override
+	public int nextIndex() {
+		return this.nextIndex;
+	}
+
+	@Override
+	public E previous() {
+		this.loadPreviousIterator();
+		E result = this.nextIterator.previous();
+
+		// the statement above will throw a NoSuchElementException
+		// if the current iterator is at the end of the line;
+		// so if we get here, we can set the 'lastIteratorToReturnElement'
+		this.lastIteratorToReturnElement = this.nextIterator;
+		this.nextIndex--;
+		this.nextReturned = false;
+
+		return result;
+	}
+
+	@Override
+	public int previousIndex() {
+		return this.nextIndex  - 1;
+	}
+
+	@Override
+	public void remove() {
+		if (this.lastIteratorToReturnElement == null) {
+			throw new IllegalStateException();
+		}
+		this.lastIteratorToReturnElement.remove();
+		if (this.nextReturned) {
+			// decrement the index because the "next" element has moved forward in the list
+			this.nextIndex--;
+		}
+	}
+
+	@Override
+	public void set(E e) {
+		if (this.lastIteratorToReturnElement == null) {
+			throw new IllegalStateException();
+		}
+		this.lastIteratorToReturnElement.set(e);
+	}
+
+	/**
+	 * Load 'nextIterator' with the first iterator that <code>hasNext()</code>
+	 * or the final iterator if all the elements have already been retrieved.
+	 */
+	private void loadNextIterator() {
+		this.checkNextIterator();
+		while (( ! this.nextIterator.hasNext()) && this.iterators.hasNext()) {
+			this.nextIterator = this.iterators.next();
+		}
+	}
+
+	/**
+	 * Load 'nextIterator' with the first iterator that <code>hasPrevious()</code>
+	 * or the first iterator if all the elements have already been retrieved.
+	 */
+	private void loadPreviousIterator() {
+		this.checkNextIterator();
+		while (( ! this.nextIterator.hasPrevious()) && this.iterators.hasPrevious()) {
+			this.nextIterator = this.iterators.previous();
+		}
+	}
+
+	/**
+	 * If 'nextIterator' is null, load it with the first iterator.
+	 */
+	private void checkNextIterator() {
+		if (this.nextIterator == null) {
+			this.nextIterator = this.iterators.next();
+		}
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.iterators);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/EmptyIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/EmptyIterator.java
new file mode 100644
index 0000000..4729060
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/EmptyIterator.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * An <code>EmptyIterator</code> is just that.
+ *
+ * @param <E> the type of elements (not) returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.EmptyIterable
+ */
+public final class EmptyIterator<E>
+	implements Iterator<E>, Serializable
+{
+	// singleton
+	@SuppressWarnings("rawtypes")
+	private static final EmptyIterator INSTANCE = new EmptyIterator();
+
+	/**
+	 * Return the singleton.
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> Iterator<T> instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure single instance.
+	 */
+	private EmptyIterator() {
+		super();
+	}
+
+	@Override
+	public boolean hasNext() {
+		return false;
+	}
+
+	@Override
+	public E next() {
+		throw new NoSuchElementException();
+	}
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return this.getClass().getSimpleName();
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the singleton
+		return INSTANCE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/EmptyListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/EmptyListIterator.java
new file mode 100644
index 0000000..6732c22
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/EmptyListIterator.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.io.Serializable;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+ * An <code>EmptyListIterator</code> is just that.
+ *
+ * @param <E> the type of elements (not) returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.EmptyListIterable
+ */
+public final class EmptyListIterator<E>
+	implements ListIterator<E>, Serializable
+{
+	// singleton
+	@SuppressWarnings("rawtypes")
+	private static final EmptyListIterator INSTANCE = new EmptyListIterator();
+
+	/**
+	 * Return the singleton.
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> ListIterator<T> instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure single instance.
+	 */
+	private EmptyListIterator() {
+		super();
+	}
+
+	@Override
+	public void add(E e) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public boolean hasNext() {
+		return false;
+	}
+
+	@Override
+	public boolean hasPrevious() {
+		return false;
+	}
+
+	@Override
+	public E next() {
+		throw new NoSuchElementException();
+	}
+
+	@Override
+	public int nextIndex() {
+		return 0;
+	}
+
+	@Override
+	public E previous() {
+		throw new NoSuchElementException();
+	}
+
+	@Override
+	public int previousIndex() {
+		return -1;
+	}
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void set(E e) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return this.getClass().getSimpleName();
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the singleton
+		return INSTANCE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/EnumerationIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/EnumerationIterator.java
new file mode 100644
index 0000000..c4bb509
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/EnumerationIterator.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * An <code>EnumerationIterator</code> wraps an
+ * {@link Enumeration} so that it can be treated like an
+ * {@link Iterator}.
+ *
+ * @param <E> the type of elements returned by the iterator
+ */
+public class EnumerationIterator<E>
+	implements Iterator<E>
+{
+	private final Enumeration<? extends E> enumeration;
+
+	/**
+	 * Construct an iterator that wraps the specified enumeration.
+	 */
+	public EnumerationIterator(Enumeration<? extends E> enumeration) {
+		super();
+		if (enumeration == null) {
+			throw new NullPointerException();
+		}
+		this.enumeration = enumeration;
+	}
+
+	@Override
+	public boolean hasNext() {
+		return this.enumeration.hasMoreElements();
+	}
+
+	@Override
+	public E next() {
+		return this.enumeration.nextElement();
+	}
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.enumeration);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/FilteringIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/FilteringIterator.java
new file mode 100644
index 0000000..a3b96ef
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/FilteringIterator.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+
+/**
+ * A <code>FilteringIterator</code> wraps another {@link Iterator}
+ * and uses a {@link Filter} to determine which elements in the
+ * nested iterator are to be returned by calls to {@link #next()}.
+ * <p>
+ * As an alternative to building a {@link Filter}, a subclass
+ * of <code>FilteringIterator</code> can override the
+ * {@link #accept(Object)} method.
+ * <p>
+ * One, possibly undesirable, side-effect of using this iterator is that
+ * the nested iterator's <code>next()</code> method will be invoked
+ * <em>before</em> the filtered iterator's {@link #next()}
+ * method is invoked. This is because the "next" element must be
+ * checked for whether it is to be accepted before the filtered iterator
+ * can determine whether it has a "next" element (i.e. that the
+ * {@link #hasNext()} method should return <code>true</code>).
+ * This also prevents a filtered iterator from supporting the optional
+ * <code>remove()</code> method.
+ *
+ * @param <E> the type of elements to be filtered
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.FilteringIterable
+ */
+public class FilteringIterator<E>
+	implements Iterator<E>
+{
+	private final Iterator<? extends E> iterator;
+	private final Filter<E> filter;
+	private E next;
+	private boolean done;
+
+
+	/**
+	 * Construct an iterator with the specified
+	 * iterable and a disabled filter.
+	 * Use this constructor if you want to override the
+	 * {@link #accept(Object)} method instead of building
+	 * a {@link Filter}.
+	 */
+	public FilteringIterator(Iterable<? extends E> iterable) {
+		this(iterable.iterator());
+	}
+
+	/**
+	 * Construct an iterator with the specified nested
+	 * iterator and a disabled filter.
+	 * Use this constructor if you want to override the
+	 * {@link #accept(Object)} method instead of building
+	 * a {@link Filter}.
+	 */
+	public FilteringIterator(Iterator<? extends E> iterator) {
+		this(iterator, Filter.Disabled.<E>instance());
+	}
+
+	/**
+	 * Construct an iterator with the specified
+	 * iterable and filter.
+	 */
+	public FilteringIterator(Iterable<? extends E> iterable, Filter<E> filter) {
+		this(iterable.iterator(), filter);
+	}
+
+	/**
+	 * Construct an iterator with the specified nested
+	 * iterator and filter.
+	 */
+	public FilteringIterator(Iterator<? extends E> iterator, Filter<E> filter) {
+		super();
+		if ((iterator == null) || (filter == null)) {
+			throw new NullPointerException();
+		}
+		this.iterator = iterator;
+		this.filter = filter;
+		this.loadNext();
+	}
+
+	@Override
+	public boolean hasNext() {
+		return ! this.done;
+	}
+
+	@Override
+	public E next() {
+		if (this.done) {
+			throw new NoSuchElementException();
+		}
+		E result = this.next;
+		this.loadNext();
+		return result;
+	}
+
+	/**
+	 * Because we need to pre-load the next element
+	 * to be returned, we cannot support the <code>remove()</code>
+	 * method.
+	 */
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Load next with the next valid entry from the nested
+	 * iterator. If there are none, next is set to <code>END</code>.
+	 */
+	private void loadNext() {
+		this.done = true;
+		while (this.iterator.hasNext() && (this.done)) {
+			E temp = this.iterator.next();
+			if (this.accept(temp)) {
+				// assume that if the object was accepted it is of type E
+				this.next = temp;
+				this.done = false;
+			} else {
+				this.next = null;
+				this.done = true;
+			}
+		}
+	}
+
+	/**
+	 * Return whether the {@link FilteringIterator}
+	 * should return the specified next element from a call to the
+	 * {@link #next()} method.
+	 * <p>
+	 * This method can be overridden by a subclass as an
+	 * alternative to building a {@link Filter}.
+	 */
+	protected boolean accept(E o) {
+		return this.filter.accept(o);
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.iterator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/GraphIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/GraphIterator.java
new file mode 100644
index 0000000..84e67b4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/GraphIterator.java
@@ -0,0 +1,297 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * A <code>GraphIterator</code> is similar to a {@link TreeIterator}
+ * except that it cannot be assumed that all nodes assume a strict tree
+ * structure. For instance, in a tree, a node cannot be a descendent of
+ * itself, but a graph may have a cyclical structure.
+ *
+ * A <code>GraphIterator</code> simplifies the traversal of a
+ * graph of objects, where the objects' protocol(s) provides
+ * a method for getting the next collection of nodes in the graph,
+ * (or <em>neighbors</em>), but does not provide a method for
+ * getting <em>all</em> of the nodes in the graph.
+ * (e.g. a neighbor can return his neighbors, and those neighbors
+ * can return their neighbors, which might also include the original
+ * neighbor, but you only want to visit the original neighbor once.)
+ * <p>
+ * If a neighbor has already been visited (determined by using
+ * {@link #equals(Object)}), that neighbor is not visited again,
+ * nor are the neighbors of that object.
+ * <p>
+ * It is up to the user of this class to ensure a <em>complete</em> graph.
+ * <p>
+ * To use, supply:<ul>
+ * <li> either the initial node of the graph or an {@link Iterator}
+ * over an initial collection of graph nodes
+ * <li> a {@link MisterRogers} that tells who the neighbors are
+ * of each node
+ * (alternatively, subclass <code>GraphIterator</code>
+ * and override the {@link #neighbors(Object)} method)
+ * </ul>
+ * {@link #remove()} is not supported. This behavior, if
+ * desired, must be implemented by the user of this class.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.GraphIterable
+ */
+public class GraphIterator<E>
+	implements Iterator<E>
+{
+	// use a LinkedList since we will be pulling off the front and adding to the end
+	private final LinkedList<Iterator<? extends E>> iterators = new LinkedList<Iterator<? extends E>>();
+	private final HashSet<E> visitedNeighbors = new HashSet<E>();
+	private final MisterRogers<E> misterRogers;
+
+	private Iterator<? extends E> currentIterator;
+
+	private E nextNeighbor;
+	private boolean done;
+
+
+	/**
+	 * Construct an iterator that returns the nodes of a graph
+	 * with the specified collection of roots
+	 * and a disabled Mr. Rogers.
+	 * Use this constructor if you want to override the
+	 * {@link #neighbors(Object)} method instead of building
+	 * a {@link MisterRogers}.
+	 */
+	public GraphIterator(E... roots) {
+		this(new ArrayIterator<E>(roots));
+	}
+
+	/**
+	 * Construct an iterator that returns the nodes of a graph
+	 * with the specified collection of roots
+	 * and a disabled Mr. Rogers.
+	 * Use this constructor if you want to override the
+	 * {@link #neighbors(Object)} method instead of building
+	 * a {@link MisterRogers}.
+	 */
+	public GraphIterator(Iterable<? extends E> roots) {
+		this(roots.iterator());
+	}
+
+	/**
+	 * Construct an iterator that returns the nodes of a graph
+	 * with the specified collection of roots
+	 * and a disabled Mr. Rogers.
+	 * Use this constructor if you want to override the
+	 * {@link #neighbors(Object)} method instead of building
+	 * a {@link MisterRogers}.
+	 */
+	public GraphIterator(Iterator<? extends E> roots) {
+		this(roots, MisterRogers.Disabled.<E>instance());
+	}
+
+	/**
+	 * Construct an iterator that returns the nodes of a graph
+	 * with the specified root
+	 * and a disabled Mr. Rogers.
+	 * Use this constructor if you want to override the
+	 * <code>neighbors(Object)</code> method instead of building
+	 * a <code>MisterRogers</code>.
+	 */
+	public GraphIterator(E root) {
+		this(root, MisterRogers.Disabled.<E>instance());
+	}
+
+	/**
+	 * Construct an iterator that returns the nodes of a graph
+	 * with the specified root and Mr. Rogers.
+	 */
+	public GraphIterator(E root, MisterRogers<E> misterRogers) {
+		this(new SingleElementIterator<E>(root), misterRogers);
+	}
+
+	/**
+	 * Construct an iterator that returns the nodes of a graph
+	 * with the specified collection of roots and Mr. Rogers.
+	 */
+	public GraphIterator(E[] roots, MisterRogers<E> misterRogers) {
+		this(new ArrayIterator<E>(roots), misterRogers);
+	}
+
+	/**
+	 * Construct an iterator that returns the nodes of a graph
+	 * with the specified roots and Mr. Rogers.
+	 */
+	public GraphIterator(Iterable<? extends E> roots, MisterRogers<E> misterRogers) {
+		this(roots.iterator(), misterRogers);
+	}
+
+	/**
+	 * Construct an iterator that returns the nodes of a graph
+	 * with the specified roots and Mr. Rogers.
+	 */
+	public GraphIterator(Iterator<? extends E> roots, MisterRogers<E> misterRogers) {
+		super();
+		if ((roots == null) || (misterRogers == null)) {
+			throw new NullPointerException();
+		}
+		this.currentIterator = roots;
+		this.misterRogers = misterRogers;
+		this.loadNextNeighbor();
+	}
+
+	/**
+	 * Load next neighbor with the next entry from the current iterator.
+	 * If the current iterator has none, load the next iterator.
+	 * If there are no more, the {@link #done} flag is set.
+	 */
+	private void loadNextNeighbor() {
+		if (this.currentIterator == EmptyIterator.instance()) {
+			this.done = true;
+		}
+		else if (this.currentIterator.hasNext()) {
+			E nextPossibleNeighbor = this.currentIterator.next();
+			if (this.visitedNeighbors.contains(nextPossibleNeighbor)) {
+				this.loadNextNeighbor();  // recurse
+			} else {
+				this.nextNeighbor = nextPossibleNeighbor;
+				this.visitedNeighbors.add(nextPossibleNeighbor);
+				this.iterators.add(this.neighbors(nextPossibleNeighbor));
+			}
+		}
+		else {
+			for (Iterator<? extends Iterator<? extends E>> stream = this.iterators.iterator(); ! this.currentIterator.hasNext() && stream.hasNext(); ) {
+				this.currentIterator = stream.next();
+				stream.remove();
+			}
+			if ( ! this.currentIterator.hasNext()) {
+				this.currentIterator = EmptyIterator.instance();
+			}
+			this.loadNextNeighbor();  // recurse
+		}
+	}
+
+	@Override
+	public boolean hasNext() {
+		return ! this.done;
+	}
+
+	@Override
+	public E next() {
+		if (this.done) {
+			throw new NoSuchElementException();
+		}
+		E next = this.nextNeighbor;
+		this.loadNextNeighbor();
+		return next;
+	}
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Return the immediate neighbors of the specified object.
+	 */
+	protected Iterator<? extends E> neighbors(E next) {
+		return this.misterRogers.neighbors(next);
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.currentIterator);
+	}
+
+
+	//********** inner classes **********
+
+	/**
+	 * Used by {@link GraphIterator} to retrieve
+	 * the immediate neighbors of a node in the graph.
+	 * "These are the people in your neighborhood..."
+	 */
+	public interface MisterRogers<T> {
+
+		/**
+		 * Return the immediate neighbors of the specified object.
+		 */
+		Iterator<? extends T> neighbors(T next);
+
+
+		final class Null<S>
+			implements MisterRogers<S>, Serializable
+		{
+			@SuppressWarnings("rawtypes")
+			public static final MisterRogers INSTANCE = new Null();
+			@SuppressWarnings("unchecked")
+			public static <R> MisterRogers<R> instance() {
+				return INSTANCE;
+			}
+			// ensure single instance
+			private Null() {
+				super();
+			}
+			// return no neighbors
+			@Override
+			public Iterator<S> neighbors(S next) {
+				return EmptyIterator.instance();
+			}
+			@Override
+			public String toString() {
+				return ObjectTools.singletonToString(this);
+			}
+			private static final long serialVersionUID = 1L;
+			private Object readResolve() {
+				// replace this object with the singleton
+				return INSTANCE;
+			}
+		}
+
+		/** The Mr. Rogers used when the {@link GraphIterator#neighbors(Object)} method is overridden. */
+		final class Disabled<S>
+			implements MisterRogers<S>, Serializable
+		{
+			@SuppressWarnings("rawtypes")
+			public static final MisterRogers INSTANCE = new Disabled();
+			@SuppressWarnings("unchecked")
+			public static <R> MisterRogers<R> instance() {
+				return INSTANCE;
+			}
+			// ensure single instance
+			private Disabled() {
+				super();
+			}
+			// throw an exception
+			@Override
+			public Iterator<S> neighbors(S next) {
+				throw new UnsupportedOperationException();  // GraphIterator.neighbors(Object) was not implemented
+			}
+			@Override
+			public String toString() {
+				return ObjectTools.singletonToString(this);
+			}
+			private static final long serialVersionUID = 1L;
+			private Object readResolve() {
+				// replace this object with the singleton
+				return INSTANCE;
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/IteratorTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/IteratorTools.java
new file mode 100644
index 0000000..f926748
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/IteratorTools.java
@@ -0,0 +1,1589 @@
+/*******************************************************************************

+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.iterator;

+

+import java.sql.ResultSet;

+import java.util.ArrayList;

+import java.util.Arrays;

+import java.util.Collection;

+import java.util.Comparator;

+import java.util.Enumeration;

+import java.util.Iterator;

+import java.util.List;

+import java.util.ListIterator;

+import org.eclipse.persistence.tools.utility.ObjectTools;

+import org.eclipse.persistence.tools.utility.collection.CollectionTools;

+import org.eclipse.persistence.tools.utility.collection.HashBag;

+import org.eclipse.persistence.tools.utility.collection.ListTools;

+import org.eclipse.persistence.tools.utility.collection.Queue;

+import org.eclipse.persistence.tools.utility.collection.Stack;

+import org.eclipse.persistence.tools.utility.command.InterruptibleParameterizedCommand;

+import org.eclipse.persistence.tools.utility.command.ParameterizedCommand;

+import org.eclipse.persistence.tools.utility.filter.Filter;

+import org.eclipse.persistence.tools.utility.iterable.IterableTools;

+import org.eclipse.persistence.tools.utility.iterable.ListIterable;

+import org.eclipse.persistence.tools.utility.transformer.Transformer;

+

+/**

+ * {@link Iterator} utility methods.

+ * @see org.eclipse.jpt.common.utility.internal.ArrayTools

+ * @see CollectionTools

+ * @see IterableTools

+ * @see ListTools

+ */

+public final class IteratorTools {

+	/**

+	 * Return a bag corresponding to the specified iterator.

+	 */

+	public static <E> HashBag<E> bag(Iterator<? extends E> iterator) {

+		return CollectionTools.bag(iterator);

+	}

+

+	/**

+	 * Return a bag corresponding to the specified iterator.

+	 * The specified iterator size is a performance hint.

+	 */

+	public static <E> HashBag<E> bag(Iterator<? extends E> iterator, int iteratorSize) {

+		return CollectionTools.bag(iterator, iteratorSize);

+	}

+

+	/**

+	 * Return a collection corresponding to the specified iterator.

+	 */

+	public static <E> HashBag<E> collection(Iterator<? extends E> iterator) {

+		return CollectionTools.collection(iterator);

+	}

+

+	/**

+	 * Return a collection corresponding to the specified iterator.

+	 * The specified iterator size is a performance hint.

+	 */

+	public static <E> HashBag<E> collection(Iterator<? extends E> iterator, int iteratorSize) {

+		return CollectionTools.collection(iterator, iteratorSize);

+	}

+

+	/**

+	 * Return whether the specified iterator contains the

+	 * specified element.

+	 */

+	public static boolean contains(Iterator<?> iterator, Object value) {

+		if (value == null) {

+			while (iterator.hasNext()) {

+				if (iterator.next() == null) {

+					return true;

+				}

+			}

+		} else {

+			while (iterator.hasNext()) {

+				if (value.equals(iterator.next())) {

+					return true;

+				}

+			}

+		}

+		return false;

+	}

+

+	/**

+	 * Return whether the specified iterator contains all of the

+	 * elements in the specified collection.

+	 */

+	public static boolean containsAll(Iterator<?> iterator, Collection<?> collection) {

+		return CollectionTools.set(iterator).containsAll(collection);

+	}

+

+	/**

+	 * Return whether the specified iterator contains all of the

+	 * elements in the specified collection.

+	 * The specified iterator size is a performance hint.

+	 */

+	public static boolean containsAll(Iterator<?> iterator, int iteratorSize, Collection<?> collection) {

+		return CollectionTools.set(iterator, iteratorSize).containsAll(collection);

+	}

+

+	/**

+	 * Return whether the specified iterator contains all of the

+	 * elements in the specified iterable.

+	 */

+	public static boolean containsAll(Iterator<?> iterator, Iterable<?> iterable) {

+		return CollectionTools.containsAll(CollectionTools.set(iterator), iterable);

+	}

+

+	/**

+	 * Return whether the specified iterator contains all of the

+	 * elements in the specified iterable.

+	 * The specified iterator size is a performance hint.

+	 */

+	public static boolean containsAll(Iterator<?> iterator, int iteratorSize, Iterable<?> iterable) {

+		return CollectionTools.containsAll(CollectionTools.set(iterator, iteratorSize), iterable);

+	}

+

+	/**

+	 * Return whether the specified iterator 1 contains all of the

+	 * elements in the specified iterator 2.

+	 */

+	public static boolean containsAll(Iterator<?> iterator1, Iterator<?> iterator2) {

+		return CollectionTools.containsAll(CollectionTools.set(iterator1), iterator2);

+	}

+

+	/**

+	 * Return whether the specified iterator 1 contains all of the

+	 * elements in the specified iterator 2.

+	 * The specified iterator 1 size is a performance hint.

+	 */

+	public static boolean containsAll(Iterator<?> iterator1, int iterator1Size, Iterator<?> iterator2) {

+		return CollectionTools.containsAll(CollectionTools.set(iterator1, iterator1Size), iterator2);

+	}

+

+	/**

+	 * Return whether the specified iterator contains all of the

+	 * elements in the specified array.

+	 */

+	public static boolean containsAll(Iterator<?> iterator, Object... array) {

+		return CollectionTools.containsAll(CollectionTools.set(iterator), array);

+	}

+

+	/**

+	 * Return whether the specified iterator contains all of the

+	 * elements in the specified array.

+	 * The specified iterator size is a performance hint.

+	 */

+	public static boolean containsAll(Iterator<?> iterator, int iteratorSize, Object... array) {

+		return CollectionTools.containsAll(CollectionTools.set(iterator, iteratorSize), array);

+	}

+

+	/**

+	 * Return whether the specified iterators do not return the same elements

+	 * in the same order.

+	 */

+	public static boolean elementsAreDifferent(Iterator<?> iterator1, Iterator<?> iterator2) {

+		return ! elementsAreEqual(iterator1, iterator2);

+	}

+

+	/**

+	 * Return whether the specified iterators return equal elements

+	 * in the same order.

+	 */

+	public static boolean elementsAreEqual(Iterator<?> iterator1, Iterator<?> iterator2) {

+		while (iterator1.hasNext() && iterator2.hasNext()) {

+			if (ObjectTools.notEquals(iterator1.next(), iterator2.next())) {

+				return false;

+			}

+		}

+		return ! (iterator1.hasNext() || iterator2.hasNext());

+	}

+

+	/**

+	 * Return whether the specified iterators return the same elements.

+	 */

+	public static boolean elementsAreIdentical(Iterator<?> iterator1, Iterator<?> iterator2) {

+		while (iterator1.hasNext() && iterator2.hasNext()) {

+			if (iterator1.next() != iterator2.next()) {

+				return false;

+			}

+		}

+		return ! (iterator1.hasNext() || iterator2.hasNext());

+	}

+

+	/**

+	 * Return whether the specified iterators do <em>not</em> return the same

+	 * elements.

+	 */

+	public static boolean elementsAreNotIdentical(Iterator<?> iterator1, Iterator<?> iterator2) {

+		return ! elementsAreIdentical(iterator1, iterator2);

+	}

+

+	/**

+	 * Execute the specified command for each element in the specified iterator.

+	 */

+	public static <E> void execute(Iterator<? extends E> iterator, ParameterizedCommand<E> command) {

+		while (iterator.hasNext()) {

+			command.execute(iterator.next());

+		}

+	}

+

+	/**

+	 * Execute the specified command for each element in the specified iterator.

+	 */

+	public static <E> void execute(Iterator<? extends E> iterator, InterruptibleParameterizedCommand<E> command) throws InterruptedException {

+		while (iterator.hasNext()) {

+			command.execute(iterator.next());

+		}

+	}

+

+	/**

+	 * Return the element corresponding to the specified index

+	 * in the specified iterator.

+	 */

+	public static <E> E get(Iterator<? extends E> iterator, int index) {

+		int i = 0;

+		while (iterator.hasNext()) {

+			E next = iterator.next();

+			if (i++ == index) {

+				return next;

+			}

+		}

+		throw new IndexOutOfBoundsException(String.valueOf(index) + ':' + String.valueOf(i));

+	}

+

+	/**

+	 * Return a hash code corresponding to the elements in the specified iterator.

+	 */

+	public static int hashCode(Iterator<?> iterator) {

+		int hash = 1;

+		while (iterator.hasNext()) {

+			Object next = iterator.next();

+			hash = 31 * hash + ((next == null) ? 0 : next.hashCode());

+		}

+		return hash;

+	}

+

+	/**

+	 * Return the index of the first occurrence of the

+	 * specified element in the specified iterator;

+	 * return -1 if there is no such element.

+	 */

+	public static int indexOf(Iterator<?> iterator, Object value) {

+		if (value == null) {

+			for (int i = 0; iterator.hasNext(); i++) {

+				if (iterator.next() == null) {

+					return i;

+				}

+			}

+		} else {

+			for (int i = 0; iterator.hasNext(); i++) {

+				if (value.equals(iterator.next())) {

+					return i;

+				}

+			}

+		}

+		return -1;

+	}

+

+	/**

+	 * Return the index of the last occurrence of the

+	 * specified element in the specified iterator;

+	 * return -1 if there is no such element.

+	 */

+	public static int lastIndexOf(Iterator<?> iterator, Object value) {

+		int last = -1;

+		if (value == null) {

+			for (int i = 0; iterator.hasNext(); i++) {

+				if (iterator.next() == null) {

+					last = i;

+				}

+			}

+		} else {

+			for (int i = 0; iterator.hasNext(); i++) {

+				if (value.equals(iterator.next())) {

+					last = i;

+				}

+			}

+		}

+		return last;

+	}

+

+	/**

+	 * Return the specified iterator's last element.

+	 * @exception java.util.NoSuchElementException iterator is empty.

+	 */

+	public static <E> E last(Iterator<E> iterator) {

+		E last;

+		do {

+			last = iterator.next();

+		} while (iterator.hasNext());

+		return last;

+	}

+

+	/**

+	 * Return a list corresponding to the specified iterator.

+	 */

+	public static <E> ArrayList<E> list(Iterator<? extends E> iterator) {

+		return ListTools.list(iterator);

+	}

+

+	/**

+	 * Return a list corresponding to the specified iterator.

+	 * The specified iterator size is a performance hint.

+	 */

+	public static <E> ArrayList<E> list(Iterator<? extends E> iterator, int iteratorSize) {

+		return ListTools.list(iterator, iteratorSize);

+	}

+

+	/**

+	 * Return the number of elements returned by the specified iterator.

+	 */

+	public static int size(Iterator<?> iterator) {

+		int size = 0;

+		while (iterator.hasNext()) {

+			iterator.next();

+			size++;

+		}

+		return size;

+	}

+

+	/**

+	 * Return whether the specified iterator is empty

+	 * (Shortcuts the iterator rather than calculating the entire size)

+	 */

+	public static boolean isEmpty(Iterator<?> iterator) {

+		return ! iterator.hasNext();

+	}

+

+	/**

+	 * Return the iterator after it has been "sorted".

+	 */

+	public static <E extends Comparable<? super E>> ListIterator<E> sort(Iterator<? extends E> iterator) {

+		return sort(iterator, null);

+	}

+

+	/**

+	 * Return the iterator after it has been "sorted".

+	 * The specified iterator size is a performance hint.

+	 */

+	public static <E extends Comparable<? super E>> ListIterator<E> sort(Iterator<? extends E> iterator, int iteratorSize) {

+		return sort(iterator, null, iteratorSize);

+	}

+

+	/**

+	 * Return the iterator after it has been "sorted".

+	 */

+	public static <E> ListIterator<E> sort(Iterator<? extends E> iterator, Comparator<? super E> comparator) {

+		return ListTools.sort(ListTools.list(iterator), comparator).listIterator();

+	}

+

+	/**

+	 * Return the iterator after it has been "sorted".

+	 * The specified iterator size is a performance hint.

+	 */

+	public static <E> ListIterator<E> sort(Iterator<? extends E> iterator, Comparator<? super E> comparator, int iteratorSize) {

+		return ListTools.sort(ListTools.list(iterator, iteratorSize), comparator).listIterator();

+	}

+

+	/**

+	 * Convert the specified iterator into an array.

+	 * @see Collection#toArray()

+	 */

+	public static Object[] toArray(Iterator<?> iterator) {

+		return list(iterator).toArray();

+	}

+

+	/**

+	 * Convert the specified iterator into an array.

+	 * The specified iterator size is a performance hint.

+	 * @see Collection#toArray()

+	 */

+	public static Object[] toArray(Iterator<?> iterator, int iteratorSize) {

+		return list(iterator, iteratorSize).toArray();

+	}

+

+	/**

+	 * Convert the specified iterator into an array.

+	 * @see Collection#toArray(Object[])

+	 */

+	public static <E> E[] toArray(Iterator<? extends E> iterator, E[] array) {

+		return list(iterator).toArray(array);

+	}

+

+	/**

+	 * Convert the specified iterator into an array.

+	 * The specified iterator size is a performance hint.

+	 * @see Collection#toArray(Object[])

+	 */

+	public static <E> E[] toArray(Iterator<? extends E> iterator, int iteratorSize, E[] array) {

+		return list(iterator, iteratorSize).toArray(array);

+	}

+

+

+	// ********** factory methods **********

+

+	/**

+	 * Return a chain iterator that starts with the specified element and uses

+	 * the specified {@link ChainIterator.Linker linker}.

+	 * @see ChainIterator

+	 */

+	public static <E> ChainIterator<E> chainIterator(E startLink, ChainIterator.Linker<E> linker) {

+		return new ChainIterator<E>(startLink, linker);

+	}

+

+	/**

+	 * Return an iterator that clones the specified collection before returning

+	 * elements.

+	 * @see CloneIterator

+	 */

+	public static <E> CloneIterator<E> cloneIterator(Collection<? extends E> collection) {

+		return new CloneIterator<E>(collection);

+	}

+

+	/**

+	 * Return an iterator that clones the specified collection before returning

+	 * elements and uses the specified {@link CloneIterator.Remover remover}.

+	 * @see CloneIterator

+	 */

+	public static <E> CloneIterator<E> cloneIterator(Collection<? extends E> collection, CloneIterator.Remover<E> remover) {

+		return new CloneIterator<E>(collection, remover);

+	}

+

+	/**

+	 * Return an iterator that clones the specified array before returning

+	 * elements.

+	 * @see CloneIterator

+	 */

+	public static <E> CloneIterator<E> cloneIterator(E[] array) {

+		return new CloneIterator<E>(array);

+	}

+

+	/**

+	 * Return an iterator that clones the specified array before returning

+	 * elements and uses the specified {@link CloneIterator.Remover remover}.

+	 * @see CloneIterator

+	 */

+	public static <E> CloneIterator<E> cloneIterator(E[] array, CloneIterator.Remover<E> remover) {

+		return new CloneIterator<E>(array, remover);

+	}

+

+	/**

+	 * Return an iterator that clones the specified list before returning

+	 * elements.

+	 * @see CloneIterator

+	 */

+	public static <E> CloneListIterator<E> cloneListIterator(List<? extends E> list) {

+		return new CloneListIterator<E>(list);

+	}

+

+	/**

+	 * Return an iterator that clones the specified list before returning

+	 * elements and uses the specified {@link CloneListIterator.Mutator mutator}.

+	 * @see CloneIterator

+	 */

+	public static <E> CloneListIterator<E> cloneListIterator(List<? extends E> list, CloneListIterator.Mutator<E> mutator) {

+		return new CloneListIterator<E>(list, mutator);

+	}

+

+	/**

+	 * Return an iterator that clones the specified array before returning

+	 * elements.

+	 * @see CloneIterator

+	 */

+	public static <E> CloneListIterator<E> cloneListIterator(E[] array) {

+		return new CloneListIterator<E>(array);

+	}

+

+	/**

+	 * Return an iterator that clones the specified array before returning

+	 * elements and uses the specified {@link CloneListIterator.Mutator mutator}.

+	 * @see CloneIterator

+	 */

+	public static <E> CloneListIterator<E> cloneListIterator(E[] array, CloneListIterator.Mutator<E> mutator) {

+		return new CloneListIterator<E>(array, mutator);

+	}

+

+	/**

+	 * Return an iterator that returns the specified object followed by the

+	 * elements in the specified iterable.

+	 * @see CompositeIterator

+	 */

+	public static <E> CompositeIterator<E> compositeIterator(E object, Iterable<? extends E> iterable) {

+		return compositeIterator(object, iterable.iterator());

+	}

+

+	/**

+	 * Return an iterator that returns the specified object followed by the

+	 * elements in the specified iterator.

+	 * @see CompositeIterator

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> CompositeIterator<E> compositeIterator(E object, Iterator<? extends E> iterator) {

+		return compositeIterator(new Iterator[] { singletonIterator(object), iterator });

+	}

+

+	/**

+	 * Return an iterator that returns the

+	 * elements in the specified iterable followed by the specified object.

+	 * @see CompositeIterator

+	 */

+	public static <E> CompositeIterator<E> compositeIterator(Iterable<? extends E> iterable, E object) {

+		return compositeIterator(iterable.iterator(), object);

+	}

+

+	/**

+	 * Return an iterator that returns the

+	 * elements in the specified iterables.

+	 * @see CompositeIterator

+	 */

+	public static <E> CompositeIterator<E> compositeIterator(Iterable<? extends E>... iterables) {

+		return compositeIterator(Arrays.asList(iterables));

+	}

+

+	/**

+	 * Return an iterator that returns the

+	 * elements in the specified iterables.

+	 * @see CompositeIterator

+	 */

+	public static <E> CompositeIterator<E> compositeIterator(Iterable<? extends Iterable<? extends E>> iterables) {

+		Transformer<Iterable<? extends E>, Iterator<? extends E>> transformer = iterableIteratorTransformer();

+		return compositeIterator(transform(iterables.iterator(), transformer));

+	}

+

+	/**

+	 * Return an iterator that returns the

+	 * elements in the specified iterator followed by the specified object.

+	 * @see CompositeIterator

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> CompositeIterator<E> compositeIterator(Iterator<? extends E> iterator, E object) {

+		return compositeIterator(new Iterator[] { iterator, singletonIterator(object) });

+	}

+

+	/**

+	 * Return an iterator that returns the

+	 * elements in the specified iterators.

+	 * @see CompositeIterator

+	 */

+	public static <E> CompositeIterator<E> compositeIterator(Iterator<? extends E>... iterators) {

+		return compositeIterator(iterator(iterators));

+	}

+

+	/**

+	 * Return an iterator that returns the

+	 * elements in the specified iterators.

+	 * @see CompositeIterator

+	 */

+	public static <E> CompositeIterator<E> compositeIterator(Iterator<? extends Iterator<? extends E>> iterators) {

+		return new CompositeIterator<E>(iterators);

+	}

+

+	/**

+	 * Return an iterator on the children of the specified parents.

+	 * Use the specified transformer to transform each parent into its children.

+	 * @see CompositeIterator

+	 */

+	public static <P, E> CompositeIterator<E> compositeIterator(Iterator<? extends P> parents, Transformer<P, Iterator<? extends E>> childrenTransformer) {

+		return compositeIterator(transform(parents, childrenTransformer));

+	}

+

+	/**

+	 * Return an iterator on the children of the specified parents.

+	 * Use the specified transformer to transform each parent into its children.

+	 * @see CompositeIterator

+	 */

+	public static <P, E> CompositeIterator<E> compositeIterator(Iterable<? extends P> parents, Transformer<P, Iterable<? extends E>> childrenTransformer) {

+		return compositeIterator(IterableTools.transform(parents, childrenTransformer));

+	}

+

+	/**

+	 * Return a list iterator that returns the specified object followed by the

+	 * elements in the specified list.

+	 * @see CompositeListIterator

+	 */

+	public static <E> CompositeListIterator<E> compositeListIterator(E object, List<E> list) {

+		return compositeListIterator(object, list.listIterator());

+	}

+

+	/**

+	 * Return a list iterator that returns the specified object followed by the

+	 * elements in the specified iterable.

+	 * @see CompositeListIterator

+	 */

+	public static <E> CompositeListIterator<E> compositeListIterator(E object, ListIterable<E> iterable) {

+		return compositeListIterator(object, iterable.iterator());

+	}

+

+	/**

+	 * Return a list iterator that returns the specified object followed by the

+	 * elements in the specified iterator.

+	 * @see CompositeListIterator

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> CompositeListIterator<E> compositeListIterator(E object, ListIterator<E> iterator) {

+		return compositeListIterator(new ListIterator[] { singletonListIterator(object), iterator });

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified lists.

+	 * @see CompositeListIterator

+	 */

+	public static <E> CompositeListIterator<E> compositeListIterator(List<? extends List<E>> lists) {

+		Transformer<List<E>, ListIterator<E>> transformer = listListIteratorTransformer();

+		return compositeListIterator(transform(lists.listIterator(), transformer));

+	}

+

+	/**

+	 * Return a list iterator that returns the elements in the specified list

+	 * followed by the specified object.

+	 * @see CompositeListIterator

+	 */

+	public static <E> CompositeListIterator<E> compositeListIterator(List<E> list, E object) {

+		return compositeListIterator(list.listIterator(), object);

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified lists.

+	 * @see CompositeListIterator

+	 */

+	public static <E> CompositeListIterator<E> compositeListIterator(List<E>... lists) {

+		return compositeListIterator(Arrays.asList(lists));

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified iterable followed by the specified object.

+	 * @see CompositeListIterator

+	 */

+	public static <E> CompositeListIterator<E> compositeListIterator(ListIterable<E> iterable, E object) {

+		return compositeListIterator(iterable.iterator(), object);

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified iterables.

+	 * @see CompositeListIterator

+	 */

+	public static <E> CompositeListIterator<E> compositeListIterator(ListIterable<E>... iterables) {

+		return compositeListIterator(IterableTools.listIterable(iterables));

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified iterables.

+	 * @see CompositeListIterator

+	 */

+	public static <E> CompositeListIterator<E> compositeListIterator(ListIterable<? extends ListIterable<E>> iterables) {

+		Transformer<ListIterable<E>, ListIterator<E>> transformer = listIterableListIteratorTransformer();

+		return compositeListIterator(transform(iterables.iterator(), transformer));

+	}

+

+	/**

+	 * Return a list iterator on the children of the specified parents.

+	 * Use the specified transformer to transform each parent into its children.

+	 * @see CompositeListIterator

+	 */

+	public static <P, E> CompositeListIterator<E> compositeListIterator(ListIterable<? extends P> parents, Transformer<P, ListIterable<E>> childrenTransformer) {

+		return compositeListIterator(IterableTools.transform(parents, childrenTransformer));

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified iterator followed by the specified object.

+	 * @see CompositeListIterator

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> CompositeListIterator<E> compositeListIterator(ListIterator<E> iterator, E object) {

+		return compositeListIterator(new ListIterator[] { iterator, singletonListIterator(object) });

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified iterators.

+	 * @see CompositeListIterator

+	 */

+	public static <E> CompositeListIterator<E> compositeListIterator(ListIterator<E>... iterators) {

+		return compositeListIterator(listIterator(iterators));

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified iterators.

+	 * @see CompositeListIterator

+	 */

+	public static <E> CompositeListIterator<E> compositeListIterator(ListIterator<? extends ListIterator<E>> iterators) {

+		return new CompositeListIterator<E>(iterators);

+	}

+

+	/**

+	 * Return a list iterator on the children of the specified parents.

+	 * Use the specified transformer to transform each parent into its children.

+	 * @see CompositeListIterator

+	 */

+	public static <P, E> CompositeListIterator<E> compositeListIterator(ListIterator<? extends P> parents, Transformer<P, ListIterator<E>> childrenTransformer) {

+		return compositeListIterator(transform(parents, childrenTransformer));

+	}

+

+	/**

+	 * Return an empty iterator.

+	 */

+	public static <E> Iterator<E> emptyIterator() {

+		return EmptyIterator.instance();

+	}

+

+	/**

+	 * Return an empty list iterator.

+	 */

+	public static <E> ListIterator<E> emptyListIterator() {

+		return EmptyListIterator.instance();

+	}

+

+	/**

+	 * Return an iterator that will use the specified filter to filter the

+	 * elements in the specified iterable.

+	 * @see FilteringIterator

+	 */

+	public static <E> FilteringIterator<E> filteringIterator(Iterable<? extends E> iterable, Filter<E> filter) {

+		return new FilteringIterator<E>(iterable, filter);

+	}

+

+	/**

+	 * Return an iterator that will use the specified filter to filter the

+	 * elements in the specified iterator.

+	 * @see FilteringIterator

+	 */

+	public static <E> FilteringIterator<E> filter(Iterator<? extends E> iterator, Filter<E> filter) {

+		return new FilteringIterator<E>(iterator, filter);

+	}

+

+	/**

+	 * Return an iterator that will return the specified root element followed

+	 * by its children etc. as determined by the specified Mr. Rogers.

+	 * @see GraphIterator

+	 */

+	public static <E> GraphIterator<E> graphIterator(E root, GraphIterator.MisterRogers<E> misterRogers) {

+		return new GraphIterator<E>(root, misterRogers);

+	}

+

+	/**

+	 * Return an iterator that will return the specified root elements followed

+	 * by their children etc. as determined by the specified Mr. Rogers.

+	 * @see GraphIterator

+	 */

+	public static <E> GraphIterator<E> graphIterator(E[] roots, GraphIterator.MisterRogers<E> misterRogers) {

+		return new GraphIterator<E>(roots, misterRogers);

+	}

+

+	/**

+	 * Return an iterator that will return the specified root elements followed

+	 * by their children etc. as determined by the specified Mr. Rogers.

+	 * @see GraphIterator

+	 */

+	public static <E> GraphIterator<E> graphIterator(Iterable<E> roots, GraphIterator.MisterRogers<E> misterRogers) {

+		return new GraphIterator<E>(roots, misterRogers);

+	}

+

+	/**

+	 * Return an iterator that will return the specified root elements followed

+	 * by their children etc. as determined by the specified Mr. Rogers.

+	 * @see GraphIterator

+	 */

+	public static <E> GraphIterator<E> graphIterator(Iterator<E> roots, GraphIterator.MisterRogers<E> misterRogers) {

+		return new GraphIterator<E>(roots, misterRogers);

+	}

+

+	/**

+	 * Return a transformer that transforms an {@link Iterable} into an {@link Iterator}.

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> Transformer<Iterable<? extends E>, Iterator<? extends E>> iterableIteratorTransformer() {

+		return ITERABLE_ITERATOR_TRANSFORMER;

+	}

+

+	/**

+	 * A transformer that transforms an {@link Iterable} into an {@link Iterator}.

+	 */

+	@SuppressWarnings("rawtypes")

+	public static final Transformer ITERABLE_ITERATOR_TRANSFORMER = new IterableIteratorTransformer();

+	/* CU private */ static class IterableIteratorTransformer<E>

+		implements Transformer<Iterable<E>, Iterator<E>>

+	{

+		@Override

+		public Iterator<E> transform(Iterable<E> iterable) {

+			return iterable.iterator();

+		}

+	}

+

+	/**

+	 * Return an iterator the corresponds to the specified enumeration.

+	 */

+	public static <E> EnumerationIterator<E> iterator(Enumeration<E> enumeration) {

+		return new EnumerationIterator<E>(enumeration);

+	}

+

+	/**

+	 * Return an iterator on the elements in the specified array.

+	 */

+	public static <E> ArrayIterator<E> iterator(E... array) {

+		return iterator(array, 0);

+	}

+

+	/**

+	 * Return an iterator on the elements in the specified array

+	 * starting at the specified position in the array.

+	 */

+	public static <E> ArrayIterator<E> iterator(E[] array, int start) {

+		return iterator(array, start, array.length);

+	}

+

+	/**

+	 * Return an iterator on the elements in the specified array

+	 * starting at the specified start index, inclusive, and continuing to

+	 * the specified end index, exclusive.

+	 */

+	public static <E> ArrayIterator<E> iterator(E[] array, int start, int end) {

+		return new ArrayIterator<E>(array, start, end);

+	}

+

+	/**

+	 * Return an iterator on the specified queue.

+	 * @see Queue

+	 */

+	public static <E> QueueIterator<E> iterator(Queue<E> queue) {

+		return new QueueIterator<E>(queue);

+	}

+

+	/**

+	 * Return an iterator on the specified stack.

+	 * @see Stack

+	 */

+	public static <E> StackIterator<E> iterator(Stack<E> stack) {

+		return new StackIterator<E>(stack);

+	}

+

+	/**

+	 * Return an iterator that converts the specified iterable's element type.

+	 * @see LateralIteratorWrapper

+	 */

+	public static <E1, E2> LateralIteratorWrapper<E1, E2> lateralIterator(Iterable<E1> iterable) {

+		return new LateralIteratorWrapper<E1, E2>(iterable);

+	}

+

+	/**

+	 * Return an iterator that converts the specified iterator's element type.

+	 * @see LateralIteratorWrapper

+	 */

+	public static <E1, E2> LateralIteratorWrapper<E1, E2> lateralIterator(Iterator<E1> iterator) {

+		return new LateralIteratorWrapper<E1, E2>(iterator);

+	}

+

+	/**

+	 * Return a list iterator that converts the specified list's element type.

+	 * @see LateralListIteratorWrapper

+	 */

+	public static <E1, E2> LateralListIteratorWrapper<E1, E2> lateralListIterator(List<E1> list) {

+		return new LateralListIteratorWrapper<E1, E2>(list);

+	}

+

+	/**

+	 * Return a list iterator that converts the specified iterable's element type.

+	 * @see LateralListIteratorWrapper

+	 */

+	public static <E1, E2> LateralListIteratorWrapper<E1, E2> lateralListIterator(ListIterable<E1> iterable) {

+		return new LateralListIteratorWrapper<E1, E2>(iterable);

+	}

+

+	/**

+	 * Return a list iterator that converts the specified iterator's element type.

+	 * @see LateralListIteratorWrapper

+	 */

+	public static <E1, E2> LateralListIteratorWrapper<E1, E2> lateralListIterator(ListIterator<E1> iterator) {

+		return new LateralListIteratorWrapper<E1, E2>(iterator);

+	}

+

+	/**

+	 * Return a transformer that transforms a {@link ListIterable} into a

+	 * {@link ListIterator}.

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> Transformer<ListIterable<E>, ListIterator<E>> listIterableListIteratorTransformer() {

+		return LIST_ITERABLE_LIST_ITERATOR_TRANSFORMER;

+	}

+

+	/**

+	 * A transformer that transforms a {@link ListIterable} into a

+	 * {@link ListIterator}.

+	 */

+	@SuppressWarnings("rawtypes")

+	public static final Transformer LIST_ITERABLE_LIST_ITERATOR_TRANSFORMER = new ListIterableListIteratorTransformer();

+	/* CU private */ static class ListIterableListIteratorTransformer<E>

+		implements Transformer<ListIterable<E>, ListIterator<E>>

+	{

+		@Override

+		public ListIterator<E> transform(ListIterable<E> list) {

+			return list.iterator();

+		}

+	}

+

+	/**

+	 * Return a list iterator for the specified array.

+	 */

+	public static <E> ArrayListIterator<E> listIterator(E... array) {

+		return listIterator(array, 0);

+	}

+

+	/**

+	 * Return a list iterator for the specified array

+	 * starting at the specified position in the array.

+	 */

+	public static <E> ArrayListIterator<E> listIterator(E[] array, int start) {

+		return listIterator(array, start, array.length);

+	}

+

+	/**

+	 * Return a list iterator for the specified array

+	 * starting at the specified start index, inclusive, and continuing to

+	 * the specified end index, exclusive.

+	 */

+	public static <E> ArrayListIterator<E> listIterator(E[] array, int start, int end) {

+		return new ArrayListIterator<E>(array, start, end);

+	}

+

+	/**

+	 * Return a transformer that transforms a {@link List} into a

+	 * {@link ListIterator}.

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> Transformer<List<E>, ListIterator<E>> listListIteratorTransformer() {

+		return LIST_LIST_ITERATOR_TRANSFORMER;

+	}

+

+	/**

+	 * A transformer that transforms a {@link List} into a

+	 * {@link ListIterator}.

+	 */

+	@SuppressWarnings("rawtypes")

+	public static final Transformer LIST_LIST_ITERATOR_TRANSFORMER = new ListListIteratorTransformer();

+	/* CU private */ static class ListListIteratorTransformer<E>

+		implements Transformer<List<E>, ListIterator<E>>

+	{

+		@Override

+		public ListIterator<E> transform(List<E> list) {

+			return list.listIterator();

+		}

+	}

+

+	/**

+	 * Return an iterator the returns <code>null</code> the specified number of times.

+	 * @see NullElementIterator

+	 */

+	public static <E> NullElementIterator<E> nullElementIterator(int size) {

+		return new NullElementIterator<E>(size);

+	}

+

+	/**

+	 * Return a list iterator the returns <code>null</code> the specified number of times.

+	 * @see NullElementListIterator

+	 */

+	public static <E> NullElementListIterator<E> nullElementListIterator(int size) {

+		return new NullElementListIterator<E>(size);

+	}

+

+	/**

+	 * Return a "peekable" iterator.

+	 */

+	public static <E> PeekableIterator<E> peekableIterator(Iterable<E> iterable) {

+		return new PeekableIterator<E>(iterable);

+	}

+

+	/**

+	 * Return a "peekable" iterator.

+	 */

+	public static <E> PeekableIterator<E> peekableIterator(Iterator<E> iterator) {

+		return new PeekableIterator<E>(iterator);

+	}

+

+	/**

+	 * Return a list iterator that returns the specified object followed by the

+	 * elements in the specified list.

+	 * @see ReadOnlyCompositeListIterator

+	 */

+	public static <E> ReadOnlyCompositeListIterator<E> readOnlyCompositeListIterator(E object, List<? extends E> list) {

+		return readOnlyCompositeListIterator(object, list.listIterator());

+	}

+

+	/**

+	 * Return a list iterator that returns the specified object followed by the

+	 * elements in the specified iterable.

+	 * @see ReadOnlyCompositeListIterator

+	 */

+	public static <E> ReadOnlyCompositeListIterator<E> readOnlyCompositeListIterator(E object, ListIterable<? extends E> iterable) {

+		return readOnlyCompositeListIterator(object, iterable.iterator());

+	}

+

+	/**

+	 * Return a list iterator that returns the specified object followed by the

+	 * elements in the specified iterator.

+	 * @see ReadOnlyCompositeListIterator

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> ReadOnlyCompositeListIterator<E> readOnlyCompositeListIterator(E object, ListIterator<? extends E> iterator) {

+		return readOnlyCompositeListIterator(new ListIterator[] { singletonListIterator(object), iterator });

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified lists.

+	 * @see ReadOnlyCompositeListIterator

+	 */

+	public static <E> ReadOnlyCompositeListIterator<E> readOnlyCompositeListIterator(List<? extends List<? extends E>> lists) {

+		Transformer<List<? extends E>, ListIterator<? extends E>> transformer = readOnlyListListIteratorTransformer();

+		return readOnlyCompositeListIterator(transform(lists.listIterator(), transformer));

+	}

+

+	/**

+	 * Return a list iterator that returns the elements in the specified list

+	 * followed by the specified object.

+	 * @see ReadOnlyCompositeListIterator

+	 */

+	public static <E> ReadOnlyCompositeListIterator<E> readOnlyCompositeListIterator(List<? extends E> list, E object) {

+		return readOnlyCompositeListIterator(list.listIterator(), object);

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified lists.

+	 * @see ReadOnlyCompositeListIterator

+	 */

+	public static <E> ReadOnlyCompositeListIterator<E> readOnlyCompositeListIterator(List<? extends E>... lists) {

+		return readOnlyCompositeListIterator(Arrays.asList(lists));

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified iterable followed by the specified object.

+	 * @see ReadOnlyCompositeListIterator

+	 */

+	public static <E> ReadOnlyCompositeListIterator<E> readOnlyCompositeListIterator(ListIterable<? extends E> iterable, E object) {

+		return readOnlyCompositeListIterator(iterable.iterator(), object);

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified iterables.

+	 * @see ReadOnlyCompositeListIterator

+	 */

+	public static <E> ReadOnlyCompositeListIterator<E> readOnlyCompositeListIterator(ListIterable<? extends E>... iterables) {

+		return readOnlyCompositeListIterator(IterableTools.listIterable(iterables));

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified iterables.

+	 * @see ReadOnlyCompositeListIterator

+	 */

+	public static <E> ReadOnlyCompositeListIterator<E> readOnlyCompositeListIterator(ListIterable<? extends ListIterable<? extends E>> iterables) {

+		Transformer<ListIterable<? extends E>, ListIterator<? extends E>> transformer = readOnlyListIterableListIteratorTransformer();

+		return readOnlyCompositeListIterator(transform(iterables.iterator(), transformer));

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified iterator followed by the specified object.

+	 * @see ReadOnlyCompositeListIterator

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> ReadOnlyCompositeListIterator<E> readOnlyCompositeListIterator(ListIterator<? extends E> iterator, E object) {

+		return readOnlyCompositeListIterator(new ListIterator[] { iterator, singletonListIterator(object) });

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified iterators.

+	 * @see ReadOnlyCompositeListIterator

+	 */

+	public static <E> ReadOnlyCompositeListIterator<E> readOnlyCompositeListIterator(ListIterator<? extends E>... iterators) {

+		return readOnlyCompositeListIterator(listIterator(iterators));

+	}

+

+	/**

+	 * Return a list iterator that returns the

+	 * elements in the specified iterators.

+	 * @see ReadOnlyCompositeListIterator

+	 */

+	public static <E> ReadOnlyCompositeListIterator<E> readOnlyCompositeListIterator(ListIterator<? extends ListIterator<? extends E>> iterators) {

+		return new ReadOnlyCompositeListIterator<E>(iterators);

+	}

+

+	/**

+	 * Return a list iterator on the children of the specified parents.

+	 * Use the specified transformer to transform each parent into its children.

+	 * @see ReadOnlyCompositeListIterator

+	 */

+	public static <P, E> ReadOnlyCompositeListIterator<E> readOnlyCompositeListIterator(ListIterator<? extends P> parents, Transformer<P, ListIterator<? extends E>> childrenTransformer) {

+		return readOnlyCompositeListIterator(transform(parents, childrenTransformer));

+	}

+

+	/**

+	 * Return a transformer that transforms a {@link ListIterable} into a

+	 * read-only {@link ListIterator}.

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> Transformer<ListIterable<? extends E>, ListIterator<? extends E>> readOnlyListIterableListIteratorTransformer() {

+		return READ_ONLY_LIST_ITERABLE_LIST_ITERATOR_TRANSFORMER;

+	}

+

+	/**

+	 * A transformer that transforms a {@link ListIterable} into a

+	 * read-only {@link ListIterator}.

+	 */

+	@SuppressWarnings("rawtypes")

+	public static final Transformer READ_ONLY_LIST_ITERABLE_LIST_ITERATOR_TRANSFORMER = new ReadOnlyListIterableListIteratorTransformer();

+	/* CU private */ static class ReadOnlyListIterableListIteratorTransformer<E>

+		implements Transformer<ListIterable<? extends E>, ListIterator<? extends E>>

+	{

+		@Override

+		public ListIterator<? extends E> transform(ListIterable<? extends E> iterable) {

+			return readOnlyListIterator(iterable);

+		}

+	}

+

+	/**

+	 * Convert the specified iterable to read-only.

+	 * @see ReadOnlyIterator

+	 */

+	public static <E> ReadOnlyIterator<E> readOnlyIterator(Iterable<? extends E> iterable) {

+		return new ReadOnlyIterator<E>(iterable);

+	}

+

+	/**

+	 * Convert the specified iterator to read-only.

+	 * @see ReadOnlyIterator

+	 */

+	public static <E> ReadOnlyIterator<E> readOnlyIterator(Iterator<? extends E> iterator) {

+		return new ReadOnlyIterator<E>(iterator);

+	}

+

+	/**

+	 * Convert the specified list to read-only.

+	 * @see ReadOnlyListIterator

+	 */

+	public static <E> ReadOnlyListIterator<E> readOnlyListIterator(List<? extends E> list) {

+		return new ReadOnlyListIterator<E>(list);

+	}

+

+	/**

+	 * Convert the specified iterable to read-only.

+	 * @see ReadOnlyListIterator

+	 */

+	public static <E> ReadOnlyListIterator<E> readOnlyListIterator(ListIterable<? extends E> iterable) {

+		return new ReadOnlyListIterator<E>(iterable);

+	}

+

+	/**

+	 * Convert the specified iterator to read-only.

+	 * @see ReadOnlyListIterator

+	 */

+	public static <E> ReadOnlyListIterator<E> readOnlyListIterator(ListIterator<? extends E> iterator) {

+		return new ReadOnlyListIterator<E>(iterator);

+	}

+

+	/**

+	 * Return a transformer that transforms a {@link List} into a

+	 * read-only {@link ListIterator}.

+	 */

+	@SuppressWarnings("unchecked")

+	public static <E> Transformer<List<? extends E>, ListIterator<? extends E>> readOnlyListListIteratorTransformer() {

+		return READ_ONLY_LIST_LIST_ITERATOR_TRANSFORMER;

+	}

+

+	/**

+	 * A transformer that transforms a {@link List} into a

+	 * read-only {@link ListIterator}.

+	 */

+	@SuppressWarnings("rawtypes")

+	public static final Transformer READ_ONLY_LIST_LIST_ITERATOR_TRANSFORMER = new ReadOnlyListListIteratorTransformer();

+	/* CU private */ static class ReadOnlyListListIteratorTransformer<E>

+		implements Transformer<List<? extends E>, ListIterator<? extends E>>

+	{

+		@Override

+		public ListIterator<? extends E> transform(List<? extends E> list) {

+			return readOnlyListIterator(list);

+		}

+	}

+

+	/**

+	 * Return an iterator the returns the specified object the specified number

+	 * of times.

+	 * @see RepeatingElementIterator

+	 */

+	public static <E> RepeatingElementIterator<E> repeatingElementIterator(E element, int size) {

+		return new RepeatingElementIterator<E>(element, size);

+	}

+

+	/**

+	 * Return a list iterator the returns the specified object the specified number

+	 * of times.

+	 * @see RepeatingElementIterator

+	 */

+	public static <E> RepeatingElementListIterator<E> repeatingElementListIterator(E element, int size) {

+		return new RepeatingElementListIterator<E>(element, size);

+	}

+

+	/**

+	 * Return an iterator the returns the first object in each row of the

+	 * specified result set.

+	 * @see ResultSetIterator

+	 */

+	public static <E> ResultSetIterator<E> resultSetIterator(ResultSet resultSet) {

+		return new ResultSetIterator<E>(resultSet);

+	}

+

+	/**

+	 * Return an iterator the returns the objects produced by the specified adapter.

+	 * @see ResultSetIterator

+	 */

+	public static <E> ResultSetIterator<E> resultSetIterator(ResultSet resultSet, ResultSetIterator.Adapter<E> adapter) {

+		return new ResultSetIterator<E>(resultSet, adapter);

+	}

+

+	/**

+	 * Return an iterator that returns the objects in the specified iterable

+	 * in reverse order.

+	 */

+	public static <E> ReverseIterator<E> reverseIterator(Iterable<E> iterable) {

+		return new ReverseIterator<E>(iterable);

+	}

+

+	/**

+	 * Return an iterator that returns the objects in the specified iterable

+	 * in reverse order.

+	 */

+	public static <E> ReverseIterator<E> reverseIterator(Iterable<E> iterable, int iterableSize) {

+		return new ReverseIterator<E>(iterable, iterableSize);

+	}

+

+	/**

+	 * Return an iterator that returns the objects in the specified iterator

+	 * in reverse order.

+	 */

+	public static <E> ReverseIterator<E> reverseIterator(Iterator<E> iterator) {

+		return new ReverseIterator<E>(iterator);

+	}

+

+	/**

+	 * Return an iterator that returns the objects in the specified iterable

+	 * in reverse order.

+	 * The specified iterator size is a performance hint.

+	 */

+	public static <E> ReverseIterator<E> reverseIterator(Iterator<E> iterator, int iteratorSize) {

+		return new ReverseIterator<E>(iterator, iteratorSize);

+	}

+

+	/**

+	 * Return an iterator that provides simultaneous processing of the elements

+	 * in the specified iterators.

+	 * @see SimultaneousIterator

+	 */

+	public static <E, I extends Iterator<E>> SimultaneousIterator<E> simultaneousIterator(I... iterators) {

+		return new SimultaneousIterator<E>(iterators);

+	}

+

+	/**

+	 * Return an iterator that provides simultaneous processing of the elements

+	 * in the specified iterables.

+	 * @see SimultaneousIterator

+	 */

+	public static <E, I extends Iterator<E>> SimultaneousIterator<E> simultaneousIterator(Iterable<I> iterables) {

+		return new SimultaneousIterator<E>(iterables);

+	}

+

+	/**

+	 * Return an iterator that provides simultaneous processing of the elements

+	 * in the specified iterables.

+	 * @see SimultaneousIterator

+	 */

+	public static <E, I extends Iterator<E>> SimultaneousIterator<E> simultaneousIterator(Iterable<I> iterables, int iterablesSize) {

+		return new SimultaneousIterator<E>(iterables, iterablesSize);

+	}

+

+	/**

+	 * Return an iterator that provides simultaneous processing of the elements

+	 * in the specified iterators.

+	 * @see SimultaneousListIterator

+	 */

+	public static <E, I extends ListIterator<E>> SimultaneousListIterator<E> simultaneousListIterator(I... iterators) {

+		return new SimultaneousListIterator<E>(iterators);

+	}

+

+	/**

+	 * Return an iterator that provides simultaneous processing of the elements

+	 * in the specified iterables.

+	 * @see SimultaneousListIterator

+	 */

+	public static <E, I extends ListIterator<E>> SimultaneousListIterator<E> simultaneousListIterator(Iterable<I> iterables) {

+		return new SimultaneousListIterator<E>(iterables);

+	}

+

+	/**

+	 * Return an iterator that provides simultaneous processing of the elements

+	 * in the specified iterators.

+	 * @see SimultaneousListIterator

+	 */

+	public static <E, I extends ListIterator<E>> SimultaneousListIterator<E> simultaneousListIterator(Iterable<I> iterators, int iteratorsSize) {

+		return new SimultaneousListIterator<E>(iterators, iteratorsSize);

+	}

+

+	/**

+	 * Return an iterator that returns only the single,

+	 * specified object.

+	 * @see SingleElementIterator

+	 */

+	public static <E> SingleElementIterator<E> singletonIterator(E value) {

+		return new SingleElementIterator<E>(value);

+	}

+

+	/**

+	 * Return a list iterator that returns only the single,

+	 * specified object.

+	 * @see SingleElementListIterator

+	 */

+	public static <E> SingleElementListIterator<E> singletonListIterator(E value) {

+		return new SingleElementListIterator<E>(value);

+	}

+

+	/**

+	 * Return an iterator that converts the specified iterable's element type.

+	 * @see SubIteratorWrapper

+	 */

+	public static <E1, E2 extends E1> SubIteratorWrapper<E1, E2> subIterator(Iterable<E1> iterable) {

+		return new SubIteratorWrapper<E1, E2>(iterable);

+	}

+

+	/**

+	 * Return an iterator that converts the specified iterator's element type.

+	 * @see SubIteratorWrapper

+	 */

+	public static <E1, E2 extends E1> SubIteratorWrapper<E1, E2> subIterator(Iterator<E1> iterator) {

+		return new SubIteratorWrapper<E1, E2>(iterator);

+	}

+

+	/**

+	 * Return an iterator that converts the specified list's element type.

+	 * @see SubListIteratorWrapper

+	 */

+	public static <E1, E2 extends E1> SubListIteratorWrapper<E1, E2> subListIterator(List<E1> list) {

+		return new SubListIteratorWrapper<E1, E2>(list);

+	}

+

+	/**

+	 * Return an iterator that converts the specified iterable's element type.

+	 * @see SubListIteratorWrapper

+	 */

+	public static <E1, E2 extends E1> SubListIteratorWrapper<E1, E2> subListIterator(ListIterable<E1> iterable) {

+		return new SubListIteratorWrapper<E1, E2>(iterable);

+	}

+

+	/**

+	 * Return an iterator that converts the specified iterator's element type.

+	 * @see SubListIteratorWrapper

+	 */

+	public static <E1, E2 extends E1> SubListIteratorWrapper<E1, E2> subListIterator(ListIterator<E1> iterator) {

+		return new SubListIteratorWrapper<E1, E2>(iterator);

+	}

+

+	/**

+	 * Return an iterator that converts the specified iterable's element type.

+	 * @see SuperIteratorWrapper

+	 */

+	public static <E> Iterator<E> SuperIteratorWrapper(Iterable<? extends E> iterable) {

+		return new SuperIteratorWrapper<E>(iterable);

+	}

+

+	/**

+	 * Return an iterator that converts the specified iterator's element type.

+	 * @see SuperIteratorWrapper

+	 */

+	public static <E> Iterator<E> SuperIteratorWrapper(Iterator<? extends E> iterator) {

+		return new SuperIteratorWrapper<E>(iterator);

+	}

+

+	/**

+	 * Return an iterator that converts the specified list's element type.

+	 * @see SuperListIteratorWrapper

+	 */

+	public static <E> ListIterator<E> SuperListIteratorWrapper(List<? extends E> list) {

+		return new SuperListIteratorWrapper<E>(list);

+	}

+

+	/**

+	 * Return an iterator that converts the specified iterable's element type.

+	 * @see SuperListIteratorWrapper

+	 */

+	public static <E> ListIterator<E> SuperListIteratorWrapper(ListIterable<? extends E> iterable) {

+		return new SuperListIteratorWrapper<E>(iterable);

+	}

+

+	/**

+	 * Return an iterator that converts the specified iterator's element type.

+	 * @see SuperListIteratorWrapper

+	 */

+	public static <E> ListIterator<E> SuperListIteratorWrapper(ListIterator<? extends E> iterator) {

+		return new SuperListIteratorWrapper<E>(iterator);

+	}

+

+	/**

+	 * Return an iterator that synchronizes the specified iterable's iterator on itself.

+	 * @see SynchronizedIterator

+	 */

+	public static <E> SynchronizedIterator<E> synchronizedIterator(Iterable<? extends E> iterable) {

+		return new SynchronizedIterator<E>(iterable);

+	}

+

+	/**

+	 * Return an iterator that synchronizes the specified iterable's iterator with the

+	 * specified mutex.

+	 * @see SynchronizedIterator

+	 */

+	public static <E> SynchronizedIterator<E> synchronizedIterator(Iterable<? extends E> iterable, Object mutex) {

+		return new SynchronizedIterator<E>(iterable, mutex);

+	}

+

+	/**

+	 * Return an iterator that synchronizes the specified iterator on itself.

+	 * @see SynchronizedIterator

+	 */

+	public static <E> SynchronizedIterator<E> synchronizedIterator(Iterator<? extends E> iterator) {

+		return new SynchronizedIterator<E>(iterator);

+	}

+

+	/**

+	 * Return an iterator that synchronizes the specified iterator with the

+	 * specified mutex.

+	 * @see SynchronizedIterator

+	 */

+	public static <E> SynchronizedIterator<E> synchronizedIterator(Iterator<? extends E> iterator, Object mutex) {

+		return new SynchronizedIterator<E>(iterator, mutex);

+	}

+

+	/**

+	 * Return an iterator that synchronizes the specified list's iterator on itself.

+	 * @see SynchronizedListIterator

+	 */

+	public static <E> SynchronizedListIterator<E> synchronizedListIterator(List<E> list) {

+		return new SynchronizedListIterator<E>(list);

+	}

+

+	/**

+	 * Return an iterator that synchronizes the specified iterable's iterator on itself.

+	 * @see SynchronizedListIterator

+	 */

+	public static <E> SynchronizedListIterator<E> synchronizedListIterator(ListIterable<E> iterable) {

+		return new SynchronizedListIterator<E>(iterable);

+	}

+

+	/**

+	 * Return an iterator that synchronizes the specified iterable's iterator with the

+	 * specified mutex.

+	 * @see SynchronizedListIterator

+	 */

+	public static <E> SynchronizedListIterator<E> synchronizedListIterator(ListIterable<E> iterable, Object mutex) {

+		return new SynchronizedListIterator<E>(iterable, mutex);

+	}

+

+	/**

+	 * Return an iterator that synchronizes the specified iterator on itself.

+	 * @see SynchronizedListIterator

+	 */

+	public static <E> SynchronizedListIterator<E> synchronizedListIterator(ListIterator<E> iterator) {

+		return new SynchronizedListIterator<E>(iterator);

+	}

+

+	/**

+	 * Return an iterator that synchronizes the specified iterator with the

+	 * specified mutex.

+	 * @see SynchronizedListIterator

+	 */

+	public static <E> SynchronizedListIterator<E> synchronizedListIterator(ListIterator<E> iterator, Object mutex) {

+		return new SynchronizedListIterator<E>(iterator, mutex);

+	}

+

+	/**

+	 * Return an iterator that will use the specified transformer to transform the

+	 * elements in the specified iterable.

+	 * @see TransformationIterator

+	 */

+	public static <E1, E2> TransformationIterator<E1, E2> transformationIterator(Iterable<? extends E1> iterable, Transformer<E1, ? extends E2> transformer) {

+		return new TransformationIterator<E1, E2>(iterable, transformer);

+	}

+

+	/**

+	 * Return an iterator that will use the specified transformer to transform the

+	 * elements in the specified iterator.

+	 * @see TransformationIterator

+	 */

+	public static <E1, E2> TransformationIterator<E1, E2> transform(Iterator<? extends E1> iterator, Transformer<E1, ? extends E2> transformer) {

+		return new TransformationIterator<E1, E2>(iterator, transformer);

+	}

+

+	/**

+	 * Return an iterator that will use the specified transformer to transform the

+	 * elements in the specified list.

+	 * @see TransformationListIterator

+	 */

+	public static <E1, T1 extends E1, E2> TransformationListIterator<E1, E2> transformationListIterator(List<? extends E1> list, Transformer<E1, ? extends E2> transformer) {

+		return new TransformationListIterator<E1, E2>(list, transformer);

+	}

+

+	/**

+	 * Return an iterator that will use the specified transformer to transform the

+	 * elements in the specified iterable.

+	 * @see TransformationListIterator

+	 */

+	public static <E1, E2> TransformationListIterator<E1, E2> transformationListIterator(ListIterable<? extends E1> iterable, Transformer<E1, ? extends E2> transformer) {

+		return new TransformationListIterator<E1, E2>(iterable, transformer);

+	}

+

+	/**

+	 * Return an iterator that will use the specified transformer to transform the

+	 * elements in the specified iterator.

+	 * @see TransformationListIterator

+	 */

+	public static <E1, E2> TransformationListIterator<E1, E2> transform(ListIterator<? extends E1> iterator, Transformer<E1, ? extends E2> transformer) {

+		return new TransformationListIterator<E1, E2>(iterator, transformer);

+	}

+

+	/**

+	 * Construct an iterator that returns the nodes of a tree

+	 * with the specified root and transformer.

+	 * @see TreeIterator

+	 */

+	public static <E> TreeIterator<E> treeIterator(E root, Transformer<E, Iterator<? extends E>> transformer) {

+		return treeIterator(new SingleElementIterator<E>(root), transformer);

+	}

+

+	/**

+	 * Construct an iterator that returns the nodes of a tree

+	 * with the specified roots and transformer.

+	 * @see TreeIterator

+	 */

+	public static <E> TreeIterator<E> treeIterator(E[] roots, Transformer<E, Iterator<? extends E>> transformer) {

+		return treeIterator(new ArrayIterator<E>(roots), transformer);

+	}

+

+	/**

+	 * Construct an iterator that returns the nodes of a tree

+	 * with the specified roots and transformer.

+	 * @see TreeIterator

+	 */

+	public static <E> TreeIterator<E> treeIterator(Iterable<? extends E> roots, Transformer<E, Iterator<? extends E>> transformer) {

+		return treeIterator(roots.iterator(), transformer);

+	}

+

+	/**

+	 * Construct an iterator that returns the nodes of a tree

+	 * with the specified roots and transformer.

+	 * @see TreeIterator

+	 */

+	public static <E> TreeIterator<E> treeIterator(Iterator<? extends E> roots, Transformer<E, Iterator<? extends E>> transformer) {

+		return new TreeIterator<E>(roots, transformer);

+	}

+

+

+	// ********** constructor **********

+

+	/**

+	 * Suppress default constructor, ensuring non-instantiability.

+	 */

+	private IteratorTools() {

+		super();

+		throw new UnsupportedOperationException();

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/LateralIteratorWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/LateralIteratorWrapper.java
new file mode 100644
index 0000000..ffa758c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/LateralIteratorWrapper.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Wrap an iterator on elements of type <code>E1</code>, converting it into an
+ * iterator on elements of type <code>E2</code>. <em>Assume</em> the wrapped
+ * iterator returns only elements of type <code>E2</code>. The result is a
+ * {@link ClassCastException} if this assumption is false.
+ *
+ * @param <E1> input: the type of elements returned by the wrapped iterator
+ * @param <E2> output: the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.LateralIterableWrapper
+ * @see SubIteratorWrapper
+ */
+public class LateralIteratorWrapper<E1, E2>
+	implements Iterator<E2>
+{
+	private final Iterator<E1> iterator;
+
+
+	public LateralIteratorWrapper(Iterable<E1> iterable) {
+		this(iterable.iterator());
+	}
+
+	public LateralIteratorWrapper(Iterator<E1> iterator) {
+		super();
+		if (iterator == null) {
+			throw new NullPointerException();
+		}
+		this.iterator = iterator;
+	}
+
+	@Override
+	public boolean hasNext() {
+		return this.iterator.hasNext();
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public E2 next() {
+		return (E2) this.iterator.next();
+	}
+
+	@Override
+	public void remove() {
+		this.iterator.remove();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.iterator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/LateralListIteratorWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/LateralListIteratorWrapper.java
new file mode 100644
index 0000000..9c56017
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/LateralListIteratorWrapper.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
+/**
+ * Wrap a list iterator on elements of type <code>E1</code>, converting it into
+ * a list iterator on elements of type <code>E2</code>. <em>Assume</em> the
+ * wrapped list iterator returns only elements of type <code>E2</code>.
+ * The result is a {@link ClassCastException} if this assumption is false.
+ *
+ * @param <E1> input: the type of elements returned by the wrapped list iterator
+ * @param <E2> output: the type of elements returned by the list iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.LateralIterableWrapper
+ * @see SubListIteratorWrapper
+ */
+public class LateralListIteratorWrapper<E1, E2>
+	implements ListIterator<E2>
+{
+	final ListIterator<E1> listIterator;
+
+
+	public LateralListIteratorWrapper(List<E1> list) {
+		this(list.listIterator());
+	}
+
+	public LateralListIteratorWrapper(ListIterable<E1> listIterable) {
+		this(listIterable.iterator());
+	}
+
+	public LateralListIteratorWrapper(ListIterator<E1> iterator) {
+		super();
+		if (iterator == null) {
+			throw new NullPointerException();
+		}
+		this.listIterator = iterator;
+	}
+
+	@Override
+	public boolean hasNext() {
+		return this.listIterator.hasNext();
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public E2 next() {
+		return (E2) this.listIterator.next();
+	}
+
+	@Override
+	public int nextIndex() {
+		return this.listIterator.nextIndex();
+	}
+
+	@Override
+	public boolean hasPrevious() {
+		return this.listIterator.hasPrevious();
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public E2 previous() {
+		return (E2) this.listIterator.previous();
+	}
+
+	@Override
+	public int previousIndex() {
+		return this.listIterator.previousIndex();
+	}
+
+	@Override
+	public void remove() {
+		this.listIterator.remove();
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public void set(E2 e) {
+		this.listIterator.set((E1) e);
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public void add(E2 e) {
+		this.listIterator.add((E1) e);
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.listIterator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/NullElementIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/NullElementIterator.java
new file mode 100644
index 0000000..9fa524b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/NullElementIterator.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+/**
+ * A <code>NullElementIterator</code> provides an {@link java.util.Iterator}
+ * that returns a <code>null</code> a specific number of times.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.collection.NullElementList
+ */
+public class NullElementIterator<E>
+	extends AbstractRepeatingElementIterator<E>
+{
+	/**
+	 * Construct an iterator for the specified number of <code>null</code>s.
+	 */
+	public NullElementIterator(int size) {
+		super(size);
+	}
+
+	@Override
+	protected E getElement() {
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/NullElementListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/NullElementListIterator.java
new file mode 100644
index 0000000..27c54dd
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/NullElementListIterator.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+/**
+ * A <code>NullElementIterator</code> provides a {@link java.util.ListIterator}
+ * that returns a <code>null</code> a specific number of times.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.collection.NullElementList
+ */
+public class NullElementListIterator<E>
+	extends AbstractRepeatingElementListIterator<E>
+{
+	/**
+	 * Construct a list iterator for the specified number of <code>null</code>s.
+	 */
+	public NullElementListIterator(int size) {
+		super(size);
+	}
+
+	@Override
+	protected E getElement() {
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/PeekableIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/PeekableIterator.java
new file mode 100644
index 0000000..54c0a1b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/PeekableIterator.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * A <code>PeekableIterator</code> wraps another {@link Iterator}
+ * and allows a {@link #peek()} at the next element to be
+ * returned by {@link #next()}.
+ * <p>
+ * One, possibly undesirable, side-effect of using this iterator is that
+ * the nested iterator's <code>next()</code> method will be invoked
+ * <em>before</em> the peekable iterator's {@link #next()}
+ * method is invoked. This is because the "next" element must be
+ * pre-loaded for the {@link #peek()} method.
+ * This also prevents a peekable iterator from supporting the optional
+ * {@link #remove()} method.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.PeekableIterable
+ */
+public class PeekableIterator<E>
+	implements Iterator<E>
+{
+	private final Iterator<? extends E> iterator;
+	private E next;
+	private boolean done;
+
+
+	/**
+	 * Construct a peekable iterator that wraps the specified
+	 * iterable.
+	 */
+	public PeekableIterator(Iterable<? extends E> iterable) {
+		this(iterable.iterator());
+	}
+
+	/**
+	 * Construct a peekable iterator that wraps the specified nested
+	 * iterator.
+	 */
+	public PeekableIterator(Iterator<? extends E> iterator) {
+		super();
+		if (iterator == null) {
+			throw new NullPointerException();
+		}
+		this.iterator = iterator;
+		this.done = false;
+		this.loadNext();
+	}
+
+	@Override
+	public boolean hasNext() {
+		return ! this.done;
+	}
+
+	@Override
+	public E next() {
+		if (this.done) {
+			throw new NoSuchElementException();
+		}
+		E result = this.next;
+		this.loadNext();
+		return result;
+	}
+
+	/**
+	 * Return the element that will be returned by the next call to the
+	 * {@link #next()} method, without advancing past it.
+	 */
+	public E peek() {
+		if (this.done) {
+			throw new NoSuchElementException();
+		}
+		return this.next;
+	}
+
+	/**
+	 * Because we need to pre-load the next element
+	 * to be returned, we cannot support the {@link #remove()}
+	 * method.
+	 */
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Load next with the next entry from the nested
+	 * iterator. If there are none, {@link #next} is set to <code>null</code>
+	 * and {@link #done} is set to <code>true</code>.
+	 */
+	private void loadNext() {
+		if (this.iterator.hasNext()) {
+			this.next = this.iterator.next();
+		} else {
+			this.next = null;
+			this.done = true;
+		}
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.iterator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/QueueIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/QueueIterator.java
new file mode 100644
index 0000000..dc7c928
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/QueueIterator.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.Queue;
+
+/**
+ * A <code>QueueIterator</code> provides an {@link Iterator}
+ * for a {@link Queue} of objects of type <code>E</code>. The queue's elements
+ * are {@link Queue#dequeue() dequeued}" as the iterator returns them with
+ * calls to {@link #next()}.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see Queue
+ * @see org.eclipse.jpt.common.utility.internal.iterable.QueueIterable
+ */
+public class QueueIterator<E>
+	implements Iterator<E>
+{
+	private final Queue<E> queue;
+
+
+	/**
+	 * Construct an iterator for the specified queue.
+	 */
+	public QueueIterator(Queue<E> queue) {
+		super();
+		if (queue == null) {
+			throw new NullPointerException();
+		}
+		this.queue = queue;
+	}
+
+	@Override
+	public boolean hasNext() {
+		return ! this.queue.isEmpty();
+	}
+
+	@Override
+	public E next() {
+		return this.queue.dequeue();
+	}
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.queue);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ReadOnlyCompositeListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ReadOnlyCompositeListIterator.java
new file mode 100644
index 0000000..80704ed
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ReadOnlyCompositeListIterator.java
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
+/**
+ * A <code>ReadOnlyCompositeListIterator</code> wraps a list
+ * of {@link ListIterator}s and makes them appear to be a single
+ * read-only {@link ListIterator}. A read-only composite list
+ * iterator is more flexible than a normal composite list iterator when it
+ * comes to the element types of the nested iterators.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.ReadOnlyCompositeListIterable
+ */
+public class ReadOnlyCompositeListIterator<E>
+	implements ListIterator<E>
+{
+	private final ListIterator<? extends ListIterator<? extends E>> iterators;
+	private ListIterator<? extends E> nextIterator;
+	private int nextIndex;
+
+
+	/**
+	 * Construct a read-only list iterator with the specified list of lists.
+	 */
+	public ReadOnlyCompositeListIterator(List<? extends List<? extends E>> lists) {
+		this(
+			new TransformationListIterator<List<? extends E>, ListIterator<? extends E>>(lists.listIterator()) {
+				@Override
+				protected ListIterator<? extends E> transform(List<? extends E> list) {
+					return list.listIterator();
+				}
+			}
+		);
+	}
+
+	/**
+	 * Construct a read-only list iterator with the specified list of lists.
+	 */
+	public ReadOnlyCompositeListIterator(ListIterable<? extends ListIterable<? extends E>> iterables) {
+		this(
+			new TransformationListIterator<ListIterable<? extends E>, ListIterator<? extends E>>(iterables.iterator()) {
+				@Override
+				protected ListIterator<? extends E> transform(ListIterable<? extends E> iterable) {
+					return iterable.iterator();
+				}
+			}
+		);
+	}
+
+	/**
+	 * Construct a read-only list iterator with the specified list of
+	 * list iterators.
+	 */
+	public ReadOnlyCompositeListIterator(ListIterator<? extends ListIterator<? extends E>> iterators) {
+		super();
+		if (iterators == null) {
+			throw new NullPointerException();
+		}
+		this.iterators = iterators;
+		this.nextIndex = 0;
+	}
+
+	/**
+	 * Construct a read-only list iterator with the specified object prepended
+	 * to the specified list.
+	 */
+	public ReadOnlyCompositeListIterator(E object, List<? extends E> list) {
+		this(object, list.listIterator());
+	}
+
+	/**
+	 * Construct a read-only list iterator with the specified object prepended
+	 * to the specified list.
+	 */
+	public ReadOnlyCompositeListIterator(E object, ListIterable<? extends E> iterable) {
+		this(object, iterable.iterator());
+	}
+
+	/**
+	 * Construct a read-only list iterator with the specified object prepended
+	 * to the specified iterator.
+	 */
+	@SuppressWarnings("unchecked")
+	public ReadOnlyCompositeListIterator(E object, ListIterator<? extends E> iterator) {
+		this(new SingleElementListIterator<E>(object), iterator);
+	}
+
+	/**
+	 * Construct a read-only list iterator with the specified object appended
+	 * to the specified list.
+	 */
+	public ReadOnlyCompositeListIterator(List<? extends E> list, E object) {
+		this(list.listIterator(), object);
+	}
+
+	/**
+	 * Construct a read-only list iterator with the specified object appended
+	 * to the specified list.
+	 */
+	public ReadOnlyCompositeListIterator(ListIterable<? extends E> iterable, E object) {
+		this(iterable.iterator(), object);
+	}
+
+	/**
+	 * Construct a read-only list iterator with the specified object appended
+	 * to the specified iterator.
+	 */
+	@SuppressWarnings("unchecked")
+	public ReadOnlyCompositeListIterator(ListIterator<? extends E> iterator, E object) {
+		this(iterator, new SingleElementListIterator<E>(object));
+	}
+
+	/**
+	 * Construct a read-only list iterator with the specified lists.
+	 */
+	public ReadOnlyCompositeListIterator(List<? extends E>... lists) {
+		this(Arrays.asList(lists));
+	}
+
+	/**
+	 * Construct a read-only list iterator with the specified lists.
+	 */
+	public ReadOnlyCompositeListIterator(ListIterable<? extends E>... iterables) {
+		this(new ArrayListIterable<ListIterable<? extends E>>(iterables));
+	}
+
+	/**
+	 * Construct a read-only list iterator with the specified list iterators.
+	 */
+	public ReadOnlyCompositeListIterator(ListIterator<? extends E>... iterators) {
+		this(new ArrayListIterator<ListIterator<? extends E>>(iterators));
+	}
+
+	@Override
+	public boolean hasNext() {
+		try {
+			this.loadNextIterator();
+		} catch (NoSuchElementException ex) {
+			// this occurs if there are no iterators at all
+			return false;
+		}
+		return this.nextIterator.hasNext();
+	}
+
+	@Override
+	public boolean hasPrevious() {
+		try {
+			this.loadPreviousIterator();
+		} catch (NoSuchElementException ex) {
+			// this occurs if there are no iterators at all
+			return false;
+		}
+		return this.nextIterator.hasPrevious();
+	}
+
+	@Override
+	public E next() {
+		this.loadNextIterator();
+		E result = this.nextIterator.next();
+
+		// the statement above will throw a NoSuchElementException
+		// if the current iterator is at the end of the line;
+		// so if we get here, we can increment 'nextIndex'
+		this.nextIndex++;
+
+		return result;
+	}
+
+	@Override
+	public int nextIndex() {
+		return this.nextIndex;
+	}
+
+	@Override
+	public E previous() {
+		this.loadPreviousIterator();
+		E result = this.nextIterator.previous();
+
+		// the statement above will throw a NoSuchElementException
+		// if the current iterator is at the end of the line;
+		// so if we get here, we can decrement 'nextIndex'
+		this.nextIndex--;
+
+		return result;
+	}
+
+	@Override
+	public int previousIndex() {
+		return this.nextIndex  - 1;
+	}
+
+	@Override
+	public void add(E o) {
+		// the list iterator is read-only
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void remove() {
+		// the list iterator is read-only
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void set(E e) {
+		// the list iterator is read-only
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Load {@link #nextIterator} with the first iterator that {@link #hasNext()}
+	 * or the final iterator if all the elements have already been retrieved.
+	 */
+	private void loadNextIterator() {
+		this.checkNextIterator();
+		while (( ! this.nextIterator.hasNext()) && this.iterators.hasNext()) {
+			this.nextIterator = this.iterators.next();
+		}
+	}
+
+	/**
+	 * Load {@link #nextIterator} with the first iterator that {@link #hasPrevious()}
+	 * or the first iterator if all the elements have already been retrieved.
+	 */
+	private void loadPreviousIterator() {
+		this.checkNextIterator();
+		while (( ! this.nextIterator.hasPrevious()) && this.iterators.hasPrevious()) {
+			this.nextIterator = this.iterators.previous();
+		}
+	}
+
+	/**
+	 * If {@link #nextIterator} is null, load it with the first iterator.
+	 */
+	private void checkNextIterator() {
+		if (this.nextIterator == null) {
+			this.nextIterator = this.iterators.next();
+		}
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.iterators);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ReadOnlyIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ReadOnlyIterator.java
new file mode 100644
index 0000000..ec333b4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ReadOnlyIterator.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * A <code>ReadOnlyIterator</code> wraps another {@link Iterator}
+ * and removes support for {@link #remove()}.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.ReadOnlyIterable
+ */
+public class ReadOnlyIterator<E>
+	implements Iterator<E>
+{
+	private final Iterator<? extends E> iterator;
+
+	/**
+	 * Construct an iterator on the specified collection that
+	 * disallows removes.
+	 */
+	public ReadOnlyIterator(Iterable<? extends E> c) {
+		this(c.iterator());
+	}
+
+	/**
+	 * Construct an iterator with the specified nested iterator
+	 * and disallow removes.
+	 */
+	public ReadOnlyIterator(Iterator<? extends E> iterator) {
+		super();
+		if (iterator == null) {
+			throw new NullPointerException();
+		}
+		this.iterator = iterator;
+	}
+
+	@Override
+	public boolean hasNext() {
+		// delegate to the nested iterator
+		return this.iterator.hasNext();
+	}
+
+	@Override
+	public E next() {
+		// delegate to the nested iterator
+		return this.iterator.next();
+	}
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.iterator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ReadOnlyListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ReadOnlyListIterator.java
new file mode 100644
index 0000000..1c4dc5b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ReadOnlyListIterator.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
+/**
+ * A <code>ReadOnlyListIterator</code> wraps another
+ * {@link ListIterator} and removes support for:<ul>
+ * <li>{@link #remove()}
+ * 	<li>{@link #set(Object)}
+ * 	<li>{@link #add(Object)}
+ * </ul>
+ *
+ * @param <E> the type of elements returned by the list iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.ReadOnlyListIterable
+ */
+public class ReadOnlyListIterator<E>
+	implements ListIterator<E>
+{
+	private final ListIterator<? extends E> listIterator;
+
+
+	/**
+	 * Construct a list iterator on the specified list that
+	 * disallows removes, sets, and adds.
+	 */
+	public ReadOnlyListIterator(List<? extends E> list) {
+		this(list.listIterator());
+	}
+
+	/**
+	 * Construct a list iterator on the specified list that
+	 * disallows removes, sets, and adds.
+	 */
+	public ReadOnlyListIterator(ListIterable<? extends E> listIterable) {
+		this(listIterable.iterator());
+	}
+
+	/**
+	 * Construct a list iterator on the specified list iterator that
+	 * disallows removes, sets, and adds.
+	 */
+	public ReadOnlyListIterator(ListIterator<? extends E> listIterator) {
+		super();
+		if (listIterator == null) {
+			throw new NullPointerException();
+		}
+		this.listIterator = listIterator;
+	}
+
+	@Override
+	public boolean hasNext() {
+		// delegate to the nested iterator
+		return this.listIterator.hasNext();
+	}
+
+	@Override
+	public E next() {
+		// delegate to the nested iterator
+		return this.listIterator.next();
+	}
+
+	@Override
+	public boolean hasPrevious() {
+		// delegate to the nested iterator
+		return this.listIterator.hasPrevious();
+	}
+
+	@Override
+	public E previous() {
+		// delegate to the nested iterator
+		return this.listIterator.previous();
+	}
+
+	@Override
+	public int nextIndex() {
+		// delegate to the nested iterator
+		return this.listIterator.nextIndex();
+	}
+
+	@Override
+	public int previousIndex() {
+		// delegate to the nested iterator
+		return this.listIterator.previousIndex();
+	}
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void set(E o) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void add(E o) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.listIterator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/RepeatingElementIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/RepeatingElementIterator.java
new file mode 100644
index 0000000..40008d3
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/RepeatingElementIterator.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+/**
+ * A <code>RepeatingElementIterator</code> provides an {@link java.util.Iterator}
+ * that returns a specific object a specific number of times.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.collection.RepeatingElementList
+ */
+public class RepeatingElementIterator<E>
+	extends AbstractRepeatingElementIterator<E>
+{
+	private final E element;
+
+
+	public RepeatingElementIterator(E element, int size) {
+		super(size);
+		this.element = element;
+	}
+
+	@Override
+	protected E getElement() {
+		return this.element;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/RepeatingElementListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/RepeatingElementListIterator.java
new file mode 100644
index 0000000..6ef227a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/RepeatingElementListIterator.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+/**
+ * A <code>RepeatingElementListIterator</code> provides a {@link java.util.ListIterator}
+ * that returns a specific object a specific number of times.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.collection.RepeatingElementList
+ */
+public class RepeatingElementListIterator<E>
+	extends AbstractRepeatingElementListIterator<E>
+{
+	private final E element;
+
+
+	public RepeatingElementListIterator(E element, int size) {
+		super(size);
+		this.element = element;
+	}
+
+	@Override
+	protected E getElement() {
+		return this.element;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ResultSetIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ResultSetIterator.java
new file mode 100644
index 0000000..e2b0adf
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ResultSetIterator.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * A <code>ResultSetIterator</code> wraps an SQL {@link ResultSet}
+ * and transforms its rows for client consumption. Subclasses can override
+ * {@link #buildNext(ResultSet)} to build the expected object from
+ * the current row of the result set.
+ * <p>
+ * To use, supply:<ul>
+ * <li> a {@link ResultSet}
+ * <li> an {@link Adapter} that converts a row in the {@link ResultSet}
+ * into the desired object
+ * (alternatively, subclass <code>ResultSetIterator</code>
+ * and override the {@link #buildNext(ResultSet)} method)
+ * </ul>
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see java.sql.ResultSet
+ */
+public class ResultSetIterator<E>
+	implements Iterator<E>
+{
+	private final ResultSet resultSet;
+	private final Adapter<E> adapter;
+	private E next;
+	private boolean done;
+
+
+	/**
+	 * Construct an iterator on the specified result set that returns
+	 * the objects produced by the specified adapter.
+	 */
+	public ResultSetIterator(ResultSet resultSet, Adapter<E> adapter) {
+		super();
+		if ((resultSet == null) || (adapter == null)) {
+			throw new NullPointerException();
+		}
+		this.resultSet = resultSet;
+		this.adapter = adapter;
+		this.done = false;
+		this.next = this.buildNext();
+	}
+
+	/**
+	 * Construct an iterator on the specified result set that returns
+	 * the first object in each row of the result set.
+	 */
+	public ResultSetIterator(ResultSet resultSet) {
+		this(resultSet, Adapter.Default.<E>instance());
+	}
+
+	/**
+	 * Build the next object for the iterator to return.
+	 * Close the result set when we reach the end.
+	 */
+	private E buildNext() {
+		try {
+			if (this.resultSet.next()) {
+				return this.buildNext(this.resultSet);
+			}
+			this.resultSet.close();
+			this.done = true;
+			return null;
+		} catch (SQLException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+	/**
+	 * By default, return the first object in the current row
+	 * of the result set. Any {@link SQLException}s will
+	 * be caught and wrapped in a {@link RuntimeException}.
+	 */
+	protected E buildNext(ResultSet rs) throws SQLException {
+		return this.adapter.buildNext(rs);
+	}
+
+	@Override
+	public boolean hasNext() {
+		return ! this.done;
+	}
+
+	@Override
+	public E next() {
+		if (this.done) {
+			throw new NoSuchElementException();
+		}
+		E temp = this.next;
+		this.next = this.buildNext();
+		return temp;
+	}
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.resultSet);
+	}
+
+
+	// ********** interface **********
+
+	/**
+	 * Used by {@link ResultSetIterator} to convert a
+	 * {@link ResultSet}'s current row into the next object
+	 * to be returned by the {@link Iterator}.
+	 */
+	public interface Adapter<T> {
+
+		/**
+		 * Return an object corresponding to the result set's
+		 * "current" row. Any {@link SQLException}s will
+		 * be caught and wrapped in a {@link RuntimeException}.
+		 * @see java.sql.ResultSet
+		 */
+		T buildNext(ResultSet rs) throws SQLException;
+
+
+		final class Default<S>
+			implements Adapter<S>, Serializable
+		{
+			@SuppressWarnings("rawtypes")
+			public static final Adapter INSTANCE = new Default();
+			@SuppressWarnings("unchecked")
+			public static <R> Adapter<R> instance() {
+				return INSTANCE;
+			}
+			// ensure single instance
+			private Default() {
+				super();
+			}
+			// return the first object in the current row of the result set
+			@Override
+			@SuppressWarnings("unchecked")
+			public S buildNext(ResultSet rs) throws SQLException {
+				// result set columns are indexed starting with 1
+				return (S) rs.getObject(1);
+			}
+			@Override
+			public String toString() {
+				return ObjectTools.singletonToString(this);
+			}
+			private static final long serialVersionUID = 1L;
+			private Object readResolve() {
+				// replace this object with the singleton
+				return INSTANCE;
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ReverseIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ReverseIterator.java
new file mode 100644
index 0000000..8428a8b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/ReverseIterator.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+
+/**
+ * A <code>ReverseIterator</code> wraps another {@link Iterator} and returns
+ * its elements in the reverse order in which the wrapped {@link Iterator}
+ * returns the elements.
+ *
+ * @param <E> the type of elements returned by the iterator
+ */
+public class ReverseIterator<E>
+	implements Iterator<E>
+{
+	/**
+	 * The elements in this iterator are already reversed.
+	 */
+	private final Iterator<E> iterator;
+
+
+	/**
+	 * Construct a reverse iterator for the specified iterator.
+	 */
+	public ReverseIterator(Iterator<E> iterator) {
+		this((ArrayList<E>) ListTools.reverse(ListTools.list(iterator)));
+	}
+
+	/**
+	 * Construct a reverse iterator for the specified iterator.
+	 */
+	public ReverseIterator(Iterator<E> iterator, int size) {
+		this((ArrayList<E>) ListTools.reverse(ListTools.list(iterator, size)));
+	}
+
+	/**
+	 * Construct a reverse iterator for the specified iterable.
+	 */
+	public ReverseIterator(Iterable<E> iterable) {
+		this((ArrayList<E>) ListTools.reverse(ListTools.list(iterable)));
+	}
+
+	/**
+	 * Construct a reverse iterator for the specified iterable.
+	 */
+	public ReverseIterator(Iterable<E> iterable, int size) {
+		this((ArrayList<E>) ListTools.reverse(ListTools.list(iterable, size)));
+	}
+
+	private ReverseIterator(ArrayList<E> reverseList) {
+		super();
+		this.iterator = reverseList.iterator();
+	}
+
+	@Override
+	public boolean hasNext() {
+		return this.iterator.hasNext();
+	}
+
+	@Override
+	public E next() {
+		return this.iterator.next();
+	}
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SimultaneousIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SimultaneousIterator.java
new file mode 100644
index 0000000..2fa8047
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SimultaneousIterator.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+
+/**
+ * A <code>SimultaneousIterator</code> provides an {@link Iterator}
+ * for the simultaneous processing of a set of {@link Iterator}s
+ * of objects of type <code>E</code>. Each call to {@link #next()}
+ * returns a {@link java.util.List List} of elements of type <code>E</code>. The elements
+ * in the list are in the same order as the order of the {@link Iterator}s
+ * passed to the simultaneous iterator's constructor. The simultaneous iterator
+ * will return as many lists as there are elements returned by <em>all</em>
+ * the nested {@link Iterator}s. Any elements returned by {@link Iterator}s
+ * that are longer than the shortest of the {@link Iterator}s will be ignored.
+ * If an empty list of {@link Iterator}s is passed to the simultaneuous
+ * iterator's constructor, the resulting iterator will be empty.
+ *
+ * @param <E> the type of elements returned by the nested iterators
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.SimultaneousIterable
+ */
+public class SimultaneousIterator<E>
+	extends AbstractSimultaneousIterator<E, Iterator<E>>
+{
+	/**
+	 * Construct a "simultaneous" iterator for the specified iterators.
+	 */
+	public <I extends Iterator<E>> SimultaneousIterator(I... iterators) {
+		super(iterators);
+	}
+
+	/**
+	 * Construct a "simultaneous" iterator for the specified iterators.
+	 */
+	public <I extends Iterator<E>> SimultaneousIterator(Iterable<I> iterators) {
+		super(iterators);
+	}
+
+	/**
+	 * Construct a "simultaneous" iterator for the specified iterators.
+	 * Use the specified size as a performance hint.
+	 */
+	public <I extends Iterator<E>> SimultaneousIterator(Iterable<I> iterators, int iteratorsSize) {
+		super(iterators, iteratorsSize);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SimultaneousListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SimultaneousListIterator.java
new file mode 100644
index 0000000..8df0ece
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SimultaneousListIterator.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+
+/**
+ * A <code>SimultaneousListIterator</code> provides a {@link ListIterator}
+ * for the simultaneous processing of a set of {@link ListIterator}s
+ * of objects of type <code>E</code>. Each call to {@link #next()}
+ * returns a {@link List} of elements of type <code>E</code>. The elements
+ * in the list are in the same order as the order of the {@link ListIterator}s
+ * passed to the simultaneous iterator's constructor. The simultaneous list iterator
+ * will return as many lists as there are elements returned by <em>all</em>
+ * the nested {@link ListIterator}s. Any elements returned by {@link ListIterator}s
+ * that are longer than the shortest of the {@link ListIterator}s will be ignored.
+ * If an empty list of {@link ListIterator}s is passed to the simultaneuous
+ * list iterator's constructor, the resulting list iterator will be empty.
+ *
+ * @param <E> the type of elements returned by the nested iterators
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.SimultaneousListIterable
+ */
+@SuppressWarnings("nls")
+public class SimultaneousListIterator<E>
+	extends AbstractSimultaneousIterator<E, ListIterator<E>>
+	implements ListIterator<List<E>>
+{
+	/**
+	 * Construct a "simultaneous" list iterator for the specified list iterators.
+	 */
+	public <I extends ListIterator<E>> SimultaneousListIterator(I... iterators) {
+		super(iterators);
+	}
+
+	/**
+	 * Construct a "simultaneous" list iterator for the specified list iterators.
+	 */
+	public <I extends ListIterator<E>> SimultaneousListIterator(Iterable<I> iterators) {
+		super(iterators);
+	}
+
+	/**
+	 * Construct a "simultaneous" list iterator for the specified list iterators.
+	 * Use the specified size as a performance hint.
+	 */
+	public <I extends ListIterator<E>> SimultaneousListIterator(Iterable<I> iterators, int iteratorsSize) {
+		super(iterators, iteratorsSize);
+	}
+
+	@Override
+	public int nextIndex() {
+		// get the index from the first iterator
+		return this.iteratorsIsEmpty() ? 0 : this.iterators.iterator().next().nextIndex();
+	}
+
+	@Override
+	public boolean hasPrevious() {
+		if (this.iteratorsIsEmpty()) {
+			return false;
+		}
+		for (ListIterator<E> iterator : this.iterators) {
+			if ( ! iterator.hasPrevious()) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	@Override
+	public List<E> previous() {
+		if (this.iteratorsIsEmpty()) {
+			throw new NoSuchElementException();
+		}
+		ArrayList<E> result = this.buildList();
+		for (ListIterator<E> iterator : this.iterators) {
+			result.add(iterator.next());
+		}
+		return result;
+	}
+
+	@Override
+	public int previousIndex() {
+		// get the index from the first iterator
+		return this.iteratorsIsEmpty() ? -1 : this.iterators.iterator().next().previousIndex();
+	}
+
+	@Override
+	public void add(List<E> elements) {
+		this.checkElements(elements);
+		Iterator<E> addElements = elements.iterator();
+		for (ListIterator<E> iterator : this.iterators) {
+			iterator.add(addElements.next());
+		}
+	}
+
+	@Override
+	public void set(List<E> elements) {
+		this.checkElements(elements);
+		Iterator<E> setElements = elements.iterator();
+		for (ListIterator<E> iterator : this.iterators) {
+			iterator.set(setElements.next());
+		}
+	}
+
+	private void checkElements(List<E> elements) {
+		if (elements.size() != this.iteratorsSize()) {
+			throw new IllegalArgumentException("invalid elements: " + elements);
+		}
+	}
+
+	private int iteratorsSize() {
+		return IterableTools.size(this.iterators);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SingleElementIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SingleElementIterator.java
new file mode 100644
index 0000000..02cc243
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SingleElementIterator.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * A <code>SingleElementIterator</code> holds a single element
+ * and returns it with the first call to {@link #next()}, at
+ * which point it will return <code>false</code> to any subsequent
+ * call to {@link #hasNext()}.
+ * <p>
+ * A <code>SingleElementIterator</code> is equivalent to the
+ * {@link Iterator} returned by:
+ * 	{@link java.util.Collections#singleton(Object element)}<code>.iterator()</code>
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.SingleElementIterable
+ */
+public class SingleElementIterator<E>
+	implements Iterator<E>
+{
+	private final E element;
+	private boolean done;
+
+
+	/**
+	 * Construct an iterator that returns only the specified element.
+	 */
+	public SingleElementIterator(E element) {
+		super();
+		this.element = element;
+		this.done = false;
+	}
+
+	@Override
+	public boolean hasNext() {
+		return ! this.done;
+	}
+
+	@Override
+	public E next() {
+		if (this.done) {
+			throw new NoSuchElementException();
+		}
+		this.done = true;
+		return this.element;
+	}
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.element);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SingleElementListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SingleElementListIterator.java
new file mode 100644
index 0000000..bfead77
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SingleElementListIterator.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * A <code>SingleElementListIterator</code> holds a single element
+ * and returns it with the first call to {@link #next()}, at
+ * which point it will return <code>false</code> to any subsequent
+ * call to {@link #hasNext()}. Likewise, it will return <code>false</code>
+ * to a call to {@link #hasPrevious()} until a call to {@link #next()},
+ * at which point a call to {@link #previous()} will return the
+ * single element.
+ * <p>
+ * A <code>SingleElementListIterator</code> is equivalent to the
+ * {@link ListIterator} returned by:
+ * 	{@link java.util.Collections#singletonList(Object element)}<code>.listIterator()</code>
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.SingleElementListIterable
+ */
+public class SingleElementListIterator<E>
+	implements ListIterator<E>
+{
+	private final E element;
+	private boolean hasNext;
+
+
+	/**
+	 * Construct a list iterator that returns only the specified element.
+	 */
+	public SingleElementListIterator(E element) {
+		super();
+		this.element = element;
+		this.hasNext = true;
+	}
+
+	@Override
+	public boolean hasNext() {
+		return this.hasNext;
+	}
+
+	@Override
+	public E next() {
+		if (this.hasNext) {
+			this.hasNext = false;
+			return this.element;
+		}
+		throw new NoSuchElementException();
+	}
+
+	@Override
+	public int nextIndex() {
+		return this.hasNext ? 0 : 1;
+	}
+
+	@Override
+	public boolean hasPrevious() {
+		return ! this.hasNext;
+	}
+
+	@Override
+	public E previous() {
+		if (this.hasNext) {
+			throw new NoSuchElementException();
+		}
+		this.hasNext = true;
+		return this.element;
+	}
+
+	@Override
+	public int previousIndex() {
+		return this.hasNext ? -1 : 0;
+	}
+
+	@Override
+	public void add(E e) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void set(E e) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.element);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/StackIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/StackIterator.java
new file mode 100644
index 0000000..d693963
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/StackIterator.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.Stack;
+
+/**
+ * A <code>StackIterator</code> provides an {@link Iterator}
+ * for a {@link Stack} of objects of type <code>E</code>. The stack's elements
+ * are {@link Stack#pop() pop}ped" as the iterator returns them with
+ * calls to {@link #next()}.
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see Stack
+ * @see org.eclipse.jpt.common.utility.internal.iterable.StackIterable
+ */
+public class StackIterator<E>
+	implements Iterator<E>
+{
+	private final Stack<E> stack;
+
+
+	/**
+	 * Construct an iterator for the specified stack.
+	 */
+	public StackIterator(Stack<E> stack) {
+		super();
+		this.stack = stack;
+	}
+
+	@Override
+	public boolean hasNext() {
+		return ! this.stack.isEmpty();
+	}
+
+	@Override
+	public E next() {
+		return this.stack.pop();
+	}
+
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.stack);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SubIteratorWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SubIteratorWrapper.java
new file mode 100644
index 0000000..2cfbc68
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SubIteratorWrapper.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+
+/**
+ * Wrap an iterator on elements of type <code>E1</code>, converting it into an
+ * iterator on elements of type <code>E2</code>. <em>Assume</em> the wrapped
+ * iterator returns only elements of type <code>E2</code>. The result is a
+ * {@link ClassCastException} if this assumption is false.
+ * <p>
+ * This is a {@link LateralIteratorWrapper} with more restrictive type
+ * parameters.
+ *
+ * @param <E1> input: the type of elements returned by the wrapped iterator
+ * @param <E2> output: the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.SubIterableWrapper
+ */
+public class SubIteratorWrapper<E1, E2 extends E1>
+	extends LateralIteratorWrapper<E1, E2>
+{
+	public SubIteratorWrapper(Iterable<E1> iterable) {
+		super(iterable);
+	}
+
+	public SubIteratorWrapper(Iterator<E1> iterator) {
+		super(iterator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SubListIteratorWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SubListIteratorWrapper.java
new file mode 100644
index 0000000..3dbf403
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SubListIteratorWrapper.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
+/**
+ * Wrap a list iterator on elements of type <code>E1</code>, converting it into
+ * a list iterator on elements of type <code>E2</code>. <em>Assume</em> the
+ * wrapped list iterator returns only elements of type <code>E2</code>.
+ * The result is a {@link ClassCastException} if this assumption is false.
+ * <p>
+ * This is a {@link LateralListIteratorWrapper} with more restrictive type
+ * parameters.
+ *
+ * @param <E1> input: the type of elements returned by the wrapped list iterator
+ * @param <E2> output: the type of elements returned by the list iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.SubListIterableWrapper
+ */
+public class SubListIteratorWrapper<E1, E2 extends E1>
+	extends LateralListIteratorWrapper<E1, E2>
+{
+	public SubListIteratorWrapper(List<E1> list) {
+		super(list);
+	}
+
+	public SubListIteratorWrapper(ListIterable<E1> listIterable) {
+		super(listIterable);
+	}
+
+	public SubListIteratorWrapper(ListIterator<E1> iterator) {
+		super(iterator);
+	}
+
+	@Override
+	public void set(E2 e) {
+		// no explicit cast necessary
+		this.listIterator.set(e);
+	}
+
+	@Override
+	public void add(E2 e) {
+		// no explicit cast necessary
+		this.listIterator.add(e);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SuperIteratorWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SuperIteratorWrapper.java
new file mode 100644
index 0000000..6fd69e0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SuperIteratorWrapper.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Wrap an iterator on elements of any sub-type of <code>E</code>, converting
+ * it into a iterator on elements of type <code>E</code>. This shouldn't be a
+ * problem since there is no way to add invalid elements to the iterator's
+ * backing collection. (Note the lack of compiler warnings, suppressed or
+ * otherwise.)
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.SuperIterableWrapper
+ */
+public class SuperIteratorWrapper<E>
+	implements Iterator<E>
+{
+	private final Iterator<? extends E> iterator;
+
+
+	public SuperIteratorWrapper(Iterable<? extends E> iterable) {
+		this(iterable.iterator());
+	}
+
+	public SuperIteratorWrapper(Iterator<? extends E> iterator) {
+		super();
+		if (iterator == null) {
+			throw new NullPointerException();
+		}
+		this.iterator = iterator;
+	}
+
+	@Override
+	public boolean hasNext() {
+		return this.iterator.hasNext();
+	}
+
+	@Override
+	public E next() {
+		return this.iterator.next();
+	}
+
+	@Override
+	public void remove() {
+		this.iterator.remove();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.iterator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SuperListIteratorWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SuperListIteratorWrapper.java
new file mode 100644
index 0000000..646f02c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SuperListIteratorWrapper.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
+/**
+ * Wrap a list iterator on elements of any sub-type of <code>E</code>,
+ * converting it into a <em>non-writable</em> list iterator on elements of type
+ * <code>E</code>. This shouldn't be a problem since the
+ * resulting list iterator disables the methods that would put invalid elements
+ * in the iterator's backing list (i.e. {@link #set(Object)} and {@link #add(Object)}).
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.SuperListIterableWrapper
+ */
+public class SuperListIteratorWrapper<E>
+	implements ListIterator<E>
+{
+	private final ListIterator<? extends E> listIterator;
+
+
+	public SuperListIteratorWrapper(List<? extends E> list) {
+		this(list.listIterator());
+	}
+
+	public SuperListIteratorWrapper(ListIterable<? extends E> listIterable) {
+		this(listIterable.iterator());
+	}
+
+	public SuperListIteratorWrapper(ListIterator<? extends E> listIterator) {
+		super();
+		if (listIterator == null) {
+			throw new NullPointerException();
+		}
+		this.listIterator = listIterator;
+	}
+
+	@Override
+	public boolean hasNext() {
+		return this.listIterator.hasNext();
+	}
+
+	@Override
+	public E next() {
+		return this.listIterator.next();
+	}
+
+	@Override
+	public int nextIndex() {
+		return this.listIterator.nextIndex();
+	}
+
+	@Override
+	public boolean hasPrevious() {
+		return this.listIterator.hasPrevious();
+	}
+
+	@Override
+	public E previous() {
+		return this.listIterator.previous();
+	}
+
+	@Override
+	public int previousIndex() {
+		return this.listIterator.previousIndex();
+	}
+
+	@Override
+	public void remove() {
+		this.listIterator.remove();
+	}
+
+	@Override
+	public void set(E e) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void add(E e) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.listIterator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SynchronizedIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SynchronizedIterator.java
new file mode 100644
index 0000000..acc6d87
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SynchronizedIterator.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Wrap an iterator and synchronize all its methods so it can be safely shared
+ * among multiple threads.
+ *
+ * @param <E> the type of elements returned by the iterator
+ */
+public class SynchronizedIterator<E>
+	implements Iterator<E>
+{
+	private final Iterator<? extends E> iterator;
+
+	/** Object to synchronize on. */
+	private final Object mutex;
+
+
+	public SynchronizedIterator(Iterable<? extends E> iterable) {
+		this(iterable.iterator());
+	}
+
+	public SynchronizedIterator(Iterable<? extends E> iterable, Object mutex) {
+		this(iterable.iterator(), mutex);
+	}
+
+	public SynchronizedIterator(Iterator<? extends E> iterator) {
+		super();
+		if (iterator == null) {
+			throw new NullPointerException();
+		}
+		this.iterator = iterator;
+		this.mutex = this;
+	}
+
+	public SynchronizedIterator(Iterator<? extends E> iterator, Object mutex) {
+		super();
+		if ((iterator == null) || (mutex == null)) {
+			throw new NullPointerException();
+		}
+		this.iterator = iterator;
+		this.mutex = mutex;
+	}
+
+	@Override
+	public synchronized boolean hasNext() {
+		synchronized (this.mutex) {
+			return this.iterator.hasNext();
+		}
+	}
+
+	@Override
+	public synchronized E next() {
+		synchronized (this.mutex) {
+			return this.iterator.next();
+		}
+	}
+
+	@Override
+	public synchronized void remove() {
+		synchronized (this.mutex) {
+			this.iterator.remove();
+		}
+	}
+
+	@Override
+	public String toString() {
+		synchronized (this.mutex) {
+			return ObjectTools.toString(this, this.iterator);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SynchronizedListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SynchronizedListIterator.java
new file mode 100644
index 0000000..56cc4fe
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/SynchronizedListIterator.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+
+/**
+ * Wrap a list iterator and synchronize all its methods so it can be safely shared
+ * among multiple threads.
+ *
+ * @param <E> the type of elements returned by the iterator
+ */
+public class SynchronizedListIterator<E>
+	implements ListIterator<E>
+{
+	private final ListIterator<E> listIterator;
+
+	/** Object to synchronize on. */
+	private final Object mutex;
+
+
+	public SynchronizedListIterator(List<E> list) {
+		this(list.listIterator());
+	}
+
+	public SynchronizedListIterator(List<E> list, Object mutex) {
+		this(list.listIterator(), mutex);
+	}
+
+	public SynchronizedListIterator(ListIterable<E> listIterable) {
+		this(listIterable.iterator());
+	}
+
+	public SynchronizedListIterator(ListIterable<E> listIterable, Object mutex) {
+		this(listIterable.iterator(), mutex);
+	}
+
+	public SynchronizedListIterator(ListIterator<E> listIterator) {
+		super();
+		if (listIterator == null) {
+			throw new NullPointerException();
+		}
+		this.listIterator = listIterator;
+		this.mutex = this;
+	}
+
+	public SynchronizedListIterator(ListIterator<E> listIterator, Object mutex) {
+		super();
+		if ((listIterator == null) || (mutex == null)) {
+			throw new NullPointerException();
+		}
+		this.listIterator = listIterator;
+		this.mutex = mutex;
+	}
+
+	@Override
+	public synchronized boolean hasNext() {
+		synchronized (this.mutex) {
+			return this.listIterator.hasNext();
+		}
+	}
+
+	@Override
+	public synchronized E next() {
+		synchronized (this.mutex) {
+			return this.listIterator.next();
+		}
+	}
+
+	@Override
+	public synchronized int nextIndex() {
+		synchronized (this.mutex) {
+			return this.listIterator.nextIndex();
+		}
+	}
+
+	@Override
+	public synchronized boolean hasPrevious() {
+		synchronized (this.mutex) {
+			return this.listIterator.hasPrevious();
+		}
+	}
+
+	@Override
+	public synchronized E previous() {
+		synchronized (this.mutex) {
+			return this.listIterator.previous();
+		}
+	}
+
+	@Override
+	public synchronized int previousIndex() {
+		synchronized (this.mutex) {
+			return this.listIterator.previousIndex();
+		}
+	}
+
+	@Override
+	public synchronized void remove() {
+		synchronized (this.mutex) {
+			this.listIterator.remove();
+		}
+	}
+
+	@Override
+	public synchronized void add(E e) {
+		synchronized (this.mutex) {
+			this.listIterator.add(e);
+		}
+	}
+
+	@Override
+	public synchronized void set(E e) {
+		synchronized (this.mutex) {
+			this.listIterator.set(e);
+		}
+	}
+
+	@Override
+	public String toString() {
+		synchronized (this.mutex) {
+			return ObjectTools.toString(this, this.listIterator);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/TransformationIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/TransformationIterator.java
new file mode 100644
index 0000000..c78bf73
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/TransformationIterator.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * A <code>TransformationIterator</code> wraps another {@link Iterator}
+ * and transforms its results for client consumption. To use, supply a
+ * {@link Transformer} or subclass <code>TransformationIterator</code>
+ * and override the {@link #transform(Object)} method.
+ * Objects of type <code>E1</code> are transformed into objects of type <code>E2</code>;
+ * i.e. the iterator returns objects of type <code>E2</code>.
+ *
+ * @param <E1> input: the type of elements to be transformed
+ * @param <E2> output: the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.TransformationIterable
+ */
+public class TransformationIterator<E1, E2>
+	implements Iterator<E2>
+{
+	private final Iterator<? extends E1> iterator;
+	private final Transformer<E1, ? extends E2> transformer;
+
+
+	/**
+	 * Construct an iterator with the specified iterable
+	 * and a disabled transformer.
+	 * Use this constructor if you want to override the
+	 * {@link #transform(Object)} method instead of building
+	 * a {@link Transformer}.
+	 */
+	public TransformationIterator(Iterable<? extends E1> iterable) {
+		this(iterable.iterator());
+	}
+
+	/**
+	 * Construct an iterator with the specified nested iterator
+	 * and a disabled transformer.
+	 * Use this constructor if you want to override the
+	 * {@link #transform(Object)} method instead of building
+	 * a {@link Transformer}.
+	 */
+	public TransformationIterator(Iterator<? extends E1> iterator) {
+		this(iterator, Transformer.Disabled.<E1, E2>instance());
+	}
+
+	/**
+	 * Construct an iterator with the specified iterable and transformer.
+	 */
+	public TransformationIterator(Iterable<? extends E1> iterable, Transformer<E1, ? extends E2> transformer) {
+		this(iterable.iterator(), transformer);
+	}
+
+	/**
+	 * Construct an iterator with the specified nested iterator
+	 * and transformer.
+	 */
+	public TransformationIterator(Iterator<? extends E1> iterator, Transformer<E1, ? extends E2> transformer) {
+		super();
+		if ((iterator == null) || (transformer == null)) {
+			throw new NullPointerException();
+		}
+		this.iterator = iterator;
+		this.transformer = transformer;
+	}
+
+	@Override
+	public boolean hasNext() {
+		// delegate to the nested iterator
+		return this.iterator.hasNext();
+	}
+
+	@Override
+	public E2 next() {
+		// transform the object returned by the nested iterator before returning it
+		return this.transform(this.iterator.next());
+	}
+
+	@Override
+	public void remove() {
+		// delegate to the nested iterator
+		this.iterator.remove();
+	}
+
+	/**
+	 * Transform the specified object and return the result.
+	 */
+	protected E2 transform(E1 next) {
+		return this.transformer.transform(next);
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.iterator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/TransformationListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/TransformationListIterator.java
new file mode 100644
index 0000000..0e51e55
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/TransformationListIterator.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * A <code>TransformationListIterator</code> wraps another {@link ListIterator}
+ * and transforms its results for client consumption. To use, supply a
+ * {@link Transformer} or subclass <code>TransformationIterator</code>
+ * and override the {@link #transform(Object)} method.
+ * <p>
+ * The methods {@link #set(Object)} and {@link #add(Object)}
+ * are left unsupported in this class.
+ *
+ * @param <E1> input: the type of elements to be transformed
+ * @param <E2> output: the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.TransformationListIterable
+ */
+public class TransformationListIterator<E1, E2>
+	implements ListIterator<E2>
+{
+	private final ListIterator<? extends E1> listIterator;
+	private final Transformer<E1, ? extends E2> transformer;
+
+
+	/**
+	 * Construct an iterator with the specified list
+	 * and a disabled transformer.
+	 * Use this constructor if you want to override the
+	 * {@link #transform(Object)} method instead of building
+	 * a {@link Transformer}.
+	 */
+	public TransformationListIterator(List<? extends E1> list) {
+		this(list.listIterator());
+	}
+
+	/**
+	 * Construct an iterator with the specified nested listed iterator
+	 * and a disabled transformer.
+	 * Use this constructor if you want to override the
+	 * {@link #transform(Object)} method instead of building
+	 * a {@link Transformer}.
+	 */
+	public TransformationListIterator(ListIterator<? extends E1> listIterator) {
+		this(listIterator, Transformer.Disabled.<E1, E2>instance());
+	}
+
+	/**
+	 * Construct an iterator with the specified list
+	 * and a disabled transformer.
+	 * Use this constructor if you want to override the
+	 * {@link #transform(Object)} method instead of building
+	 * a {@link Transformer}.
+	 */
+	public TransformationListIterator(ListIterable<? extends E1> listIterable) {
+		this(listIterable.iterator());
+	}
+
+	/**
+	 * Construct an iterator with the specified list and transformer.
+	 */
+	public TransformationListIterator(List<? extends E1> list, Transformer<E1, ? extends E2> transformer) {
+		this(list.listIterator(), transformer);
+	}
+
+	/**
+	 * Construct an iterator with the specified list and transformer.
+	 */
+	public TransformationListIterator(ListIterable<? extends E1> listIterable, Transformer<E1, ? extends E2> transformer) {
+		this(listIterable.iterator(), transformer);
+	}
+
+	/**
+	 * Construct an iterator with the specified nested iterator
+	 * and transformer.
+	 */
+	public TransformationListIterator(ListIterator<? extends E1> listIterator, Transformer<E1, ? extends E2> transformer) {
+		super();
+		if ((listIterator == null) || (transformer == null)) {
+			throw new NullPointerException();
+		}
+		this.listIterator = listIterator;
+		this.transformer = transformer;
+	}
+
+	@Override
+	public boolean hasNext() {
+		// delegate to the nested iterator
+		return this.listIterator.hasNext();
+	}
+
+	@Override
+	public E2 next() {
+		// transform the object returned by the nested iterator before returning it
+		return this.transform(this.listIterator.next());
+	}
+
+	@Override
+	public int nextIndex() {
+		// delegate to the nested iterator
+		return this.listIterator.nextIndex();
+	}
+
+	@Override
+	public boolean hasPrevious() {
+		// delegate to the nested iterator
+		return this.listIterator.hasPrevious();
+	}
+
+	@Override
+	public E2 previous() {
+		// transform the object returned by the nested iterator before returning it
+		return this.transform(this.listIterator.previous());
+	}
+
+	@Override
+	public int previousIndex() {
+		// delegate to the nested iterator
+		return this.listIterator.previousIndex();
+	}
+
+	@Override
+	public void add(E2 o) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void set(E2 o) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void remove() {
+		// delegate to the nested iterator
+		this.listIterator.remove();
+	}
+
+	/**
+	 * Transform the specified object and return the result.
+	 */
+	protected E2 transform(E1 next) {
+		return this.transformer.transform(next);
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.listIterator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/TreeIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/TreeIterator.java
new file mode 100644
index 0000000..3bdc191
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterator/TreeIterator.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.iterator;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * A <code>TreeIterator</code> simplifies the traversal of a
+ * tree of objects, where the objects' protocol(s) provides
+ * a method for getting the immediate children of the given
+ * node but does not provide a method for getting all the
+ * descendants (children, grandchildren, etc.) of the given node.
+ * <p>
+ * To use, supply:<ul>
+ * <li> either the root element of the tree or, if the tree has
+ * multiple roots, an {@link Iterator} over the set of roots
+ * <li> a {@link Transformer} that delivers the children
+ * of each child
+ * </ul>
+ *
+ * @param <E> the type of elements returned by the iterator
+ *
+ * @see org.eclipse.jpt.common.utility.internal.iterable.TreeIterable
+ */
+public class TreeIterator<E>
+	implements Iterator<E>
+{
+	private final LinkedList<Iterator<? extends E>> iterators;
+	private final Transformer<E, Iterator<? extends E>> transformer;
+	private Iterator<? extends E> currentIterator;
+
+
+	/**
+	 * Construct an iterator that returns the nodes of a tree
+	 * with the specified roots and transformer.
+	 */
+	public TreeIterator(Iterator<? extends E> roots, Transformer<E, Iterator<? extends E>> transformer) {
+		super();
+		if ((roots == null) || (transformer == null)) {
+			throw new NullPointerException();
+		}
+		this.currentIterator = roots;
+		// use a LinkedList since we will be pulling off the front and adding to the end
+		this.iterators = new LinkedList<Iterator<? extends E>>();
+		this.transformer = transformer;
+	}
+
+	@Override
+	public boolean hasNext() {
+		if (this.currentIterator.hasNext()) {
+			return true;
+		}
+		for (Iterator<? extends E> iterator : this.iterators) {
+			if (iterator.hasNext()) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	@Override
+	public E next() {
+		if (this.currentIterator.hasNext()) {
+			return this.nextInternal();
+		}
+		for (Iterator<Iterator<? extends E>> stream = this.iterators.iterator(); stream.hasNext(); ) {
+			this.currentIterator = stream.next();
+			if (this.currentIterator.hasNext()) {
+				break;
+			}
+			stream.remove();
+		}
+		return this.nextInternal();
+	}
+
+	/**
+	 * Fetch the children of the next node before returning it.
+	 */
+	private E nextInternal() {
+		E next = this.currentIterator.next();
+		this.iterators.add(this.transformer.transform(next));
+		return next;
+	}
+
+	@Override
+	public void remove() {
+		this.currentIterator.remove();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.currentIterator);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ArrayIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ArrayIterator.java
deleted file mode 100644
index 091b1eb..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ArrayIterator.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * An <code>ArrayIterator</code> provides an {@link Iterator}
- * for an array of objects of type <code>E</code>.
- *
- * @param <E> the type of elements returned by the iterator
- *
- * @see org.eclipse.persistence.tools.utility.iterables.ArrayIterable
- */
-@SuppressWarnings("nls")
-public class ArrayIterator<E>
-	implements Iterator<E>
-{
-	final E[] array;	// private-protected
-	int cursor;		// private-protected
-	private final int max;
-
-	/**
-	 * Construct an iterator for the specified array.
-	 */
-	public ArrayIterator(E... array) {
-		this(array, 0, array.length);
-	}
-
-	/**
-	 * Construct an iterator for the specified array,
-	 * starting at the specified start index and continuing for
-	 * the rest of the array.
-	 */
-	public ArrayIterator(E[] array, int start) {
-		this(array, start, array.length - start);
-	}
-
-	/**
-	 * Construct an iterator for the specified array,
-	 * starting at the specified start index and continuing for
-	 * the specified length.
-	 */
-	public ArrayIterator(E[] array, int start, int length) {
-		super();
-		if ((start < 0) || (start > array.length)) {
-			throw new IllegalArgumentException("start: " + start);
-		}
-		if ((length < 0) || (length > array.length - start)) {
-			throw new IllegalArgumentException("length: " + length);
-		}
-		this.array = array;
-		this.cursor = start;
-		this.max = start + length;
-	}
-
-	@Override
-	public boolean hasNext() {
-		return this.cursor != this.max;
-	}
-
-	@Override
-	public E next() {
-		if (this.hasNext()) {
-			return this.array[this.cursor++];
-		}
-		throw new NoSuchElementException();
-	}
-
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, Arrays.toString(this.array));
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ArrayListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ArrayListIterator.java
deleted file mode 100644
index 5db42a3..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ArrayListIterator.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-/**
- * An <code>ArrayListIterator</code> provides a {@link ListIterator}
- * for an array of objects.
- * <p>
- * The name might be a bit confusing:
- * This is a {@link ListIterator} for an <code>Array</code>;
- * <em>not</em> an {@link java.util.Iterator Iterator} for an
- * {@link java.util.ArrayList ArrayList}.
- *
- * @param <E> the type of elements returned by the iterator
- *
- * @see org.eclipse.persistence.tools.utility.iterables.ArrayListIterable
- */
-public class ArrayListIterator<E>
-	extends ArrayIterator<E>
-	implements ListIterator<E>
-{
-	private final int min;
-
-	/**
-	 * Construct a list iterator for the specified array.
-	 */
-	public ArrayListIterator(E... array) {
-		this(array, 0, array.length);
-	}
-
-	/**
-	 * Construct a list iterator for the specified array,
-	 * starting at the specified start index and continuing for
-	 * the rest of the array.
-	 */
-	public ArrayListIterator(E[] array, int start) {
-		this(array, start, array.length - start);
-	}
-
-	/**
-	 * Construct a list iterator for the specified array,
-	 * starting at the specified start index and continuing for
-	 * the specified length.
-	 */
-	public ArrayListIterator(E[] array, int start, int length) {
-		super(array, start, length);
-		this.min = start;
-	}
-
-	@Override
-	public int nextIndex() {
-		return this.cursor;
-	}
-
-	@Override
-	public int previousIndex() {
-		return this.cursor - 1;
-	}
-
-	@Override
-	public boolean hasPrevious() {
-		return this.cursor != this.min;
-	}
-
-	@Override
-	public E previous() {
-		if (this.hasPrevious()) {
-			return this.array[--this.cursor];
-		}
-		throw new NoSuchElementException();
-	}
-
-	@Override
-	public void add(E e) {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public void set(E e) {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public String toString() {
-		return super.toString();
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ChainIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ChainIterator.java
deleted file mode 100644
index 51a733d..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ChainIterator.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>ChainIterator</code> provides a pluggable {@link Iterator}
- * that loops over a chain of arbitrarily linked objects. The chain
- * should be null-terminated (i.e. a call to the {@link #nextLink(Object)}
- * Returns <code>null</code> when it is passed the last
- * link of the chain).
- * To use, supply a starting link and supply a {@link Linker} or 
- * subclass <code>ChainIterator</code> and override the
- * {@link #nextLink(Object)} method.
- * The starting link will be the first object returned by the iterator.
- * If the starting link is <code>null</code>, the iterator will be empty.
- * Note this iterator does not support <code>null</code> elements.
- * 
- * @param <E> the type of elements returned by the iterator
- * 
- * @see org.eclipse.persistence.tools.utility.iterables.ChainIterable
- */
-public class ChainIterator<E>
-	implements Iterator<E>
-{
-	private E nextLink;
-	private final Linker<E> linker;
-
-	/**
-	 * Construct an iterator with the specified starting link
-	 * and a disabled linker.
-	 * Use this constructor if you want to override the
-	 * {@link #nextLink(Object)} method instead of building
-	 * a {@link Linker}.
-	 */
-	public ChainIterator(E startLink) {
-		this(startLink, Linker.Disabled.<E>instance());
-	}
-
-	/**
-	 * Construct an iterator with the specified starting link
-	 * and linker.
-	 */
-	public ChainIterator(E startLink, Linker<E> linker) {
-		super();
-		this.nextLink = startLink;
-		this.linker = linker;
-	}
-
-	@Override
-	public boolean hasNext() {
-		return this.nextLink != null;
-	}
-
-	@Override
-	public E next() {
-		if (this.nextLink == null) {
-			throw new NoSuchElementException();
-		}
-		E result = this.nextLink;
-		this.nextLink = this.nextLink(this.nextLink);
-		return result;
-	}
-
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	/**
-	 * Returns the next link in the chain; null if there are no more links.
-	 */
-	protected E nextLink(E currentLink) {
-		return this.linker.nextLink(currentLink);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.nextLink);
-	}
-
-
-	//********** member interface **********
-
-	/**
-	 * Used by {@link ChainIterator} to link
-	 * the elements in the chain.
-	 */
-	public interface Linker<T> {
-
-		/**
-		 * Returns the next link in the chain; null if there are no more links.
-		 */
-		T nextLink(T currentLink);
-
-		final class Null<S>
-			implements Linker<S>, Serializable
-		{
-			@SuppressWarnings("rawtypes")
-			public static final Linker INSTANCE = new Null();
-			@SuppressWarnings("unchecked")
-			public static <R> Linker<R> instance() {
-				return INSTANCE;
-			}
-			// ensure single instance
-			private Null() {
-				super();
-			}
-			// * Returns null, indicating the chain is ended
-			@Override
-			public S nextLink(S currentLink) {
-				return null;
-			}
-			@Override
-			public String toString() {
-				return StringTools.buildSingletonToString(this);
-			}
-			private static final long serialVersionUID = 1L;
-			private Object readResolve() {
-				// replace this object with the singleton
-				return INSTANCE;
-			}
-		}
-
-
-		final class Disabled<S>
-			implements Linker<S>, Serializable
-		{
-			@SuppressWarnings("rawtypes")
-			public static final Linker INSTANCE = new Disabled();
-			@SuppressWarnings("unchecked")
-			public static <R> Linker<R> instance() {
-				return INSTANCE;
-			}
-			// ensure single instance
-			private Disabled() {
-				super();
-			}
-			// throw an exception
-			@Override
-			public S nextLink(S currentLink) {
-				throw new UnsupportedOperationException();  // ChainIterator.nextLink(Object) was not implemented
-			}
-			@Override
-			public String toString() {
-				return StringTools.buildSingletonToString(this);
-			}
-			private static final long serialVersionUID = 1L;
-			private Object readResolve() {
-				// replace this object with the singleton
-				return INSTANCE;
-			}
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/CloneIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/CloneIterator.java
deleted file mode 100644
index 34e459b..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/CloneIterator.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>CloneIterator</code> iterates over a copy of a collection,
- * allowing for concurrent access to the original collection.
- * <p>
- * The original collection passed to the <code>CloneIterator</code>'s
- * constructor should be synchronized (e.g. {@link java.util.Vector});
- * otherwise you run the risk of a corrupted collection.
- * <p>
- * By default, a <code>CloneIterator</code> does not support the
- * {@link #remove()} operation; this is because it does not have
- * access to the original collection. But if the <code>CloneIterator</code>
- * is supplied with an {@link Remover} it will delegate the
- * {@link #remove()} operation to the {@link Remover}.
- * Alternatively, a subclass can override the {@link #remove(Object)}
- * method.
- * 
- * @param <E> the type of elements returned by the iterator
- * 
- * @see org.eclipse.persistence.tools.utility.iterables.LiveCloneIterable
- * @see org.eclipse.persistence.tools.utility.iterables.SnapshotCloneIterable
- */
-public class CloneIterator<E>
-	implements Iterator<E>
-{
-	private final Iterator<Object> iterator;
-	private E current;
-	private final Remover<E> remover;
-	private boolean removeAllowed;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct an iterator on a copy of the specified collection.
-	 * The {@link #remove()} method will not be supported,
-	 * unless a subclass overrides the {@link #remove(Object)}.
-	 */
-	public CloneIterator(Collection<? extends E> collection) {
-		this(collection, Remover.ReadOnly.<E>instance());
-	}
-
-	/**
-	 * Construct an iterator on a copy of the specified array.
-	 * The {@link #remove()} method will not be supported,
-	 * unless a subclass overrides the {@link #remove(Object)}.
-	 */
-	public CloneIterator(E[] array) {
-		this(array, Remover.ReadOnly.<E>instance());
-	}
-
-	/**
-	 * Construct an iterator on a copy of the specified collection.
-	 * Use the specified remover to remove objects from the
-	 * original collection.
-	 */
-	public CloneIterator(Collection<? extends E> collection, Remover<E> remover) {
-		this(remover, collection.toArray());
-	}
-
-	/**
-	 * Construct an iterator on a copy of the specified array.
-	 * Use the specified remover to remove objects from the
-	 * original array.
-	 */
-	public CloneIterator(E[] array, Remover<E> remover) {
-		this(remover, array.clone());
-	}
-
-	/**
-	 * Internal constructor used by subclasses.
-	 * Swap order of arguments to prevent collision with other constructor.
-	 * The passed in array will *not* be cloned.
-	 */
-	protected CloneIterator(Remover<E> remover, Object... array) {
-		super();
-		this.iterator = new ArrayIterator<Object>(array);
-		this.current = null;
-		this.remover = remover;
-		this.removeAllowed = false;
-	}
-
-
-	// ********** Iterator implementation **********
-
-	@Override
-	public boolean hasNext() {
-		return this.iterator.hasNext();
-	}
-
-	@Override
-	public E next() {
-		this.current = this.nestedNext();
-		this.removeAllowed = true;
-		return this.current;
-	}
-
-	@Override
-	public void remove() {
-		if ( ! this.removeAllowed) {
-			throw new IllegalStateException();
-		}
-		this.remove(this.current);
-		this.removeAllowed = false;
-	}
-
-
-	// ********** internal methods **********
-
-	/**
-	 * The collection passed in during construction held elements of type <code>E</code>,
-	 * so this cast is not a problem. We need this cast because
-	 * all the elements of the original collection were copied into
-	 * an object array (<code>Object[]</code>).
-	 */
-	@SuppressWarnings("unchecked")
-	protected E nestedNext() {
-		return (E) this.iterator.next();
-	}
-
-	/**
-	 * Remove the specified element from the original collection.
-	 * <p>
-	 * This method can be overridden by a subclass as an
-	 * alternative to building a {@link Remover}.
-	 */
-	protected void remove(E e) {
-		this.remover.remove(e);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this);
-	}
-
-
-	//********** member interface **********
-
-	/**
-	 * Used by {@link CloneIterator} to remove
-	 * elements from the original collection; since the iterator
-	 * does not have direct access to the original collection.
-	 */
-	public interface Remover<T> {
-
-		/**
-		 * Remove the specified object from the original collection.
-		 */
-		void remove(T element);
-
-		final class ReadOnly<S>
-			implements Remover<S>, Serializable
-		{
-			@SuppressWarnings("rawtypes")
-			public static final Remover INSTANCE = new ReadOnly();
-			@SuppressWarnings("unchecked")
-			public static <R> Remover<R> instance() {
-				return INSTANCE;
-			}
-			// ensure single instance
-			private ReadOnly() {
-				super();
-			}
-			// remove is not supported
-			@Override
-			public void remove(Object element) {
-				throw new UnsupportedOperationException();
-			}
-			@Override
-			public String toString() {
-				return StringTools.buildSingletonToString(this);
-			}
-			private static final long serialVersionUID = 1L;
-			private Object readResolve() {
-				// replace this object with the singleton
-				return INSTANCE;
-			}
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/CloneListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/CloneListIterator.java
deleted file mode 100644
index 6ce26eb..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/CloneListIterator.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.io.Serializable;
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>CloneListIterator</code> iterates over a copy of a list,
- * allowing for concurrent access to the original list.
- * <p>
- * The original list passed to the <code>CloneListIterator</code>'s
- * constructor should be synchronized; otherwise you run the risk of
- * a corrupted list (e.g. {@link java.util.Vector}.
- * <p>
- * By default, a <code>CloneListIterator</code> does not support the
- * modification operations; this is because it does not have
- * access to the original list. But if the <code>CloneListIterator</code>
- * is supplied with a {@link Mutator} it will delegate the
- * modification operations to the {@link Mutator}.
- * Alternatively, a subclass can override the modification methods.
- * 
- * @param <E> the type of elements returned by the iterator
- * 
- * @see org.eclipse.persistence.tools.utility.iterables.LiveCloneListIterable
- * @see org.eclipse.persistence.tools.utility.iterables.SnapshotCloneListIterable
- */
-public class CloneListIterator<E>
-	implements ListIterator<E>
-{
-	private final ListIterator<Object> listIterator;
-	private int cursor;
-	private State state;
-	private final Mutator<E> mutator;
-
-	private enum State {
-		UNKNOWN,
-		PREVIOUS,
-		NEXT
-	}
-
-
-	// ********** constructors **********
-
-	/**
-	 * Construct a list iterator on a copy of the specified list.
-	 * The modification methods will not be supported,
-	 * unless a subclass overrides them.
-	 */
-	public CloneListIterator(List<? extends E> list) {
-		this(list, Mutator.ReadOnly.<E>instance());
-	}
-
-	/**
-	 * Construct a list iterator on a copy of the specified array.
-	 * The modification methods will not be supported,
-	 * unless a subclass overrides them.
-	 */
-	public CloneListIterator(E[] array) {
-		this(array, Mutator.ReadOnly.<E>instance());
-	}
-
-	/**
-	 * Construct a list iterator on a copy of the specified list.
-	 * Use the specified list mutator to modify the original list.
-	 */
-	public CloneListIterator(List<? extends E> list, Mutator<E> mutator) {
-		this(mutator, list.toArray());
-	}
-
-	/**
-	 * Construct a list iterator on a copy of the specified array.
-	 * Use the specified list mutator to modify the original list.
-	 */
-	public CloneListIterator(E[] array, Mutator<E> mutator) {
-		this(mutator, array.clone());
-	}
-
-	/**
-	 * Internal constructor used by subclasses.
-	 * Swap order of arguments to prevent collision with other constructor.
-	 * The passed in array will *not* be cloned.
-	 */
-	protected CloneListIterator(Mutator<E> mutator, Object... array) {
-		super();
-		// build a copy of the list and keep it in sync with original (if the mutator allows changes)
-		// that way the nested list iterator will maintain some of our state
-		this.listIterator = CollectionTools.list(array).listIterator();
-		this.mutator = mutator;
-		this.cursor = 0;
-		this.state = State.UNKNOWN;
-	}
-
-
-	// ********** ListIterator implementation **********
-
-	@Override
-	public boolean hasNext() {
-		return this.listIterator.hasNext();
-	}
-
-	@Override
-	public E next() {
-		// allow the nested iterator to throw an exception before we modify the index
-		E next = this.nestedNext();
-		this.cursor++;
-		this.state = State.NEXT;
-		return next;
-	}
-
-	@Override
-	public void remove() {
-		// allow the nested iterator to throw an exception before we modify the original list
-		this.listIterator.remove();
-		if (this.state == State.PREVIOUS) {
-			this.remove(this.cursor);
-		} else {
-			this.cursor--;
-			this.remove(this.cursor);
-		}
-	}
-
-	@Override
-	public int nextIndex() {
-		return this.listIterator.nextIndex();
-	}
-
-	@Override
-	public int previousIndex() {
-		return this.listIterator.previousIndex();
-	}
-
-	@Override
-	public boolean hasPrevious() {
-		return this.listIterator.hasPrevious();
-	}
-
-	@Override
-	public E previous() {
-		// allow the nested iterator to throw an exception before we modify the index
-		E previous = this.nestedPrevious();
-		this.cursor--;
-		this.state = State.PREVIOUS;
-		return previous;
-	}
-
-	@Override
-	public void add(E o) {
-		// allow the nested iterator to throw an exception before we modify the original list
-		this.listIterator.add(o);
-		this.add(this.cursor, o);
-		this.cursor++;
-	}
-
-	@Override
-	public void set(E o) {
-		// allow the nested iterator to throw an exception before we modify the original list
-		this.listIterator.set(o);
-		if (this.state == State.PREVIOUS) {
-			this.set(this.cursor, o);
-		} else {
-			this.set(this.cursor - 1, o);
-		}
-	}
-
-
-	// ********** internal methods **********
-
-	/**
-	 * The list passed in during construction held elements of type <code>E</code>,
-	 * so this cast is not a problem. We need this cast because
-	 * all the elements of the original collection were copied into
-	 * an object array (<code>Object[]</code>).
-	 */
-	@SuppressWarnings("unchecked")
-	protected E nestedNext() {
-		return (E) this.listIterator.next();
-	}
-
-	/**
-	 * The list passed in during construction held elements of type <code>E</code>,
-	 * so this cast is not a problem. We need this cast because
-	 * all the elements of the original collection were copied into
-	 * an object array (<code>Object[]</code>).
-	 */
-	@SuppressWarnings("unchecked")
-	protected E nestedPrevious() {
-		return (E) this.listIterator.previous();
-	}
-
-	/**
-	 * Add the specified element to the original list.
-	 * <p>
-	 * This method can be overridden by a subclass as an
-	 * alternative to building a {@link Mutator}.
-	 */
-	protected void add(int index, E o) {
-		this.mutator.add(index, o);
-	}
-
-	/**
-	 * Remove the specified element from the original list.
-	 * <p>
-	 * This method can be overridden by a subclass as an
-	 * alternative to building a {@link Mutator}.
-	 */
-	protected void remove(int index) {
-		this.mutator.remove(index);
-	}
-
-	/**
-	 * Set the specified element in the original list.
-	 * <p>
-	 * This method can be overridden by a subclass as an
-	 * alternative to building a {@link Mutator}.
-	 */
-	protected void set(int index, E o) {
-		this.mutator.set(index, o);
-	}
-
-
-	// ********** overrides **********
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this);
-	}
-
-
-	//********** member interface **********
-
-	/**
-	 * Used by {@link CloneListIterator} to remove
-	 * elements from the original list; since the list iterator
-	 * does not have direct access to the original list.
-	 */
-	public interface Mutator<T> {
-
-		/**
-		 * Add the specified object to the original list.
-		 */
-		void add(int index, T o);
-
-		/**
-		 * Remove the specified object from the original list.
-		 */
-		void remove(int index);
-
-		/**
-		 * Set the specified object in the original list.
-		 */
-		void set(int index, T o);
-
-		final class ReadOnly<S>
-			implements Mutator<S>, Serializable
-		{
-			@SuppressWarnings("rawtypes")
-			public static final Mutator INSTANCE = new ReadOnly();
-			@SuppressWarnings("unchecked")
-			public static <R> Mutator<R> instance() {
-				return INSTANCE;
-			}
-			// ensure single instance
-			private ReadOnly() {
-				super();
-			}
-			// add is not supported
-			@Override
-			public void add(int index, Object o) {
-				throw new UnsupportedOperationException();
-			}
-			// remove is not supported
-			@Override
-			public void remove(int index) {
-				throw new UnsupportedOperationException();
-			}
-			// set is not supported
-			@Override
-			public void set(int index, Object o) {
-				throw new UnsupportedOperationException();
-			}
-			@Override
-			public String toString() {
-				return StringTools.buildSingletonToString(this);
-			}
-			private static final long serialVersionUID = 1L;
-			private Object readResolve() {
-				// replace this object with the singleton
-				return INSTANCE;
-			}
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/CompositeIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/CompositeIterator.java
deleted file mode 100644
index 6653687..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/CompositeIterator.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
-
-/**
- * A <code>CompositeIterator</code> wraps a collection
- * of {@link Iterator}s and makes them appear to be a single
- * {@link Iterator}.
- *
- * @param <E> the type of elements returned by the iterator
- *
- * @see org.eclipse.persistence.tools.utility.iterables.CompositeIterable
- */
-public class CompositeIterator<E>
-	implements Iterator<E>
-{
-	private final Iterator<? extends Iterator<? extends E>> iterators;
-	private Iterator<? extends E> currentIterator;
-	private Iterator<? extends E> lastIteratorToReturnNext;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct an iterator that returns all the elements held by the
-	 * specified iterables.
-	 */
-	public CompositeIterator(Iterable<? extends Iterable<? extends E>> iterables) {
-		this(
-			new TransformationIterator<Iterator<? extends E>, Iterable<? extends E>>(iterables.iterator()) {
-				@Override
-				protected Iterator<? extends E> transform(Iterable<? extends E> iterable) {
-					return iterable.iterator();
-				}
-			}
-		);
-	}
-
-	/**
-	 * Construct an iterator with the specified collection of iterators.
-	 */
-	public CompositeIterator(Iterator<? extends Iterator<? extends E>> iterators) {
-		super();
-		this.iterators = iterators;
-	}
-
-	/**
-	 * Construct an iterator with the specified object prepended
-	 * to the specified iterable.
-	 */
-	public CompositeIterator(E object, Iterable<? extends E> iterable) {
-		this(object, iterable.iterator());
-	}
-
-	/**
-	 * Construct an iterator with the specified object prepended
-	 * to the specified iterator.
-	 */
-	@SuppressWarnings("unchecked")
-	public CompositeIterator(E object, Iterator<? extends E> iterator) {
-		this(new SingleElementIterator<E>(object), iterator);
-	}
-
-	/**
-	 * Construct an iterator with the specified object appended
-	 * to the specified iterable.
-	 */
-	public CompositeIterator(Iterable<? extends E> iterable, E object) {
-		this(iterable.iterator(), object);
-	}
-
-	/**
-	 * Construct an iterator with the specified object appended
-	 * to the specified iterator.
-	 */
-	@SuppressWarnings("unchecked")
-	public CompositeIterator(Iterator<? extends E> iterator, E object) {
-		this(iterator, new SingleElementIterator<E>(object));
-	}
-
-	/**
-	 * Construct an iterator with the specified iterables.
-	 */
-	public CompositeIterator(Iterable<? extends E>... iterables) {
-		this(new ArrayIterable<Iterable<? extends E>>(iterables));
-	}
-
-	/**
-	 * Construct an iterator with the specified iterators.
-	 */
-	public CompositeIterator(Iterator<? extends E>... iterators) {
-		this(new ArrayIterator<Iterator<? extends E>>(iterators));
-	}
-
-
-	// ********** Iterator implementation **********
-
-	@Override
-	public boolean hasNext() {
-		try {
-			this.loadCurrentIterator();
-		} catch (NoSuchElementException ex) {
-			// this occurs if there are no iterators at all
-			return false;
-		}
-		return this.currentIterator.hasNext();
-	}
-
-	@Override
-	public E next() {
-		this.loadCurrentIterator();
-		E result = this.currentIterator.next();
-
-		// the statement above will throw a NoSuchElementException
-		// if the current iterator is at the end of the line;
-		// so if we get here, we can set 'lastIteratorToReturnNext'
-		this.lastIteratorToReturnNext = this.currentIterator;
-
-		return result;
-	}
-
-	@Override
-	public void remove() {
-		if (this.lastIteratorToReturnNext == null) {
-			// CompositeIterator#next() has never been called
-			throw new IllegalStateException();
-		}
-		this.lastIteratorToReturnNext.remove();
-	}
-
-	/**
-	 * Load {@link #currentIterator} with the first iterator that {@link Iterator#hasNext()}
-	 * or the final iterator if all the elements have already been retrieved.
-	 */
-	private void loadCurrentIterator() {
-		if (this.currentIterator == null) {
-			this.currentIterator = this.iterators.next();
-		}
-		while (( ! this.currentIterator.hasNext()) && this.iterators.hasNext()) {
-			this.currentIterator = this.iterators.next();
-		}
-	}
-
-
-	// ********** overrides **********
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterators);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/CompositeListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/CompositeListIterator.java
deleted file mode 100644
index 0ab5657..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/CompositeListIterator.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ArrayListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-
-/**
- * A <code>CompositeListIterator</code> wraps a list
- * of {@link ListIterator}s and makes them appear to be a single
- * {@link ListIterator}.
- *
- * @param <E> the type of elements returned by the iterator
- *
- * @see org.eclipse.persistence.tools.utility.iterables.CompositeListIterable
- */
-public class CompositeListIterator<E>
-	implements ListIterator<E>
-{
-	private final ListIterator<? extends ListIterator<E>> iterators;
-	private ListIterator<E> nextIterator;
-	private int nextIndex;
- 	/**
- 	 * <code>true</code> if "next" was last returned;
- 	 * <code>false</code> if "previous" was last returned;
- 	 * this determines the effect of {@link #remove()} on {@link #nextIndex}
- 	 */
-	private boolean nextReturned;
-	private ListIterator<E> lastIteratorToReturnElement;
-
-	/**
-	 * Construct a list iterator on the elements in the specified list of lists.
-	 */
-	public CompositeListIterator(List<? extends List<E>> lists) {
-		this(
-			new TransformationListIterator<ListIterator<E>, List<E>>(lists.listIterator()) {
-				@Override
-				protected ListIterator<E> transform(List<E> list) {
-					return list.listIterator();
-				}
-			}
-		);
-	}
-
-	/**
-	 * Construct a list iterator on the elements in the specified list of lists.
-	 */
-	public CompositeListIterator(ListIterable<? extends ListIterable<E>> listIterables) {
-		this(
-			new TransformationListIterator<ListIterator<E>, ListIterable<E>>(listIterables.iterator()) {
-				@Override
-				protected ListIterator<E> transform(ListIterable<E> list) {
-					return list.iterator();
-				}
-			}
-		);
-	}
-
-	/**
-	 * Construct a list iterator with the specified list of list iterators.
-	 */
-	public CompositeListIterator(ListIterator<? extends ListIterator<E>> iterators) {
-		super();
-		this.iterators = iterators;
-		this.nextIndex = 0;
-		this.nextReturned = false;
-	}
-
-	/**
-	 * Construct a list iterator with the specified object prepended
-	 * to the specified list.
-	 */
-	public CompositeListIterator(E object, List<E> list) {
-		this(object, list.listIterator());
-	}
-
-	/**
-	 * Construct a list iterator with the specified object prepended
-	 * to the specified list.
-	 */
-	public CompositeListIterator(E object, ListIterable<E> listIterable) {
-		this(object, listIterable.iterator());
-	}
-
-	/**
-	 * Construct a list iterator with the specified object prepended
-	 * to the specified iterator.
-	 */
-	@SuppressWarnings("unchecked")
-	public CompositeListIterator(E object, ListIterator<E> iterator) {
-		this(new SingleElementListIterator<E>(object), iterator);
-	}
-
-	/**
-	 * Construct a list iterator with the specified object appended
-	 * to the specified list.
-	 */
-	public CompositeListIterator(List<E> list, E object) {
-		this(list.listIterator(), object);
-	}
-
-	/**
-	 * Construct a list iterator with the specified object appended
-	 * to the specified list.
-	 */
-	public CompositeListIterator(ListIterable<E> listIterable, E object) {
-		this(listIterable.iterator(), object);
-	}
-
-	/**
-	 * Construct a list iterator with the specified object appended
-	 * to the specified iterator.
-	 */
-	@SuppressWarnings("unchecked")
-	public CompositeListIterator(ListIterator<E> iterator, E object) {
-		this(iterator, new SingleElementListIterator<E>(object));
-	}
-
-	/**
-	 * Construct a list iterator with the specified lists.
-	 */
-	public CompositeListIterator(List<E>... lists) {
-		this(Arrays.asList(lists));
-	}
-
-	/**
-	 * Construct a list iterator with the specified lists.
-	 */
-	public CompositeListIterator(ListIterable<E>... listIterables) {
-		this(new ArrayListIterable<ListIterable<E>>(listIterables));
-	}
-
-	/**
-	 * Construct a list iterator with the specified list iterators.
-	 */
-	public CompositeListIterator(ListIterator<E>... iterators) {
-		this(new ArrayListIterator<ListIterator<E>>(iterators));
-	}
-
-	@Override
-	public void add(E o) {
-		this.checkNextIterator();
-		this.nextIterator.add(o);
-		this.nextIndex++;
-	}
-
-	@Override
-	public boolean hasNext() {
-		try {
-			this.loadNextIterator();
-		} catch (NoSuchElementException ex) {
-			// this occurs if there are no iterators at all
-			return false;
-		}
-		return this.nextIterator.hasNext();
-	}
-
-	@Override
-	public boolean hasPrevious() {
-		try {
-			this.loadPreviousIterator();
-		} catch (NoSuchElementException ex) {
-			// this occurs if there are no iterators at all
-			return false;
-		}
-		return this.nextIterator.hasPrevious();
-	}
-
-	@Override
-	public E next() {
-		this.loadNextIterator();
-		E result = this.nextIterator.next();
-
-		// the statement above will throw a NoSuchElementException
-		// if the current iterator is at the end of the line;
-		// so if we get here, we can set the 'lastIteratorToReturnElement'
-		this.lastIteratorToReturnElement = this.nextIterator;
-		this.nextIndex++;
-		this.nextReturned = true;
-
-		return result;
-	}
-
-	@Override
-	public int nextIndex() {
-		return this.nextIndex;
-	}
-
-	@Override
-	public E previous() {
-		this.loadPreviousIterator();
-		E result = this.nextIterator.previous();
-
-		// the statement above will throw a NoSuchElementException
-		// if the current iterator is at the end of the line;
-		// so if we get here, we can set the 'lastIteratorToReturnElement'
-		this.lastIteratorToReturnElement = this.nextIterator;
-		this.nextIndex--;
-		this.nextReturned = false;
-
-		return result;
-	}
-
-	@Override
-	public int previousIndex() {
-		return this.nextIndex  - 1;
-	}
-
-	@Override
-	public void remove() {
-		if (this.lastIteratorToReturnElement == null) {
-			throw new IllegalStateException();
-		}
-		this.lastIteratorToReturnElement.remove();
-		if (this.nextReturned) {
-			// decrement the index because the "next" element has moved forward in the list
-			this.nextIndex--;
-		}
-	}
-
-	@Override
-	public void set(E e) {
-		if (this.lastIteratorToReturnElement == null) {
-			throw new IllegalStateException();
-		}
-		this.lastIteratorToReturnElement.set(e);
-	}
-
-	/**
-	 * Load 'nextIterator' with the first iterator that <code>hasNext()</code>
-	 * or the final iterator if all the elements have already been retrieved.
-	 */
-	private void loadNextIterator() {
-		this.checkNextIterator();
-		while (( ! this.nextIterator.hasNext()) && this.iterators.hasNext()) {
-			this.nextIterator = this.iterators.next();
-		}
-	}
-
-	/**
-	 * Load 'nextIterator' with the first iterator that <code>hasPrevious()</code>
-	 * or the first iterator if all the elements have already been retrieved.
-	 */
-	private void loadPreviousIterator() {
-		this.checkNextIterator();
-		while (( ! this.nextIterator.hasPrevious()) && this.iterators.hasPrevious()) {
-			this.nextIterator = this.iterators.previous();
-		}
-	}
-
-	/**
-	 * If 'nextIterator' is null, load it with the first iterator.
-	 */
-	private void checkNextIterator() {
-		if (this.nextIterator == null) {
-			this.nextIterator = this.iterators.next();
-		}
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterators);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/EmptyIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/EmptyIterator.java
deleted file mode 100644
index ff4b54c..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/EmptyIterator.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * An <code>EmptyIterator</code> is just that.
- * 
- * @param <E> the type of elements (not) returned by the iterator
- * 
- * @see org.eclipse.persistence.tools.utility.iterables.EmptyIterable
- */
-public final class EmptyIterator<E>
-	implements Iterator<E>, Serializable
-{
-	// singleton
-	@SuppressWarnings("rawtypes")
-	private static final EmptyIterator INSTANCE = new EmptyIterator();
-
-	/**
-	 * Returns the singleton.
-	 */
-	@SuppressWarnings("unchecked")
-	public static <T> Iterator<T> instance() {
-		return INSTANCE;
-	}
-
-
-	/**
-	 * Ensure single instance.
-	 */
-	private EmptyIterator() {
-		super();
-	}
-
-	@Override
-	public boolean hasNext() {
-		return false;
-	}
-
-	@Override
-	public E next() {
-		throw new NoSuchElementException();
-	}
-
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public String toString() {
-		return this.getClass().getSimpleName();
-	}
-
-	private static final long serialVersionUID = 1L;
-	private Object readResolve() {
-		// replace this object with the singleton
-		return INSTANCE;
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/EmptyListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/EmptyListIterator.java
deleted file mode 100644
index 20d5aa5..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/EmptyListIterator.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.io.Serializable;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-/**
- * An <code>EmptyListIterator</code> is just that.
- * 
- * @param <E> the type of elements (not) returned by the iterator
- * 
- * @see org.eclipse.persistence.tools.utility.iterables.EmptyListIterable
- */
-public final class EmptyListIterator<E>
-	implements ListIterator<E>, Serializable
-{
-	// singleton
-	@SuppressWarnings("rawtypes")
-	private static final EmptyListIterator INSTANCE = new EmptyListIterator();
-
-	/**
-	 * Returns the singleton.
-	 */
-	@SuppressWarnings("unchecked")
-	public static <T> ListIterator<T> instance() {
-		return INSTANCE;
-	}
-
-
-	/**
-	 * Ensure single instance.
-	 */
-	private EmptyListIterator() {
-		super();
-	}
-	
-	@Override
-	public void add(E e) {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public boolean hasNext() {
-		return false;
-	}
-
-	@Override
-	public boolean hasPrevious() {
-		return false;
-	}
-
-	@Override
-	public E next() {
-		throw new NoSuchElementException();
-	}
-
-	@Override
-	public int nextIndex() {
-		return 0;
-	}
-
-	@Override
-	public E previous() {
-		throw new NoSuchElementException();
-	}
-
-	@Override
-	public int previousIndex() {
-		return -1;
-	}
-
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public void set(E e) {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public String toString() {
-		return this.getClass().getSimpleName();
-	}
-	
-	private static final long serialVersionUID = 1L;
-	private Object readResolve() {
-		// replace this object with the singleton
-		return INSTANCE;
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/EnumerationIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/EnumerationIterator.java
deleted file mode 100644
index b883377..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/EnumerationIterator.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Enumeration;
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * An <code>EnumerationIterator</code> wraps an
- * {@link Enumeration} so that it can be treated like an
- * {@link Iterator}.
- *
- * @param <E> the type of elements returned by the iterator
- */
-public class EnumerationIterator<E>
-	implements Iterator<E>
-{
-	private final Enumeration<? extends E> enumeration;
-
-	/**
-	 * Construct an iterator that wraps the specified enumeration.
-	 */
-	public EnumerationIterator(Enumeration<? extends E> enumeration) {
-		this.enumeration = enumeration;
-	}
-
-	@Override
-	public boolean hasNext() {
-		return this.enumeration.hasMoreElements();
-	}
-
-	@Override
-	public E next() {
-		return this.enumeration.nextElement();
-	}
-
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.enumeration);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/FilteringIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/FilteringIterator.java
deleted file mode 100644
index de2b1e5..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/FilteringIterator.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import org.eclipse.persistence.tools.utility.Filter;
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>FilteringIterator</code> wraps another {@link Iterator}
- * and uses a {@link Filter} to determine which elements in the
- * nested iterator are to be returned by calls to {@link #next()}.
- * <p>
- * As an alternative to building a {@link Filter}, a subclass
- * of <code>FilteringIterator</code> can override the
- * {@link #accept(Object)} method.
- * <p>
- * One, possibly undesirable, side-effect of using this iterator is that
- * the nested iterator's <code>next()</code> method will be invoked
- * <em>before</em> the filtered iterator's {@link #next()}
- * method is invoked. This is because the "next" element must be
- * checked for whether it is to be accepted before the filtered iterator
- * can determine whether it has a "next" element (i.e. that the
- * Returns <code>true</code>).
- * This also prevents a filtered iterator from supporting the optional
- * <code>remove()</code> method.
- *
- * @param <E> the type of elements to be filtered
- *
- * @see org.eclipse.persistence.tools.utility.iterables.FilteringIterable
- */
-public class FilteringIterator<E>
-	implements Iterator<E>
-{
-	private final Iterator<? extends E> iterator;
-	private final Filter<E> filter;
-	private E next;
-	private boolean done;
-
-	/**
-	 * Construct an iterator with the specified
-	 * iterable and a disabled filter.
-	 * Use this constructor if you want to override the
-	 * {@link #accept(Object)} method instead of building
-	 * a {@link Filter}.
-	 */
-	public FilteringIterator(Iterable<? extends E> iterable) {
-		this(iterable.iterator());
-	}
-
-	/**
-	 * Construct an iterator with the specified nested
-	 * iterator and a disabled filter.
-	 * Use this constructor if you want to override the
-	 * {@link #accept(Object)} method instead of building
-	 * a {@link Filter}.
-	 */
-	public FilteringIterator(Iterator<? extends E> iterator) {
-		this(iterator, Filter.Disabled.<E>instance());
-	}
-
-	/**
-	 * Construct an iterator with the specified
-	 * iterable and filter.
-	 */
-	public FilteringIterator(Iterable<? extends E> iterable, Filter<E> filter) {
-		this(iterable.iterator(), filter);
-	}
-
-	/**
-	 * Construct an iterator with the specified nested
-	 * iterator and filter.
-	 */
-	public FilteringIterator(Iterator<? extends E> iterator, Filter<E> filter) {
-		super();
-		this.iterator = iterator;
-		this.filter = filter;
-		this.loadNext();
-	}
-
-	@Override
-	public boolean hasNext() {
-		return ! this.done;
-	}
-
-	@Override
-	public E next() {
-		if (this.done) {
-			throw new NoSuchElementException();
-		}
-		E result = this.next;
-		this.loadNext();
-		return result;
-	}
-
-	/**
-	 * Because we need to pre-load the next element
-	 * to be returned, we cannot support the <code>remove()</code>
-	 * method.
-	 */
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	/**
-	 * Load next with the next valid entry from the nested
-	 * iterator. If there are none, next is set to <code>END</code>.
-	 */
-	private void loadNext() {
-		this.done = true;
-		while (this.iterator.hasNext() && (this.done)) {
-			E temp = this.iterator.next();
-			if (this.accept(temp)) {
-				// assume that if the object was accepted it is of type E
-				this.next = temp;
-				this.done = false;
-			} else {
-				this.next = null;
-				this.done = true;
-			}
-		}
-	}
-
-	/**
-	 * Returns whether the {@link FilteringIterator}
-	 * Returns the specified next element from a call to the
-	 * {@link #next()} method.
-	 * <p>
-	 * This method can be overridden by a subclass as an
-	 * alternative to building a {@link Filter}.
-	 */
-	protected boolean accept(E o) {
-		return this.filter.accept(o);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterator);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/GraphIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/GraphIterator.java
deleted file mode 100644
index 47f5b21..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/GraphIterator.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.io.Serializable;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>GraphIterator</code> is similar to a {@link TreeIterator}
- * except that it cannot be assumed that all nodes assume a strict tree
- * structure. For instance, in a tree, a node cannot be a descendent of
- * itself, but a graph may have a cyclical structure.
- *
- * A <code>GraphIterator</code> simplifies the traversal of a
- * graph of objects, where the objects' protocol(s) provides
- * a method for getting the next collection of nodes in the graph,
- * (or <em>neighbors</em>), but does not provide a method for
- * getting <em>all</em> of the nodes in the graph.
- * Returns his neighbors, and those neighbors
- * Returns their neighbors, which might also include the original
- * neighbor, but you only want to visit the original neighbor once.)
- * <p>
- * If a neighbor has already been visited (determined by using
- * {@link #equals(Object)}), that neighbor is not visited again,
- * nor are the neighbors of that object.
- * <p>
- * It is up to the user of this class to ensure a <em>complete</em> graph.
- * <p>
- * To use, supply:<ul>
- * <li> either the initial node of the graph or an {@link Iterator}
- * over an initial collection of graph nodes
- * <li> a {@link MisterRogers} that tells who the neighbors are
- * of each node
- * (alternatively, subclass <code>GraphIterator</code>
- * and override the {@link #neighbors(Object)} method)
- * </ul>
- * {@link #remove()} is not supported. This behavior, if
- * desired, must be implemented by the user of this class.
- *
- * @param <E> the type of elements returned by the iterator
- *
- * @see org.eclipse.persistence.tools.utility.iterables.GraphIterable
- */
-public class GraphIterator<E>
-	implements Iterator<E>
-{
-	// use a LinkedList since we will be pulling off the front and adding to the end
-	private final LinkedList<Iterator<? extends E>> iterators = new LinkedList<Iterator<? extends E>>();
-	private final HashSet<E> visitedNeighbors = new HashSet<E>();
-	private final MisterRogers<E> misterRogers;
-
-	private Iterator<? extends E> currentIterator;
-
-	private E nextNeighbor;
-	private boolean done;
-
-	/**
-	 * Construct an iterator that returns the nodes of a graph
-	 * with the specified collection of roots
-	 * and a disabled Mr. Rogers.
-	 * Use this constructor if you want to override the
-	 * {@link #neighbors(Object)} method instead of building
-	 * a {@link MisterRogers}.
-	 */
-	public GraphIterator(E... roots) {
-		this(new ArrayIterator<E>(roots));
-	}
-
-	/**
-	 * Construct an iterator that returns the nodes of a graph
-	 * with the specified collection of roots
-	 * and a disabled Mr. Rogers.
-	 * Use this constructor if you want to override the
-	 * {@link #neighbors(Object)} method instead of building
-	 * a {@link MisterRogers}.
-	 */
-	public GraphIterator(Iterable<? extends E> roots) {
-		this(roots.iterator());
-	}
-
-	/**
-	 * Construct an iterator that returns the nodes of a graph
-	 * with the specified collection of roots
-	 * and a disabled Mr. Rogers.
-	 * Use this constructor if you want to override the
-	 * {@link #neighbors(Object)} method instead of building
-	 * a {@link MisterRogers}.
-	 */
-	public GraphIterator(Iterator<? extends E> roots) {
-		this(roots, MisterRogers.Disabled.<E>instance());
-	}
-
-	/**
-	 * Construct an iterator that returns the nodes of a graph
-	 * with the specified root
-	 * and a disabled Mr. Rogers.
-	 * Use this constructor if you want to override the
-	 * <code>neighbors(Object)</code> method instead of building
-	 * a <code>MisterRogers</code>.
-	 */
-	public GraphIterator(E root) {
-		this(root, MisterRogers.Disabled.<E>instance());
-	}
-
-	/**
-	 * Construct an iterator that returns the nodes of a graph
-	 * with the specified root and Mr. Rogers.
-	 */
-	public GraphIterator(E root, MisterRogers<E> misterRogers) {
-		this(new SingleElementIterator<E>(root), misterRogers);
-	}
-
-	/**
-	 * Construct an iterator that returns the nodes of a graph
-	 * with the specified collection of roots and Mr. Rogers.
-	 */
-	public GraphIterator(E[] roots, MisterRogers<E> misterRogers) {
-		this(new ArrayIterator<E>(roots), misterRogers);
-	}
-
-	/**
-	 * Construct an iterator that returns the nodes of a graph
-	 * with the specified roots and Mr. Rogers.
-	 */
-	public GraphIterator(Iterable<? extends E> roots, MisterRogers<E> misterRogers) {
-		this(roots.iterator(), misterRogers);
-	}
-
-	/**
-	 * Construct an iterator that returns the nodes of a graph
-	 * with the specified roots and Mr. Rogers.
-	 */
-	public GraphIterator(Iterator<? extends E> roots, MisterRogers<E> misterRogers) {
-		super();
-		this.currentIterator = roots;
-		this.misterRogers = misterRogers;
-		this.loadNextNeighbor();
-	}
-
-	/**
-	 * Load next neighbor with the next entry from the current iterator.
-	 * If the current iterator has none, load the next iterator.
-	 * If there are no more, the {@link #done} flag is set.
-	 */
-	private void loadNextNeighbor() {
-		if (this.currentIterator == EmptyIterator.instance()) {
-			this.done = true;
-		}
-		else if (this.currentIterator.hasNext()) {
-			E nextPossibleNeighbor = this.currentIterator.next();
-			if (this.visitedNeighbors.contains(nextPossibleNeighbor)) {
-				this.loadNextNeighbor();  // recurse
-			} else {
-				this.nextNeighbor = nextPossibleNeighbor;
-				this.visitedNeighbors.add(nextPossibleNeighbor);
-				this.iterators.add(this.neighbors(nextPossibleNeighbor));
-			}
-		}
-		else {
-			for (Iterator<? extends Iterator<? extends E>> stream = this.iterators.iterator(); ! this.currentIterator.hasNext() && stream.hasNext(); ) {
-				this.currentIterator = stream.next();
-				stream.remove();
-			}
-			if ( ! this.currentIterator.hasNext()) {
-				this.currentIterator = EmptyIterator.instance();
-			}
-			this.loadNextNeighbor();  // recurse
-		}
-	}
-
-	@Override
-	public boolean hasNext() {
-		return ! this.done;
-	}
-
-	@Override
-	public E next() {
-		if (this.done) {
-			throw new NoSuchElementException();
-		}
-		E next = this.nextNeighbor;
-		this.loadNextNeighbor();
-		return next;
-	}
-
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	/**
-	 * Returns the immediate neighbors of the specified object.
-	 */
-	protected Iterator<? extends E> neighbors(E next) {
-		return this.misterRogers.neighbors(next);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.currentIterator);
-	}
-
-
-	//********** inner classes **********
-
-	/**
-	 * Used by {@link GraphIterator} to retrieve
-	 * the immediate neighbors of a node in the graph.
-	 * "These are the people in your neighborhood..."
-	 */
-	public interface MisterRogers<T> {
-
-		/**
-		 * Returns the immediate neighbors of the specified object.
-		 */
-		Iterator<? extends T> neighbors(T next);
-
-		final class Null<S>
-			implements MisterRogers<S>, Serializable
-		{
-			@SuppressWarnings("rawtypes")
-			public static final MisterRogers INSTANCE = new Null();
-			@SuppressWarnings("unchecked")
-			public static <R> MisterRogers<R> instance() {
-				return INSTANCE;
-			}
-			// ensure single instance
-			private Null() {
-				super();
-			}
-			// return no neighbors
-			@Override
-			public Iterator<S> neighbors(S next) {
-				return EmptyIterator.instance();
-			}
-			@Override
-			public String toString() {
-				return StringTools.buildSingletonToString(this);
-			}
-			private static final long serialVersionUID = 1L;
-			private Object readResolve() {
-				// replace this object with the singleton
-				return INSTANCE;
-			}
-		}
-
-		/** The Mr. Rogers used when the {@link GraphIterator#neighbors(Object)} method is overridden. */
-		final class Disabled<S>
-			implements MisterRogers<S>, Serializable
-		{
-			@SuppressWarnings("rawtypes")
-			public static final MisterRogers INSTANCE = new Disabled();
-			@SuppressWarnings("unchecked")
-			public static <R> MisterRogers<R> instance() {
-				return INSTANCE;
-			}
-			// ensure single instance
-			private Disabled() {
-				super();
-			}
-			// throw an exception
-			@Override
-			public Iterator<S> neighbors(S next) {
-				throw new UnsupportedOperationException();  // GraphIterator.neighbors(Object) was not implemented
-			}
-			@Override
-			public String toString() {
-				return StringTools.buildSingletonToString(this);
-			}
-			private static final long serialVersionUID = 1L;
-			private Object readResolve() {
-				// replace this object with the singleton
-				return INSTANCE;
-			}
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/LateralIteratorWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/LateralIteratorWrapper.java
deleted file mode 100644
index 5d75953..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/LateralIteratorWrapper.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * Wrap an iterator on elements of type <code>E1</code>, converting it into an
- * iterator on elements of type <code>E2</code>. <em>Assume</em> the wrapped
- * iterator returns only elements of type <code>E2</code>. The result is a
- * {@link ClassCastException} if this assumption is false.
- *
- * @param <E1> input: the type of elements returned by the wrapped iterator
- * @param <E2> output: the type of elements returned by the iterator
- *
- * @see org.eclipse.persistence.tools.utility.iterables.LateralIterableWrapper
- * @see SubIteratorWrapper
- */
-public class LateralIteratorWrapper<E1, E2>
-	implements Iterator<E2>
-{
-	private final Iterator<E1> iterator;
-
-	public LateralIteratorWrapper(Iterable<E1> iterable) {
-		this(iterable.iterator());
-	}
-
-	public LateralIteratorWrapper(Iterator<E1> iterator) {
-		super();
-		this.iterator = iterator;
-	}
-
-	@Override
-	public boolean hasNext() {
-		return this.iterator.hasNext();
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	public E2 next() {
-		return (E2) this.iterator.next();
-	}
-
-	@Override
-	public void remove() {
-		this.iterator.remove();
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterator);
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/LateralListIteratorWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/LateralListIteratorWrapper.java
deleted file mode 100644
index 875a9b8..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/LateralListIteratorWrapper.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-
-/**
- * Wrap a list iterator on elements of type <code>E1</code>, converting it into
- * a list iterator on elements of type <code>E2</code>. <em>Assume</em> the
- * wrapped list iterator returns only elements of type <code>E2</code>.
- * The result is a {@link ClassCastException} if this assumption is false.
- *
- * @param <E1> input: the type of elements returned by the wrapped list iterator
- * @param <E2> output: the type of elements returned by the list iterator
- *
- * @see org.eclipse.persistence.tools.utility.iterables.LateralIterableWrapper
- * @see SubListIteratorWrapper
- */
-public class LateralListIteratorWrapper<E1, E2>
-	implements ListIterator<E2>
-{
-	final ListIterator<E1> listIterator;
-
-	public LateralListIteratorWrapper(List<E1> list) {
-		this(list.listIterator());
-	}
-
-	public LateralListIteratorWrapper(ListIterable<E1> listIterable) {
-		this(listIterable.iterator());
-	}
-
-	public LateralListIteratorWrapper(ListIterator<E1> iterator) {
-		super();
-		this.listIterator = iterator;
-	}
-
-	@Override
-	public boolean hasNext() {
-		return this.listIterator.hasNext();
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	public E2 next() {
-		return (E2) this.listIterator.next();
-	}
-
-	@Override
-	public int nextIndex() {
-		return this.listIterator.nextIndex();
-	}
-
-	@Override
-	public boolean hasPrevious() {
-		return this.listIterator.hasPrevious();
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	public E2 previous() {
-		return (E2) this.listIterator.previous();
-	}
-
-	@Override
-	public int previousIndex() {
-		return this.listIterator.previousIndex();
-	}
-
-	@Override
-	public void remove() {
-		this.listIterator.remove();
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	public void set(E2 e) {
-		this.listIterator.set((E1) e);
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	public void add(E2 e) {
-		this.listIterator.add((E1) e);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.listIterator);
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/PeekableIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/PeekableIterator.java
deleted file mode 100644
index 8c2c63b..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/PeekableIterator.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>PeekableIterator</code> wraps another {@link Iterator}
- * and allows a {@link #peek()} at the next element to be
- * returned by {@link #next()}.
- * <p>
- * One, possibly undesirable, side-effect of using this iterator is that
- * the nested iterator's <code>next()</code> method will be invoked
- * <em>before</em> the peekable iterator's {@link #next()}
- * method is invoked. This is because the "next" element must be
- * pre-loaded for the {@link #peek()} method.
- * This also prevents a peekable iterator from supporting the optional
- * {@link #remove()} method.
- *
- * @param <E> the type of elements returned by the iterator
- *
- * @see org.eclipse.persistence.tools.utility.iterables.PeekableIterable
- */
-public class PeekableIterator<E>
-	implements Iterator<E>
-{
-	private final Iterator<? extends E> iterator;
-	private E next;
-	private boolean done;
-
-	/**
-	 * Construct a peekable iterator that wraps the specified
-	 * iterable.
-	 */
-	public PeekableIterator(Iterable<? extends E> iterable) {
-		this(iterable.iterator());
-	}
-
-	/**
-	 * Construct a peekable iterator that wraps the specified nested
-	 * iterator.
-	 */
-	public PeekableIterator(Iterator<? extends E> iterator) {
-		super();
-		this.iterator = iterator;
-		this.done = false;
-		this.loadNext();
-	}
-
-	@Override
-	public boolean hasNext() {
-		return ! this.done;
-	}
-
-	@Override
-	public E next() {
-		if (this.done) {
-			throw new NoSuchElementException();
-		}
-		E result = this.next;
-		this.loadNext();
-		return result;
-	}
-
-	/**
-	 * Returns the element that will be returned by the next call to the
-	 * {@link #next()} method, without advancing past it.
-	 */
-	public E peek() {
-		if (this.done) {
-			throw new NoSuchElementException();
-		}
-		return this.next;
-	}
-
-	/**
-	 * Because we need to pre-load the next element
-	 * to be returned, we cannot support the {@link #remove()}
-	 * method.
-	 */
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	/**
-	 * Load next with the next entry from the nested
-	 * iterator. If there are none, {@link #next} is set to <code>null</code>
-	 * and {@link #done} is set to <code>true</code>.
-	 */
-	private void loadNext() {
-		if (this.iterator.hasNext()) {
-			this.next = this.iterator.next();
-		} else {
-			this.next = null;
-			this.done = true;
-		}
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterator);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/QueueIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/QueueIterator.java
deleted file mode 100644
index e58ffa7..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/QueueIterator.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.Queue;
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>QueueIterator</code> provides an {@link Iterator}
- * for a {@link Queue} of objects of type <code>E</code>. The queue's elements
- * are {@link Queue#dequeue() dequeue}d" as the iterator returns them with
- * calls to {@link #next()}.
- *
- * @param <E> the type of elements returned by the iterator
- *
- * @see Queue
- * @see org.eclipse.persistence.tools.utility.iterables.QueueIterable
- */
-public class QueueIterator<E>
-	implements Iterator<E>
-{
-	private final Queue<E> queue;
-
-	/**
-	 * Construct an iterator for the specified queue.
-	 */
-	public QueueIterator(Queue<E> queue) {
-		super();
-		this.queue = queue;
-	}
-
-	@Override
-	public boolean hasNext() {
-		return ! this.queue.isEmpty();
-	}
-
-	@Override
-	public E next() {
-		return this.queue.dequeue();
-	}
-
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.queue);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ReadOnlyCompositeListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ReadOnlyCompositeListIterator.java
deleted file mode 100644
index 1350f38..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ReadOnlyCompositeListIterator.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ArrayListIterable;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-
-/**
- * A <code>ReadOnlyCompositeListIterator</code> wraps a list
- * of {@link ListIterator}s and makes them appear to be a single
- * read-only {@link ListIterator}. A read-only composite list
- * iterator is more flexible than a normal composite list iterator when it
- * comes to the element types of the nested iterators.
- *
- * @param <E> the type of elements returned by the iterator
- *
- * @see org.eclipse.persistence.tools.utility.iterables.ReadOnlyCompositeListIterable
- */
-public class ReadOnlyCompositeListIterator<E>
-	implements ListIterator<E>
-{
-	private final ListIterator<? extends ListIterator<? extends E>> iterators;
-	private ListIterator<? extends E> nextIterator;
-	private int nextIndex;
-
-	/**
-	 * Construct a read-only list iterator with the specified list of lists.
-	 */
-	public ReadOnlyCompositeListIterator(List<? extends List<? extends E>> lists) {
-		this(
-			new TransformationListIterator<ListIterator<? extends E>, List<? extends E>>(lists.listIterator()) {
-				@Override
-				protected ListIterator<? extends E> transform(List<? extends E> list) {
-					return list.listIterator();
-				}
-			}
-		);
-	}
-
-	/**
-	 * Construct a read-only list iterator with the specified list of lists.
-	 */
-	public ReadOnlyCompositeListIterator(ListIterable<? extends ListIterable<? extends E>> listIterables) {
-		this(
-			new TransformationListIterator<ListIterator<? extends E>, ListIterable<? extends E>>(listIterables.iterator()) {
-				@Override
-				protected ListIterator<? extends E> transform(ListIterable<? extends E> listIterable) {
-					return listIterable.iterator();
-				}
-			}
-		);
-	}
-
-	/**
-	 * Construct a read-only list iterator with the specified list of
-	 * list iterators.
-	 */
-	public ReadOnlyCompositeListIterator(ListIterator<? extends ListIterator<? extends E>> iterators) {
-		super();
-		this.iterators = iterators;
-		this.nextIndex = 0;
-	}
-
-	/**
-	 * Construct a read-only list iterator with the specified object prepended
-	 * to the specified list.
-	 */
-	public ReadOnlyCompositeListIterator(E object, List<? extends E> list) {
-		this(object, list.listIterator());
-	}
-
-	/**
-	 * Construct a read-only list iterator with the specified object prepended
-	 * to the specified list.
-	 */
-	public ReadOnlyCompositeListIterator(E object, ListIterable<? extends E> listIterable) {
-		this(object, listIterable.iterator());
-	}
-
-	/**
-	 * Construct a read-only list iterator with the specified object prepended
-	 * to the specified iterator.
-	 */
-	@SuppressWarnings("unchecked")
-	public ReadOnlyCompositeListIterator(E object, ListIterator<? extends E> iterator) {
-		this(new SingleElementListIterator<E>(object), iterator);
-	}
-
-	/**
-	 * Construct a read-only list iterator with the specified object appended
-	 * to the specified list.
-	 */
-	public ReadOnlyCompositeListIterator(List<? extends E> list, E object) {
-		this(list.listIterator(), object);
-	}
-
-	/**
-	 * Construct a read-only list iterator with the specified object appended
-	 * to the specified list.
-	 */
-	public ReadOnlyCompositeListIterator(ListIterable<? extends E> listIterable, E object) {
-		this(listIterable.iterator(), object);
-	}
-
-	/**
-	 * Construct a read-only list iterator with the specified object appended
-	 * to the specified iterator.
-	 */
-	@SuppressWarnings("unchecked")
-	public ReadOnlyCompositeListIterator(ListIterator<? extends E> iterator, E object) {
-		this(iterator, new SingleElementListIterator<E>(object));
-	}
-
-	/**
-	 * Construct a read-only list iterator with the specified lists.
-	 */
-	public ReadOnlyCompositeListIterator(List<? extends E>... lists) {
-		this(Arrays.asList(lists));
-	}
-
-	/**
-	 * Construct a read-only list iterator with the specified lists.
-	 */
-	public ReadOnlyCompositeListIterator(ListIterable<? extends E>... listIterables) {
-		this(new ArrayListIterable<ListIterable<? extends E>>(listIterables));
-	}
-
-	/**
-	 * Construct a read-only list iterator with the specified list iterators.
-	 */
-	public ReadOnlyCompositeListIterator(ListIterator<? extends E>... iterators) {
-		this(new ArrayListIterator<ListIterator<? extends E>>(iterators));
-	}
-
-	@Override
-	public boolean hasNext() {
-		try {
-			this.loadNextIterator();
-		} catch (NoSuchElementException ex) {
-			// this occurs if there are no iterators at all
-			return false;
-		}
-		return this.nextIterator.hasNext();
-	}
-
-	@Override
-	public boolean hasPrevious() {
-		try {
-			this.loadPreviousIterator();
-		} catch (NoSuchElementException ex) {
-			// this occurs if there are no iterators at all
-			return false;
-		}
-		return this.nextIterator.hasPrevious();
-	}
-
-	@Override
-	public E next() {
-		this.loadNextIterator();
-		E result = this.nextIterator.next();
-
-		// the statement above will throw a NoSuchElementException
-		// if the current iterator is at the end of the line;
-		// so if we get here, we can increment 'nextIndex'
-		this.nextIndex++;
-
-		return result;
-	}
-
-	@Override
-	public int nextIndex() {
-		return this.nextIndex;
-	}
-
-	@Override
-	public E previous() {
-		this.loadPreviousIterator();
-		E result = this.nextIterator.previous();
-
-		// the statement above will throw a NoSuchElementException
-		// if the current iterator is at the end of the line;
-		// so if we get here, we can decrement 'nextIndex'
-		this.nextIndex--;
-
-		return result;
-	}
-
-	@Override
-	public int previousIndex() {
-		return this.nextIndex  - 1;
-	}
-
-	@Override
-	public void add(E o) {
-		// the list iterator is read-only
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public void remove() {
-		// the list iterator is read-only
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public void set(E e) {
-		// the list iterator is read-only
-		throw new UnsupportedOperationException();
-	}
-
-	/**
-	 * Load {@link #nextIterator} with the first iterator that {@link #hasNext()}
-	 * or the final iterator if all the elements have already been retrieved.
-	 */
-	private void loadNextIterator() {
-		this.checkNextIterator();
-		while (( ! this.nextIterator.hasNext()) && this.iterators.hasNext()) {
-			this.nextIterator = this.iterators.next();
-		}
-	}
-
-	/**
-	 * Load {@link #nextIterator} with the first iterator that {@link #hasPrevious()}
-	 * or the first iterator if all the elements have already been retrieved.
-	 */
-	private void loadPreviousIterator() {
-		this.checkNextIterator();
-		while (( ! this.nextIterator.hasPrevious()) && this.iterators.hasPrevious()) {
-			this.nextIterator = this.iterators.previous();
-		}
-	}
-
-	/**
-	 * If {@link #nextIterator} is null, load it with the first iterator.
-	 */
-	private void checkNextIterator() {
-		if (this.nextIterator == null) {
-			this.nextIterator = this.iterators.next();
-		}
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterators);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ReadOnlyIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ReadOnlyIterator.java
deleted file mode 100644
index 1eda268..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ReadOnlyIterator.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>ReadOnlyIterator</code> wraps another {@link Iterator}
- * and removes support for {@link #remove()}.
- *
- * @param <E> the type of elements returned by the iterator
- *
- * @see org.eclipse.persistence.tools.utility.iterables.ReadOnlyIterable
- */
-public class ReadOnlyIterator<E>
-	implements Iterator<E>
-{
-	private final Iterator<? extends E> iterator;
-
-	/**
-	 * Construct an iterator on the specified collection that
-	 * disallows removes.
-	 */
-	public ReadOnlyIterator(Iterable<? extends E> c) {
-		this(c.iterator());
-	}
-
-	/**
-	 * Construct an iterator with the specified nested iterator
-	 * and disallow removes.
-	 */
-	public ReadOnlyIterator(Iterator<? extends E> iterator) {
-		super();
-		this.iterator = iterator;
-	}
-
-	@Override
-	public boolean hasNext() {
-		// delegate to the nested iterator
-		return this.iterator.hasNext();
-	}
-
-	@Override
-	public E next() {
-		// delegate to the nested iterator
-		return this.iterator.next();
-	}
-
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterator);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ReadOnlyListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ReadOnlyListIterator.java
deleted file mode 100644
index 6000391..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ReadOnlyListIterator.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-
-/**
- * A <code>ReadOnlyListIterator</code> wraps another
- * {@link ListIterator} and removes support for:<ul>
- * <li>{@link #remove()}
- * 	<li>{@link #set(Object)}
- * 	<li>{@link #add(Object)}
- * </ul>
- *
- * @param <E> the type of elements returned by the list iterator
- *
- * @see org.eclipse.persistence.tools.utility.iterables.ReadOnlyListIterable
- */
-public class ReadOnlyListIterator<E>
-	implements ListIterator<E>
-{
-	private final ListIterator<? extends E> listIterator;
-
-	/**
-	 * Construct a list iterator on the specified list that
-	 * disallows removes, sets, and adds.
-	 */
-	public ReadOnlyListIterator(List<? extends E> list) {
-		this(list.listIterator());
-	}
-
-	/**
-	 * Construct a list iterator on the specified list that
-	 * disallows removes, sets, and adds.
-	 */
-	public ReadOnlyListIterator(ListIterable<? extends E> listIterable) {
-		this(listIterable.iterator());
-	}
-
-	/**
-	 * Construct a list iterator on the specified list iterator that
-	 * disallows removes, sets, and adds.
-	 */
-	public ReadOnlyListIterator(ListIterator<? extends E> listIterator) {
-		super();
-		this.listIterator = listIterator;
-	}
-
-	@Override
-	public boolean hasNext() {
-		// delegate to the nested iterator
-		return this.listIterator.hasNext();
-	}
-
-	@Override
-	public E next() {
-		// delegate to the nested iterator
-		return this.listIterator.next();
-	}
-
-	@Override
-	public boolean hasPrevious() {
-		// delegate to the nested iterator
-		return this.listIterator.hasPrevious();
-	}
-
-	@Override
-	public E previous() {
-		// delegate to the nested iterator
-		return this.listIterator.previous();
-	}
-
-	@Override
-	public int nextIndex() {
-		// delegate to the nested iterator
-		return this.listIterator.nextIndex();
-	}
-
-	@Override
-	public int previousIndex() {
-		// delegate to the nested iterator
-		return this.listIterator.previousIndex();
-	}
-
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public void set(E o) {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public void add(E o) {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.listIterator);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ResultSetIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ResultSetIterator.java
deleted file mode 100644
index 53aac34..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ResultSetIterator.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>ResultSetIterator</code> wraps an SQL {@link ResultSet}
- * and transforms its rows for client consumption. Subclasses can override
- * {@link #buildNext(ResultSet)} to build the expected object from
- * the current row of the result set.
- * <p>
- * To use, supply:<ul>
- * <li> a {@link ResultSet}
- * <li> an {@link Adapter} that converts a row in the {@link ResultSet}
- * into the desired object
- * (alternatively, subclass <code>ResultSetIterator</code>
- * and override the {@link #buildNext(ResultSet)} method)
- * </ul>
- * 
- * @param <E> the type of elements returned by the iterator
- * 
- * @see java.sql.ResultSet
- */
-public class ResultSetIterator<E>
-	implements Iterator<E>
-{
-	private final ResultSet resultSet;
-	private final Adapter<E> adapter;
-	private E next;
-	private boolean done;
-
-	/**
-	 * Construct an iterator on the specified result set that returns
-	 * the objects produced by the specified adapter.
-	 */
-	public ResultSetIterator(ResultSet resultSet, Adapter<E> adapter) {
-		super();
-		this.resultSet = resultSet;
-		this.adapter = adapter;
-		this.done = false;
-		this.next = this.buildNext();
-	}
-
-	/**
-	 * Construct an iterator on the specified result set that returns
-	 * the first object in each row of the result set.
-	 */
-	public ResultSetIterator(ResultSet resultSet) {
-		this(resultSet, Adapter.Default.<E>instance());
-	}
-
-	/**
-	 * Build the next object for the iterator to return.
-	 * Close the result set when we reach the end.
-	 */
-	private E buildNext() {
-		try {
-			if (this.resultSet.next()) {
-				return this.buildNext(this.resultSet);
-			}
-			this.resultSet.close();
-			this.done = true;
-			return null;
-		} catch (SQLException ex) {
-			throw new RuntimeException(ex);
-		}
-	}
-
-	/**
-	 * Returns the first object in the current row
-	 * of the result set. Any {@link SQLException}s will
-	 * be caught and wrapped in a {@link RuntimeException}.
-	 */
-	protected E buildNext(ResultSet rs) throws SQLException {
-		return this.adapter.buildNext(rs);
-	}
-
-	@Override
-	public boolean hasNext() {
-		return ! this.done;
-	}
-
-	@Override
-	public E next() {
-		if (this.done) {
-			throw new NoSuchElementException();
-		}
-		E temp = this.next;
-		this.next = this.buildNext();
-		return temp;
-	}
-
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.resultSet);
-	}
-
-
-	// ********** interface **********
-
-	/**
-	 * Used by {@link ResultSetIterator} to convert a
-	 * {@link ResultSet}'s current row into the next object
-	 * to be returned by the {@link Iterator}.
-	 */
-	public interface Adapter<T> {
-
-		/**
-		 * Returns an object corresponding to the result set's
-		 * "current" row. Any {@link SQLException}s will
-		 * be caught and wrapped in a {@link RuntimeException}.
-		 * @see java.sql.ResultSet
-		 */
-		T buildNext(ResultSet rs) throws SQLException;
-
-		final class Default<S>
-			implements Adapter<S>, Serializable
-		{
-			@SuppressWarnings("rawtypes")
-			public static final Adapter INSTANCE = new Default();
-			@SuppressWarnings("unchecked")
-			public static <R> Adapter<R> instance() {
-				return INSTANCE;
-			}
-			// ensure single instance
-			private Default() {
-				super();
-			}
-			// return the first object in the current row of the result set
-			@Override
-			@SuppressWarnings("unchecked")
-			public S buildNext(ResultSet rs) throws SQLException {
-				// result set columns are indexed starting with 1
-				return (S) rs.getObject(1);
-			}
-			@Override
-			public String toString() {
-				return StringTools.buildSingletonToString(this);
-			}
-			private static final long serialVersionUID = 1L;
-			private Object readResolve() {
-				// replace this object with the singleton
-				return INSTANCE;
-			}
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ReverseIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ReverseIterator.java
deleted file mode 100644
index 2fb90e5..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/ReverseIterator.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>ReverseIterator</code> wraps another {@link Iterator} and returns
- * its elements in the reverse order in which the wrapped {@link Iterator}
- * returns the elements.
- *
- * @param <E> the type of elements returned by the iterator
- */
-public class ReverseIterator<E>
-	implements Iterator<E>
-{
-	/**
-	 * The elements in this iterator are already reversed.
-	 */
-	private final Iterator<E> iterator;
-
-	/**
-	 * Construct a reverse iterator for the specified iterator.
-	 */
-	public ReverseIterator(Iterator<E> iterator) {
-		this(CollectionTools.reverseList(iterator));
-	}
-
-	/**
-	 * Construct a reverse iterator for the specified iterator.
-	 */
-	public ReverseIterator(Iterator<E> iterator, int size) {
-		this(CollectionTools.reverseList(iterator, size));
-	}
-
-	/**
-	 * Construct a reverse iterator for the specified iterable.
-	 */
-	public ReverseIterator(Iterable<E> iterable) {
-		this(CollectionTools.reverseList(iterable));
-	}
-
-	/**
-	 * Construct a reverse iterator for the specified iterable.
-	 */
-	public ReverseIterator(Iterable<E> iterable, int size) {
-		this(CollectionTools.reverseList(iterable, size));
-	}
-
-	private ReverseIterator(ArrayList<E> reverseList) {
-		super();
-		this.iterator = reverseList.iterator();
-	}
-
-	@Override
-	public boolean hasNext() {
-		return this.iterator.hasNext();
-	}
-
-	@Override
-	public E next() {
-		return this.iterator.next();
-	}
-
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this);
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SingleElementIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SingleElementIterator.java
deleted file mode 100644
index 2d5886a..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SingleElementIterator.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>SingleElementIterator</code> holds a single element
- * and returns it with the first call to {@link #next()}, at
- * Returns <code>false</code> to any subsequent
- * call to {@link #hasNext()}.
- * <p>
- * A <code>SingleElementIterator</code> is equivalent to the
- * {@link Iterator} returned by:
- * 	{@link java.util.Collections#singleton(Object element)}<code>.iterator()</code>
- *
- * @param <E> the type of elements returned by the iterator
- *
- * @see org.eclipse.persistence.tools.utility.iterables.SingleElementIterable
- */
-public class SingleElementIterator<E>
-	implements Iterator<E>
-{
-	private final E element;
-	private boolean done;
-
-	/**
-	 * Construct an iterator that returns only the specified element.
-	 */
-	public SingleElementIterator(E element) {
-		super();
-		this.element = element;
-		this.done = false;
-	}
-
-	@Override
-	public boolean hasNext() {
-		return ! this.done;
-	}
-
-	@Override
-	public E next() {
-		if (this.done) {
-			throw new NoSuchElementException();
-		}
-		this.done = true;
-		return this.element;
-	}
-
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.element);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SingleElementListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SingleElementListIterator.java
deleted file mode 100644
index 043d9ad..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SingleElementListIterator.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>SingleElementListIterator</code> holds a single element
- * and returns it with the first call to {@link #next()}, at
- * Returns <code>false</code> to any subsequent
- * Returns <code>false</code>
- * to a call to {@link #hasPrevious()} until a call to {@link #next()},
- * Returns the
- * single element.
- * <p>
- * A <code>SingleElementListIterator</code> is equivalent to the
- * {@link ListIterator} returned by:
- * 	{@link java.util.Collections#singletonList(Object element)}<code>.listIterator()</code>
- *
- * @param <E> the type of elements returned by the iterator
- *
- * @see org.eclipse.persistence.tools.utility.iterables.SingleElementListIterable
- */
-public class SingleElementListIterator<E>
-	implements ListIterator<E>
-{
-	private final E element;
-	private boolean hasNext;
-
-	/**
-	 * Construct a list iterator that returns only the specified element.
-	 */
-	public SingleElementListIterator(E element) {
-		super();
-		this.element = element;
-		this.hasNext = true;
-	}
-
-	@Override
-	public boolean hasNext() {
-		return this.hasNext;
-	}
-
-	@Override
-	public E next() {
-		if (this.hasNext) {
-			this.hasNext = false;
-			return this.element;
-		}
-		throw new NoSuchElementException();
-	}
-
-	@Override
-	public int nextIndex() {
-		return this.hasNext ? 0 : 1;
-	}
-
-	@Override
-	public boolean hasPrevious() {
-		return ! this.hasNext;
-	}
-
-	@Override
-	public E previous() {
-		if (this.hasNext) {
-			throw new NoSuchElementException();
-		}
-		this.hasNext = true;
-		return this.element;
-	}
-
-	@Override
-	public int previousIndex() {
-		return this.hasNext ? -1 : 0;
-	}
-
-	@Override
-	public void add(E e) {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public void set(E e) {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.element);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/StackIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/StackIterator.java
deleted file mode 100644
index d4da9ba..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/StackIterator.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.Stack;
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>StackIterator</code> provides an {@link Iterator}
- * for a {@link Stack} of objects of type <code>E</code>. The stack's elements
- * are {@link Stack#pop() pop}ped" as the iterator returns them with
- * calls to {@link #next()}.
- *
- * @param <E> the type of elements returned by the iterator
- *
- * @see Stack
- * @see org.eclipse.persistence.tools.utility.iterables.StackIterable
- */
-public class StackIterator<E> implements Iterator<E> {
-
-	private final Stack<E> stack;
-
-	/**
-	 * Construct an iterator for the specified stack.
-	 */
-	public StackIterator(Stack<E> stack) {
-		super();
-		this.stack = stack;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean hasNext() {
-		return ! this.stack.isEmpty();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public E next() {
-		return this.stack.pop();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.stack);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SubIteratorWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SubIteratorWrapper.java
deleted file mode 100644
index cd639d4..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SubIteratorWrapper.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Iterator;
-
-/**
- * Wrap an iterator on elements of type <code>E1</code>, converting it into an iterator on elements
- * of type <code>E2</code>. <em>Assume</em> the wrapped iterator returns only elements of type
- * <code>E2</code>. The result is a {@link ClassCastException} if this assumption is false.
- * <p>
- * This is a {@link LateralIteratorWrapper} with more restrictive type parameters.
- *
- * @see org.eclipse.persistence.tools.utility.iterables.SubIterableWrapper
- * @param <E1> input: the type of elements returned by the wrapped iterator
- * @param <E2> output: the type of elements returned by the iterator
- * @version 2.5
- */
-public class SubIteratorWrapper<E1, E2 extends E1> extends LateralIteratorWrapper<E1, E2> {
-
-	/**
-	 * Creates a new <code>SubIteratorWrapper</code>.
-	 *
-	 * @param iterable The {@link Iterable} containing elements of type <code>E1</code>
-	 */
-	public SubIteratorWrapper(Iterable<E1> iterable) {
-		super(iterable);
-	}
-
-	/**
-	 * Creates a new <code>SubIteratorWrapper</code>.
-	 *
-	 * @param iterable The {@link Iterator} containing elements of type <code>E1</code>
-	 */
-	public SubIteratorWrapper(Iterator<E1> iterator) {
-		super(iterator);
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SubListIteratorWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SubListIteratorWrapper.java
deleted file mode 100644
index f581d53..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SubListIteratorWrapper.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-
-/**
- * Wrap a list iterator on elements of type <code>E1</code>, converting it into a list iterator on
- * elements of type <code>E2</code>. <em>Assume</em> the wrapped list iterator returns only elements
- * of type <code>E2</code>. The result is a {@link ClassCastException} if this assumption is false.
- * <p>
- * This is a {@link LateralListIteratorWrapper} with more restrictive type parameters.
- *
- * @see org.eclipse.persistence.tools.utility.iterables.SubListIterableWrapper
- * @param <E1> input: the type of elements returned by the wrapped list iterator
- * @param <E2> output: the type of elements returned by the list iterator
- * @version 2.5
- */
-public class SubListIteratorWrapper<E1, E2 extends E1> extends LateralListIteratorWrapper<E1, E2> {
-
-	public SubListIteratorWrapper(List<E1> list) {
-		super(list);
-	}
-
-	public SubListIteratorWrapper(ListIterable<E1> listIterable) {
-		super(listIterable);
-	}
-
-	public SubListIteratorWrapper(ListIterator<E1> iterator) {
-		super(iterator);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void set(E2 e) {
-		// no explicit cast necessary
-		this.listIterator.set(e);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void add(E2 e) {
-		// no explicit cast necessary
-		this.listIterator.add(e);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SuperIteratorWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SuperIteratorWrapper.java
deleted file mode 100644
index c67e41c..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SuperIteratorWrapper.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * Wrap an iterator on elements of any sub-type of <code>E</code>, converting it into a iterator on
- * elements of type <code>E</code>. This shouldn't be a problem since there is no way to add invalid
- * elements to the iterator's backing collection. (Note the lack of compiler warnings, suppressed or
- * otherwise.)
- *
- * @see org.eclipse.persistence.tools.utility.iterables.SuperIterableWrapper
- * @param <E> the type of elements returned by the iterator
- * @version 2.5
- */
-public class SuperIteratorWrapper<E> implements Iterator<E> {
-
-	private final Iterator<? extends E> iterator;
-
-	/**
-	 * Creates a new <code>SuperIteratorWrapper</code>.
-	 *
-	 * @param iterable The {@link Iterable} containing elements of any sub-type of <code>E</code>
-	 */
-	public SuperIteratorWrapper(Iterable<? extends E> iterable) {
-		this(iterable.iterator());
-	}
-
-	/**
-	 * Creates a new <code>SuperIteratorWrapper</code>.
-	 *
-	 * @param iterable The {@link Iterator} containing elements of any sub-type of <code>E</code>
-	 */
-	public SuperIteratorWrapper(Iterator<? extends E> iterator) {
-		super();
-		this.iterator = iterator;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean hasNext() {
-		return this.iterator.hasNext();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public E next() {
-		return this.iterator.next();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void remove() {
-		this.iterator.remove();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterator);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SuperListIteratorWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SuperListIteratorWrapper.java
deleted file mode 100644
index 69bf4b6..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SuperListIteratorWrapper.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-
-/**
- * Wrap a list iterator on elements of any sub-type of <code>E</code>, converting it into a
- * <em>non-writable</em> list iterator on elements of type <code>E</code>. This shouldn't be a
- * problem since the resulting list iterator disables the methods that would put invalid elements
- * in the iterator's backing list (i.e. {@link #set(Object)} and {@link #add(Object)}).
- *
- * @see org.eclipse.persistence.tools.utility.iterables.SuperListIterableWrapper
- * @param <E> the type of elements returned by the iterator
- * @since 2.5
- */
-public class SuperListIteratorWrapper<E> implements ListIterator<E> {
-
-	private final ListIterator<? extends E> listIterator;
-
-	/**
-	 * Creates a new <code>SuperIteratorWrapper</code>.
-	 *
-	 * @param list The {@link List} containing elements of any sub-type of <code>E</code>
-	 */
-	public SuperListIteratorWrapper(List<? extends E> list) {
-		this(list.listIterator());
-	}
-
-	/**
-	 * Creates a new <code>SuperIteratorWrapper</code>.
-	 *
-	 * @param iterable The {@link ListIterable} containing elements of any sub-type of <code>E</code>
-	 */
-	public SuperListIteratorWrapper(ListIterable<? extends E> listIterable) {
-		this(listIterable.iterator());
-	}
-
-	/**
-	 * Creates a new <code>SuperIteratorWrapper</code>.
-	 *
-	 * @param iterable The {@link ListIterator} containing elements of any sub-type of <code>E</code>
-	 */
-	public SuperListIteratorWrapper(ListIterator<? extends E> listIterator) {
-		super();
-		this.listIterator = listIterator;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void add(E e) {
-		throw new UnsupportedOperationException();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean hasNext() {
-		return this.listIterator.hasNext();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean hasPrevious() {
-		return this.listIterator.hasPrevious();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public E next() {
-		return this.listIterator.next();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int nextIndex() {
-		return this.listIterator.nextIndex();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public E previous() {
-		return this.listIterator.previous();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int previousIndex() {
-		return this.listIterator.previousIndex();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void remove() {
-		this.listIterator.remove();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void set(E e) {
-		throw new UnsupportedOperationException();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.listIterator);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SynchronizedIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SynchronizedIterator.java
deleted file mode 100644
index 369a743..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SynchronizedIterator.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * Wrap an iterator and synchronize all its methods so it can be safely shared
- * among multiple threads.
- *
- * @param <E> the type of elements returned by the iterator
- */
-public class SynchronizedIterator<E>
-	implements Iterator<E>
-{
-	private final Iterator<? extends E> iterator;
-
-	/** Object to synchronize on. */
-	private final Object mutex;
-
-	public SynchronizedIterator(Iterable<? extends E> iterable) {
-		this(iterable.iterator());
-	}
-
-	public SynchronizedIterator(Iterable<? extends E> iterable, Object mutex) {
-		this(iterable.iterator(), mutex);
-	}
-
-	public SynchronizedIterator(Iterator<? extends E> iterator) {
-		super();
-		this.iterator = iterator;
-		this.mutex = this;
-	}
-
-	public SynchronizedIterator(Iterator<? extends E> iterator, Object mutex) {
-		super();
-		this.iterator = iterator;
-		this.mutex = mutex;
-	}
-
-	@Override
-	public synchronized boolean hasNext() {
-		synchronized (this.mutex) {
-			return this.iterator.hasNext();
-		}
-	}
-
-	@Override
-	public synchronized E next() {
-		synchronized (this.mutex) {
-			return this.iterator.next();
-		}
-	}
-
-	@Override
-	public synchronized void remove() {
-		synchronized (this.mutex) {
-			this.iterator.remove();
-		}
-	}
-
-	@Override
-	public String toString() {
-		synchronized (this.mutex) {
-			return StringTools.buildToStringFor(this, this.iterator);
-		}
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SynchronizedListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SynchronizedListIterator.java
deleted file mode 100644
index c62ea87..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/SynchronizedListIterator.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-
-/**
- * Wrap a list iterator and synchronize all its methods so it can be safely shared
- * among multiple threads.
- *
- * @param <E> the type of elements returned by the iterator
- */
-public class SynchronizedListIterator<E>
-	implements ListIterator<E>
-{
-	private final ListIterator<E> listIterator;
-
-	/** Object to synchronize on. */
-	private final Object mutex;
-
-	public SynchronizedListIterator(List<E> list) {
-		this(list.listIterator());
-	}
-
-	public SynchronizedListIterator(List<E> list, Object mutex) {
-		this(list.listIterator(), mutex);
-	}
-
-	public SynchronizedListIterator(ListIterable<E> listIterable) {
-		this(listIterable.iterator());
-	}
-
-	public SynchronizedListIterator(ListIterable<E> listIterable, Object mutex) {
-		this(listIterable.iterator(), mutex);
-	}
-
-	public SynchronizedListIterator(ListIterator<E> listIterator) {
-		super();
-		this.listIterator = listIterator;
-		this.mutex = this;
-	}
-
-	public SynchronizedListIterator(ListIterator<E> listIterator, Object mutex) {
-		super();
-		this.listIterator = listIterator;
-		this.mutex = mutex;
-	}
-
-	@Override
-	public synchronized boolean hasNext() {
-		synchronized (this.mutex) {
-			return this.listIterator.hasNext();
-		}
-	}
-
-	@Override
-	public synchronized E next() {
-		synchronized (this.mutex) {
-			return this.listIterator.next();
-		}
-	}
-
-	@Override
-	public synchronized int nextIndex() {
-		synchronized (this.mutex) {
-			return this.listIterator.nextIndex();
-		}
-	}
-
-	@Override
-	public synchronized boolean hasPrevious() {
-		synchronized (this.mutex) {
-			return this.listIterator.hasPrevious();
-		}
-	}
-
-	@Override
-	public synchronized E previous() {
-		synchronized (this.mutex) {
-			return this.listIterator.previous();
-		}
-	}
-
-	@Override
-	public synchronized int previousIndex() {
-		synchronized (this.mutex) {
-			return this.listIterator.previousIndex();
-		}
-	}
-
-	@Override
-	public synchronized void remove() {
-		synchronized (this.mutex) {
-			this.listIterator.remove();
-		}
-	}
-
-	@Override
-	public synchronized void add(E e) {
-		synchronized (this.mutex) {
-			this.listIterator.add(e);
-		}
-	}
-
-	@Override
-	public synchronized void set(E e) {
-		synchronized (this.mutex) {
-			this.listIterator.set(e);
-		}
-	}
-
-	@Override
-	public String toString() {
-		synchronized (this.mutex) {
-			return StringTools.buildToStringFor(this, this.listIterator);
-		}
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TransformationFilteringIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TransformationFilteringIterator.java
deleted file mode 100644
index 15ff590..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TransformationFilteringIterator.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import org.eclipse.persistence.tools.utility.Filter;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.Transformer;
-
-/**
- * A <code>TransformationFilteringIterator</code> wraps another <code>Iterator</code> and uses a
- * <code>Filter</code> to determine which elements in the nested iterator are to be returned by
- * calls to <code>next()</code>.
- * <p>
- * As an alternative to building a <code>Filter</code>, a subclass can override the
- * <code>accept(E2)</code> method.
- * <p>
- * One, possibly undesirable, side-effect of using this iterator is that the nested iterator's
- * <code>next()</code> method will be invoked <em>before</em> the filtered iterator's <code>next()</code>
- * method is invoked. This is because the "next" element must be checked for whether it is to be
- * accepted before the filtered iterator can determine whether it has a "next" element (i.e. that
- * the <code>hasNext()</code> method should return <code>true</code>). This also prevents a filtered
- * iterator from supporting the optional <code>remove()</code> method.
- *
- * @version 2.5
- */
-@SuppressWarnings("nls")
-public class TransformationFilteringIterator<E1, E2> implements Iterator<E1> {
-
-	/**
-	 * This <code>Filter</code> determines if an item can be returned or should be filtered out.
-	 */
-	private Filter<E2> filter;
-
-	/**
-	 * The <code>Iterator</code> wrapped by this one.
-	 */
-	private Iterator<E2> nestedIterator;
-
-	/**
-	 * The element that can be returned by {@link #next()}.
-	 */
-	private Object next;
-
-	/**
-	 * This <code>Transformer</code> is used to transform the item before return it.
-	 */
-	private Transformer<E1, E2> transformer;
-
-	/**
-	 * Constant used to determine if this <code>Iterator</code> reached the end of its iteration.
-	 */
-	private static final Object END = new Object();
-
-	/**
-	 * Constant used to determine if this <code>Iterator</code> is at the beginning of its iteration.
-	 */
-	private static final Object START = new Object();
-
-	/**
-	 * Creates a new <code>TransformationFilteringIterator</code> with the specified nested {@link
-	 * Iterator} and a filter that simply accepts every object. Use this constructor if you want to
-	 * override the {@link #accept(E2)} method instead of building a {@link Filter}.
-	 *
-	 * @param nestedIterator The <code>Iterator</code> wrapped by this one
-	 */
-	public TransformationFilteringIterator(Iterator<? extends E2> nestedIterator) {
-		this(nestedIterator, Filter.Disabled.<E2>instance());
-	}
-
-	/**
-	 * Creates a new <code>TransformationFilteringIterator</code> with the specified nested {@link
-	 * Iterator} and {@link BidiTransformer}.
-	 *
-	 * @param nestedIterator The <code>Iterator</code> wrapped by this one
-	 * @param filter This <code>Filter</code> determines if an item can be returned or should be filtered out
-	 */
-	public TransformationFilteringIterator(Iterator<? extends E2> nestedIterator,
-	                                       Filter<? extends E2> filter) {
-
-		this(nestedIterator, filter, Transformer.Disabled.<E1, E2>instance());
-	}
-
-	/**
-	 * Creates a new <code>TransformationFilteringIterator</code> with the specified nested {@link
-	 * Iterator}, {@link Filter} and {@link BidiTransformer}.
-	 *
-	 * @param nestedIterator The <code>Iterator</code> wrapped by this one
-	 * @param filter This <code>Filter</code> determines if an item can be returned or should be
-	 * filtered out
-	 * @param transformer This <code>BidiTransformer</code> is used to transform the item before
-	 * return it
-	 */
-	@SuppressWarnings("unchecked")
-	public TransformationFilteringIterator(Iterator<? extends E2> nestedIterator,
-	                                       Filter<? extends E2> filter,
-	                                       Transformer<E1, ? extends E2> transformer) {
-
-		super();
-
-		this.filter         = (Filter<E2>) filter;
-		this.transformer    = (Transformer<E1, E2>) transformer;
-		this.nestedIterator = (Iterator<E2>) nestedIterator;
-
-		// Postpone the pre-load until after the constructor has finished executing
-		this.next = START;
-	}
-
-	/**
-	 * Creates a new <code>TransformationFilteringListIterator</code> with the specified nested
-	 * {@link Iterator} and {@link Transformer}.
-	 *
-	 * @param nestedIterator The <code>Iterator</code> wrapped by this one
-	 * @param transformer This <code>Transformer</code> is used to transform the item before return it
-	 */
-	public TransformationFilteringIterator(Iterator<? extends E2> nestedIterator,
-	                                       Transformer<E1, ? extends E2> transformer) {
-
-		this(nestedIterator, Filter.Disabled.<E2>instance(), transformer);
-	}
-
-	/**
-	 * Returns whether the <code>FilteringIterator</code> should return the specified next element
-	 * from a call to the <code>next()</code> method.
-	 * <p>
-	 * This method can be overridden by a subclass as an alternative to building a <code>Filter</code>.
-	 */
-	protected boolean accept(E2 object) {
-		return filter.accept(object);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean hasNext() {
-
-		if (next == START) {
-			loadNext();
-		}
-
-		return next != END;
-	}
-
-	/**
-	 * Loads next with the next valid entry from the nested iterator. If there are none, next is set
-	 * to <code>END</code>.
-	 */
-	@SuppressWarnings("unchecked")
-	private void loadNext() {
-
-		next = END;
-
-		while (nestedIterator.hasNext() && (next == END)) {
-			next = nestedIterator.next();
-			if (!accept((E2) next)) {
-				next = END;
-			}
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	@SuppressWarnings("unchecked")
-	public E1 next() {
-
-		if (next == START) {
-			loadNext();
-		}
-
-		if (next == END) {
-			throw new NoSuchElementException("No more object can be loaded");
-		}
-
-		Object result = next;
-		loadNext();
-		return transform((E2) result);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void remove() {
-		throw new UnsupportedOperationException("This TransformationFilteringIterator is read-only.");
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		StringBuilder sb = new StringBuilder();
-		StringTools.appendToStringClassName(sb, getClass());
-		sb.append("(");
-		sb.append(nestedIterator);
-		sb.append(")");
-		return sb.toString();
-	}
-
-	/**
-	 * Transforms the specified object and returns the result.
-	 *
-	 * @param next The object to transform, which can be <code>null</code>
-	 * @return The result of the transformation
-	 */
-	protected E1 transform(E2 next) {
-		return (next != null) ? transformNonNull(next) : transformer.transform(next);
-	}
-
-	/**
-	 * Transforms the specified object and returns the result.
-	 *
-	 * @param next The object to transform, which is never <code>null</code>
-	 * @return The result of the transformation
-	 */
-	protected E1 transformNonNull(E2 next) {
-		return transformer.transform(next);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TransformationFilteringListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TransformationFilteringListIterator.java
deleted file mode 100644
index be3fff2..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TransformationFilteringListIterator.java
+++ /dev/null
@@ -1,401 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-import org.eclipse.persistence.tools.utility.BidiTransformer;
-import org.eclipse.persistence.tools.utility.Filter;
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>TransformationFilteringListIterator</code> wraps another {@link ListIterator} and uses
- * a {@link Filter} to determine which elements in the nested iterator are to be returned. The
- * element to return will have been transformed and filtered a second time.
- * <p>
- * As an alternative to building a {@link Filter}, a subclass can override {@link #accept(Object)}.
- * <p>
- * One, possibly undesirable, side-effect of using this iterator is that the nested iterator's
- * {@link ListIterator#next()} method will be invoked <em>before</em> the filtered iterator's
- * {@link ListIterator#next()} method is invoked. This is because the "next" element must be checked
- * for whether it is to be accepted before the filtered iterator can determine whether it has a
- * "next" element (i.e. that the {@link #hasNext()} method should return <code>true</code>). This
- * also prevents a filtered iterator from supporting the optional {@link #remove()} method.
- *
- * @version 2.5
- */
-@SuppressWarnings("nls")
-public class TransformationFilteringListIterator<E1, E2> implements ListIterator<E1> {
-
-	/**
-	 * This {@link Filter} determines if an item can be returned or should be filtered out.
-	 */
-	private Filter<E2> filter;
-
-	/**
-	 * The {@link ListIterator} wrapped by this one.
-	 */
-	private ListIterator<E2> nestedIterator;
-
-	/**
-	 * The element that can be returned by {@link #next()}.
-	 */
-	private Object next;
-
-	/**
-	 * This {@link Filter} determines if the transformed item can be returned or should be filtered out.
-	 */
-	private Filter<E1> postFilter;
-
-	/**
-	 * The element that can be returned by {@link #previous()}.
-	 */
-	private Object previous;
-
-	/**
-	 * This {@link BidiTransformer} is used to transform the item before return it.
-	 */
-	private BidiTransformer<E1, E2> transformer;
-
-	/**
-	 * Constant used to determine if this iterator reached the end of its iteration.
-	 */
-	private static final Object END = new Object();
-
-	/**
-	 * Constant used to determine if this iterator is at the beginning of its iteration.
-	 */
-	private static final Object START = new Object();
-
-	/**
-	 * Creates a new <code>TransformationFilteringListIterator</code> with the specified nested
-	 * {@link ListIterator} and a filter that simply accepts every object. Use this constructor if
-	 * you want to override the {@link #accept(E2)} method instead of building a {@link Filter}.
-	 *
-	 * @param nestedIterator The {@link ListIterator} wrapped by this one
-	 */
-	public TransformationFilteringListIterator(ListIterator<? extends E2> nestedIterator) {
-		this(nestedIterator, Filter.Disabled.<E2>instance());
-	}
-
-	/**
-	 * Creates a new <code>TransformationFilteringListIterator</code> with the specified nested
-	 * {@link Iterator} and {@link BidiTransformer}.
-	 *
-	 * @param nestedIterator The {@link ListIterator} wrapped by this one
-	 * @param transformer This {@link BidiTransformer} is used to transform the item before return it
-	 */
-	public TransformationFilteringListIterator(ListIterator<? extends E2> nestedIterator,
-	                                           BidiTransformer<E1, ? extends E2> transformer) {
-
-		this(nestedIterator, Filter.Disabled.<E2>instance(), Filter.Disabled.<E1>instance(), transformer);
-	}
-
-	/**
-	 * Creates a new <code>TransformationFilteringListIterator</code> with the specified nested
-	 * {@link Iterator} and {@link Filter}.
-	 *
-	 * @param nestedIterator The {@link ListIterator} wrapped by this one
-	 * @param filter This {@link Filter} determines if an item can be returned or should be filtered out
-	 */
-	public TransformationFilteringListIterator(ListIterator<? extends E2> nestedIterator,
-	                                           Filter<? extends E2> filter) {
-
-		this(nestedIterator, filter, Filter.Disabled.<E1>instance(), BidiTransformer.Disabled.<E1, E2>instance());
-	}
-
-	/**
-	 * Creates a new <code>TransformationFilteringListIterator</code> with the specified nested
-	 * {@link Iterator} and {@link Filter}.
-	 *
-	 * @param nestedIterator The {@link ListIterator} wrapped by this one
-	 * @param postFilter This {@link Filter} determines if the transformed item can be returned or
-	 * should be filtered out
-	 * @param filter This {@link Filter} determines if an item can be returned or should be filtered out
-	 */
-	public TransformationFilteringListIterator(ListIterator<? extends E2> nestedIterator,
-	                                           Filter<? extends E2> filter,
-	                                           Filter<? extends E1> postFilter) {
-
-		this(nestedIterator, filter, postFilter, BidiTransformer.Disabled.<E1, E2>instance());
-	}
-
-	/**
-	 * Creates a new <code>TransformationFilteringListIterator</code> with the specified nested
-	 * {@link ListIterator}, {@link Filter} and {@link BidiTransformer}.
-	 *
-	 * @param nestedIterator The {@link ListIterator} wrapped by this one
-	 * @param filter This {@link Filter} determines if an item can be returned or should be filtered out
-	 * @param postFilter This {@link Filter} determines if the transformed item can be returned or
-	 * should be filtered out
-	 * @param transformer This {@link BidiTransformer} is used to transform the item before return it
-	 */
-	@SuppressWarnings("unchecked")
-	public TransformationFilteringListIterator(ListIterator<? extends E2> nestedIterator,
-	                                           Filter<? extends E2> filter,
-	                                           Filter<? extends E1> postFilter,
-	                                           BidiTransformer<E1, ? extends E2> transformer) {
-
-		super();
-
-		this.filter         = (Filter<E2>) filter;
-		this.postFilter     = (Filter<E1>) postFilter;
-		this.transformer    = (BidiTransformer<E1, E2>) transformer;
-		this.nestedIterator = (ListIterator<E2>) nestedIterator;
-
-		// Postpone the pre-load until after the constructor has finished executing
-		this.next = START;
-		this.previous = START;
-	}
-
-	/**
-	 * Returns whether the {@link Filter} should return the specified next element from a call to the
-	 * {@link #next()} method.
-	 * <p>
-	 * This method can be overridden by a subclass as an alternative to building a {@link Filter}.
-	 */
-	protected boolean accept(E2 object) {
-		return filter.accept(object);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void add(E1 value) {
-
-		if (postAccept(value)) {
-			E2 transformedValue = reverseTransform(value);
-
-			if (accept(transformedValue)) {
-				nestedIterator.add(transformedValue);
-			}
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean hasNext() {
-		if (next == START) {
-			loadNext();
-		}
-		return (next != END);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean hasPrevious() {
-		if (previous == START) {
-			loadPrevious();
-		}
-		return (previous != START);
-	}
-
-	/**
-	 * Loads {@link #next} with the next valid entry from the nested iterator. If there are none,
-	 * {@link #next} is set to {@link #END}.
-	 */
-	@SuppressWarnings("unchecked")
-	private void loadNext() {
-
-		next = END;
-
-		while (nestedIterator.hasNext() && (next == END)) {
-
-			// Retrieve the next item from the nested iterator
-			next = nestedIterator.next();
-
-			// Check to see if the item is filtered out or accepted
-			if (accept((E2) next)) {
-
-				// The item is not filtered out, transform it
-				next = transform((E2) next);
-
-				// Now check if the transformed item is filtered out or accepted
-				if (!postAccept((E1) next)) {
-					next = END;
-				}
-			}
-			else {
-				next = END;
-			}
-		}
-	}
-
-	/**
-	 * Loads {@link #previous} with the previous valid entry from the nested iterator. If there are
-	 * none, {@link #next} is set to {@link #START}.
-	 */
-	@SuppressWarnings("unchecked")
-	private void loadPrevious() {
-
-		previous = START;
-
-		while (nestedIterator.hasPrevious() && (next == START)) {
-
-			// Retrieve the previous item from the nested iterator
-			previous = nestedIterator.previous();
-
-			// Check to see if the item is filtered out or accepted
-			if (accept((E2) previous)) {
-
-				// The item is not filtered out, transform it
-				next = transform((E2) previous);
-
-				// Now check if the transformed item is filtered out or accepted
-				if (!postAccept((E1) next)) {
-					next = START;
-				}
-			}
-			else {
-				next = START;
-			}
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	@SuppressWarnings("unchecked")
-	public E1 next() {
-
-		if (next == START) {
-			loadNext();
-		}
-
-		if (next == END) {
-			throw new NoSuchElementException("No more object can be loaded.");
-		}
-
-		Object result = next;
-		loadNext();
-		return (E1) result;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int nextIndex() {
-		throw new NoSuchElementException("This TransformationFilteringListIterator does not support nextIndex().");
-	}
-
-	/**
-	 * Determines whether the transformed value should be filtered out or not before being returned
-	 * by {@link #next()}.
-	 * <p>
-	 * This method can be overridden by a subclass as an alternative to building a {@link Filter}.
-	 */
-	protected boolean postAccept(E1 object) {
-		return postFilter.accept(object);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	@SuppressWarnings("unchecked")
-	public E1 previous() {
-
-		if (previous == START) {
-			throw new NoSuchElementException("No more object can be loaded.");
-		}
-
-		Object result = previous;
-		loadPrevious();
-		return (E1) result;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int previousIndex() {
-		throw new NoSuchElementException("This TransformationFilteringListIterator does not support previousIndex().");
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void remove() {
-		// Because we need to pre-load the next element to be returned,
-		// we cannot support the remove() method
-		throw new UnsupportedOperationException();
-	}
-
-	/**
-	 * Reverses transforms the specified object and returns the result.
-	 * <p>
-	 * This method can be overridden by a subclass as an alternative to building a {@link BidiTransformer}.
-	 */
-	protected E2 reverseTransform(E1 value) {
-		return transformer.reverseTransform(value);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void set(E1 value) {
-
-		if (postAccept(value)) {
-			E2 transformedValue = reverseTransform(value);
-
-			if (accept(transformedValue)) {
-				nestedIterator.set(transformedValue);
-			}
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		StringBuilder sb = new StringBuilder();
-		StringTools.appendToStringClassName(sb, getClass());
-		sb.append("(");
-		sb.append(nestedIterator);
-		sb.append(")");
-		return sb.toString();
-	}
-
-	/**
-	 * Transforms the specified object and returns the result. If the object is not <code>null</code>,
-	 * then {@link #transformNonNull(Object)} is called.
-	 *
-	 * @param next The object to transform, which can be <code>null</code>
-	 * @return The result of the transformation
-	 */
-	protected E1 transform(E2 next) {
-		return (next != null) ? transformNonNull(next) : transformer.transform(next);
-	}
-
-	/**
-	 * Transforms the specified object and returns the result.
-	 *
-	 * @param next The object to transform, which is never <code>null</code>
-	 * @return The result of the transformation
-	 */
-	protected E1 transformNonNull(E2 next) {
-		return transformer.transform(next);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TransformationIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TransformationIterator.java
deleted file mode 100644
index c5cfcb6..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TransformationIterator.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.Iterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.Transformer;
-
-/**
- * A <code>TransformationIterator</code> wraps another {@link Iterator} and transforms its results
- * for client consumption. To use, supply a {@link Transformer} or subclass <code>TransformationIterator</code>
- * and override the {@link #transform(Object)} method. Objects of type <code>E2</code> are transformed
- * into objects of type <code>E1</code>; i.e. the iterator returns objects of type <code>E1</code>.
- *
- * @param <E1> output: the type of elements returned by the iterator
- * @param <E2> input: the type of elements to be transformed
- *
- * @see org.eclipse.persistence.tools.utility.iterables.TransformationIterable
- * @version 2.5
- */
-public class TransformationIterator<E1, E2> implements Iterator<E1> {
-
-	private final Iterator<? extends E2> iterator;
-	private final Transformer<? extends E1, E2> transformer;
-
-	/**
-	 * Construct an iterator with the specified iterable
-	 * and a disabled transformer.
-	 * Use this constructor if you want to override the
-	 * {@link #transform(Object)} method instead of building
-	 * a {@link Transformer}.
-	 */
-	public TransformationIterator(Iterable<? extends E2> iterable) {
-		this(iterable.iterator());
-	}
-
-	/**
-	 * Construct an iterator with the specified nested iterator
-	 * and a disabled transformer.
-	 * Use this constructor if you want to override the
-	 * {@link #transform(Object)} method instead of building
-	 * a {@link Transformer}.
-	 */
-	public TransformationIterator(Iterator<? extends E2> iterator) {
-		this(iterator, Transformer.Disabled.<E1, E2>instance());
-	}
-
-	/**
-	 * Construct an iterator with the specified iterable and transformer.
-	 */
-	public TransformationIterator(Iterable<? extends E2> iterable, Transformer<? extends E1, E2> transformer) {
-		this(iterable.iterator(), transformer);
-	}
-
-	/**
-	 * Construct an iterator with the specified nested iterator and transformer.
-	 */
-	public TransformationIterator(Iterator<? extends E2> iterator, Transformer<? extends E1, E2> transformer) {
-		super();
-		this.iterator = iterator;
-		this.transformer = transformer;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean hasNext() {
-		// Delegate to the nested iterator
-		return this.iterator.hasNext();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public E1 next() {
-		// transform the object returned by the nested iterator before returning it
-		return this.transform(this.iterator.next());
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void remove() {
-		// Delegate to the nested iterator
-		this.iterator.remove();
-	}
-
-	/**
-	 * Returns the result.
-	 */
-	protected E1 transform(E2 next) {
-		return this.transformer.transform(next);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.iterator);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TransformationListIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TransformationListIterator.java
deleted file mode 100644
index 58b1cbe..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TransformationListIterator.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.Transformer;
-import org.eclipse.persistence.tools.utility.iterables.ListIterable;
-
-/**
- * A <code>TransformationListIterator</code> wraps another {@link ListIterator} and transforms its
- * results for client consumption. To use, supply a {@link Transformer} or subclass
- * <code>TransformationIterator</code> and override the {@link #transform(Object)} method.
- * <p>
- * The methods {@link #set(Object)} and {@link #add(Object)} are left unsupported in this class.
- *
- * @param <E1> output: the type of elements returned by the iterator
- * @param <E2> input: the type of elements to be transformed
- *
- * @see org.eclipse.persistence.tools.utility.iterables.TransformationListIterable
- * @version 2.5
- */
-public class TransformationListIterator<E1, E2> implements ListIterator<E1> {
-
-	private final ListIterator<? extends E2> listIterator;
-	private final Transformer<? extends E1, E2> transformer;
-
-	/**
-	 * Construct an iterator with the specified list
-	 * and a disabled transformer.
-	 * Use this constructor if you want to override the
-	 * {@link #transform(Object)} method instead of building
-	 * a {@link Transformer}.
-	 */
-	public TransformationListIterator(List<? extends E2> list) {
-		this(list.listIterator());
-	}
-
-	/**
-	 * Construct an iterator with the specified nested listed iterator
-	 * and a disabled transformer.
-	 * Use this constructor if you want to override the
-	 * {@link #transform(Object)} method instead of building
-	 * a {@link Transformer}.
-	 */
-	public TransformationListIterator(ListIterator<? extends E2> listIterator) {
-		this(listIterator, Transformer.Disabled.<E1, E2>instance());
-	}
-
-	/**
-	 * Construct an iterator with the specified list
-	 * and a disabled transformer.
-	 * Use this constructor if you want to override the
-	 * {@link #transform(Object)} method instead of building
-	 * a {@link Transformer}.
-	 */
-	public TransformationListIterator(ListIterable<? extends E2> listIterable) {
-		this(listIterable.iterator());
-	}
-
-	/**
-	 * Construct an iterator with the specified list and transformer.
-	 */
-	public TransformationListIterator(List<? extends E2> list, Transformer<? extends E1, E2> transformer) {
-		this(list.listIterator(), transformer);
-	}
-
-	/**
-	 * Construct an iterator with the specified list and transformer.
-	 */
-	public TransformationListIterator(ListIterable<? extends E2> listIterable, Transformer<? extends E1, E2> transformer) {
-		this(listIterable.iterator(), transformer);
-	}
-
-	/**
-	 * Construct an iterator with the specified nested iterator and transformer.
-	 */
-	public TransformationListIterator(ListIterator<? extends E2> listIterator, Transformer<? extends E1, E2> transformer) {
-		super();
-		this.listIterator = listIterator;
-		this.transformer = transformer;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean hasNext() {
-		// delegate to the nested iterator
-		return this.listIterator.hasNext();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public E1 next() {
-		// transform the object returned by the nested iterator before returning it
-		return this.transform(this.listIterator.next());
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int nextIndex() {
-		// delegate to the nested iterator
-		return this.listIterator.nextIndex();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean hasPrevious() {
-		// delegate to the nested iterator
-		return this.listIterator.hasPrevious();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public E1 previous() {
-		// transform the object returned by the nested iterator before returning it
-		return this.transform(this.listIterator.previous());
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int previousIndex() {
-		// delegate to the nested iterator
-		return this.listIterator.previousIndex();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void add(E1 o) {
-		throw new UnsupportedOperationException();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void set(E1 o) {
-		throw new UnsupportedOperationException();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void remove() {
-		// delegate to the nested iterator
-		this.listIterator.remove();
-	}
-
-	/**
-	 * Returns the result.
-	 */
-	protected E1 transform(E2 next) {
-		return this.transformer.transform(next);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.listIterator);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TreeIterator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TreeIterator.java
deleted file mode 100644
index b942083..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/iterators/TreeIterator.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.iterators;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.LinkedList;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * A <code>TreeIterator</code> simplifies the traversal of a
- * tree of objects, where the objects' protocol(s) provides
- * a method for getting the immediate children of the given
- * node but does not provide a method for getting all the
- * descendants (children, grandchildren, etc.) of the given node.
- * <p>
- * To use, supply:<ul>
- * <li> either the root element of the tree or, if the tree has
- * multiple roots, an {@link Iterator} over the set of roots
- * <li> a {@link Midwife} that delivers the children
- * of each child
- * (alternatively, subclass <code>TreeIterator</code>
- * and override the {@link #children(Object)} method)
- * </ul>
- * 
- * @param <E> the type of elements returned by the iterator
- * 
- * @see org.eclipse.persistence.tools.utility.iterables.TreeIterable
- */
-public class TreeIterator<E>
-	implements Iterator<E>
-{
-	private final LinkedList<Iterator<? extends E>> iterators;
-	private final Midwife<E> midwife;
-	private Iterator<? extends E> currentIterator;
-
-	/**
-	 * Construct an iterator that returns the nodes of a tree
-	 * with the specified collection of roots
-	 * and a disabled midwife.
-	 * Use this constructor if you want to override the
-	 * {@link #children(Object)} method instead of building
-	 * a {@link Midwife}.
-	 */
-	public TreeIterator(E... roots) {
-		this(new ArrayIterator<E>(roots));
-	}
-
-	/**
-	 * Construct an iterator that returns the nodes of a tree
-	 * with the specified collection of roots
-	 * and a disabled midwife.
-	 * Use this constructor if you want to override the
-	 * {@link #children(Object)} method instead of building
-	 * a {@link Midwife}.
-	 */
-	public TreeIterator(Iterable<? extends E> roots) {
-		this(roots.iterator());
-	}
-
-	/**
-	 * Construct an iterator that returns the nodes of a tree
-	 * with the specified collection of roots
-	 * and a disabled midwife.
-	 * Use this constructor if you want to override the
-	 * {@link #children(Object)} method instead of building
-	 * a {@link Midwife}.
-	 */
-	public TreeIterator(Iterator<? extends E> roots) {
-		this(roots, Midwife.Disabled.<E>instance());
-	}
-
-	/**
-	 * Construct an iterator that returns the nodes of a tree
-	 * with the specified root and a disabled midwife.
-	 * Use this constructor if you want to override the
-	 * {@link #children(Object)} method instead of building
-	 * a {@link Midwife}.
-	 */
-	public TreeIterator(E root) {
-		this(root, Midwife.Disabled.<E>instance());
-	}
-
-	/**
-	 * Construct an iterator that returns the nodes of a tree
-	 * with the specified root and midwife.
-	 */
-	public TreeIterator(E root, Midwife<E> midwife) {
-		this(new SingleElementIterator<E>(root), midwife);
-	}
-
-	/**
-	 * Construct an iterator that returns the nodes of a tree
-	 * with the specified roots and midwife.
-	 */
-	public TreeIterator(E[] roots, Midwife<E> midwife) {
-		this(new ArrayIterator<E>(roots), midwife);
-	}
-
-	/**
-	 * Construct an iterator that returns the nodes of a tree
-	 * with the specified roots and midwife.
-	 */
-	public TreeIterator(Iterable<? extends E> roots, Midwife<E> midwife) {
-		this(roots.iterator(), midwife);
-	}
-
-	/**
-	 * Construct an iterator that returns the nodes of a tree
-	 * with the specified roots and midwife.
-	 */
-	public TreeIterator(Iterator<? extends E> roots, Midwife<E> midwife) {
-		super();
-		this.currentIterator = roots;
-		// use a LinkedList since we will be pulling off the front and adding to the end
-		this.iterators = new LinkedList<Iterator<? extends E>>();
-		this.midwife = midwife;
-	}
-
-	@Override
-	public boolean hasNext() {
-		if (this.currentIterator.hasNext()) {
-			return true;
-		}
-		for (Iterator<? extends E> iterator : this.iterators) {
-			if (iterator.hasNext()) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	@Override
-	public E next() {
-		if (this.currentIterator.hasNext()) {
-			return this.nextInternal();
-		}
-		for (Iterator<Iterator<? extends E>> stream = this.iterators.iterator(); stream.hasNext(); ) {
-			this.currentIterator = stream.next();
-			if (this.currentIterator.hasNext()) {
-				break;
-			}
-			stream.remove();
-		}
-		return this.nextInternal();
-	}
-
-	/**
-	 * Fetch the children of the next node before returning it.
-	 */
-	private E nextInternal() {
-		E next = this.currentIterator.next();
-		this.iterators.add(this.children(next));
-		return next;
-	}
-
-	@Override
-	public void remove() {
-		this.currentIterator.remove();
-	}
-
-	/**
-	 * Returns the immediate children of the specified object.
-	 * <p>
-	 * This method can be overridden by a subclass as an
-	 * alternative to building a {@link Midwife}.
-	 */
-	protected Iterator<? extends E> children(E next) {
-		return this.midwife.children(next);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.currentIterator);
-	}
-
-
-	//********** inner classes **********
-
-	/**
-	 * Used by {@link TreeIterator} to retrieve
-	 * the immediate children of a node in the tree.
-	 */
-	public interface Midwife<T> {
-
-		/**
-		 * Returns the immediate children of the specified object.
-		 */
-		Iterator<? extends T> children(T o);
-
-		final class Null<S> implements
-			Midwife<S>, Serializable
-		{
-			@SuppressWarnings("rawtypes")
-			public static final Midwife INSTANCE = new Null();
-			@SuppressWarnings("unchecked")
-			public static <R> Midwife<R> instance() {
-				return INSTANCE;
-			}
-			// ensure single instance
-			private Null() {
-				super();
-			}
-			// return no neighbors
-			@Override
-			public Iterator<S> children(S next) {
-				return EmptyIterator.instance();
-			}
-			@Override
-			public String toString() {
-				return StringTools.buildSingletonToString(this);
-			}
-			private static final long serialVersionUID = 1L;
-			private Object readResolve() {
-				// replace this object with the singleton
-				return INSTANCE;
-			}
-		}
-
-		/**
-		 * The midwife used when the {@link TreeIterator#children(Object)}
-		 * method is overridden.
-		 */
-		final class Disabled<S>
-			implements Midwife<S>, Serializable
-		{
-			@SuppressWarnings("rawtypes")
-			public static final Midwife INSTANCE = new Disabled();
-			@SuppressWarnings("unchecked")
-			public static <R> Midwife<R> instance() {
-				return INSTANCE;
-			}
-			// ensure single instance
-			private Disabled() {
-				super();
-			}
-			// throw an exception
-			@Override
-			public Iterator<S> children(S next) {
-				throw new UnsupportedOperationException();  // TreeIterator.children(Object) was not implemented
-			}
-			@Override
-			public String toString() {
-				return StringTools.buildSingletonToString(this);
-			}
-			private static final long serialVersionUID = 1L;
-			private Object readResolve() {
-				// replace this object with the singleton
-				return INSTANCE;
-			}
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/jdbc/DriverWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/jdbc/DriverWrapper.java
new file mode 100644
index 0000000..2c35a15
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/jdbc/DriverWrapper.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.jdbc;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+import java.util.Properties;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * This implementation of the {@link Driver JDBC interface} delegates all calls
+ * to a "real" JDBC driver. This wrapper simplifies the dynamic loading of a
+ * JDBC driver that is not on the "Java" classpath (the classpath set at
+ * the time the JVM starts up). This is because, if you use a URL class loader
+ * to load a driver directly, the {@link java.sql.DriverManager} will not allow your code
+ * access to the driver. For security reasons, the driver must be loaded
+ * by the same class loader chain that loaded the code that calls
+ * {@link java.sql.DriverManager#getConnection(String)}.
+ */
+public class DriverWrapper
+	implements Driver
+{
+	/** the "real" JDBC driver */
+	private final Driver driver;
+
+
+	/**
+	 * Wrap the driver for the specified driver class and class loader
+	 * that can load the driver.
+	 */
+	@SuppressWarnings("unchecked")
+	public DriverWrapper(String driverClassName, ClassLoader classLoader)
+		throws ClassNotFoundException, InstantiationException, IllegalAccessException
+	{
+		this((Class<Driver>) Class.forName(driverClassName, true, classLoader));
+	}
+
+	/**
+	 * Wrap the driver for the specified driver class.
+	 */
+	public DriverWrapper(Class<Driver> driverClass)
+		throws InstantiationException, IllegalAccessException
+	{
+		this(driverClass.newInstance());
+	}
+
+	/**
+	 * Wrap the specified driver.
+	 */
+	public DriverWrapper(Driver driver) {
+		super();
+		if (driver == null) {
+			throw new NullPointerException();
+		}
+		this.driver = driver;
+	}
+
+
+	// ********** Driver implementation **********
+
+	@Override
+	public Connection connect(String url, Properties info) throws SQLException {
+		return this.driver.connect(url, info);
+	}
+
+	@Override
+	public boolean acceptsURL(String url) throws SQLException {
+		return this.driver.acceptsURL(url);
+	}
+
+	@Override
+	public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+		return this.driver.getPropertyInfo(url, info);
+	}
+
+	@Override
+	public int getMajorVersion() {
+		return this.driver.getMajorVersion();
+	}
+
+	@Override
+	public int getMinorVersion() {
+		return this.driver.getMinorVersion();
+	}
+
+	@Override
+	public boolean jdbcCompliant() {
+		return this.driver.jdbcCompliant();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.driver);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/jdbc/JDBCTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/jdbc/JDBCTools.java
new file mode 100644
index 0000000..83944f7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/jdbc/JDBCTools.java
@@ -0,0 +1,350 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.jdbc;
+
+import java.sql.Types;
+import java.util.HashMap;
+import org.eclipse.persistence.tools.utility.JavaType;
+import org.eclipse.persistence.tools.utility.SimpleJavaType;
+
+/**
+ * JDBC utility methods.
+ */
+@SuppressWarnings("nls")
+public final class JDBCTools {
+
+	/**
+	 * Return the JDBC type corresponding to the specified class.
+	 * @see java.sql.Types
+	 */
+	public static JDBCType jdbcTypeForClassNamed(String className) {
+		JavaToJDBCTypeMapping mapping = getJavaToJDBCTypeMapping(className);
+		return (mapping == null) ? DEFAULT_JDBC_TYPE : mapping.getJDBCType();
+	}
+
+	/**
+	 * Return the JDBC type corresponding to the specified class.
+	 * @see java.sql.Types
+	 */
+	public static JDBCType jdbcType(Class<?> javaClass) {
+		return jdbcTypeForClassNamed(javaClass.getName());
+	}
+
+	/**
+	 * Return the JDBC type corresponding to the specified class.
+	 * @see java.sql.Types
+	 */
+	public static JDBCType jdbcType(JavaType javaType) {
+		return jdbcTypeForClassNamed(javaType.getJavaClassName());
+	}
+
+	/**
+	 * Return the Java type corresponding to the specified JDBC type.
+	 * @see java.sql.Types
+	 */
+	public static JavaType javaTypeForJDBCTypeNamed(String jdbcTypeName) {
+		JDBCToJavaTypeMapping mapping = getJDBCToJavaTypeMapping(jdbcTypeName);
+		return (mapping == null) ? DEFAULT_JAVA_TYPE : mapping.getJavaType();
+	}
+
+	/**
+	 * Return the Java type corresponding to the specified JDBC type.
+	 * @see java.sql.Types
+	 */
+	public static JavaType javaType(JDBCType jdbcType) {
+		return javaTypeForJDBCTypeNamed(jdbcType.name());
+	}
+
+	/**
+	 * Return the Java type corresponding to the specified JDBC type.
+	 * @see java.sql.Types
+	 */
+	public static JavaType javaTypeForJDBCTypeCode(int jdbcTypeCode) {
+		return javaType(JDBCType.type(jdbcTypeCode));
+	}
+
+
+	// ********** JDBC => Java **********
+
+	/**
+	 * JDBC => Java type mappings, keyed by JDBC type name
+	 * (e.g. <code>"VARCHAR"</code>)
+	 */
+	private static HashMap<String, JDBCToJavaTypeMapping> JDBC_TO_JAVA_TYPE_MAPPINGS;  // pseudo 'final' - lazy-initialized
+	private static final JavaType DEFAULT_JAVA_TYPE = new SimpleJavaType(java.lang.Object.class);  // TODO Object is the default?
+
+
+	private static JDBCToJavaTypeMapping getJDBCToJavaTypeMapping(String jdbcTypeName) {
+		return getJDBCToJavaTypeMappings().get(jdbcTypeName);
+	}
+
+	private static synchronized HashMap<String, JDBCToJavaTypeMapping> getJDBCToJavaTypeMappings() {
+		if (JDBC_TO_JAVA_TYPE_MAPPINGS == null) {
+			JDBC_TO_JAVA_TYPE_MAPPINGS = buildJDBCToJavaTypeMappings();
+		}
+		return JDBC_TO_JAVA_TYPE_MAPPINGS;
+	}
+
+	private static HashMap<String, JDBCToJavaTypeMapping> buildJDBCToJavaTypeMappings() {
+		HashMap<String, JDBCToJavaTypeMapping> mappings = new HashMap<String, JDBCToJavaTypeMapping>();
+		addJDBCToJavaTypeMappings(mappings);
+		return mappings;
+	}
+
+	/**
+	 * Hard code the default mappings from the JDBC types to the
+	 * appropriate Java types.
+	 * See "JDBC 3.0 Specification" Appendix B.
+	 * @see java.sql.Types
+	 */
+	private static void addJDBCToJavaTypeMappings(HashMap<String, JDBCToJavaTypeMapping> mappings) {
+		addJDBCToJavaTypeMapping(Types.ARRAY, java.sql.Array.class, mappings);
+		addJDBCToJavaTypeMapping(Types.BIGINT, long.class, mappings);
+		addJDBCToJavaTypeMapping(Types.BINARY, byte[].class, mappings);
+		addJDBCToJavaTypeMapping(Types.BIT, boolean.class, mappings);
+		addJDBCToJavaTypeMapping(Types.BLOB, java.sql.Blob.class, mappings);
+		addJDBCToJavaTypeMapping(Types.BOOLEAN, boolean.class, mappings);
+		addJDBCToJavaTypeMapping(Types.CHAR, java.lang.String.class, mappings);
+		addJDBCToJavaTypeMapping(Types.CLOB, java.sql.Clob.class, mappings);
+		addJDBCToJavaTypeMapping(Types.DATALINK, java.net.URL.class, mappings);
+		addJDBCToJavaTypeMapping(Types.DATE, java.sql.Date.class, mappings);
+		addJDBCToJavaTypeMapping(Types.DECIMAL, java.math.BigDecimal.class, mappings);
+		addJDBCToJavaTypeMapping(Types.DISTINCT, java.lang.Object.class, mappings);  // ???
+		addJDBCToJavaTypeMapping(Types.DOUBLE, double.class, mappings);
+		addJDBCToJavaTypeMapping(Types.FLOAT, double.class, mappings);
+		addJDBCToJavaTypeMapping(Types.INTEGER, int.class, mappings);
+		addJDBCToJavaTypeMapping(Types.JAVA_OBJECT, java.lang.Object.class, mappings);  // ???
+		addJDBCToJavaTypeMapping(Types.LONGVARBINARY, byte[].class, mappings);
+		addJDBCToJavaTypeMapping(Types.LONGVARCHAR, java.lang.String.class, mappings);
+		// not sure why this is defined in java.sql.Types
+//		addJDBCToJavaTypeMappingTo(Types.NULL, java.lang.Object.class, mappings);
+		addJDBCToJavaTypeMapping(Types.NUMERIC, java.math.BigDecimal.class, mappings);
+		addJDBCToJavaTypeMapping(Types.OTHER, java.lang.Object.class, mappings);	// ???
+		addJDBCToJavaTypeMapping(Types.REAL, float.class, mappings);
+		addJDBCToJavaTypeMapping(Types.REF, java.sql.Ref.class, mappings);
+		addJDBCToJavaTypeMapping(Types.SMALLINT, short.class, mappings);
+		addJDBCToJavaTypeMapping(Types.STRUCT, java.sql.Struct.class, mappings);
+		addJDBCToJavaTypeMapping(Types.TIME, java.sql.Time.class, mappings);
+		addJDBCToJavaTypeMapping(Types.TIMESTAMP, java.sql.Timestamp.class, mappings);
+		addJDBCToJavaTypeMapping(Types.TINYINT, byte.class, mappings);
+		addJDBCToJavaTypeMapping(Types.VARBINARY, byte[].class, mappings);
+		addJDBCToJavaTypeMapping(Types.VARCHAR, java.lang.String.class, mappings);
+	}
+
+	private static void addJDBCToJavaTypeMapping(int jdbcTypeCode, Class<?> javaClass, HashMap<String, JDBCToJavaTypeMapping> mappings) {
+		// check for duplicates
+		JDBCType jdbcType = JDBCType.type(jdbcTypeCode);
+		Object prev = mappings.put(jdbcType.name(), buildJDBCToJavaTypeMapping(jdbcType, javaClass));
+		if (prev != null) {
+			throw new IllegalArgumentException("duplicate JDBC type: " + jdbcType.name());
+		}
+	}
+
+	private static JDBCToJavaTypeMapping buildJDBCToJavaTypeMapping(JDBCType jdbcType, Class<?> javaClass) {
+		return new JDBCToJavaTypeMapping(jdbcType, new SimpleJavaType(javaClass));
+	}
+
+
+	// ********** Java => JDBC **********
+
+	/**
+	 * Java => JDBC type mappings, keyed by Java class name
+	 * (e.g. <code>"java.lang.Object"</code>).
+	 */
+	private static HashMap<String, JavaToJDBCTypeMapping> JAVA_TO_JDBC_TYPE_MAPPINGS;  // pseudo 'final' - lazy-initialized
+	private static final JDBCType DEFAULT_JDBC_TYPE = JDBCType.type(Types.VARCHAR);  // TODO VARCHAR is the default?
+
+
+	private static JavaToJDBCTypeMapping getJavaToJDBCTypeMapping(String className) {
+		return getJavaToJDBCTypeMappings().get(className);
+	}
+
+	private static synchronized HashMap<String, JavaToJDBCTypeMapping> getJavaToJDBCTypeMappings() {
+		if (JAVA_TO_JDBC_TYPE_MAPPINGS == null) {
+			JAVA_TO_JDBC_TYPE_MAPPINGS = buildJavaToJDBCTypeMappings();
+		}
+		return JAVA_TO_JDBC_TYPE_MAPPINGS;
+	}
+
+	private static HashMap<String, JavaToJDBCTypeMapping> buildJavaToJDBCTypeMappings() {
+		HashMap<String, JavaToJDBCTypeMapping> mappings = new HashMap<String, JavaToJDBCTypeMapping>();
+		addJavaToJDBCTypeMappings(mappings);
+		return mappings;
+	}
+
+	/**
+	 * Hard code the default mappings from the Java types to the
+	 * appropriate JDBC types.
+	 * See "JDBC 3.0 Specification" Appendix B.
+	 * @see java.sql.Types
+	 */
+	private static void addJavaToJDBCTypeMappings(HashMap<String, JavaToJDBCTypeMapping> mappings) {
+		// primitives
+		addJavaToJDBCTypeMapping(boolean.class, Types.BIT, mappings);
+		addJavaToJDBCTypeMapping(byte.class, Types.TINYINT, mappings);
+		addJavaToJDBCTypeMapping(double.class, Types.DOUBLE, mappings);
+		addJavaToJDBCTypeMapping(float.class, Types.REAL, mappings);
+		addJavaToJDBCTypeMapping(int.class, Types.INTEGER, mappings);
+		addJavaToJDBCTypeMapping(long.class, Types.BIGINT, mappings);
+		addJavaToJDBCTypeMapping(short.class, Types.SMALLINT, mappings);
+
+		// reference classes
+		addJavaToJDBCTypeMapping(java.lang.Boolean.class, Types.BIT, mappings);
+		addJavaToJDBCTypeMapping(java.lang.Byte.class, Types.TINYINT, mappings);
+		addJavaToJDBCTypeMapping(java.lang.Double.class, Types.DOUBLE, mappings);
+		addJavaToJDBCTypeMapping(java.lang.Float.class, Types.REAL, mappings);
+		addJavaToJDBCTypeMapping(java.lang.Integer.class, Types.INTEGER, mappings);
+		addJavaToJDBCTypeMapping(java.lang.Long.class, Types.BIGINT, mappings);
+		addJavaToJDBCTypeMapping(java.lang.Short.class, Types.SMALLINT, mappings);
+		addJavaToJDBCTypeMapping(java.lang.String.class, Types.VARCHAR, mappings);
+		addJavaToJDBCTypeMapping(java.math.BigDecimal.class, Types.NUMERIC, mappings);
+		addJavaToJDBCTypeMapping(java.net.URL.class, Types.DATALINK, mappings);
+		addJavaToJDBCTypeMapping(java.sql.Array.class, Types.ARRAY, mappings);
+		addJavaToJDBCTypeMapping(java.sql.Blob.class, Types.BLOB, mappings);
+		addJavaToJDBCTypeMapping(java.sql.Clob.class, Types.CLOB, mappings);
+		addJavaToJDBCTypeMapping(java.sql.Date.class, Types.DATE, mappings);
+		addJavaToJDBCTypeMapping(java.sql.Ref.class, Types.REF, mappings);
+		addJavaToJDBCTypeMapping(java.sql.Struct.class, Types.STRUCT, mappings);
+		addJavaToJDBCTypeMapping(java.sql.Time.class, Types.TIME, mappings);
+		addJavaToJDBCTypeMapping(java.sql.Timestamp.class, Types.TIMESTAMP, mappings);
+
+		// arrays
+		addJavaToJDBCTypeMapping(byte[].class, Types.VARBINARY, mappings);
+		addJavaToJDBCTypeMapping(java.lang.Byte[].class, Types.VARBINARY, mappings);
+	}
+
+	private static void addJavaToJDBCTypeMapping(Class<?> javaClass, int jdbcTypeCode, HashMap<String, JavaToJDBCTypeMapping> mappings) {
+		// check for duplicates
+		Object prev = mappings.put(javaClass.getName(), buildJavaToJDBCTypeMapping(javaClass, jdbcTypeCode));
+		if (prev != null) {
+			throw new IllegalArgumentException("duplicate Java class: " + ((JavaToJDBCTypeMapping) prev).getJavaType().declaration());
+		}
+	}
+
+	private static JavaToJDBCTypeMapping buildJavaToJDBCTypeMapping(Class<?> javaClass, int jdbcTypeCode) {
+		return new JavaToJDBCTypeMapping(new SimpleJavaType(javaClass), JDBCType.type(jdbcTypeCode));
+	}
+
+
+	// ********** constructor **********
+
+	/**
+	 * Suppress default constructor, ensuring non-instantiability.
+	 */
+	private JDBCTools() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+
+
+	// ********** mapping classes **********
+
+	/**
+	 * JDBC => Java
+	 */
+	static class JDBCToJavaTypeMapping {
+		private final JDBCType jdbcType;
+		private final JavaType javaType;
+
+		JDBCToJavaTypeMapping(JDBCType jdbcType, JavaType javaType) {
+			super();
+			this.jdbcType = jdbcType;
+			this.javaType = javaType;
+		}
+
+		public JDBCType getJDBCType() {
+			return this.jdbcType;
+		}
+
+		public JavaType getJavaType() {
+			return this.javaType;
+		}
+
+		public boolean maps(int jdbcTypeCode) {
+			return this.jdbcType.code() == jdbcTypeCode;
+		}
+
+		public boolean maps(String jdbcTypeName) {
+			return this.jdbcType.name().equals(jdbcTypeName);
+		}
+
+		public boolean maps(JDBCType type) {
+			return this.jdbcType == type;
+		}
+
+		@Override
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			this.appendTo(sb);
+			return sb.toString();
+		}
+
+		public void appendTo(StringBuilder sb) {
+			this.jdbcType.appendTo(sb);
+			sb.append(" => ");
+			this.javaType.appendDeclarationTo(sb);
+		}
+	}
+
+	/**
+	 * Java => JDBC
+	 */
+	static class JavaToJDBCTypeMapping {
+		private final JavaType javaType;
+		private final JDBCType jdbcType;
+
+		JavaToJDBCTypeMapping(JavaType javaType, JDBCType jdbcType) {
+			super();
+			this.javaType = javaType;
+			this.jdbcType = jdbcType;
+		}
+
+		public JavaType getJavaType() {
+			return this.javaType;
+		}
+
+		public JDBCType getJDBCType() {
+			return this.jdbcType;
+		}
+
+		public boolean maps(JavaType jt) {
+			return this.javaType.equals(jt);
+		}
+
+		public boolean maps(String elementTypeName, int arrayDepth) {
+			return this.javaType.equals(elementTypeName, arrayDepth);
+		}
+
+		public boolean maps(String javaClassName) {
+			return this.javaType.describes(javaClassName);
+		}
+
+		public boolean maps(Class<?> javaClass) {
+			return this.javaType.describes(javaClass);
+		}
+
+		@Override
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			this.appendTo(sb);
+			return sb.toString();
+		}
+
+		public void appendTo(StringBuilder sb) {
+			this.javaType.appendDeclarationTo(sb);
+			sb.append(" => ");
+			this.jdbcType.appendTo(sb);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/jdbc/JDBCType.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/jdbc/JDBCType.java
new file mode 100644
index 0000000..6b6dc1b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/jdbc/JDBCType.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.jdbc;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.sql.Types;
+
+/**
+ * Associate the Java constant and the JDBC type name.
+ * These are derived from java.sql.Types.
+ *
+ * @see java.sql.Types
+ */
+@SuppressWarnings("nls")
+public final class JDBCType
+	implements Cloneable, Serializable
+{
+
+	/**
+	 * the constant name (e.g. VARCHAR)
+	 */
+	private final String name;
+
+	/**
+	 * the JDBC code used by JDBC drivers
+	 */
+	private final int code;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a JDBC type with the specified name and type code.
+	 * This is private because all the possible JDBC types are built and
+	 * stored in the static array TYPES.
+	 * @see #types()
+	 */
+	private JDBCType(String name, int code) {
+		super();
+		this.name = name;
+		this.code = code;
+	}
+
+
+	// ********** accessors **********
+
+	/**
+	 * Return the name of the type, as defined in java.sql.Types.
+	 */
+	public String name() {
+		return this.name;
+	}
+
+
+	/**
+	 * Return the type code, as defined in java.sql.Types.
+	 */
+	public int code() {
+		return this.code;
+	}
+
+
+	// ********** printing and displaying **********
+
+	public void appendTo(StringBuilder sb) {
+		sb.append(this.name);
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		sb.append(this.getClass().getSimpleName());
+		sb.append('(');
+		this.appendTo(sb);
+		sb.append(')');
+		return sb.toString();
+	}
+
+	@Override
+	public JDBCType clone() {
+		try {
+			return (JDBCType) super.clone();
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+
+	// ********** static stuff **********
+
+	/**
+	 * all the JDBC type defined in java.sql.Types
+	 */
+	private static JDBCType[] TYPES;		// pseudo 'final' - lazy-initialized
+
+
+	public synchronized static JDBCType[] types() {
+		if (TYPES == null) {
+			TYPES = buildTypes();
+		}
+		return TYPES;
+	}
+
+	/**
+	 * Return the JDBC type for the specified type code (e.g. Types.VARCHAR).
+	 * @see java.sql.Types
+	 */
+	public static JDBCType type(int code) {
+		JDBCType[] types = types();
+		for (int i = types.length; i-- > 0; ) {
+			if (types[i].code() == code) {
+				return types[i];
+			}
+		}
+		throw new IllegalArgumentException("invalid JDBC type code: " + code);
+	}
+
+	/**
+	 * Return the JDBC type for the specified type name (e.g. "VARCHAR").
+	 * @see java.sql.Types
+	 */
+	public static JDBCType type(String name) {
+		JDBCType[] types = types();
+		for (int i = types.length; i-- > 0; ) {
+			if (types[i].name().equals(name)) {
+				return types[i];
+			}
+		}
+		throw new IllegalArgumentException("invalid JDBC type name: " + name);
+	}
+
+	/**
+	 * build up the JDBC types via reflection
+	 * @see java.sql.Types
+	 */
+	private static JDBCType[] buildTypes() {
+		Field[] fields = Types.class.getDeclaredFields();
+		int len = fields.length;
+		JDBCType[] types = new JDBCType[len];
+		for (int i = len; i-- > 0; ) {
+			String name = fields[i].getName();
+			int code;
+			try {
+				code = ((Integer) fields[i].get(null)).intValue();
+			} catch (IllegalAccessException ex) {
+				throw new RuntimeException(ex);	// shouldn't happen...
+			}
+			types[i] = new JDBCType(name, code);
+		}
+		return types;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/log/LoggingMultiThreadedExceptionHandler.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/log/LoggingMultiThreadedExceptionHandler.java
new file mode 100644
index 0000000..08509f7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/log/LoggingMultiThreadedExceptionHandler.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.log;
+
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+import org.eclipse.persistence.tools.utility.MultiThreadedExceptionHandlerAdapter;
+
+/**
+ * This exception handler logs any exceptions to a JDK logger.
+ */
+@SuppressWarnings("nls")
+public class LoggingMultiThreadedExceptionHandler
+	extends MultiThreadedExceptionHandlerAdapter
+{
+	private final Logger logger;
+	private final Level level;
+	private final String message;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a listener that logs exceptions to the root logger
+	 * at the SEVERE level with the generic message "Unexpected Exception".
+	 */
+	public LoggingMultiThreadedExceptionHandler() {
+		this(Logger.getLogger(null));
+	}
+
+	/**
+	 * Construct a handler that logs exceptions to the specified logger
+	 * at the SEVERE level with the generic message "Unexpected Exception".
+	 */
+	public LoggingMultiThreadedExceptionHandler(Logger logger) {
+		this(logger, Level.SEVERE);
+	}
+
+	/**
+	 * Construct a handler that logs exceptions to the specified logger
+	 * at the specified level with the generic message "Unexpected Exception".
+	 */
+	public LoggingMultiThreadedExceptionHandler(Logger logger, Level level) {
+		this(logger, level, "Unexpected Exception");
+	}
+
+	/**
+	 * Construct a handler that logs exceptions to the specified logger
+	 * at the specified level with the specified message.
+	 */
+	public LoggingMultiThreadedExceptionHandler(Logger logger, Level level, String message) {
+		super();
+		if ((logger == null) || (level == null) || (message == null)) {
+			throw new NullPointerException();
+		}
+		this.logger = logger;
+		this.level = level;
+		this.message = message;
+	}
+
+
+	@Override
+	public void handleException(Throwable exception) {
+		this.handleException(null, exception);
+	}
+
+	/**
+	 * We need to do all this because {@link Logger#log(LogRecord)}
+	 * does not pass through {@link Logger#doLog(LogRecord)}
+	 * like all the other <code>Logger#log(...)</code> methods.
+	 */
+	@Override
+	public void handleException(Thread thread, Throwable exception) {
+		LogRecord logRecord = new LogRecord(this.level, this.message);
+		logRecord.setParameters(new Object[] { (thread == null) ? "null" : thread.getName() });
+		logRecord.setThrown(exception);
+		logRecord.setLoggerName(this.logger.getName());
+		logRecord.setResourceBundle(this.logger.getResourceBundle());
+		this.logger.log(logRecord);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/log/SystemExitLoggingHandler.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/log/SystemExitLoggingHandler.java
new file mode 100644
index 0000000..2c22914
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/log/SystemExitLoggingHandler.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.log;
+
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.RunnableSystemExit;
+
+/**
+ * This logging handler will shutdown the JVM if it receives
+ * a sufficiently severe log record.
+ */
+@SuppressWarnings("nls")
+public class SystemExitLoggingHandler
+	extends Handler
+{
+	Runnable runnableSystemExit;
+
+
+	/**
+	 * Construct a logging handler that will shut down the JVM if it
+	 * receives a sufficiently severe log record. It will wait the
+	 * specified amount of time and exit with the specified status.
+	 */
+	public SystemExitLoggingHandler(int wait, int exitStatus) {
+		super();
+		this.runnableSystemExit = new RunnableSystemExit(wait, exitStatus);
+	}
+
+	@Override
+	public void close() throws SecurityException {
+		// do nothing
+	}
+
+	@Override
+	public void flush() {
+		// do nothing
+	}
+
+	@Override
+	public void publish(LogRecord record) {
+		if (this.isLoggable(record)) {
+			new Thread(this.runnableSystemExit, "System exit").start();
+		}
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/AbstractModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/AbstractModel.java
index 6f8671b..f44ca6d 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/AbstractModel.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/AbstractModel.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -16,8 +16,7 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
-
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
 import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
@@ -30,16 +29,11 @@
 import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
 import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeRemoveEvent;
 import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.TreeChangeListener;
 
 /**
  * Reasonable implementation of the {@link Model} protocol
@@ -65,6 +59,7 @@
 	 */
 	protected ChangeSupport changeSupport;
 
+
 	// ********** constructors/initialization **********
 
 	/**
@@ -120,7 +115,7 @@
 	}
 
 	/**
-	 * Returns whether the model has no change listeners.
+	 * Return whether the model has no change listeners.
 	 */
 	public boolean hasNoChangeListeners() {
 		return ! this.hasAnyChangeListeners();
@@ -153,7 +148,7 @@
 	}
 
 	/**
-	 * Returns whether the model has no state change listeners.
+	 * Return whether the model has no state change listeners.
 	 */
 	public boolean hasNoStateChangeListeners() {
 		return ! this.hasAnyStateChangeListeners();
@@ -200,7 +195,7 @@
 	}
 
 	/**
-	 * Returns whether the model has no property change listeners that will
+	 * Return whether the model has no property change listeners that will
 	 * be notified when the specified property has changed.
 	 */
 	public boolean hasNoPropertyChangeListeners(String propertyName) {
@@ -270,7 +265,7 @@
 	}
 
 	/**
-	 * Returns whether the model has no collection change listeners that will
+	 * Return whether the model has no collection change listeners that will
 	 * be notified when the specified collection has changed.
 	 */
 	public boolean hasNoCollectionChangeListeners(String collectionName) {
@@ -494,7 +489,7 @@
 	}
 
 	/**
-	 * Returns whether the model has no list change listeners that will
+	 * Return whether the model has no list change listeners that will
 	 * be notified when the specified list has changed.
 	 */
 	public boolean hasNoListChangeListeners(String listName) {
@@ -846,100 +841,10 @@
 	}
 
 
-	// ********** tree change support **********
-
-	/**
-	 * @see ChangeSupport#addTreeChangeListener(String, TreeChangeListener)
-	 */
-	@Override
-	public void addTreeChangeListener(String treeName, TreeChangeListener listener) {
-		this.getChangeSupport().addTreeChangeListener(treeName, listener);
-	}
-
-	/**
-	 * @see ChangeSupport#removeTreeChangeListener(String, TreeChangeListener)
-	 */
-	@Override
-	public void removeTreeChangeListener(String treeName, TreeChangeListener listener) {
-		this.getChangeSupport().removeTreeChangeListener(treeName, listener);
-	}
-
-	/**
-	 * @see ChangeSupport#hasAnyTreeChangeListeners(String)
-	 */
-	public boolean hasAnyTreeChangeListeners(String treeName) {
-		return (this.changeSupport != null) && this.changeSupport.hasAnyTreeChangeListeners(treeName);
-	}
-
-	/**
-	 * Returns whether the model has no tree change listeners that will
-	 * be notified when the specified tree has changed.
-	 */
-	public boolean hasNoTreeChangeListeners(String treeName) {
-		return ! this.hasAnyTreeChangeListeners(treeName);
-	}
-
-	/**
-	 * @see ChangeSupport#fireNodeAdded(TreeAddEvent)
-	 */
-	protected final void fireNodeAdded(TreeAddEvent event) {
-		this.getChangeSupport().fireNodeAdded(event);
-	}
-
-	/**
-	 * @see ChangeSupport#fireNodeAdded(String, List)
-	 */
-	protected final void fireNodeAdded(String treeName, List<?> path) {
-		this.getChangeSupport().fireNodeAdded(treeName, path);
-	}
-
-	/**
-	 * @see ChangeSupport#fireNodeRemoved(TreeRemoveEvent)
-	 */
-	protected final void fireNodeRemoved(TreeRemoveEvent event) {
-		this.getChangeSupport().fireNodeRemoved(event);
-	}
-
-	/**
-	 * @see ChangeSupport#fireNodeRemoved(String, List)
-	 */
-	protected final void fireNodeRemoved(String treeName, List<?> path) {
-		this.getChangeSupport().fireNodeRemoved(treeName, path);
-	}
-
-	/**
-	 * @see ChangeSupport#fireTreeCleared(TreeClearEvent)
-	 */
-	protected final void fireTreeCleared(TreeClearEvent event) {
-		this.getChangeSupport().fireTreeCleared(event);
-	}
-
-	/**
-	 * @see ChangeSupport#fireTreeCleared(String)
-	 */
-	protected final void fireTreeCleared(String treeName) {
-		this.getChangeSupport().fireTreeCleared(treeName);
-	}
-
-	/**
-	 * @see ChangeSupport#fireTreeChanged(TreeChangeEvent)
-	 */
-	protected final void fireTreeChanged(TreeChangeEvent event) {
-		this.getChangeSupport().fireTreeChanged(event);
-	}
-
-	/**
-	 * @see ChangeSupport#fireTreeChanged(String, Collection)
-	 */
-	protected final void fireTreeChanged(String treeName, Collection<?> nodes) {
-		this.getChangeSupport().fireTreeChanged(treeName, nodes);
-	}
-
-
 	// ********** convenience methods **********
 
 	/**
-	 * Returns whether the specified values are equal, with the appropriate <code>null</code> checks.
+	 * Return whether the specified values are equal, with the appropriate <code>null</code> checks.
 	 * Convenience method for checking whether an attribute value has changed.
 	 * <p>
 	 * <em>Do not</em> use this to determine whether to fire a change notification,
@@ -999,7 +904,7 @@
 	@Override
 	public String toString() {
 		StringBuilder sb = new StringBuilder();
-		StringTools.appendSimpleToString(sb, this);
+		StringBuilderTools.appendHashCodeToString(sb, this);
 		sb.append('(');
 		int len = sb.length();
 		this.toString(sb);
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/AspectChangeSupport.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/AspectChangeSupport.java
index 3493ecb..1834e34 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/AspectChangeSupport.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/AspectChangeSupport.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -16,7 +16,6 @@
 import java.util.Collection;
 import java.util.EventListener;
 import java.util.List;
-
 import org.eclipse.persistence.tools.utility.ListenerList;
 import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
@@ -30,10 +29,6 @@
 import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
 import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeRemoveEvent;
 
 /**
  * This change support class will notify listeners whenever one of the source's
@@ -50,6 +45,7 @@
 	private static final long serialVersionUID = 1L;
 	protected static final Class<Listener> LISTENER_CLASS = Listener.class;
 
+
 	public AspectChangeSupport(Model source, Listener listener) {
 		this(source);
 		this.addListener(listener);
@@ -297,56 +293,4 @@
 		super.fireListChanged(listName, list);
 		this.aspectChanged(listName);
 	}
-
-
-	// ********** tree change support **********
-
-	@Override
-	public void fireNodeAdded(TreeAddEvent event) {
-		super.fireNodeAdded(event);
-		this.aspectChanged(event.getTreeName());
-	}
-
-	@Override
-	public void fireNodeAdded(String treeName, List<?> path) {
-		super.fireNodeAdded(treeName, path);
-		this.aspectChanged(treeName);
-	}
-
-	@Override
-	public void fireNodeRemoved(TreeRemoveEvent event) {
-		super.fireNodeRemoved(event);
-		this.aspectChanged(event.getTreeName());
-	}
-
-	@Override
-	public void fireNodeRemoved(String treeName, List<?> path) {
-		super.fireNodeRemoved(treeName, path);
-		this.aspectChanged(treeName);
-	}
-
-	@Override
-	public void fireTreeCleared(TreeClearEvent event) {
-		super.fireTreeCleared(event);
-		this.aspectChanged(event.getTreeName());
-	}
-
-	@Override
-	public void fireTreeCleared(String treeName) {
-		super.fireTreeCleared(treeName);
-		this.aspectChanged(treeName);
-	}
-
-	@Override
-	public void fireTreeChanged(TreeChangeEvent event) {
-		super.fireTreeChanged(event);
-		this.aspectChanged(event.getTreeName());
-	}
-
-	@Override
-	public void fireTreeChanged(String treeName, Collection<?> nodes) {
-		super.fireTreeChanged(treeName, nodes);
-		this.aspectChanged(treeName);
-	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/ChangeSupport.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/ChangeSupport.java
index 678801f..cdd6551 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/ChangeSupport.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/ChangeSupport.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -21,14 +21,14 @@
 import java.util.EventListener;
 import java.util.Iterator;
 import java.util.List;
-
 import org.eclipse.persistence.tools.utility.ArrayTools;
-import org.eclipse.persistence.tools.utility.CollectionTools;
-import org.eclipse.persistence.tools.utility.HashBag;
 import org.eclipse.persistence.tools.utility.ListenerList;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.Tools;
-import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterable.IterableTools;
+import org.eclipse.persistence.tools.utility.iterator.ArrayIterator;
 import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
@@ -41,16 +41,11 @@
 import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
 import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeRemoveEvent;
 import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.TreeChangeListener;
 
 /**
  * Support object that can be used by implementors of the {@link Model} interface.
@@ -83,6 +78,7 @@
  * @see Model
  * @see AbstractModel
  */
+// TODO add ExceptionHandler
 @SuppressWarnings("nls")
 public class ChangeSupport
 	implements Serializable
@@ -96,6 +92,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructor **********
 
 	/**
@@ -166,8 +163,8 @@
 	}
 
 	/**
-	 * Returns the listener list for the specified listener class and aspect name.
-	 * Returns <code>null</code> if the listener list is not present.
+	 * Return the listener list for the specified listener class and aspect name.
+	 * Return <code>null</code> if the listener list is not present.
 	 * The aspect name cannot be <code>null</code>.
 	 */
 	protected <L extends EventListener> ListenerList<L> getListenerList(Class<L> listenerClass, String aspectName) {
@@ -179,16 +176,16 @@
 	}
 
 	/**
-	 * Returns the listener list for the specified listener class.
-	 * Returns <code>null</code> if the listener list is not present.
+	 * Return the listener list for the specified listener class.
+	 * Return <code>null</code> if the listener list is not present.
 	 */
 	protected <L extends EventListener> ListenerList<L> getListenerList(Class<L> listenerClass) {
 		return this.getListenerList_(listenerClass, null);
 	}
 
 	/**
-	 * Returns the listener list for the specified listener class and aspect name.
-	 * Returns <code>null</code> if the listener list is not present.
+	 * Return the listener list for the specified listener class and aspect name.
+	 * Return <code>null</code> if the listener list is not present.
 	 */
 	protected synchronized <L extends EventListener> ListenerList<L> getListenerList_(Class<L> listenerClass, String aspectName) {
 		for (AspectListenerListPair<?> pair : this.aspectListenerListPairs) {
@@ -201,7 +198,7 @@
 	}
 
 	/**
-	 * Returns whether there are any listeners for the specified listener class
+	 * Return whether there are any listeners for the specified listener class
 	 * and aspect name.
 	 */
 	protected <L extends EventListener> boolean hasAnyListeners(Class<L> listenerClass, String aspectName) {
@@ -213,7 +210,7 @@
 	}
 
 	/**
-	 * Returns whether there are no listeners for the specified listener class
+	 * Return whether there are no listeners for the specified listener class
 	 * and aspect name.
 	 */
 	protected <L extends EventListener> boolean hasNoListeners(Class<L> listenerClass, String aspectName) {
@@ -221,7 +218,7 @@
 	}
 
 	/**
-	 * Returns whether there are any listeners for the specified listener class.
+	 * Return whether there are any listeners for the specified listener class.
 	 */
 	protected <L extends EventListener> boolean hasAnyListeners(Class<L> listenerClass) {
 		ListenerList<L> aspectListenerList = this.getListenerList(listenerClass);
@@ -233,7 +230,7 @@
 	}
 
 	/**
-	 * Returns whether there are no listeners for the specified listener class.
+	 * Return whether there are no listeners for the specified listener class.
 	 */
 	protected <L extends EventListener> boolean hasNoListeners(Class<L> listenerClass) {
 		return ! this.hasAnyListeners(listenerClass);
@@ -244,7 +241,7 @@
 
 	/**
 	 * Subclasses that add other types of listeners should override this method
-	 * Returns the extension to ChangeListener that also extends whatever new
+	 * to return the extension to ChangeListener that also extends whatever new
 	 * listener types are supported.
 	 */
 	@SuppressWarnings("unchecked")
@@ -273,7 +270,7 @@
 	}
 
 	/**
-	 * Returns whether there are any general purpose listeners that will be
+	 * Return whether there are any general purpose listeners that will be
 	 * notified of any changes.
 	 */
 	public boolean hasAnyChangeListeners() {
@@ -290,7 +287,7 @@
 	}
 
 	private boolean hasChangeListener(ChangeListener listener) {
-		return CollectionTools.contains(this.getChangeListeners(), listener);
+		return IterableTools.contains(this.getChangeListeners(), listener);
 	}
 
 
@@ -313,7 +310,7 @@
 	}
 
 	/**
-	 * Returns whether there are any state change listeners.
+	 * Return whether there are any state change listeners.
 	 */
 	public boolean hasAnyStateChangeListeners() {
 		return this.hasAnyListeners(STATE_CHANGE_LISTENER_CLASS);
@@ -329,7 +326,7 @@
 	}
 
 	private boolean hasStateChangeListener(StateChangeListener listener) {
-		return CollectionTools.contains(this.getStateChangeListeners(), listener);
+		return IterableTools.contains(this.getStateChangeListeners(), listener);
 	}
 
 	/**
@@ -408,7 +405,7 @@
 	}
 
 	/**
-	 * Returns whether there are any property change listeners that will
+	 * Return whether there are any property change listeners that will
 	 * be notified when the specified property has changed.
 	 */
 	public boolean hasAnyPropertyChangeListeners(String propertyName) {
@@ -425,7 +422,7 @@
 	}
 
 	private boolean hasPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
-		return CollectionTools.contains(this.getPropertyChangeListeners(propertyName), listener);
+		return IterableTools.contains(this.getPropertyChangeListeners(propertyName), listener);
 	}
 
 	/**
@@ -433,7 +430,7 @@
 	 * No event is fired if the specified event's old and new values are the same;
 	 * this includes when both values are null. Use a state change event
 	 * for general purpose notification of changes.
-	 * Returns whether the old and new values are different.
+	 * Return whether the old and new values are different.
 	 */
 	public boolean firePropertyChanged(PropertyChangeEvent event) {
 		if (this.valuesAreDifferent(event.getOldValue(), event.getNewValue())) {
@@ -472,7 +469,7 @@
 	 * No event is fired if the specified old and new values are the same;
 	 * this includes when both values are null. Use a state change event
 	 * for general purpose notification of changes.
-	 * Returns whether the old and new values are different.
+	 * Return whether the old and new values are different.
 	 */
 	public boolean firePropertyChanged(String propertyName, Object oldValue, Object newValue) {
 //		return this.firePropertyChanged(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue));
@@ -516,7 +513,7 @@
 	/**
 	 * Report an <code>int</code> bound property update to any registered listeners.
 	 * No event is fired if the specified old and new values are equal.
-	 * Returns whether the old and new values are different.
+	 * Return whether the old and new values are different.
 	 * <p>
 	 * This is merely a convenience wrapper around the more general method
 	 * {@link #firePropertyChanged(String, Object, Object)}.
@@ -563,7 +560,7 @@
 	/**
 	 * Report a <code>boolean</code> bound property update to any registered listeners.
 	 * No event is fired if the specified old and new values are equal.
-	 * Returns whether the old and new values are different.
+	 * Return whether the old and new values are different.
 	 * <p>
 	 * This is merely a convenience wrapper around the more general method
 	 * {@link #firePropertyChanged(String, Object, Object)}.
@@ -628,7 +625,7 @@
 	}
 
 	/**
-	 * Returns whether there are any collection change listeners that will
+	 * Return whether there are any collection change listeners that will
 	 * be notified when the specified collection has changed.
 	 */
 	public boolean hasAnyCollectionChangeListeners(String collectionName) {
@@ -645,12 +642,12 @@
 	}
 
 	private boolean hasCollectionChangeListener(String collectionName, CollectionChangeListener listener) {
-		return CollectionTools.contains(this.getCollectionChangeListeners(collectionName), listener);
+		return IterableTools.contains(this.getCollectionChangeListeners(collectionName), listener);
 	}
 
 	/**
 	 * Report a bound collection update to any registered listeners.
-	 * Returns whether the event has any items.
+	 * Return whether the event has any items.
 	 */
 	public boolean fireItemsAdded(CollectionAddEvent event) {
 		if (event.getItemsSize() != 0) {
@@ -686,7 +683,7 @@
 
 	/**
 	 * Report a bound collection update to any registered listeners.
-	 * Returns whether there are any added items.
+	 * Return whether there are any added items.
 	 */
 	public boolean fireItemsAdded(String collectionName, Collection<?> addedItems) {
 //		return this.fireItemsAdded(new CollectionAddEvent(this.source, collectionName, addedItems));
@@ -761,7 +758,7 @@
 
 	/**
 	 * Report a bound collection update to any registered listeners.
-	 * Returns whether the event has any items.
+	 * Return whether the event has any items.
 	 */
 	public boolean fireItemsRemoved(CollectionRemoveEvent event) {
 		if (event.getItemsSize() != 0) {
@@ -797,7 +794,7 @@
 
 	/**
 	 * Report a bound collection update to any registered listeners.
-	 * Returns whether there are any removed items.
+	 * Return whether there are any removed items.
 	 */
 	public boolean fireItemsRemoved(String collectionName, Collection<?> removedItems) {
 //		return this.fireItemsRemoved(new CollectionRemoveEvent(this.source, collectionName, removedItems));
@@ -985,7 +982,7 @@
 	/**
 	 * Add the specified item to the specified bound collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the collection changed.
+	 * Return whether the collection changed.
 	 * @see Collection#add(Object)
 	 */
 	public <E> boolean addItemToCollection(E item, Collection<E> collection, String collectionName) {
@@ -999,7 +996,7 @@
 	/**
 	 * Add the specified items to the specified bound collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether collection changed.
+	 * Return whether collection changed.
 	 * @see Collection#addAll(Collection)
 	 */
 	public <E> boolean addItemsToCollection(E[] items, Collection<E> collection, String collectionName) {
@@ -1010,7 +1007,7 @@
 	/**
 	 * Add the specified items to the specified bound collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether collection changed.
+	 * Return whether collection changed.
 	 * @see Collection#addAll(Collection)
 	 */
 	public <E> boolean addItemsToCollection(Collection<? extends E> items, Collection<E> collection, String collectionName) {
@@ -1021,7 +1018,7 @@
 	/**
 	 * Add the specified items to the specified bound collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether collection changed.
+	 * Return whether collection changed.
 	 * @see Collection#addAll(Collection)
 	 */
 	public <E> boolean addItemsToCollection(Iterable<? extends E> items, Collection<E> collection, String collectionName) {
@@ -1031,7 +1028,7 @@
 	/**
 	 * Add the specified items to the specified bound collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether collection changed.
+	 * Return whether collection changed.
 	 * @see Collection#addAll(Collection)
 	 */
 	public <E> boolean addItemsToCollection(Iterator<? extends E> items, Collection<E> collection, String collectionName) {
@@ -1063,7 +1060,7 @@
 	/**
 	 * Remove the specified item from the specified bound collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the collection changed.
+	 * Return whether the collection changed.
 	 * @see Collection#remove(Object)
 	 */
 	public boolean removeItemFromCollection(Object item, Collection<?> collection, String collectionName) {
@@ -1077,7 +1074,7 @@
 	/**
 	 * Remove the specified items from the specified bound collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the collection changed.
+	 * Return whether the collection changed.
 	 * @see Collection#removeAll(Collection)
 	 */
 	public boolean removeItemsFromCollection(Object[] items, Collection<?> collection, String collectionName) {
@@ -1089,7 +1086,7 @@
 	/**
 	 * Remove the specified items from the specified bound collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the collection changed.
+	 * Return whether the collection changed.
 	 * @see Collection#removeAll(Collection)
 	 */
 	public boolean removeItemsFromCollection(Collection<?> items, Collection<?> collection, String collectionName) {
@@ -1101,7 +1098,7 @@
 	/**
 	 * Remove the specified items from the specified bound collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the collection changed.
+	 * Return whether the collection changed.
 	 * @see Collection#removeAll(Collection)
 	 */
 	public boolean removeItemsFromCollection(Iterable<?> items, Collection<?> collection, String collectionName) {
@@ -1111,7 +1108,7 @@
 	/**
 	 * Remove the specified items from the specified bound collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the collection changed.
+	 * Return whether the collection changed.
 	 * @see Collection#removeAll(Collection)
 	 */
 	public boolean removeItemsFromCollection(Iterator<?> items, Collection<?> collection, String collectionName) {
@@ -1137,7 +1134,7 @@
 	/**
 	 * Retain the specified items in the specified bound collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the collection changed.
+	 * Return whether the collection changed.
 	 * @see Collection#retainAll(Collection)
 	 */
 	public boolean retainItemsInCollection(Object[] items, Collection<?> collection, String collectionName) {
@@ -1153,7 +1150,7 @@
 	/**
 	 * Retain the specified items in the specified bound collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the collection changed.
+	 * Return whether the collection changed.
 	 * @see Collection#retainAll(Collection)
 	 */
 	public boolean retainItemsInCollection(Collection<?> items, Collection<?> collection, String collectionName) {
@@ -1169,7 +1166,7 @@
 	/**
 	 * Retain the specified items in the specified bound collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the collection changed.
+	 * Return whether the collection changed.
 	 * @see Collection#retainAll(Collection)
 	 */
 	public boolean retainItemsInCollection(Iterable<?> items, Collection<?> collection, String collectionName) {
@@ -1179,7 +1176,7 @@
 	/**
 	 * Retain the specified items in the specified bound collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the collection changed.
+	 * Return whether the collection changed.
 	 * @see Collection#retainAll(Collection)
 	 */
 	public boolean retainItemsInCollection(Iterator<?> items, Collection<?> collection, String collectionName) {
@@ -1210,7 +1207,7 @@
 	/**
 	 * Clear the entire collection
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the collection changed.
+	 * Return whether the collection changed.
 	 * @see Collection#clear()
 	 */
 	public boolean clearCollection(Collection<?> collection, String collectionName) {
@@ -1232,7 +1229,7 @@
 	/**
 	 * Synchronize the collection with the specified new collection,
 	 * making a minimum number of removes and adds.
-	 * Returns whether the collection changed.
+	 * Return whether the collection changed.
 	 */
 	public <E> boolean synchronizeCollection(Collection<E> newCollection, Collection<E> collection, String collectionName) {
 		if (newCollection.isEmpty()) {
@@ -1249,7 +1246,7 @@
 	/**
 	 * Synchronize the collection with the specified new collection,
 	 * making a minimum number of removes and adds.
-	 * Returns whether the collection changed.
+	 * Return whether the collection changed.
 	 */
 	public <E> boolean synchronizeCollection(Iterable<E> newCollection, Collection<E> collection, String collectionName) {
 		return this.synchronizeCollection(newCollection.iterator(), collection, collectionName);
@@ -1258,7 +1255,7 @@
 	/**
 	 * Synchronize the collection with the specified new collection,
 	 * making a minimum number of removes and adds.
-	 * Returns whether the collection changed.
+	 * Return whether the collection changed.
 	 */
 	public <E> boolean synchronizeCollection(Iterator<E> newCollection, Collection<E> collection, String collectionName) {
 		if ( ! newCollection.hasNext()) {
@@ -1309,7 +1306,7 @@
 	}
 
 	/**
-	 * Returns whether there are any list change listeners that will
+	 * Return whether there are any list change listeners that will
 	 * be notified when the specified list has changed.
 	 */
 	public boolean hasAnyListChangeListeners(String listName) {
@@ -1326,12 +1323,12 @@
 	}
 
 	private boolean hasListChangeListener(String listName, ListChangeListener listener) {
-		return CollectionTools.contains(this.getListChangeListeners(listName), listener);
+		return IterableTools.contains(this.getListChangeListeners(listName), listener);
 	}
 
 	/**
 	 * Report a bound list update to any registered listeners.
-	 * Returns whether there are any added items.
+	 * Return whether there are any added items.
 	 */
 	public boolean fireItemsAdded(ListAddEvent event) {
 		if (event.getItemsSize() != 0) {
@@ -1367,7 +1364,7 @@
 
 	/**
 	 * Report a bound list update to any registered listeners.
-	 * Returns whether there are any added items.
+	 * Return whether there are any added items.
 	 */
 	public boolean fireItemsAdded(String listName, int index, List<?> addedItems) {
 //		return this.fireItemsAdded(new ListAddEvent(this.source, listName, index, addedItems));
@@ -1442,7 +1439,7 @@
 
 	/**
 	 * Report a bound list update to any registered listeners.
-	 * Returns whether there are any removed items.
+	 * Return whether there are any removed items.
 	 */
 	public boolean fireItemsRemoved(ListRemoveEvent event) {
 		if (event.getItemsSize() != 0) {
@@ -1478,7 +1475,7 @@
 
 	/**
 	 * Report a bound list update to any registered listeners.
-	 * Returns whether there are any removed items.
+	 * Return whether there are any removed items.
 	 */
 	public boolean fireItemsRemoved(String listName, int index, List<?> removedItems) {
 //		return this.fireItemsRemoved(new ListRemoveEvent(this.source, listName, index, removedItems));
@@ -1553,7 +1550,7 @@
 
 	/**
 	 * Report a bound list update to any registered listeners.
-	 * Returns whether there are any replaced items.
+	 * Return whether there are any replaced items.
 	 */
 	public boolean fireItemsReplaced(ListReplaceEvent event) {
 		if ((event.getItemsSize() != 0) && this.elementsAreDifferent(event.getNewItems(), event.getOldItems())) {
@@ -1589,7 +1586,7 @@
 
 	/**
 	 * Report a bound list update to any registered listeners.
-	 * Returns whether there are any replaced items.
+	 * Return whether there are any replaced items.
 	 */
 	public boolean fireItemsReplaced(String listName, int index, List<?> newItems, List<?> oldItems) {
 //		return this.fireItemsReplaced(new ListReplaceEvent(this.source, listName, index, newItems, oldItems));
@@ -1632,7 +1629,7 @@
 
 	/**
 	 * Report a bound list update to any registered listeners.
-	 * Returns whether the item changed.
+	 * Return whether the item changed.
 	 */
 	public boolean fireItemReplaced(String listName, int index, Object newItem, Object oldItem) {
 //		return this.fireItemsReplaced(listName, index, Collections.singletonList(newItem), Collections.singletonList(oldItem));
@@ -1675,7 +1672,7 @@
 
 	/**
 	 * Report a bound list update to any registered listeners.
-	 * Returns whether there are any moved items.
+	 * Return whether there are any moved items.
 	 */
 	// it's unlikely but possible the list is unchanged by the move...
 	// e.g. any moves within ["foo", "foo", "foo"]
@@ -1713,7 +1710,7 @@
 
 	/**
 	 * Report a bound list update to any registered listeners.
-	 * Returns whether there are any moved items.
+	 * Return whether there are any moved items.
 	 */
 	// it's unlikely but possible the list is unchanged by the move...
 	// e.g. any moves within ["foo", "foo", "foo"]
@@ -1758,7 +1755,7 @@
 
 	/**
 	 * Report a bound list update to any registered listeners.
-	 * Returns whether there are any moved items.
+	 * Return whether there are any moved items.
 	 */
 	// it's unlikely but possible the list is unchanged by the move...
 	// e.g. any moves within ["foo", "foo", "foo"]
@@ -1902,7 +1899,7 @@
 	/**
 	 * Add the specified item to the end of the specified bound list
 	 * and fire the appropriate event.
-	 * Returns whether the list changed (i.e. 'true').
+	 * Return whether the list changed (i.e. 'true').
 	 * @see List#add(Object)
 	 */
 	public <E> boolean addItemToList(E item, List<E> list, String listName) {
@@ -1916,7 +1913,7 @@
 	/**
 	 * Add the specified items to the specified bound list at the specified index
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#addAll(int, Collection)
 	 */
 	public <E> boolean addItemsToList(int index, E[] items, List<E> list, String listName) {
@@ -1927,7 +1924,7 @@
 	/**
 	 * Add the specified items to the specified bound list at the specified index
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#addAll(int, Collection)
 	 */
 	public <E> boolean addItemsToList(int index, Collection<? extends E> items, List<E> list, String listName) {
@@ -1949,7 +1946,7 @@
 	/**
 	 * Add the specified items to the specified bound list
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#addAll(int, Collection)
 	 */
 	public <E> boolean addItemsToList(int index, Iterable<? extends E> items, List<E> list, String listName) {
@@ -1959,7 +1956,7 @@
 	/**
 	 * Add the specified items to the specified bound list
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#addAll(int, Collection)
 	 */
 	public <E> boolean addItemsToList(int index, Iterator<? extends E> items, List<E> list, String listName) {
@@ -1967,7 +1964,7 @@
 			return false;
 		}
 
-		ArrayList<E> addedItems = CollectionTools.list(items);
+		ArrayList<E> addedItems = ListTools.list(items);
 		if (list.addAll(index, addedItems)) {
 			this.fireItemsAdded(listName, index, addedItems);
 			return true;
@@ -1978,7 +1975,7 @@
 	/**
 	 * Add the specified items to the end of to the specified bound list
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#addAll(Collection)
 	 */
 	public <E> boolean addItemsToList(E[] items, List<E> list, String listName) {
@@ -1989,7 +1986,7 @@
 	/**
 	 * Add the specified items to the end of the specified bound list
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#addAll(int, Collection)
 	 */
 	public <E> boolean addItemsToList(Collection<? extends E> items, List<E> list, String listName) {
@@ -2016,7 +2013,7 @@
 	/**
 	 * Add the specified items to the end of to the specified bound list
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#addAll(Collection)
 	 */
 	public <E> boolean addItemsToList(Iterable<? extends E> items, List<E> list, String listName) {
@@ -2026,7 +2023,7 @@
 	/**
 	 * Add the specified items to the end of to the specified bound list
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#addAll(Collection)
 	 */
 	public <E> boolean addItemsToList(Iterator<? extends E> items, List<E> list, String listName) {
@@ -2040,7 +2037,7 @@
 	 * no empty check
 	 */
 	protected <E> boolean addItemsToList_(Iterator<? extends E> items, List<E> list, String listName) {
-		ArrayList<E> addedItems = CollectionTools.list(items);
+		ArrayList<E> addedItems = ListTools.list(items);
 		int index = list.size();
 		if (list.addAll(addedItems)) {
 			this.fireItemsAdded(listName, index, addedItems);
@@ -2052,7 +2049,7 @@
 	/**
 	 * Remove the specified item from the specified bound list
 	 * and fire the appropriate event if necessary.
-	 * Returns the removed item.
+	 * Return the removed item.
 	 * @see List#remove(int)
 	 */
 	public <E> E removeItemFromList(int index, List<E> list, String listName) {
@@ -2064,7 +2061,7 @@
 	/**
 	 * Remove the specified item from the specified bound list
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#remove(Object)
 	 */
 	public boolean removeItemFromList(Object item, List<?> list, String listName) {
@@ -2081,7 +2078,7 @@
 	 * Remove the items from the specified index to the end of the list
 	 * from the specified bound list
 	 * and fire the appropriate event if necessary.
-	 * Returns the removed items.
+	 * Return the removed items.
 	 * @see List#remove(int)
 	 */
 	public <E> List<E> removeItemsFromList(int index, List<E> list, String listName) {
@@ -2091,7 +2088,7 @@
 	/**
 	 * Remove the specified items from the specified bound list
 	 * and fire the appropriate event if necessary.
-	 * Returns the removed items.
+	 * Return the removed items.
 	 * @see List#remove(int)
 	 */
 	public <E> List<E> removeItemsFromList(int index, int length, List<E> list, String listName) {
@@ -2102,7 +2099,7 @@
 	 * Remove the specified items from the specified bound list
 	 * and fire the appropriate event if necessary. The begin index
 	 * is inclusive, while the end index is exclusive.
-	 * Returns the removed items.
+	 * Return the removed items.
 	 * @see List#remove(int)
 	 * @see List#subList(int, int)
 	 */
@@ -2127,7 +2124,7 @@
 	/**
 	 * Remove the specified items from the specified bound list
 	 * and fire the appropriate event(s) if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#removeAll(Collection)
 	 */
 	public boolean removeItemsFromList(Object[] items, List<?> list, String listName) {
@@ -2139,7 +2136,7 @@
 	/**
 	 * Remove the specified items from the specified bound list
 	 * and fire the appropriate event(s) if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#removeAll(Collection)
 	 */
 	public boolean removeItemsFromList(Collection<?> items, List<?> list, String listName) {
@@ -2151,7 +2148,7 @@
 	/**
 	 * Remove the specified items from the specified bound list
 	 * and fire the appropriate event(s) if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#removeAll(Collection)
 	 */
 	public boolean removeItemsFromList(Iterable<?> items, List<?> list, String listName) {
@@ -2161,7 +2158,7 @@
 	/**
 	 * Remove the specified items from the specified bound list
 	 * and fire the appropriate event(s) if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#removeAll(Collection)
 	 */
 	public boolean removeItemsFromList(Iterator<?> items, List<?> list, String listName) {
@@ -2184,7 +2181,7 @@
 	/**
 	 * Retain the specified items in the specified bound list
 	 * and fire the appropriate event(s) if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#retainAll(Collection)
 	 */
 	public boolean retainItemsInList(Object[] items, List<?> list, String listName) {
@@ -2200,7 +2197,7 @@
 	/**
 	 * Retain the specified items in the specified bound list
 	 * and fire the appropriate event(s) if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#retainAll(Collection)
 	 */
 	public boolean retainItemsInList(Collection<?> items, List<?> list, String listName) {
@@ -2216,7 +2213,7 @@
 	/**
 	 * Retain the specified items in the specified bound list
 	 * and fire the appropriate event(s) if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#retainAll(Collection)
 	 */
 	public boolean retainItemsInList(Iterable<?> items, List<?> list, String listName) {
@@ -2226,7 +2223,7 @@
 	/**
 	 * Retain the specified items in the specified bound list
 	 * and fire the appropriate event(s) if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#retainAll(Collection)
 	 */
 	public boolean retainItemsInList(Iterator<?> items, List<?> list, String listName) {
@@ -2252,7 +2249,7 @@
 	/**
 	 * Set the specified item in the specified bound list
 	 * and fire the appropriate event if necessary.
-	 * Returns the replaced item.
+	 * Return the replaced item.
 	 * @see List#set(int, Object)
 	 */
 	public <E> E setItemInList(int index, E item, List<E> list, String listName) {
@@ -2265,8 +2262,8 @@
 	 * Replace the first occurrence of the specified item
 	 * in the specified bound list
 	 * and fire the appropriate event if necessary.
-	 * Returns the index of the replaced item.
-	 * Returns -1 if the item was not found in the list.
+	 * Return the index of the replaced item.
+	 * Return -1 if the item was not found in the list.
 	 * @see List#set(int, Object)
 	 */
 	public <E> int replaceItemInList(E oldItem, E newItem, List<E> list, String listName) {
@@ -2285,7 +2282,7 @@
 	/**
 	 * Set the specified items in the specified bound list
 	 * and fire the appropriate event if necessary.
-	 * Returns the replaced items.
+	 * Return the replaced items.
 	 * @see List#set(int, Object)
 	 */
 	public <E> List<E> setItemsInList(int index, E[] items, List<E> list, String listName) {
@@ -2298,7 +2295,7 @@
 	/**
 	 * Set the specified items in the specified bound list
 	 * and fire the appropriate event if necessary.
-	 * Returns the replaced items.
+	 * Return the replaced items.
 	 * @see List#set(int, Object)
 	 */
 	public <E> List<E> setItemsInList(int index, List<? extends E> items, List<E> list, String listName) {
@@ -2325,14 +2322,14 @@
 	/**
 	 * Move items in the specified list from the specified source index to the
 	 * specified target index for the specified length.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 */
 	public <E> boolean moveItemsInList(int targetIndex, int sourceIndex, int length, List<E> list, String listName) {
 		if ((targetIndex == sourceIndex) || (length == 0)) {
 			return false;
 		}
 		// it's unlikely but possible the list is unchanged by the move... (e.g. any moves within ["foo", "foo", "foo"]...)
-		CollectionTools.move(list, targetIndex, sourceIndex, length);
+		ListTools.move(list, targetIndex, sourceIndex, length);
 		this.fireItemsMoved(listName, targetIndex, sourceIndex, length);
 		return true;
 	}
@@ -2340,7 +2337,7 @@
 	/**
 	 * Move the specified item in the specified list to the
 	 * specified target index.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 */
 	public <E> boolean moveItemInList(int targetIndex, E item, List<E> list, String listName) {
 		return this.moveItemInList(targetIndex, list.indexOf(item), list, listName);
@@ -2349,7 +2346,7 @@
 	/**
 	 * Move an item in the specified list from the specified source index to the
 	 * specified target index.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 */
 	public <E> boolean moveItemInList(int targetIndex, int sourceIndex, List<E> list, String listName) {
 		if (targetIndex == sourceIndex) {
@@ -2358,7 +2355,7 @@
 		if (this.valuesAreEqual(list.get(targetIndex), list.get(sourceIndex))) {
 			return false;
 		}
-		CollectionTools.move(list, targetIndex, sourceIndex);
+		ListTools.move(list, targetIndex, sourceIndex);
 		this.fireItemMoved_(listName, targetIndex, sourceIndex);
 		return true;
 	}
@@ -2366,7 +2363,7 @@
 	/**
 	 * Clear the entire list
 	 * and fire the appropriate event if necessary.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 * @see List#clear()
 	 */
 	public boolean clearList(List<?> list, String listName) {
@@ -2385,7 +2382,7 @@
 	/**
 	 * Synchronize the list with the specified new list,
 	 * making a minimum number of sets, removes, and/or adds.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 */
 	public <E> boolean synchronizeList(List<E> newList, List<E> list, String listName) {
 		if (newList.isEmpty()) {
@@ -2400,7 +2397,7 @@
 	/**
 	 * Synchronize the list with the specified new list,
 	 * making a minimum number of sets, removes, and/or adds.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 */
 	public <E> boolean synchronizeList(Iterable<? extends E> newList, List<E> list, String listName) {
 		return this.synchronizeList(newList.iterator(), list, listName);
@@ -2409,7 +2406,7 @@
 	/**
 	 * Synchronize the list with the specified new list,
 	 * making a minimum number of sets, removes, and/or adds.
-	 * Returns whether the list changed.
+	 * Return whether the list changed.
 	 */
 	public <E> boolean synchronizeList(Iterator<? extends E> newList, List<E> list, String listName) {
 		if ( ! newList.hasNext()) {
@@ -2418,7 +2415,7 @@
 		if (list.isEmpty()) {
 			return this.addItemsToList_(newList, list, listName);
 		}
-		return this.synchronizeList_(CollectionTools.list(newList), list, listName);
+		return this.synchronizeList_(ListTools.list(newList), list, listName);
 	}
 
 	/**
@@ -2455,305 +2452,41 @@
 	}
 
 
-	// ********** tree change support **********
-
-	protected static final Class<TreeChangeListener> TREE_CHANGE_LISTENER_CLASS = TreeChangeListener.class;
-
-	/**
-	 * Add a tree change listener for the specified tree. The listener
-	 * will be notified only for changes to the specified tree.
-	 */
-	public void addTreeChangeListener(String treeName, TreeChangeListener listener) {
-		this.addListener(TREE_CHANGE_LISTENER_CLASS, treeName, listener);
-	}
-
-	/**
-	 * Remove a tree change listener that was registered for a specific tree.
-	 */
-	public void removeTreeChangeListener(String treeName, TreeChangeListener listener) {
-		this.removeListener(TREE_CHANGE_LISTENER_CLASS, treeName, listener);
-	}
-
-	/**
-	 * Returns whether there are any tree change listeners that will
-	 * be notified when the specified tree has changed.
-	 */
-	public boolean hasAnyTreeChangeListeners(String treeName) {
-		return this.hasAnyListeners(TREE_CHANGE_LISTENER_CLASS, treeName);
-	}
-
-	private ListenerList<TreeChangeListener> getTreeChangeListenerList(String treeName) {
-		return this.getListenerList(TREE_CHANGE_LISTENER_CLASS, treeName);
-	}
-
-	private Iterable<TreeChangeListener> getTreeChangeListeners(String treeName) {
-		ListenerList<TreeChangeListener> listenerList = this.getTreeChangeListenerList(treeName);
-		return (listenerList == null) ? null : listenerList.getListeners();
-	}
-
-	private boolean hasTreeChangeListener(String treeName, TreeChangeListener listener) {
-		return CollectionTools.contains(this.getTreeChangeListeners(treeName), listener);
-	}
-
-	/**
-	 * Report a bound tree update to any registered listeners.
-	 */
-	public void fireNodeAdded(TreeAddEvent event) {
-		String treeName = event.getTreeName();
-		Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName);
-		if (listeners != null) {
-			for (TreeChangeListener listener : listeners) {
-				if (this.hasTreeChangeListener(treeName, listener)) {  // verify listener is still listening
-					listener.nodeAdded(event);
-				}
-			}
-		}
-
-		Iterable<ChangeListener> changeListeners = this.getChangeListeners();
-		if (changeListeners != null) {
-			for (ChangeListener changeListener : changeListeners) {
-				if (this.hasChangeListener(changeListener)) {  // verify listener is still listening
-					changeListener.nodeAdded(event);
-				}
-			}
-		}
-	}
-
-	/**
-	 * Report a bound tree update to any registered listeners.
-	 */
-	public void fireNodeAdded(String treeName, List<?> path) {
-//		this.fireNodeAdded(new TreeAddEvent(this.source, treeName, path));
-		TreeAddEvent event = null;
-		Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName);
-		if (listeners != null) {
-			for (TreeChangeListener listener : listeners) {
-				if (this.hasTreeChangeListener(treeName, listener)) {  // verify listener is still listening
-					if (event == null) {
-						event = new TreeAddEvent(this.source, treeName, path);
-					}
-					listener.nodeAdded(event);
-				}
-			}
-		}
-
-		Iterable<ChangeListener> changeListeners = this.getChangeListeners();
-		if (changeListeners != null) {
-			for (ChangeListener changeListener : changeListeners) {
-				if (this.hasChangeListener(changeListener)) {  // verify listener is still listening
-					if (event == null) {
-						event = new TreeAddEvent(this.source, treeName, path);
-					}
-					changeListener.nodeAdded(event);
-				}
-			}
-		}
-	}
-
-	/**
-	 * Report a bound tree update to any registered listeners.
-	 */
-	public void fireNodeRemoved(TreeRemoveEvent event) {
-		String treeName = event.getTreeName();
-		Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName);
-		if (listeners != null) {
-			for (TreeChangeListener listener : listeners) {
-				if (this.hasTreeChangeListener(treeName, listener)) {  // verify listener is still listening
-					listener.nodeRemoved(event);
-				}
-			}
-		}
-
-		Iterable<ChangeListener> changeListeners = this.getChangeListeners();
-		if (changeListeners != null) {
-			for (ChangeListener changeListener : changeListeners) {
-				if (this.hasChangeListener(changeListener)) {  // verify listener is still listening
-					changeListener.nodeRemoved(event);
-				}
-			}
-		}
-	}
-
-	/**
-	 * Report a bound tree update to any registered listeners.
-	 */
-	public void fireNodeRemoved(String treeName, List<?> path) {
-//		this.fireNodeRemoved(new TreeRemoveEvent(this.source, treeName, path));
-
-		TreeRemoveEvent event = null;
-		Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName);
-		if (listeners != null) {
-			for (TreeChangeListener listener : listeners) {
-				if (this.hasTreeChangeListener(treeName, listener)) {  // verify listener is still listening
-					if (event == null) {
-						event = new TreeRemoveEvent(this.source, treeName, path);
-					}
-					listener.nodeRemoved(event);
-				}
-			}
-		}
-
-		Iterable<ChangeListener> changeListeners = this.getChangeListeners();
-		if (changeListeners != null) {
-			for (ChangeListener changeListener : changeListeners) {
-				if (this.hasChangeListener(changeListener)) {  // verify listener is still listening
-					if (event == null) {
-						event = new TreeRemoveEvent(this.source, treeName, path);
-					}
-					changeListener.nodeRemoved(event);
-				}
-			}
-		}
-	}
-
-	/**
-	 * Report a bound tree update to any registered listeners.
-	 */
-	public void fireTreeCleared(TreeClearEvent event) {
-		String treeName = event.getTreeName();
-		Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName);
-		if (listeners != null) {
-			for (TreeChangeListener listener : listeners) {
-				if (this.hasTreeChangeListener(treeName, listener)) {  // verify listener is still listening
-					listener.treeCleared(event);
-				}
-			}
-		}
-
-		Iterable<ChangeListener> changeListeners = this.getChangeListeners();
-		if (changeListeners != null) {
-			for (ChangeListener changeListener : changeListeners) {
-				if (this.hasChangeListener(changeListener)) {  // verify listener is still listening
-					changeListener.treeCleared(event);
-				}
-			}
-		}
-	}
-
-	/**
-	 * Report a bound tree update to any registered listeners.
-	 */
-	public void fireTreeCleared(String treeName) {
-//		this.fireTreeCleared(new TreeClearEvent(this.source, treeName));
-
-		TreeClearEvent event = null;
-		Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName);
-		if (listeners != null) {
-			for (TreeChangeListener listener : listeners) {
-				if (this.hasTreeChangeListener(treeName, listener)) {  // verify listener is still listening
-					if (event == null) {
-						event = new TreeClearEvent(this.source, treeName);
-					}
-					listener.treeCleared(event);
-				}
-			}
-		}
-
-		Iterable<ChangeListener> changeListeners = this.getChangeListeners();
-		if (changeListeners != null) {
-			for (ChangeListener changeListener : changeListeners) {
-				if (this.hasChangeListener(changeListener)) {  // verify listener is still listening
-					if (event == null) {
-						event = new TreeClearEvent(this.source, treeName);
-					}
-					changeListener.treeCleared(event);
-				}
-			}
-		}
-	}
-
-	/**
-	 * Report a bound tree update to any registered listeners.
-	 */
-	public void fireTreeChanged(TreeChangeEvent event) {
-		String treeName = event.getTreeName();
-		Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName);
-		if (listeners != null) {
-			for (TreeChangeListener listener : listeners) {
-				if (this.hasTreeChangeListener(treeName, listener)) {  // verify listener is still listening
-					listener.treeChanged(event);
-				}
-			}
-		}
-
-		Iterable<ChangeListener> changeListeners = this.getChangeListeners();
-		if (changeListeners != null) {
-			for (ChangeListener changeListener : changeListeners) {
-				if (this.hasChangeListener(changeListener)) {  // verify listener is still listening
-					changeListener.treeChanged(event);
-				}
-			}
-		}
-	}
-
-	/**
-	 * Report a bound tree update to any registered listeners.
-	 */
-	public void fireTreeChanged(String treeName, Collection<?> nodes) {
-//		this.fireTreeChanged(new TreeChangeEvent(this.source, treeName, nodes));
-
-		TreeChangeEvent event = null;
-		Iterable<TreeChangeListener> listeners = this.getTreeChangeListeners(treeName);
-		if (listeners != null) {
-			for (TreeChangeListener listener : listeners) {
-				if (this.hasTreeChangeListener(treeName, listener)) {  // verify listener is still listening
-					if (event == null) {
-						event = new TreeChangeEvent(this.source, treeName, nodes);
-					}
-					listener.treeChanged(event);
-				}
-			}
-		}
-
-		Iterable<ChangeListener> changeListeners = this.getChangeListeners();
-		if (changeListeners != null) {
-			for (ChangeListener changeListener : changeListeners) {
-				if (this.hasChangeListener(changeListener)) {  // verify listener is still listening
-					if (event == null) {
-						event = new TreeChangeEvent(this.source, treeName, nodes);
-					}
-					changeListener.treeChanged(event);
-				}
-			}
-		}
-	}
-
-
 	// ********** misc **********
 
 	/**
 	 * Convenience method for checking whether an attribute value has changed.
-	 * @see Tools#valuesAreEqual(Object, Object)
+	 * @see ObjectTools#equals(Object, Object)
 	 */
 	public boolean valuesAreEqual(Object value1, Object value2) {
-		return Tools.valuesAreEqual(value1, value2);
+		return ObjectTools.equals(value1, value2);
 	}
 
 	/**
 	 * Convenience method for checking whether an attribute value has changed.
-	 * @see Tools#valuesAreDifferent(Object, Object)
+	 * @see ObjectTools#notEquals(Object, Object)
 	 */
 	public boolean valuesAreDifferent(Object value1, Object value2) {
-		return Tools.valuesAreDifferent(value1, value2);
+		return ObjectTools.notEquals(value1, value2);
 	}
 
 	/**
-	 * @see CollectionTools#elementsAreEqual(Iterable, Iterable)
+	 * @see IterableTools#elementsAreEqual(Iterable, Iterable)
 	 */
 	public boolean elementsAreEqual(Iterable<?> iterable1, Iterable<?> iterable2) {
-		return CollectionTools.elementsAreEqual(iterable1, iterable2);
+		return IterableTools.elementsAreEqual(iterable1, iterable2);
 	}
 
 	/**
-	 * @see CollectionTools#elementsAreDifferent(Iterable, Iterable)
+	 * @see IterableTools#elementsAreDifferent(Iterable, Iterable)
 	 */
 	public boolean elementsAreDifferent(Iterable<?> iterable1, Iterable<?> iterable2) {
-		return CollectionTools.elementsAreDifferent(iterable1, iterable2);
+		return IterableTools.elementsAreDifferent(iterable1, iterable2);
 	}
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.source);
+		return ObjectTools.toString(this, this.source);
 	}
 
 
@@ -2785,7 +2518,7 @@
 
 		@Override
 		public String toString() {
-			return StringTools.buildToStringFor(this, this.getAspectName());
+			return ObjectTools.toString(this, this.getAspectName());
 		}
 
 		abstract String getAspectName();
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/Model.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/Model.java
index 6f98a6e..49b5d37 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/Model.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/Model.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -18,24 +18,23 @@
 import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
 import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
-import org.eclipse.persistence.tools.utility.model.listener.TreeChangeListener;
 
 /**
  * Interface to be implemented by models that notify listeners of
  * changes to bound properties, collections, lists, and/or trees.
  * <p>
- * 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.
- * 
+ * 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.
+ *
  * @see ChangeListener
  * @see StateChangeListener
  * @see PropertyChangeListener
  * @see CollectionChangeListener
  * @see ListChangeListener
- * @see TreeChangeListener
- * @see org.eclipse.persistence.tools.utility.model.AbstractModel
+ * @see org.eclipse.jpt.common.utility.internal.model.AbstractModel
  */
 // TODO use objects (IDs?) instead of strings to identify aspects?
 public interface Model {
@@ -55,6 +54,7 @@
 	 */
 	void removeChangeListener(ChangeListener listener);
 
+
 	// ********** state change **********
 
 	/**
@@ -70,6 +70,7 @@
 	 */
 	void removeStateChangeListener(StateChangeListener listener);
 
+
 	// ********** property change **********
 
 	/**
@@ -87,6 +88,7 @@
 	 */
 	void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);
 
+
 	// ********** collection change **********
 
 	/**
@@ -104,6 +106,7 @@
 	 */
 	void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener);
 
+
 	// ********** list change **********
 
 	/**
@@ -120,22 +123,4 @@
 	 * Throw an exception if the listener is null or if the listener was never added.
 	 */
 	void removeListChangeListener(String listName, ListChangeListener listener);
-
-	// ********** tree change **********
-
-	/**
-	 * Add a listener that listens to all tree change events with
-	 * the specified tree name.
-	 * Throw an exception if the same listener is added more than once.
-	 * The listener cannot be null.
-	 */
-	void addTreeChangeListener(String treeName, TreeChangeListener listener);
-
-	/**
-	 * Remove a listener that listens to all tree change events,
-	 * with the specified tree name.
-	 * Throw an exception if the listener is null or if the listener was never added.
-	 */
-	void removeTreeChangeListener(String treeName, TreeChangeListener listener);
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/SingleAspectChangeSupport.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/SingleAspectChangeSupport.java
index 2d4b4b2..63ab9ec 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/SingleAspectChangeSupport.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/SingleAspectChangeSupport.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -28,10 +28,6 @@
 import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
 import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeRemoveEvent;
 
 /**
  * This change support class changes the behavior of the standard
@@ -42,19 +38,21 @@
  * </ul>
  */
 @SuppressWarnings("nls")
-public class SingleAspectChangeSupport extends ChangeSupport {
-
+public class SingleAspectChangeSupport
+	extends ChangeSupport
+{
 	protected final Class<? extends EventListener> validListenerClass;
 	protected final String validAspectName;
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructor **********
 
 	public SingleAspectChangeSupport(Model source, Class<? extends EventListener> validListenerClass, String validAspectName) {
 		super(source);
 		if ( ! validListenerClass.isAssignableFrom(this.getChangeListenerClass())) {
-			throw new IllegalArgumentException("The change support's change listener class (" + this.getChangeListenerClass().getName() +
+			throw new IllegalArgumentException("The change support's change listener class (" + this.getChangeListenerClass().getName() + //$NON-NLS-1$
 					") does not extend the valid listener class: " + validListenerClass.getName());
 		}
 		this.validListenerClass = validListenerClass;
@@ -66,8 +64,8 @@
 
 	private UnsupportedOperationException buildUnsupportedOperationException() {
 		return new UnsupportedOperationException(
-				"This Model supports only changes for the listener type \"" + this.validListenerClass.getName()
-				+ "\" and the aspect \"" + this.validAspectName + '"'
+				"This Model supports only changes for the listener type \"" + this.validListenerClass.getName() //$NON-NLS-1$
+				+ "\" and the aspect \"" + this.validAspectName + '"' //$NON-NLS-1$
 			);
 	}
 
@@ -79,8 +77,8 @@
 	private void check(Class<? extends EventListener> listenerClass) {
 		if ((listenerClass != this.getChangeListenerClass()) && (listenerClass != this.validListenerClass)) {
 			throw new IllegalArgumentException(
-					"This Model supports only changes for the listener type \"" + this.validListenerClass.getName()
-					+ "\" : \"" + listenerClass.getName() + '"'
+					"This Model supports only changes for the listener type \"" + this.validListenerClass.getName() //$NON-NLS-1$
+					+ "\" : \"" + listenerClass.getName() + '"' //$NON-NLS-1$
 				);
 		}
 	}
@@ -89,8 +87,8 @@
 		this.check(listenerClass);
 		if ( ! aspectName.equals(this.validAspectName)) {
 			throw new IllegalArgumentException(
-					"This Model supports only changes for the aspect \"" + this.validAspectName
-					+ "\" : \"" + aspectName + '"'
+					"This Model supports only changes for the aspect \"" + this.validAspectName //$NON-NLS-1$
+					+ "\" : \"" + aspectName + '"' //$NON-NLS-1$
 				);
 		}
 	}
@@ -326,55 +324,4 @@
 		this.check(LIST_CHANGE_LISTENER_CLASS, listName);
 		super.fireListChanged(listName, list);
 	}
-
-
-	// ********** tree change support **********
-
-	@Override
-	public void fireNodeAdded(TreeAddEvent event) {
-		this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName());
-		super.fireNodeAdded(event);
-	}
-
-	@Override
-	public void fireNodeAdded(String treeName, List<?> path) {
-		this.check(TREE_CHANGE_LISTENER_CLASS, treeName);
-		super.fireNodeAdded(treeName, path);
-	}
-
-	@Override
-	public void fireNodeRemoved(TreeRemoveEvent event) {
-		this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName());
-		super.fireNodeRemoved(event);
-	}
-
-	@Override
-	public void fireNodeRemoved(String treeName, List<?> path) {
-		this.check(TREE_CHANGE_LISTENER_CLASS, treeName);
-		super.fireNodeRemoved(treeName, path);
-	}
-
-	@Override
-	public void fireTreeCleared(TreeClearEvent event) {
-		this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName());
-		super.fireTreeCleared(event);
-	}
-
-	@Override
-	public void fireTreeCleared(String treeName) {
-		this.check(TREE_CHANGE_LISTENER_CLASS, treeName);
-		super.fireTreeCleared(treeName);
-	}
-
-	@Override
-	public void fireTreeChanged(TreeChangeEvent event) {
-		this.check(TREE_CHANGE_LISTENER_CLASS, event.getTreeName());
-		super.fireTreeChanged(event);
-	}
-
-	@Override
-	public void fireTreeChanged(String treeName, Collection<?> nodes) {
-		this.check(TREE_CHANGE_LISTENER_CLASS, treeName);
-		super.fireTreeChanged(treeName, nodes);
-	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ChangeEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ChangeEvent.java
index 2a711a9..cc0482c 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ChangeEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ChangeEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,8 +14,7 @@
 package org.eclipse.persistence.tools.utility.model.event;
 
 import java.util.EventObject;
-
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
 import org.eclipse.persistence.tools.utility.model.Model;
 
 /**
@@ -31,6 +30,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	/**
 	 * Construct a new change event.
 	 *
@@ -51,7 +51,7 @@
 	@Override
 	public String toString() {
 		StringBuilder sb = new StringBuilder();
-		StringTools.appendSimpleToString(sb, this);
+		StringBuilderTools.appendHashCodeToString(sb, this);
 		sb.append('(');
 		int len = sb.length();
 		this.toString(sb);
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionAddEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionAddEvent.java
index 4f31089..1d7f370 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionAddEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionAddEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,15 +14,14 @@
 package org.eclipse.persistence.tools.utility.model.event;
 
 import java.util.Collection;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
 import org.eclipse.persistence.tools.utility.model.Model;
 
 /**
  * A "collection add" event gets delivered whenever a model adds items to a
  * "bound" or "constrained" collection. A <code>CollectionAddEvent</code> is sent as an
- * argument to the {@link org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener}.
+ * argument to the {@link org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener}.
  * <p>
  * Provisional API: This class is part of an interim API that is still
  * under development and expected to change significantly before reaching
@@ -53,6 +52,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructors **********
 
 	/**
@@ -86,14 +86,14 @@
 	// ********** standard state **********
 
 	/**
-	 * Returns the items added to the collection.
+	 * Return the items added to the collection.
 	 */
 	public Iterable<?> getItems() {
 		return new ArrayIterable<Object>(this.items);
 	}
 
 	/**
-	 * Returns the number of items added to the collection.
+	 * Return the number of items added to the collection.
 	 */
 	public int getItemsSize() {
 		return this.items.length;
@@ -103,14 +103,14 @@
 	protected void toString(StringBuilder sb) {
 		super.toString(sb);
 		sb.append(": ");
-		StringTools.append(sb, this.items);
+		StringBuilderTools.append(sb, this.items);
 	}
 
 
 	// ********** cloning **********
 
 	/**
-	 * Returns a copy of the event with the specified source
+	 * Return a copy of the event with the specified source
 	 * replacing the current source.
 	 */
 	public CollectionAddEvent clone(Model newSource) {
@@ -118,11 +118,10 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and collection name
+	 * Return a copy of the event with the specified source and collection name
 	 * replacing the current source and collection name.
 	 */
 	public CollectionAddEvent clone(Model newSource, String newCollectionName) {
 		return new CollectionAddEvent(newSource, newCollectionName, this.items);
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionChangeEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionChangeEvent.java
index c265357..d38939a 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionChangeEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionChangeEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,9 +14,8 @@
 package org.eclipse.persistence.tools.utility.model.event;
 
 import java.util.Collection;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
 import org.eclipse.persistence.tools.utility.model.Model;
 
 /**
@@ -24,7 +23,7 @@
  * or "constrained" collection in a manner that is not easily characterized by
  * the other collection events.
  * A <code>CollectionChangeEvent</code> is sent as an
- * argument to the {@link org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener}.
+ * argument to the {@link org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener}.
  * A <code>CollectionChangeEvent</code> is accompanied by the collection name and
  * the current state of the collection.
  * <p>
@@ -46,6 +45,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructors **********
 
 	/**
@@ -67,14 +67,14 @@
 	// ********** standard state **********
 
 	/**
-	 * Returns the current state of the collection.
+	 * Return the current state of the collection.
 	 */
 	public Iterable<?> getCollection() {
 		return new ArrayIterable<Object>(this.collection);
 	}
 
 	/**
-	 * Returns the number of items in the current state of the collection.
+	 * Return the number of items in the current state of the collection.
 	 */
 	public int getCollectionSize() {
 		return this.collection.length;
@@ -84,14 +84,14 @@
 	protected void toString(StringBuilder sb) {
 		super.toString(sb);
 		sb.append(": ");
-		StringTools.append(sb, this.collection);
+		StringBuilderTools.append(sb, this.collection);
 	}
 
 
 	// ********** cloning **********
 
 	/**
-	 * Returns a copy of the event with the specified source
+	 * Return a copy of the event with the specified source
 	 * replacing the current source.
 	 */
 	public CollectionChangeEvent clone(Model newSource) {
@@ -99,7 +99,7 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and collection name
+	 * Return a copy of the event with the specified source and collection name
 	 * replacing the current source and collection name.
 	 */
 	public CollectionChangeEvent clone(Model newSource, String newCollectionName) {
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionClearEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionClearEvent.java
index 9f2feb0..96ac9fc 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionClearEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionClearEvent.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -18,7 +18,7 @@
 /**
  * A "collection clear" event gets delivered whenever a model clears
  * a "bound" or "constrained" collection. A <code>CollectionClearEvent</code> is sent
- * as an argument to the {@link org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener}.
+ * as an argument to the {@link org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener}.
  * <p>
  * Provisional API: This class is part of an interim API that is still
  * under development and expected to change significantly before reaching
@@ -30,6 +30,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructors **********
 
 	/**
@@ -46,7 +47,7 @@
 	// ********** cloning **********
 
 	/**
-	 * Returns a copy of the event with the specified source
+	 * Return a copy of the event with the specified source
 	 * replacing the current source.
 	 */
 	public CollectionClearEvent clone(Model newSource) {
@@ -54,11 +55,10 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and collection name
+	 * Return a copy of the event with the specified source and collection name
 	 * replacing the current source and collection name.
 	 */
 	public CollectionClearEvent clone(Model newSource, String newCollectionName) {
 		return new CollectionClearEvent(newSource, newCollectionName);
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionEvent.java
index 74165d4..f61dba5 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionEvent.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -14,11 +14,12 @@
 package org.eclipse.persistence.tools.utility.model.event;
 
 import org.eclipse.persistence.tools.utility.model.Model;
+
 // TODO add "item/original/nested event" for item changed?
 /**
  * A "collection" event gets delivered whenever a model changes a "bound"
  * or "constrained" collection. A <code>CollectionEvent</code> is sent as an
- * argument to the {@link org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener}.
+ * argument to the {@link org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener}.
  * The intent is that any listener
  * can keep itself synchronized with the model's collection via the collection
  * events it receives and need not maintain a reference to the original
@@ -37,6 +38,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	/**
 	 * Construct a new collection event.
 	 *
@@ -52,7 +54,7 @@
 	}
 
 	/**
-	 * Returns the programmatic name of the collection that was changed.
+	 * Return the programmatic name of the collection that was changed.
 	 */
 	public String getCollectionName() {
 		return this.collectionName;
@@ -62,5 +64,4 @@
 	protected void toString(StringBuilder sb) {
 		sb.append(this.collectionName);
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionRemoveEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionRemoveEvent.java
index bc2c120..e310165 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionRemoveEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/CollectionRemoveEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,15 +14,14 @@
 package org.eclipse.persistence.tools.utility.model.event;
 
 import java.util.Collection;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
 import org.eclipse.persistence.tools.utility.model.Model;
 
 /**
  * A "collection remove" event gets delivered whenever a model removes items
  * from a "bound" or "constrained" collection. A <code>CollectionRemoveEvent</code> is sent
- * as an argument to the {@link org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener}.
+ * as an argument to the {@link org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener}.
  * <p>
  * Provisional API: This class is part of an interim API that is still
  * under development and expected to change significantly before reaching
@@ -41,6 +40,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructors **********
 
 	/**
@@ -74,14 +74,14 @@
 	// ********** standard state **********
 
 	/**
-	 * Returns the items removed from the collection.
+	 * Return the items removed from the collection.
 	 */
 	public Iterable<?> getItems() {
 		return new ArrayIterable<Object>(this.items);
 	}
 
 	/**
-	 * Returns the number of items removed from the collection.
+	 * Return the number of items removed from the collection.
 	 */
 	public int getItemsSize() {
 		return this.items.length;
@@ -91,14 +91,14 @@
 	protected void toString(StringBuilder sb) {
 		super.toString(sb);
 		sb.append(": ");
-		StringTools.append(sb, this.items);
+		StringBuilderTools.append(sb, this.items);
 	}
 
 
 	// ********** cloning **********
 
 	/**
-	 * Returns a copy of the event with the specified source
+	 * Return a copy of the event with the specified source
 	 * replacing the current source.
 	 */
 	public CollectionRemoveEvent clone(Model newSource) {
@@ -106,7 +106,7 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and collection name
+	 * Return a copy of the event with the specified source and collection name
 	 * replacing the current source and collection name.
 	 */
 	public CollectionRemoveEvent clone(Model newSource, String newCollectionName) {
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListAddEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListAddEvent.java
index 987cc1c..ca2ecb6 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListAddEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListAddEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,15 +14,14 @@
 package org.eclipse.persistence.tools.utility.model.event;
 
 import java.util.List;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
 import org.eclipse.persistence.tools.utility.model.Model;
 
 /**
  * A "list add" event gets delivered whenever a model adds items to a
  * "bound" or "constrained" list. A <code>ListAddEvent</code> is sent as an
- * argument to the {@link org.eclipse.persistence.tools.utility.model.listener.ListChangeListener}.
+ * argument to the {@link org.eclipse.jpt.common.utility.model.listener.ListChangeListener}.
  * <p>
  * Provisional API: This class is part of an interim API that is still
  * under development and expected to change significantly before reaching
@@ -44,6 +43,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructors **********
 
 	/**
@@ -80,21 +80,21 @@
 	// ********** standard state **********
 
 	/**
-	 * Returns the index at which the items were added to the list.
+	 * Return the index at which the items were added to the list.
 	 */
 	public int getIndex() {
 		return this.index;
 	}
 
 	/**
-	 * Returns the items added to the list.
+	 * Return the items added to the list.
 	 */
 	public Iterable<?> getItems() {
 		return new ArrayIterable<Object>(this.items);
 	}
 
 	/**
-	 * Returns the number of items added to the list.
+	 * Return the number of items added to the list.
 	 */
 	public int getItemsSize() {
 		return this.items.length;
@@ -104,14 +104,14 @@
 	protected void toString(StringBuilder sb) {
 		super.toString(sb);
 		sb.append(": ");
-		StringTools.append(sb, this.items);
+		StringBuilderTools.append(sb, this.items);
 	}
 
 
 	// ********** cloning **********
 
 	/**
-	 * Returns a copy of the event with the specified source
+	 * Return a copy of the event with the specified source
 	 * replacing the current source.
 	 */
 	public ListAddEvent clone(Model newSource) {
@@ -119,7 +119,7 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and list name
+	 * Return a copy of the event with the specified source and list name
 	 * replacing the current source and list name.
 	 */
 	public ListAddEvent clone(Model newSource, String newListName) {
@@ -127,7 +127,7 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and list name
+	 * Return a copy of the event with the specified source and list name
 	 * replacing the current source and list name and displacing
 	 * the index by the specified amount.
 	 */
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListChangeEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListChangeEvent.java
index ad2d64b..1bc535d 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListChangeEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListChangeEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,9 +14,8 @@
 package org.eclipse.persistence.tools.utility.model.event;
 
 import java.util.List;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
 import org.eclipse.persistence.tools.utility.model.Model;
 
 /**
@@ -24,7 +23,7 @@
  * or "constrained" list in a manner that is not easily characterized by
  * the other list events.
  * A <code>ListChangeEvent</code> is sent as an
- * argument to the {@link org.eclipse.persistence.tools.utility.model.listener.ListChangeListener}.
+ * argument to the {@link org.eclipse.jpt.common.utility.model.listener.ListChangeListener}.
  * A <code>ListChangeEvent</code> is accompanied by the list name and
  * the current state of the list.
  * <p>
@@ -46,6 +45,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructors **********
 
 	/**
@@ -67,14 +67,14 @@
 	// ********** standard state **********
 
 	/**
-	 * Returns the current state of the list.
+	 * Return the current state of the list.
 	 */
 	public Iterable<?> getList() {
 		return new ArrayIterable<Object>(this.list);
 	}
 
 	/**
-	 * Returns the number of items in the current state of the list.
+	 * Return the number of items in the current state of the list.
 	 */
 	public int getListSize() {
 		return this.list.length;
@@ -84,14 +84,14 @@
 	protected void toString(StringBuilder sb) {
 		super.toString(sb);
 		sb.append(": ");
-		StringTools.append(sb, this.list);
+		StringBuilderTools.append(sb, this.list);
 	}
 
 
 	// ********** cloning **********
 
 	/**
-	 * Returns a copy of the event with the specified source
+	 * Return a copy of the event with the specified source
 	 * replacing the current source.
 	 */
 	public ListChangeEvent clone(Model newSource) {
@@ -99,7 +99,7 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and list name
+	 * Return a copy of the event with the specified source and list name
 	 * replacing the current source and list name.
 	 */
 	public ListChangeEvent clone(Model newSource, String newListName) {
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListClearEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListClearEvent.java
index d084e79..5732fd9 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListClearEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListClearEvent.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -18,7 +18,7 @@
 /**
  * A "list clear" event gets delivered whenever a model clears
  * a "bound" or "constrained" list. A <code>ListClearEvent</code> is sent
- * as an argument to the {@link org.eclipse.persistence.tools.utility.model.listener.ListChangeListener}.
+ * as an argument to the {@link org.eclipse.jpt.common.utility.model.listener.ListChangeListener}.
  * <p>
  * Provisional API: This class is part of an interim API that is still
  * under development and expected to change significantly before reaching
@@ -30,6 +30,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructor **********
 
 	/**
@@ -46,7 +47,7 @@
 	// ********** cloning **********
 
 	/**
-	 * Returns a copy of the event with the specified source
+	 * Return a copy of the event with the specified source
 	 * replacing the current source.
 	 */
 	public ListClearEvent clone(Model newSource) {
@@ -54,11 +55,10 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and list name
+	 * Return a copy of the event with the specified source and list name
 	 * replacing the current source and list name.
 	 */
 	public ListClearEvent clone(Model newSource, String newListName) {
 		return new ListClearEvent(newSource, newListName);
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListEvent.java
index fdc6fe2..585a813 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListEvent.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -19,7 +19,7 @@
 /**
  * A "list" event gets delivered whenever a model changes a "bound"
  * or "constrained" list. A <code>ListEvent</code> is sent as an
- * argument to the {@link org.eclipse.persistence.tools.utility.model.listener.ListChangeListener}.
+ * argument to the {@link org.eclipse.jpt.common.utility.model.listener.ListChangeListener}.
  * The intent is that any listener
  * can keep itself synchronized with the model's list via the list
  * events it receives and need not maintain a reference to the original
@@ -38,6 +38,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	/**
 	 * Construct a new list event.
 	 *
@@ -53,7 +54,7 @@
 	}
 
 	/**
-	 * Returns the programmatic name of the list that was changed.
+	 * Return the programmatic name of the list that was changed.
 	 */
 	public String getListName() {
 		return this.listName;
@@ -63,5 +64,4 @@
 	protected void toString(StringBuilder sb) {
 		sb.append(this.listName);
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListMoveEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListMoveEvent.java
index b1eef7e..b7cd09a 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListMoveEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListMoveEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -18,7 +18,7 @@
 /**
  * A "list move" event gets delivered whenever a model moves the elements in
  * a "bound" or "constrained" list. A <code>ListMoveEvent</code> is sent
- * as an argument to the {@link org.eclipse.persistence.tools.utility.model.listener.ListChangeListener}.
+ * as an argument to the {@link org.eclipse.jpt.common.utility.model.listener.ListChangeListener}.
  * <p>
  * Provisional API: This class is part of an interim API that is still
  * under development and expected to change significantly before reaching
@@ -40,6 +40,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructor **********
 
 	/**
@@ -62,21 +63,21 @@
 	// ********** standard state **********
 
 	/**
-	 * Returns the index to which the items were moved.
+	 * Return the index to which the items were moved.
 	 */
 	public int getTargetIndex() {
 		return this.targetIndex;
 	}
 
 	/**
-	 * Returns the index from which the items were moved.
+	 * Return the index from which the items were moved.
 	 */
 	public int getSourceIndex() {
 		return this.sourceIndex;
 	}
 
 	/**
-	 * Returns the number of items moved.
+	 * Return the number of items moved.
 	 */
 	public int getLength() {
 		return this.length;
@@ -97,7 +98,7 @@
 	// ********** cloning **********
 
 	/**
-	 * Returns a copy of the event with the specified source
+	 * Return a copy of the event with the specified source
 	 * replacing the current source.
 	 */
 	public ListMoveEvent clone(Model newSource) {
@@ -105,7 +106,7 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and list name
+	 * Return a copy of the event with the specified source and list name
 	 * replacing the current source and list name.
 	 */
 	public ListMoveEvent clone(Model newSource, String newListName) {
@@ -113,7 +114,7 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and list name
+	 * Return a copy of the event with the specified source and list name
 	 * replacing the current source and list name and displacing
 	 * the index by the specified amount.
 	 */
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListRemoveEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListRemoveEvent.java
index ccebc16..69009e8 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListRemoveEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListRemoveEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,15 +14,14 @@
 package org.eclipse.persistence.tools.utility.model.event;
 
 import java.util.Collection;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
 import org.eclipse.persistence.tools.utility.model.Model;
 
 /**
  * A "list remove" event gets delivered whenever a model removes items
  * from a "bound" or "constrained" list. A <code>ListRemoveEvent</code> is sent
- * as an argument to the {@link org.eclipse.persistence.tools.utility.model.listener.ListChangeListener}.
+ * as an argument to the {@link org.eclipse.jpt.common.utility.model.listener.ListChangeListener}.
  * <p>
  * Provisional API: This class is part of an interim API that is still
  * under development and expected to change significantly before reaching
@@ -44,13 +43,14 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructors **********
 
 	/**
 	 * Construct a new list remove event.
 	 *
 	 * @param source The object on which the event initially occurred.
-	 * @param collectionName The programmatic name of the list that was changed.
+	 * @param listName The programmatic name of the list that was changed.
 	 * @param index The index at which the items were removed.
 	 * @param item The item removed from the list.
 	 */
@@ -62,7 +62,7 @@
 	 * Construct a new list remove event.
 	 *
 	 * @param source The object on which the event initially occurred.
-	 * @param collectionName The programmatic name of the list that was changed.
+	 * @param listName The programmatic name of the list that was changed.
 	 * @param index The index at which the items were removed.
 	 * @param items The items removed from the list.
 	 */
@@ -80,21 +80,21 @@
 	// ********** standard state **********
 
 	/**
-	 * Returns the index at which the items were removed from the list.
+	 * Return the index at which the items were removed from the list.
 	 */
 	public int getIndex() {
 		return this.index;
 	}
 
 	/**
-	 * Returns the items removed from the list.
+	 * Return the items removed from the list.
 	 */
 	public Iterable<?> getItems() {
 		return new ArrayIterable<Object>(this.items);
 	}
 
 	/**
-	 * Returns the number of items removed from the list.
+	 * Return the number of items removed from the list.
 	 */
 	public int getItemsSize() {
 		return this.items.length;
@@ -104,14 +104,14 @@
 	protected void toString(StringBuilder sb) {
 		super.toString(sb);
 		sb.append(": ");
-		StringTools.append(sb, this.items);
+		StringBuilderTools.append(sb, this.items);
 	}
 
 
 	// ********** cloning **********
 
 	/**
-	 * Returns a copy of the event with the specified source
+	 * Return a copy of the event with the specified source
 	 * replacing the current source.
 	 */
 	public ListRemoveEvent clone(Model newSource) {
@@ -119,7 +119,7 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and list name
+	 * Return a copy of the event with the specified source and list name
 	 * replacing the current source and list name.
 	 */
 	public ListRemoveEvent clone(Model newSource, String newListName) {
@@ -127,7 +127,7 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and list name
+	 * Return a copy of the event with the specified source and list name
 	 * replacing the current source and list name and displacing
 	 * the index by the specified amount.
 	 */
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListReplaceEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListReplaceEvent.java
index 237dd1a..c4b6395 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListReplaceEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/ListReplaceEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,15 +14,14 @@
 package org.eclipse.persistence.tools.utility.model.event;
 
 import java.util.List;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
 import org.eclipse.persistence.tools.utility.model.Model;
 
 /**
  * A "list replace" event gets delivered whenever a model replaces items in a
  * "bound" or "constrained" list. A <code>ListReplaceEvent</code> is sent as an
- * argument to the {@link org.eclipse.persistence.tools.utility.model.listener.ListChangeListener}.
+ * argument to the {@link org.eclipse.jpt.common.utility.model.listener.ListChangeListener}.
  * <p>
  * Provisional API: This class is part of an interim API that is still
  * under development and expected to change significantly before reaching
@@ -44,6 +43,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructors **********
 
 	/**
@@ -75,7 +75,7 @@
 	private ListReplaceEvent(Model source, String listName, int index, Object[] newItems, Object[] oldItems) {
 		super(source, listName);
 		if (newItems.length != oldItems.length) {
-			throw new IllegalArgumentException("sizes must match - new items size: " + newItems.length
+			throw new IllegalArgumentException("sizes must match - new items size: " + newItems.length //$NON-NLS-1$
 					+ " old items size: " + oldItems.length);
 		}
 		this.index = index;
@@ -87,28 +87,28 @@
 	// ********** standard state **********
 
 	/**
-	 * Returns the index at which the items were replaced in the list.
+	 * Return the index at which the items were replaced in the list.
 	 */
 	public int getIndex() {
 		return this.index;
 	}
 
 	/**
-	 * Returns the new items that replaced the old items in the list.
+	 * Return the new items that replaced the old items in the list.
 	 */
 	public Iterable<?> getNewItems() {
 		return new ArrayIterable<Object>(this.newItems);
 	}
 
 	/**
-	 * Returns the old items that were replaced by the new items in the list.
+	 * Return the old items that were replaced by the new items in the list.
 	 */
 	public Iterable<?> getOldItems() {
 		return new ArrayIterable<Object>(this.oldItems);
 	}
 
 	/**
-	 * Returns the number of items that were replaced.
+	 * Return the number of items that were replaced.
 	 */
 	public int getItemsSize() {
 		return this.newItems.length;
@@ -118,16 +118,16 @@
 	protected void toString(StringBuilder sb) {
 		super.toString(sb);
 		sb.append(": ");
-		StringTools.append(sb, this.oldItems);
+		StringBuilderTools.append(sb, this.oldItems);
 		sb.append(" => ");
-		StringTools.append(sb, this.newItems);
+		StringBuilderTools.append(sb, this.newItems);
 	}
 
 
 	// ********** cloning **********
 
 	/**
-	 * Returns a copy of the event with the specified source
+	 * Return a copy of the event with the specified source
 	 * replacing the current source.
 	 */
 	public ListReplaceEvent clone(Model newSource) {
@@ -135,7 +135,7 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and list name
+	 * Return a copy of the event with the specified source and list name
 	 * replacing the current source and list name.
 	 */
 	public ListReplaceEvent clone(Model newSource, String newListName) {
@@ -143,7 +143,7 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and list name
+	 * Return a copy of the event with the specified source and list name
 	 * replacing the current source and list name and displacing
 	 * the index by the specified amount.
 	 */
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/PropertyChangeEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/PropertyChangeEvent.java
index 0212c7c..4143103 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/PropertyChangeEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/PropertyChangeEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -18,7 +18,7 @@
 /**
  * A "property change" event gets delivered whenever a model changes a "bound"
  * or "constrained" property. A <code>PropertyChangeEvent</code> is sent as an
- * argument to the {@link org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener}.
+ * argument to the {@link org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener}.
  * A <code>PropertyChangeEvent</code> is accompanied by the old and new values
  * of the property.
  * <p>
@@ -42,6 +42,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructors **********
 
 	/**
@@ -66,21 +67,21 @@
 	// ********** standard state **********
 
 	/**
-	 * Returns the programmatic name of the property that was changed.
+	 * Return the programmatic name of the property that was changed.
 	 */
 	public String getPropertyName() {
 		return this.propertyName;
 	}
 
 	/**
-	 * Returns the old value of the property.
+	 * Return the old value of the property.
 	 */
 	public Object getOldValue() {
 		return this.oldValue;
 	}
 
 	/**
-	 * Returns the new value of the property.
+	 * Return the new value of the property.
 	 */
 	public Object getNewValue() {
 		return this.newValue;
@@ -103,7 +104,7 @@
 	}
 
 	/**
-	 * Returns a copy of the event with the specified source and property name
+	 * Return a copy of the event with the specified source and property name
 	 * replacing the current source and property name.
 	 */
 	public PropertyChangeEvent clone(Model newSource, String newPropertyName) {
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/StateChangeEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/StateChangeEvent.java
index 3e51af1..ab23abc 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/StateChangeEvent.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/StateChangeEvent.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -21,7 +21,7 @@
  * Any listener can synchronize with the model as necessary since the model is
  * available as the event's 'source'.
  * A <code>StateChangeEvent</code> is sent as an argument to the
- * {@link org.eclipse.persistence.tools.utility.model.listener.StateChangeListener}.
+ * {@link org.eclipse.jpt.common.utility.model.listener.StateChangeListener}.
  * <p>
  * Provisional API: This class is part of an interim API that is still
  * under development and expected to change significantly before reaching
@@ -33,6 +33,7 @@
 
 	private static final long serialVersionUID = 1L;
 
+
 	// ********** constructors **********
 
 	/**
@@ -50,5 +51,4 @@
 	public StateChangeEvent clone(Model newSource) {
 		return new StateChangeEvent(newSource);
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeAddEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeAddEvent.java
deleted file mode 100644
index 0b4267d..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeAddEvent.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.model.event;
-
-import java.util.List;
-
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
-import org.eclipse.persistence.tools.utility.model.Model;
-
-/**
- * A "tree add" event gets delivered whenever a model adds a node to a "bound"
- * or "constrained" tree. A <code>TreeChangeEvent</code> is sent as an
- * argument to the {@link org.eclipse.persistence.tools.utility.model.listener.TreeChangeListener}.
- * <p>
- * Provisional API: This class 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 final class TreeAddEvent extends TreeEvent {
-
-	/**
-     * Path to the node added to the tree.
-     */
-	protected final Object[] path;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct a new tree add event.
-	 *
-	 * @param source The object on which the event initially occurred.
-	 * @param treeName The programmatic name of the tree that was changed.
-	 * @param path The path to the part of the tree that was added.
-	 */
-	public TreeAddEvent(Model source, String treeName, List<?> path) {
-		this(source, treeName, path.toArray());  // NPE if 'path' is null
-	}
-
-	private TreeAddEvent(Model source, String treeName, Object[] path) {
-		super(source, treeName);
-		this.path = path;
-	}
-
-
-	// ********** standard state **********
-
-	/**
-	 * Returns the path to the part of the tree that was added.
-	 */
-	public Iterable<?> getPath() {
-		return new ArrayIterable<Object>(this.path);
-	}
-
-
-	// ********** cloning **********
-
-	public TreeAddEvent clone(Model newSource) {
-		return this.clone(newSource, this.treeName);
-	}
-
-	/**
-	 * Returns a copy of the event with the specified source and tree name
-	 * replacing the current source and tree name.
-	 */
-	public TreeAddEvent clone(Model newSource, String newTreeName) {
-		return new TreeAddEvent(newSource, newTreeName, this.path);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeChangeEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeChangeEvent.java
deleted file mode 100644
index dcf9d29..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeChangeEvent.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.model.event;
-
-import java.util.Collection;
-
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
-import org.eclipse.persistence.tools.utility.model.Model;
-
-/**
- * A "tree change" event gets delivered whenever a model changes a "bound"
- * or "constrained" tree in a manner that is not easily characterized by
- * the other tree events.
- * A <code>TreeChangeEvent</code> is sent as an
- * argument to the {@link org.eclipse.persistence.tools.utility.model.listener.TreeChangeListener}.
- * <p>
- * Provisional API: This class 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 final class TreeChangeEvent extends TreeEvent {
-
-    /**
-     * The current nodes in the changed tree.
-     */
-	protected final Object[] nodes;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructor **********
-
-	/**
-	 * Construct a new tree change event.
-	 *
-	 * @param source The object on which the event initially occurred.
-	 * @param treeName The programmatic name of the tree that was changed.
-	 * @param nodes The current nodes in the changed tree.
-	 */
-	public TreeChangeEvent(Model source, String treeName, Collection<?> nodes) {
-		this(source, treeName, nodes.toArray());  // NPE if 'nodes' is null
-	}
-	
-	private TreeChangeEvent(Model source, String treeName, Object[] nodes) {
-		super(source, treeName);
-		this.nodes = nodes;
-	}
-	
-
-	// ********** standard state **********
-
-	/**
-	 * Returns the current nodes in the changed tree.
-	 */
-	public Iterable<?> getNodes() {
-		return new ArrayIterable<Object>(this.nodes);
-	}
-
-	/**
-	 * Returns the current nodes in the changed tree.
-	 */
-	public int getNodesSize() {
-		return this.nodes.length;
-	}
-
-
-	// ********** cloning **********
-
-	public TreeChangeEvent clone(Model newSource) {
-		return this.clone(newSource, this.treeName);
-	}
-
-	/**
-	 * Returns a copy of the event with the specified source and tree name
-	 * replacing the current source and tree name.
-	 */
-	public TreeChangeEvent clone(Model newSource, String newTreeName) {
-		return new TreeChangeEvent(newSource, newTreeName, this.nodes);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeClearEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeClearEvent.java
deleted file mode 100644
index 0c04ccf..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeClearEvent.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.model.event;
-
-import org.eclipse.persistence.tools.utility.model.Model;
-
-/**
- * A "tree clear" event gets delivered whenever a model clears
- * a "bound" or "constrained" tree. A <code>TreeClearEvent</code> is sent
- * as an argument to the {@link org.eclipse.persistence.tools.utility.model.listener.TreeChangeListener}.
- * <p>
- * Provisional API: This class 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 final class TreeClearEvent extends TreeEvent {
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct a new tree clear event.
-	 *
-	 * @param source The object on which the event initially occurred.
-	 * @param collectionName The programmatic name of the tree that was changed.
-	 */
-	public TreeClearEvent(Model source, String treeName) {
-		super(source, treeName);
-	}
-
-
-	// ********** cloning **********
-
-	/**
-	 * Returns a copy of the event with the specified source
-	 * replacing the current source.
-	 */
-	public TreeClearEvent clone(Model newSource) {
-		return this.clone(newSource, this.treeName);
-	}
-
-	/**
-	 * Returns a copy of the event with the specified source and collection name
-	 * replacing the current source and collection name.
-	 */
-	public TreeClearEvent clone(Model newSource, String newCollectionName) {
-		return new TreeClearEvent(newSource, newCollectionName);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeEvent.java
deleted file mode 100644
index 7e54231..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeEvent.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.model.event;
-
-import org.eclipse.persistence.tools.utility.model.Model;
-
-/**
- * A "tree" event gets delivered whenever a model changes a "bound"
- * or "constrained" tree. A <code>TreeEvent</code> is sent as an
- * argument to the {@link org.eclipse.persistence.tools.utility.model.listener.TreeChangeListener}.
- * The intent is that any listener
- * can keep itself synchronized with the model's tree via the tree events
- * it receives and need not maintain a reference to the original tree.
- * <p>
- * Provisional API: This class 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 abstract class TreeEvent extends ChangeEvent {
-
-	/** Name of the tree that changed. */
-	final String treeName;
-
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Construct a new tree event.
-	 *
-	 * @param source The object on which the event initially occurred.
-	 * @param treeName The programmatic name of the tree that was changed.
-	 */
-	public TreeEvent(Model source, String treeName) {
-		super(source);
-		if (treeName == null) {
-			throw new NullPointerException();
-		}
-		this.treeName = treeName;
-	}
-
-	/**
-	 * Returns the programmatic name of the tree that was changed.
-	 */
-	public String getTreeName() {
-		return this.treeName;
-	}
-
-	@Override
-	protected void toString(StringBuilder sb) {
-		sb.append(this.treeName);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeRemoveEvent.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeRemoveEvent.java
deleted file mode 100644
index 3711ddc..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/event/TreeRemoveEvent.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.model.event;
-
-import java.util.List;
-
-import org.eclipse.persistence.tools.utility.iterables.ArrayIterable;
-import org.eclipse.persistence.tools.utility.model.Model;
-
-/**
- * A "tree remove" event gets delivered whenever a model removes a node rom a
- * "bound" or "constrained" tree. A <code>TreeChangeEvent</code> is sent as an
- * argument to the {@link org.eclipse.persistence.tools.utility.model.listener.TreeChangeListener}.
- * <p>
- * Provisional API: This class 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 final class TreeRemoveEvent extends TreeEvent {
-
-	/**
-     * Path to the node removed from the tree.
-     */
-	protected final Object[] path;
-
-	private static final long serialVersionUID = 1L;
-
-	// ********** constructors **********
-
-	/**
-	 * Construct a new tree remove event.
-	 *
-	 * @param source The object on which the event initially occurred.
-	 * @param treeName The programmatic name of the tree that was changed.
-	 * @param path The path to the part of the tree that was removed.
-	 */
-	public TreeRemoveEvent(Model source, String treeName, List<?> path) {
-		this(source, treeName, path.toArray());  // NPE if 'path' is null
-	}
-
-	private TreeRemoveEvent(Model source, String treeName, Object[] path) {
-		super(source, treeName);
-		this.path = path;
-	}
-
-
-	// ********** standard state **********
-
-	/**
-	 * Returns the path to the part of the tree that was removed.
-	 */
-	public Iterable<?> getPath() {
-		return new ArrayIterable<Object>(this.path);
-	}
-
-
-	// ********** cloning **********
-
-	public TreeRemoveEvent clone(Model newSource) {
-		return this.clone(newSource, this.treeName);
-	}
-
-	/**
-	 * Returns a copy of the event with the specified source and tree name
-	 * replacing the current source and tree name.
-	 */
-	public TreeRemoveEvent clone(Model newSource, String newTreeName) {
-		return new TreeRemoveEvent(newSource, newTreeName, this.path);
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/AbstractChangeListener.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/AbstractChangeListener.java
index 38a1b19..ee03ae3 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/AbstractChangeListener.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/AbstractChangeListener.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -13,7 +13,7 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.model.listener;
 
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.model.event.ChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
@@ -27,10 +27,6 @@
 import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
 import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeRemoveEvent;
 
 /**
  * Convenience abstract implementation of {@link ChangeListener}.
@@ -46,6 +42,7 @@
  * pioneering adopters on the understanding that any code that uses this API
  * will almost certainly be broken (repeatedly) as the API evolves.
  */
+@SuppressWarnings("nls")
 public abstract class AbstractChangeListener
 	implements ChangeListener
 {
@@ -113,26 +110,6 @@
 		this.modelChanged(event);
 	}
 
-	@Override
-	public void nodeAdded(TreeAddEvent event) {
-		this.modelChanged(event);
-	}
-
-	@Override
-	public void nodeRemoved(TreeRemoveEvent event) {
-		this.modelChanged(event);
-	}
-
-	@Override
-	public void treeChanged(TreeChangeEvent event) {
-		this.modelChanged(event);
-	}
-
-	@Override
-	public void treeCleared(TreeClearEvent event) {
-		this.modelChanged(event);
-	}
-
 	/**
 	 * The model has notified the listener of the change described by the
 	 * specified change event. By default the listener executes {@link #modelChanged()}.
@@ -151,6 +128,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this);
+		return ObjectTools.toString(this);
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ChangeAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ChangeAdapter.java
index 4c111ca..c6a74fa 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ChangeAdapter.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ChangeAdapter.java
@@ -1,19 +1,19 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.model.listener;
 
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
@@ -26,10 +26,6 @@
 import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
 import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeRemoveEvent;
 
 /**
  * Convenience implementation of {@link ChangeListener}.
@@ -111,29 +107,8 @@
 		// do nothing
 	}
 
-	// ***** tree
-	@Override
-	public void nodeAdded(TreeAddEvent event) {
-		// do nothing
-	}
-
-	@Override
-	public void nodeRemoved(TreeRemoveEvent event) {
-		// do nothing
-	}
-
-	@Override
-	public void treeCleared(TreeClearEvent event) {
-		// do nothing
-	}
-
-	@Override
-	public void treeChanged(TreeChangeEvent event) {
-		// do nothing
-	}
-
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this);
+		return ObjectTools.toString(this);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ChangeListener.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ChangeListener.java
index a60de8f..c027f00 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ChangeListener.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ChangeListener.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -16,13 +16,14 @@
 /**
  * General purpose change listener.
  * <p>
- * 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.
+ * 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 ChangeListener
-	extends StateChangeListener, PropertyChangeListener, CollectionChangeListener, ListChangeListener, TreeChangeListener
+	extends StateChangeListener, PropertyChangeListener, CollectionChangeListener, ListChangeListener
 {
 	// combine the other listener interfaces
 }
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/CollectionChangeAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/CollectionChangeAdapter.java
index 387e4aa..9df9106 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/CollectionChangeAdapter.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/CollectionChangeAdapter.java
@@ -1,19 +1,19 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.model.listener;
 
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
@@ -57,6 +57,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this);
+		return ObjectTools.toString(this);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/CollectionChangeListener.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/CollectionChangeListener.java
index e7f2d86..0e0ae76 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/CollectionChangeListener.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/CollectionChangeListener.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -24,16 +24,17 @@
  * collection. You can register a <code>CollectionChangeListener</code> with a source
  * model so as to be notified of any bound collection updates.
  * <p>
- * 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.
+ * 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 CollectionChangeListener extends EventListener {
 
 	/**
 	 * This method gets called when items are added to a bound collection.
-	 * 
+	 *
 	 * @param event An event describing the event source,
 	 * the collection that changed, and the items that were added.
 	 */
@@ -41,7 +42,7 @@
 
 	/**
 	 * This method gets called when items are removed from a bound collection.
-	 * 
+	 *
 	 * @param event An event describing the event source,
 	 * the collection that changed, and the items that were removed.
 	 */
@@ -49,8 +50,8 @@
 
 	/**
 	 * This method gets called when a bound collection is cleared.
-	 * 
-	 * @param event An event describing the event source 
+	 *
+	 * @param event An event describing the event source
 	 * and the collection that changed.
 	 */
 	void collectionCleared(CollectionClearEvent event);
@@ -58,10 +59,9 @@
 	/**
 	 * This method gets called when a bound collection is changed in a manner
 	 * that is not easily characterized by the other methods in this interface.
-	 * 
-	 * @param event An event describing the event source 
+	 *
+	 * @param event An event describing the event source
 	 * and the collection that changed.
 	 */
 	void collectionChanged(CollectionChangeEvent event);
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/CommandChangeListener.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/CommandChangeListener.java
index 198a160..501494d 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/CommandChangeListener.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/CommandChangeListener.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -44,4 +44,4 @@
 	protected void modelChanged() {
 		this.command.execute();
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ListChangeAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ListChangeAdapter.java
index 49298e4..71571e1 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ListChangeAdapter.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ListChangeAdapter.java
@@ -1,19 +1,19 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.model.listener;
 
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
 import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
@@ -69,6 +69,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this);
+		return ObjectTools.toString(this);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ListChangeListener.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ListChangeListener.java
index bbae04b..a4618f9 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ListChangeListener.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ListChangeListener.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -26,16 +26,17 @@
  * list. You can register a <code>ListChangeListener</code> with a source
  * model so as to be notified of any bound list updates.
  * <p>
- * 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.
+ * 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 ListChangeListener extends EventListener {
 
 	/**
 	 * This method gets called when items are added to a bound list.
-	 * 
+	 *
 	 * @param event An event describing the event source,
 	 * the list that changed, the items that were added, and the index
 	 * at which the items were added.
@@ -44,7 +45,7 @@
 
 	/**
 	 * This method gets called when items are removed from a bound list.
-	 * 
+	 *
 	 * @param event An event describing the event source,
 	 * the list that changed, the items that were removed, and the index
 	 * at which the items were removed.
@@ -53,7 +54,7 @@
 
 	/**
 	 * This method gets called when items in a bound list are replaced.
-	 * 
+	 *
 	 * @param event An event describing the event source,
 	 * the list that changed, the items that were added, the items that were
 	 * replaced, and the index at which the items were replaced.
@@ -62,7 +63,7 @@
 
 	/**
 	 * This method gets called when items in a bound list are moved.
-	 * 
+	 *
 	 * @param event An event describing the event source,
 	 * the list that changed, and the indices of where items were moved
 	 * from and to.
@@ -71,8 +72,8 @@
 
 	/**
 	 * This method gets called when a bound list is cleared.
-	 * 
-	 * @param event A ListClearEvent object describing the event source 
+	 *
+	 * @param event A ListClearEvent object describing the event source
 	 * and the list that changed.
 	 */
 	void listCleared(ListClearEvent event);
@@ -80,10 +81,9 @@
 	/**
 	 * This method gets called when a bound list is changed in a manner
 	 * that is not easily characterized by the other methods in this interface.
-	 * 
-	 * @param event A ListChangeEvent object describing the event source 
+	 *
+	 * @param event A ListChangeEvent object describing the event source
 	 * and the list that changed.
 	 */
 	void listChanged(ListChangeEvent event);
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/MultiMethodReflectiveChangeListener.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/MultiMethodReflectiveChangeListener.java
index e5986f4..01320a0 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/MultiMethodReflectiveChangeListener.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/MultiMethodReflectiveChangeListener.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -14,8 +14,7 @@
 package org.eclipse.persistence.tools.utility.model.listener;
 
 import java.lang.reflect.Method;
-
-import org.eclipse.persistence.tools.utility.ReflectionTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
@@ -28,20 +27,15 @@
 import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
 import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
 import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeRemoveEvent;
 
 /**
  * This class is used by {@link ReflectiveChangeListener} when the requested listener
- * needs to implement multiple methods (i.e. {@link CollectionChangeListener},
- * {@link ListChangeListener}, or {@link TreeChangeListener}).
+ * needs to implement multiple methods (i.e. {@link CollectionChangeListener} or
+ * {@link ListChangeListener}).
  */
 class MultiMethodReflectiveChangeListener
-	extends ReflectiveChangeListener 
-	implements CollectionChangeListener, ListChangeListener, TreeChangeListener
+	extends ReflectiveChangeListener
+	implements CollectionChangeListener, ListChangeListener
 {
 	/** the methods we will invoke on the target object */
 	private final Method addMethod;
@@ -51,6 +45,7 @@
 	private final Method clearMethod;
 	private final Method changeMethod;
 
+
 	/**
 	 * The "replace" and "move" methods are optional.
 	 */
@@ -76,9 +71,9 @@
 
 	private void invoke(Method method, CollectionEvent event) {
 		if (method.getParameterTypes().length == 0) {
-			ReflectionTools.executeMethod(method, this.target, EMPTY_OBJECT_ARRAY);
+			ObjectTools.execute(this.target, method, ObjectTools.EMPTY_OBJECT_ARRAY);
 		} else {
-			ReflectionTools.executeMethod(method, this.target, new CollectionEvent[] {event});
+			ObjectTools.execute(this.target, method, new CollectionEvent[] {event});
 		}
 	}
 
@@ -107,9 +102,9 @@
 
 	private void invoke(Method method, ListEvent event) {
 		if (method.getParameterTypes().length == 0) {
-			ReflectionTools.executeMethod(method, this.target, EMPTY_OBJECT_ARRAY);
+			ObjectTools.execute(this.target, method, ObjectTools.EMPTY_OBJECT_ARRAY);
 		} else {
-			ReflectionTools.executeMethod(method, this.target, new ListEvent[] {event});
+			ObjectTools.execute(this.target, method, new ListEvent[] {event});
 		}
 	}
 
@@ -142,36 +137,4 @@
 	public void listChanged(ListChangeEvent event) {
 		this.invoke(this.changeMethod, event);
 	}
-
-
-	// ********** TreeChangeListener implementation **********
-
-	private void invoke(Method method, TreeEvent event) {
-		if (method.getParameterTypes().length == 0) {
-			ReflectionTools.executeMethod(method, this.target, EMPTY_OBJECT_ARRAY);
-		} else {
-			ReflectionTools.executeMethod(method, this.target, new TreeEvent[] {event});
-		}
-	}
-
-	@Override
-	public void nodeAdded(TreeAddEvent event) {
-		this.invoke(this.addMethod, event);
-	}
-
-	@Override
-	public void nodeRemoved(TreeRemoveEvent event) {
-		this.invoke(this.removeMethod, event);
-	}
-
-	@Override
-	public void treeCleared(TreeClearEvent event) {
-		this.invoke(this.clearMethod, event);
-	}
-
-	@Override
-	public void treeChanged(TreeChangeEvent event) {
-		this.invoke(this.changeMethod, event);
-	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/PropertyChangeAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/PropertyChangeAdapter.java
index e110ffa..8b3b713 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/PropertyChangeAdapter.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/PropertyChangeAdapter.java
@@ -1,19 +1,19 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.model.listener;
 
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
 
 /**
@@ -42,6 +42,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this);
+		return ObjectTools.toString(this);
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/PropertyChangeListener.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/PropertyChangeListener.java
index cbfb12e..1ecda76 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/PropertyChangeListener.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/PropertyChangeListener.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -21,19 +21,19 @@
  * property. You can register a <code>PropertyChangeListener</code> with a source
  * model so as to be notified of any bound property updates.
  * <p>
- * 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.
+ * 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 PropertyChangeListener extends EventListener {
 
 	/**
 	 * This method gets called when a model has changed a bound property.
-	 * 
+	 *
 	 * @param event An event describing the event source
 	 * and the property's old and new values.
 	 */
 	void propertyChanged(PropertyChangeEvent event);
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ReflectiveChangeListener.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ReflectiveChangeListener.java
index e53cda0..ab7623c 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ReflectiveChangeListener.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/ReflectiveChangeListener.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -14,8 +14,7 @@
 package org.eclipse.persistence.tools.utility.model.listener;
 
 import java.lang.reflect.Method;
-
-import org.eclipse.persistence.tools.utility.ReflectionTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.model.event.ChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
 import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
@@ -31,11 +30,6 @@
 import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
 import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeRemoveEvent;
 
 /**
  * This factory builds listeners that reflectively forward change events.
@@ -57,14 +51,17 @@
 	/** the target object on which we will invoke the method */
 	protected final Object target;
 
+
 	protected static final Class<StateChangeEvent> STATE_CHANGE_EVENT_CLASS = StateChangeEvent.class;
 	@SuppressWarnings("unchecked")
 	protected static final Class<StateChangeEvent>[] STATE_CHANGE_EVENT_CLASS_ARRAY = new Class[] {STATE_CHANGE_EVENT_CLASS};
 
+
 	protected static final Class<PropertyChangeEvent> PROPERTY_CHANGE_EVENT_CLASS = PropertyChangeEvent.class;
 	@SuppressWarnings("unchecked")
 	protected static final Class<PropertyChangeEvent>[] PROPERTY_CHANGE_EVENT_CLASS_ARRAY = new Class[] {PROPERTY_CHANGE_EVENT_CLASS};
 
+
 	protected static final Class<CollectionEvent> COLLECTION_EVENT_CLASS = CollectionEvent.class;
 	@SuppressWarnings("unchecked")
 	protected static final Class<CollectionEvent>[] COLLECTION_EVENT_CLASS_ARRAY = new Class[] {COLLECTION_EVENT_CLASS};
@@ -85,6 +82,7 @@
 	@SuppressWarnings("unchecked")
 	protected static final Class<CollectionChangeEvent>[] COLLECTION_CHANGE_EVENT_CLASS_ARRAY = new Class[] {COLLECTION_CHANGE_EVENT_CLASS};
 
+
 	protected static final Class<ListEvent> LIST_EVENT_CLASS = ListEvent.class;
 	@SuppressWarnings("unchecked")
 	protected static final Class<ListEvent>[] LIST_EVENT_CLASS_ARRAY = new Class[] {LIST_EVENT_CLASS};
@@ -113,39 +111,18 @@
 	@SuppressWarnings("unchecked")
 	protected static final Class<ListChangeEvent>[] LIST_CHANGE_EVENT_CLASS_ARRAY = new Class[] {LIST_CHANGE_EVENT_CLASS};
 
-	protected static final Class<TreeEvent> TREE_EVENT_CLASS = TreeEvent.class;
-	@SuppressWarnings("unchecked")
-	protected static final Class<TreeEvent>[] TREE_EVENT_CLASS_ARRAY = new Class[] {TREE_EVENT_CLASS};
-
-	protected static final Class<TreeAddEvent> TREE_ADD_EVENT_CLASS = TreeAddEvent.class;
-	@SuppressWarnings("unchecked")
-	protected static final Class<TreeAddEvent>[] TREE_ADD_EVENT_CLASS_ARRAY = new Class[] {TREE_ADD_EVENT_CLASS};
-
-	protected static final Class<TreeRemoveEvent> TREE_REMOVE_EVENT_CLASS = TreeRemoveEvent.class;
-	@SuppressWarnings("unchecked")
-	protected static final Class<TreeRemoveEvent>[] TREE_REMOVE_EVENT_CLASS_ARRAY = new Class[] {TREE_REMOVE_EVENT_CLASS};
-
-	protected static final Class<TreeClearEvent> TREE_CLEAR_EVENT_CLASS = TreeClearEvent.class;
-	@SuppressWarnings("unchecked")
-	protected static final Class<TreeClearEvent>[] TREE_CLEAR_EVENT_CLASS_ARRAY = new Class[] {TREE_CLEAR_EVENT_CLASS};
-
-	protected static final Class<TreeChangeEvent> TREE_CHANGE_EVENT_CLASS = TreeChangeEvent.class;
-	@SuppressWarnings("unchecked")
-	protected static final Class<TreeChangeEvent>[] TREE_CHANGE_EVENT_CLASS_ARRAY = new Class[] {TREE_CHANGE_EVENT_CLASS};
-
-	protected static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
 
 	// ********** helper methods **********
 
 	/**
-	 * Returns a method implemented by the target that can be invoked
+	 * Find and return a method implemented by the target that can be invoked
 	 * reflectively when a change event occurs.
 	 */
 	private static Method findChangeListenerMethod(Object target, String methodName, Class<? extends ChangeEvent>[] eventClassArray) {
 		try {
-			return ReflectionTools.getMethod(target, methodName, eventClassArray);
+			return ObjectTools.method(target, methodName, eventClassArray);
 		} catch (RuntimeException ex1) {
-			return ReflectionTools.getMethod(target, methodName);
+			return ObjectTools.method(target, methodName);
 		}
 	}
 
@@ -312,55 +289,6 @@
 	}
 
 
-	// ********** factory methods: TreeChangeListener **********
-
-	/**
-	 * Construct a tree change listener that will invoke the specified methods
-	 * on the specified target.
-	 */
-	public static TreeChangeListener buildTreeChangeListener(Object target, Method addMethod, Method removeMethod, Method clearMethod, Method changeMethod) {
-		checkChangeListenerMethod(addMethod, TREE_ADD_EVENT_CLASS);
-		checkChangeListenerMethod(removeMethod, TREE_REMOVE_EVENT_CLASS);
-		checkChangeListenerMethod(clearMethod, TREE_CLEAR_EVENT_CLASS);
-		checkChangeListenerMethod(changeMethod, TREE_CHANGE_EVENT_CLASS);
-		return new MultiMethodReflectiveChangeListener(target, addMethod, removeMethod, clearMethod, changeMethod);
-	}
-
-	/**
-	 * Construct a tree change listener that will invoke the specified method
-	 * on the specified target for any change event.
-	 */
-	public static TreeChangeListener buildTreeChangeListener(Object target, Method method) {
-		return buildTreeChangeListener(target, method, method, method, method);
-	}
-
-	/**
-	 * Construct a tree change listener that will invoke the specified methods
-	 * on the specified target for change events. If a single-argument method
-	 * with the specified name and appropriate argument is found, it will be invoked;
-	 * otherwise, a zero-argument method with the specified name will be invoked.
-	 */
-	public static TreeChangeListener buildTreeChangeListener(Object target, String addMethodName, String removeMethodName, String clearMethodName, String changeMethodName) {
-		return buildTreeChangeListener(
-				target,
-				findChangeListenerMethod(target, addMethodName, TREE_ADD_EVENT_CLASS_ARRAY),
-				findChangeListenerMethod(target, removeMethodName, TREE_REMOVE_EVENT_CLASS_ARRAY),
-				findChangeListenerMethod(target, clearMethodName, TREE_CLEAR_EVENT_CLASS_ARRAY),
-				findChangeListenerMethod(target, changeMethodName, TREE_CHANGE_EVENT_CLASS_ARRAY)
-		);
-	}
-
-	/**
-	 * Construct a tree change listener that will invoke the specified method
-	 * on the specified target for any change event. If a single-argument method
-	 * with the specified name and appropriate argument is found, it will be invoked;
-	 * otherwise, a zero-argument method with the specified name will be invoked.
-	 */
-	public static TreeChangeListener buildTreeChangeListener(Object target, String methodName) {
-		return buildTreeChangeListener(target, findChangeListenerMethod(target, methodName, TREE_EVENT_CLASS_ARRAY));
-	}
-
-
 	// ********** constructor **********
 
 	/**
@@ -371,5 +299,4 @@
 		super();
 		this.target = target;
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/SingleMethodReflectiveChangeListener.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/SingleMethodReflectiveChangeListener.java
index 335e4b4..008f242 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/SingleMethodReflectiveChangeListener.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/SingleMethodReflectiveChangeListener.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -14,8 +14,7 @@
 package org.eclipse.persistence.tools.utility.model.listener;
 
 import java.lang.reflect.Method;
-
-import org.eclipse.persistence.tools.utility.ReflectionTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
 import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
 
@@ -46,9 +45,9 @@
 	@Override
 	public void stateChanged(StateChangeEvent event) {
 		if (this.methodIsZeroArgument) {
-			ReflectionTools.executeMethod(this.method, this.target, EMPTY_OBJECT_ARRAY);
+			ObjectTools.execute(this.target, this.method, ObjectTools.EMPTY_OBJECT_ARRAY);
 		} else {
-			ReflectionTools.executeMethod(this.method, this.target, new StateChangeEvent[] {event});
+			ObjectTools.execute(this.target, this.method, new StateChangeEvent[] {event});
 		}
 	}
 
@@ -58,10 +57,9 @@
 	@Override
 	public void propertyChanged(PropertyChangeEvent event) {
 		if (this.methodIsZeroArgument) {
-			ReflectionTools.executeMethod(this.method, this.target, EMPTY_OBJECT_ARRAY);
+			ObjectTools.execute(this.target, this.method, ObjectTools.EMPTY_OBJECT_ARRAY);
 		} else {
-			ReflectionTools.executeMethod(this.method, this.target, new PropertyChangeEvent[] {event});
+			ObjectTools.execute(this.target, this.method, new PropertyChangeEvent[] {event});
 		}
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/StateChangeAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/StateChangeAdapter.java
index 55b888c..8ff7801 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/StateChangeAdapter.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/StateChangeAdapter.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -32,5 +32,4 @@
 	public void stateChanged(StateChangeEvent event) {
 		// do nothing
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/StateChangeListener.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/StateChangeListener.java
index 30d956b..bc8deaf 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/StateChangeListener.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/StateChangeListener.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -17,23 +17,23 @@
 import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
 
 /**
- * A generic "state change" event gets delivered whenever a model changes to 
- * such extent that it cannot be delineated all aspects of it that have changed. 
- * You can register a <code>StateChangeListener</code> with a source model so as to be notified 
+ * A generic "state change" event gets delivered whenever a model changes to
+ * such extent that it cannot be delineated all aspects of it that have changed.
+ * You can register a <code>StateChangeListener</code> with a source model so as to be notified
  * of any such changes.
  * <p>
- * 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.
+ * 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 StateChangeListener extends EventListener {
 
 	/**
 	 * This method gets called when a model has changed in some general fashion.
-	 * 
+	 *
 	 * @param event An event describing the event source.
 	 */
 	void stateChanged(StateChangeEvent event);
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/TreeChangeAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/TreeChangeAdapter.java
deleted file mode 100644
index 95788e8..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/TreeChangeAdapter.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.model.listener;
-
-import org.eclipse.persistence.tools.utility.model.event.TreeAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeRemoveEvent;
-
-/**
- * Convenience implementation of {@link TreeChangeListener}.
- * <p>
- * Provisional API: This class 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 class TreeChangeAdapter implements TreeChangeListener {
-
-	/**
-	 * Default constructor.
-	 */
-	public TreeChangeAdapter() {
-		super();
-	}
-
-	@Override
-	public void nodeAdded(TreeAddEvent event) {
-		// do nothing
-	}
-
-	@Override
-	public void nodeRemoved(TreeRemoveEvent event) {
-		// do nothing
-	}
-
-	@Override
-	public void treeCleared(TreeClearEvent event) {
-		// do nothing
-	}
-
-	@Override
-	public void treeChanged(TreeChangeEvent event) {
-		// do nothing
-	}
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/TreeChangeListener.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/TreeChangeListener.java
deleted file mode 100644
index acf60be..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/TreeChangeListener.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.model.listener;
-
-import java.util.EventListener;
-import org.eclipse.persistence.tools.utility.model.event.TreeAddEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeChangeEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeClearEvent;
-import org.eclipse.persistence.tools.utility.model.event.TreeRemoveEvent;
-
-/**
- * A "tree change" event gets fired whenever a model changes a "bound"
- * tree. You can register a <code>TreeChangeListener</code> with a source
- * model so as to be notified of any bound tree updates.
- * <p>
- * 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 TreeChangeListener extends EventListener {
-
-	/**
-	 * This method gets called when a node is added to a bound tree.
-	 * 
-	 * @param event An event describing the event source,
-	 * the tree that changed, and the path to the node that was added.
-	 */
-	void nodeAdded(TreeAddEvent event);
-
-	/**
-	 * This method gets called when a node is removed from a bound tree.
-	 * 
-	 * @param event An event describing the event source,
-	 * the tree that changed, and the path to the node that was removed.
-	 */
-	void nodeRemoved(TreeRemoveEvent event);
-
-	/**
-	 * This method gets called when a bound tree is cleared.
-	 * 
-	 * @param event An event describing the event source,
-	 * the tree that changed, and an empty path.
-	 */
-	void treeCleared(TreeClearEvent event);
-
-	/**
-	 * This method gets called when a portion of a bound tree is changed in
-	 * a manner that is not easily characterized by the other methods in this
-	 * interface.
-	 * 
-	 * @param event An event describing the event source,
-	 * the tree that changed, and the current state of the
-	 * tree that changed.
-	 */
-	void treeChanged(TreeChangeEvent event);
-
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTChangeListenerWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTChangeListenerWrapper.java
new file mode 100644
index 0000000..8985bfb
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTChangeListenerWrapper.java
@@ -0,0 +1,381 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.listener.awt;
+
+import java.awt.EventQueue;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+
+/**
+ * Wrap another change listener and forward events to it on the AWT
+ * event queue, asynchronously if necessary. If the event arrived on the UI
+ * thread that is probably because it was initiated by a UI widget; as a
+ * result, we want to loop back synchronously so the events can be
+ * short-circuited.
+ */
+@SuppressWarnings("nls")
+public final class AWTChangeListenerWrapper
+	implements ChangeListener
+{
+	private final ChangeListener listener;
+
+
+	public AWTChangeListenerWrapper(ChangeListener listener) {
+		super();
+		if (listener == null) {
+			throw new NullPointerException();
+		}
+		this.listener = listener;
+	}
+
+	@Override
+	public void stateChanged(StateChangeEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.stateChanged_(event);
+		} else {
+			this.executeOnEventQueue(this.buildStateChangedRunnable(event));
+		}
+	}
+
+	@Override
+	public void propertyChanged(PropertyChangeEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.propertyChanged_(event);
+		} else {
+			this.executeOnEventQueue(this.buildPropertyChangedRunnable(event));
+		}
+	}
+
+	@Override
+	public void itemsAdded(CollectionAddEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsAdded_(event);
+		} else {
+			this.executeOnEventQueue(this.buildItemsAddedRunnable(event));
+		}
+	}
+
+	@Override
+	public void itemsRemoved(CollectionRemoveEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsRemoved_(event);
+		} else {
+			this.executeOnEventQueue(this.buildItemsRemovedRunnable(event));
+		}
+	}
+
+	@Override
+	public void collectionCleared(CollectionClearEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.collectionCleared_(event);
+		} else {
+			this.executeOnEventQueue(this.buildCollectionClearedRunnable(event));
+		}
+	}
+
+	@Override
+	public void collectionChanged(CollectionChangeEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.collectionChanged_(event);
+		} else {
+			this.executeOnEventQueue(this.buildCollectionChangedRunnable(event));
+		}
+	}
+
+	@Override
+	public void itemsAdded(ListAddEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsAdded_(event);
+		} else {
+			this.executeOnEventQueue(this.buildItemsAddedRunnable(event));
+		}
+	}
+
+	@Override
+	public void itemsRemoved(ListRemoveEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsRemoved_(event);
+		} else {
+			this.executeOnEventQueue(this.buildItemsRemovedRunnable(event));
+		}
+	}
+
+	@Override
+	public void itemsMoved(ListMoveEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsMoved_(event);
+		} else {
+			this.executeOnEventQueue(this.buildItemsMovedRunnable(event));
+		}
+	}
+
+	@Override
+	public void itemsReplaced(ListReplaceEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsReplaced_(event);
+		} else {
+			this.executeOnEventQueue(this.buildItemsReplacedRunnable(event));
+		}
+	}
+
+	@Override
+	public void listCleared(ListClearEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.listCleared_(event);
+		} else {
+			this.executeOnEventQueue(this.buildListClearedRunnable(event));
+		}
+	}
+
+	@Override
+	public void listChanged(ListChangeEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.listChanged_(event);
+		} else {
+			this.executeOnEventQueue(this.buildListChangedRunnable(event));
+		}
+	}
+
+	private Runnable buildStateChangedRunnable(final StateChangeEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTChangeListenerWrapper.this.stateChanged_(event);
+			}
+		};
+	}
+
+	private Runnable buildPropertyChangedRunnable(final PropertyChangeEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTChangeListenerWrapper.this.propertyChanged_(event);
+			}
+		};
+	}
+
+	private Runnable buildItemsAddedRunnable(final CollectionAddEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTChangeListenerWrapper.this.itemsAdded_(event);
+			}
+			@Override
+			public String toString() {
+				return "items added runnable";
+			}
+		};
+	}
+
+	private Runnable buildItemsRemovedRunnable(final CollectionRemoveEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTChangeListenerWrapper.this.itemsRemoved_(event);
+			}
+			@Override
+			public String toString() {
+				return "items removed runnable";
+			}
+		};
+	}
+
+	private Runnable buildCollectionClearedRunnable(final CollectionClearEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTChangeListenerWrapper.this.collectionCleared_(event);
+			}
+			@Override
+			public String toString() {
+				return "collection cleared runnable";
+			}
+		};
+	}
+
+	private Runnable buildCollectionChangedRunnable(final CollectionChangeEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTChangeListenerWrapper.this.collectionChanged_(event);
+			}
+			@Override
+			public String toString() {
+				return "collection changed runnable";
+			}
+		};
+	}
+
+	private Runnable buildItemsAddedRunnable(final ListAddEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTChangeListenerWrapper.this.itemsAdded_(event);
+			}
+			@Override
+			public String toString() {
+				return "items added runnable";
+			}
+		};
+	}
+
+	private Runnable buildItemsRemovedRunnable(final ListRemoveEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTChangeListenerWrapper.this.itemsRemoved_(event);
+			}
+			@Override
+			public String toString() {
+				return "items removed runnable";
+			}
+		};
+	}
+
+	private Runnable buildItemsMovedRunnable(final ListMoveEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTChangeListenerWrapper.this.itemsMoved_(event);
+			}
+			@Override
+			public String toString() {
+				return "items moved runnable";
+			}
+		};
+	}
+
+	private Runnable buildItemsReplacedRunnable(final ListReplaceEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTChangeListenerWrapper.this.itemsReplaced_(event);
+			}
+			@Override
+			public String toString() {
+				return "items replaced runnable";
+			}
+		};
+	}
+
+	private Runnable buildListClearedRunnable(final ListClearEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTChangeListenerWrapper.this.listCleared_(event);
+			}
+			@Override
+			public String toString() {
+				return "list cleared runnable";
+			}
+		};
+	}
+
+	private Runnable buildListChangedRunnable(final ListChangeEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTChangeListenerWrapper.this.listChanged_(event);
+			}
+			@Override
+			public String toString() {
+				return "list changed runnable";
+			}
+		};
+	}
+
+	private boolean isExecutingOnUIThread() {
+		return EventQueue.isDispatchThread();
+	}
+
+	/**
+	 * {@link EventQueue#invokeLater(Runnable)} seems to work OK;
+	 * but using {@link EventQueue#invokeAndWait(Runnable)} can sometimes make
+	 * things more predictable when debugging, at the risk of deadlocks.
+	 */
+	private void executeOnEventQueue(Runnable r) {
+		EventQueue.invokeLater(r);
+//		try {
+//			EventQueue.invokeAndWait(r);
+//		} catch (InterruptedException ex) {
+//			throw new RuntimeException(ex);
+//		} catch (java.lang.reflect.InvocationTargetException ex) {
+//			throw new RuntimeException(ex);
+//		}
+	}
+
+	void stateChanged_(StateChangeEvent event) {
+		this.listener.stateChanged(event);
+	}
+
+	void propertyChanged_(PropertyChangeEvent event) {
+		this.listener.propertyChanged(event);
+	}
+
+	void itemsAdded_(CollectionAddEvent event) {
+		this.listener.itemsAdded(event);
+	}
+
+	void itemsRemoved_(CollectionRemoveEvent event) {
+		this.listener.itemsRemoved(event);
+	}
+
+	void collectionCleared_(CollectionClearEvent event) {
+		this.listener.collectionCleared(event);
+	}
+
+	void collectionChanged_(CollectionChangeEvent event) {
+		this.listener.collectionChanged(event);
+	}
+
+	void itemsAdded_(ListAddEvent event) {
+		this.listener.itemsAdded(event);
+	}
+
+	void itemsRemoved_(ListRemoveEvent event) {
+		this.listener.itemsRemoved(event);
+	}
+
+	void itemsMoved_(ListMoveEvent event) {
+		this.listener.itemsMoved(event);
+	}
+
+	void itemsReplaced_(ListReplaceEvent event) {
+		this.listener.itemsReplaced(event);
+	}
+
+	void listCleared_(ListClearEvent event) {
+		this.listener.listCleared(event);
+	}
+
+	void listChanged_(ListChangeEvent event) {
+		this.listener.listChanged(event);
+	}
+
+	@Override
+	public String toString() {
+		return "AWT(" + this.listener.toString() + ')';
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTCollectionChangeListenerWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTCollectionChangeListenerWrapper.java
new file mode 100644
index 0000000..bc7e6a8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTCollectionChangeListenerWrapper.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.listener.awt;
+
+import java.awt.EventQueue;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+
+/**
+ * Wrap another collection change listener and forward events to it on the AWT
+ * event queue, asynchronously if necessary. If the event arrived on the UI
+ * thread that is probably because it was initiated by a UI widget; as a
+ * result, we want to loop back synchronously so the events can be
+ * short-circuited.
+ */
+@SuppressWarnings("nls")
+public final class AWTCollectionChangeListenerWrapper
+	implements CollectionChangeListener
+{
+	private final CollectionChangeListener listener;
+
+	public AWTCollectionChangeListenerWrapper(CollectionChangeListener listener) {
+		super();
+		if (listener == null) {
+			throw new NullPointerException();
+		}
+		this.listener = listener;
+	}
+
+	@Override
+	public void itemsAdded(CollectionAddEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsAdded_(event);
+		} else {
+			this.executeOnEventQueue(this.buildItemsAddedRunnable(event));
+		}
+	}
+
+	@Override
+	public void itemsRemoved(CollectionRemoveEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsRemoved_(event);
+		} else {
+			this.executeOnEventQueue(this.buildItemsRemovedRunnable(event));
+		}
+	}
+
+	@Override
+	public void collectionCleared(CollectionClearEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.collectionCleared_(event);
+		} else {
+			this.executeOnEventQueue(this.buildCollectionClearedRunnable(event));
+		}
+	}
+
+	@Override
+	public void collectionChanged(CollectionChangeEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.collectionChanged_(event);
+		} else {
+			this.executeOnEventQueue(this.buildCollectionChangedRunnable(event));
+		}
+	}
+
+	private Runnable buildItemsAddedRunnable(final CollectionAddEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTCollectionChangeListenerWrapper.this.itemsAdded_(event);
+			}
+			@Override
+			public String toString() {
+				return "items added runnable";
+			}
+		};
+	}
+
+	private Runnable buildItemsRemovedRunnable(final CollectionRemoveEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTCollectionChangeListenerWrapper.this.itemsRemoved_(event);
+			}
+			@Override
+			public String toString() {
+				return "items removed runnable";
+			}
+		};
+	}
+
+	private Runnable buildCollectionClearedRunnable(final CollectionClearEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTCollectionChangeListenerWrapper.this.collectionCleared_(event);
+			}
+			@Override
+			public String toString() {
+				return "collection cleared runnable";
+			}
+		};
+	}
+
+	private Runnable buildCollectionChangedRunnable(final CollectionChangeEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTCollectionChangeListenerWrapper.this.collectionChanged_(event);
+			}
+			@Override
+			public String toString() {
+				return "collection changed runnable";
+			}
+		};
+	}
+
+	private boolean isExecutingOnUIThread() {
+		return EventQueue.isDispatchThread();
+	}
+
+	/**
+	 * {@link EventQueue#invokeLater(Runnable)} seems to work OK;
+	 * but using {@link EventQueue#invokeAndWait(Runnable)} can sometimes make
+	 * things more predictable when debugging, at the risk of deadlocks.
+	 */
+	private void executeOnEventQueue(Runnable r) {
+		EventQueue.invokeLater(r);
+//		try {
+//			EventQueue.invokeAndWait(r);
+//		} catch (InterruptedException ex) {
+//			throw new RuntimeException(ex);
+//		} catch (java.lang.reflect.InvocationTargetException ex) {
+//			throw new RuntimeException(ex);
+//		}
+	}
+
+	void itemsAdded_(CollectionAddEvent event) {
+		this.listener.itemsAdded(event);
+	}
+
+	void itemsRemoved_(CollectionRemoveEvent event) {
+		this.listener.itemsRemoved(event);
+	}
+
+	void collectionCleared_(CollectionClearEvent event) {
+		this.listener.collectionCleared(event);
+	}
+
+	void collectionChanged_(CollectionChangeEvent event) {
+		this.listener.collectionChanged(event);
+	}
+
+	@Override
+	public String toString() {
+		return "AWT(" + this.listener.toString() + ')';
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTListChangeListenerWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTListChangeListenerWrapper.java
new file mode 100644
index 0000000..fd57b22
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTListChangeListenerWrapper.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.listener.awt;
+
+import java.awt.EventQueue;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+
+/**
+ * Wrap another list change listener and forward events to it on the AWT
+ * event queue, asynchronously if necessary. If the event arrived on the UI
+ * thread that is probably because it was initiated by a UI widget; as a
+ * result, we want to loop back synchronously so the events can be
+ * short-circuited.
+ */
+@SuppressWarnings("nls")
+public final class AWTListChangeListenerWrapper
+	implements ListChangeListener
+{
+	private final ListChangeListener listener;
+
+	public AWTListChangeListenerWrapper(ListChangeListener listener) {
+		super();
+		if (listener == null) {
+			throw new NullPointerException();
+		}
+		this.listener = listener;
+	}
+
+	@Override
+	public void itemsAdded(ListAddEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsAdded_(event);
+		} else {
+			this.executeOnEventQueue(this.buildItemsAddedRunnable(event));
+		}
+	}
+
+	@Override
+	public void itemsRemoved(ListRemoveEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsRemoved_(event);
+		} else {
+			this.executeOnEventQueue(this.buildItemsRemovedRunnable(event));
+		}
+	}
+
+	@Override
+	public void itemsMoved(ListMoveEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsMoved_(event);
+		} else {
+			this.executeOnEventQueue(this.buildItemsMovedRunnable(event));
+		}
+	}
+
+	@Override
+	public void itemsReplaced(ListReplaceEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.itemsReplaced_(event);
+		} else {
+			this.executeOnEventQueue(this.buildItemsReplacedRunnable(event));
+		}
+	}
+
+	@Override
+	public void listCleared(ListClearEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.listCleared_(event);
+		} else {
+			this.executeOnEventQueue(this.buildListClearedRunnable(event));
+		}
+	}
+
+	@Override
+	public void listChanged(ListChangeEvent event) {
+		if (this.isExecutingOnUIThread()) {
+			this.listChanged_(event);
+		} else {
+			this.executeOnEventQueue(this.buildListChangedRunnable(event));
+		}
+	}
+
+	private Runnable buildItemsAddedRunnable(final ListAddEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTListChangeListenerWrapper.this.itemsAdded_(event);
+			}
+			@Override
+			public String toString() {
+				return "items added runnable";
+			}
+		};
+	}
+
+	private Runnable buildItemsRemovedRunnable(final ListRemoveEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTListChangeListenerWrapper.this.itemsRemoved_(event);
+			}
+			@Override
+			public String toString() {
+				return "items removed runnable";
+			}
+		};
+	}
+
+	private Runnable buildItemsMovedRunnable(final ListMoveEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTListChangeListenerWrapper.this.itemsMoved_(event);
+			}
+			@Override
+			public String toString() {
+				return "items moved runnable";
+			}
+		};
+	}
+
+	private Runnable buildItemsReplacedRunnable(final ListReplaceEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTListChangeListenerWrapper.this.itemsReplaced_(event);
+			}
+			@Override
+			public String toString() {
+				return "items replaced runnable";
+			}
+		};
+	}
+
+	private Runnable buildListClearedRunnable(final ListClearEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTListChangeListenerWrapper.this.listCleared_(event);
+			}
+			@Override
+			public String toString() {
+				return "list cleared runnable";
+			}
+		};
+	}
+
+	private Runnable buildListChangedRunnable(final ListChangeEvent event) {
+		return new Runnable() {
+			@Override
+			public void run() {
+				AWTListChangeListenerWrapper.this.listChanged_(event);
+			}
+			@Override
+			public String toString() {
+				return "list changed runnable";
+			}
+		};
+	}
+
+	private boolean isExecutingOnUIThread() {
+		return EventQueue.isDispatchThread();
+	}
+
+	/**
+	 * {@link EventQueue#invokeLater(Runnable)} seems to work OK;
+	 * but using {@link EventQueue#invokeAndWait(Runnable)} can sometimes make
+	 * things more predictable when debugging, at the risk of deadlocks.
+	 */
+	private void executeOnEventQueue(Runnable r) {
+		EventQueue.invokeLater(r);
+//		try {
+//			EventQueue.invokeAndWait(r);
+//		} catch (InterruptedException ex) {
+//			throw new RuntimeException(ex);
+//		} catch (java.lang.reflect.InvocationTargetException ex) {
+//			throw new RuntimeException(ex);
+//		}
+	}
+
+	void itemsAdded_(ListAddEvent event) {
+		this.listener.itemsAdded(event);
+	}
+
+	void itemsRemoved_(ListRemoveEvent event) {
+		this.listener.itemsRemoved(event);
+	}
+
+	void itemsMoved_(ListMoveEvent event) {
+		this.listener.itemsMoved(event);
+	}
+
+	void itemsReplaced_(ListReplaceEvent event) {
+		this.listener.itemsReplaced(event);
+	}
+
+	void listCleared_(ListClearEvent event) {
+		this.listener.listCleared(event);
+	}
+
+	void listChanged_(ListChangeEvent event) {
+		this.listener.listChanged(event);
+	}
+
+	@Override
+	public String toString() {
+		return "AWT(" + this.listener.toString() + ')';
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTPropertyChangeListenerWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTPropertyChangeListenerWrapper.java
new file mode 100644
index 0000000..c3db685
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTPropertyChangeListenerWrapper.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.listener.awt;
+
+import java.awt.EventQueue;
+import org.eclipse.persistence.tools.utility.RunnableAdapter;
+import org.eclipse.persistence.tools.utility.collection.SynchronizedQueue;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+
+/**
+ * Wrap another property change listener and forward events to it on the AWT
+ * event queue, asynchronously if necessary. If the event arrived on the UI
+ * thread that is probably because it was initiated by a UI widget; as a
+ * result, we want to loop back synchronously so the events can be
+ * short-circuited. (Typically, the adapter(s) between a <em>property</em> and
+ * its corresponding UI widget are read-write; as opposed to the adapter(s)
+ * between a <em>collection</em> (or <em>list</em>) and its UI widget, which
+ * is read-only.)
+ * <p>
+ * Any events received earlier (on a non-UI thread) will be
+ * forwarded, in the order received, before the current event is forwarded.
+ */
+@SuppressWarnings("nls")
+public final class AWTPropertyChangeListenerWrapper
+	implements PropertyChangeListener
+{
+	private final PropertyChangeListener listener;
+	private final SynchronizedQueue<PropertyChangeEvent> events = new SynchronizedQueue<PropertyChangeEvent>();
+
+
+	public AWTPropertyChangeListenerWrapper(PropertyChangeListener listener) {
+		super();
+		if (listener == null) {
+			throw new NullPointerException();
+		}
+		this.listener = listener;
+	}
+
+	@Override
+	public void propertyChanged(PropertyChangeEvent event) {
+		this.events.enqueue(event);
+		if (this.isExecutingOnUIThread()) {
+			this.forwardEvents();
+		} else {
+			this.executeOnEventQueue(new ForwardEventsRunnable());
+		}
+	}
+
+	private boolean isExecutingOnUIThread() {
+		return EventQueue.isDispatchThread();
+	}
+
+	/* CU private */ class ForwardEventsRunnable
+		extends RunnableAdapter
+	{
+		@Override
+		public void run() {
+			AWTPropertyChangeListenerWrapper.this.forwardEvents();
+		}
+	}
+
+	/**
+	 * {@link EventQueue#invokeLater(Runnable)} seems to work OK;
+	 * but using {@link EventQueue#invokeAndWait(Runnable)} can sometimes make
+	 * things more predictable when debugging, at the risk of deadlocks.
+	 */
+	private void executeOnEventQueue(Runnable r) {
+		EventQueue.invokeLater(r);
+//		try {
+//			EventQueue.invokeAndWait(r);
+//		} catch (InterruptedException ex) {
+//			throw new RuntimeException(ex);
+//		} catch (java.lang.reflect.InvocationTargetException ex) {
+//			throw new RuntimeException(ex);
+//		}
+	}
+
+	void forwardEvents() {
+		for (PropertyChangeEvent event : this.events.drain()) {
+			this.listener.propertyChanged(event);
+		}
+	}
+
+	@Override
+	public String toString() {
+		return "AWT(" + this.listener.toString() + ')';
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTStateChangeListenerWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTStateChangeListenerWrapper.java
new file mode 100644
index 0000000..cc875ea
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/listener/awt/AWTStateChangeListenerWrapper.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.listener.awt;
+
+import java.awt.EventQueue;
+import org.eclipse.persistence.tools.utility.RunnableAdapter;
+import org.eclipse.persistence.tools.utility.collection.SynchronizedQueue;
+import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
+
+/**
+ * Wrap another state change listener and forward events to it on the AWT
+ * event queue, asynchronously if necessary. If the event arrived on the UI
+ * thread that is probably because it was initiated by a UI widget; as a
+ * result, we want to loop back synchronously so the events can be
+ * short-circuited.
+ * <p>
+ * Any events received earlier (on a non-UI thread) will be
+ * forwarded, in the order received, before the current event is forwarded.
+ * @see AWTPropertyChangeListenerWrapper
+ */
+@SuppressWarnings("nls")
+public final class AWTStateChangeListenerWrapper
+	implements StateChangeListener
+{
+	private final StateChangeListener listener;
+	private final SynchronizedQueue<StateChangeEvent> events = new SynchronizedQueue<StateChangeEvent>();
+
+
+	public AWTStateChangeListenerWrapper(StateChangeListener listener) {
+		super();
+		if (listener == null) {
+			throw new NullPointerException();
+		}
+		this.listener = listener;
+	}
+
+	@Override
+	public void stateChanged(StateChangeEvent event) {
+		this.events.enqueue(event);
+		if (this.isExecutingOnUIThread()) {
+			this.forwardEvents();
+		} else {
+			this.executeOnEventQueue(new ForwardEventsRunnable());
+		}
+	}
+
+	private boolean isExecutingOnUIThread() {
+		return EventQueue.isDispatchThread();
+	}
+
+	/* CU private */ class ForwardEventsRunnable
+		extends RunnableAdapter
+	{
+		@Override
+		public void run() {
+			AWTStateChangeListenerWrapper.this.forwardEvents();
+		}
+	}
+
+	/**
+	 * {@link EventQueue#invokeLater(Runnable)} seems to work OK;
+	 * but using {@link EventQueue#invokeAndWait(Runnable)} can sometimes make
+	 * things more predictable when debugging, at the risk of deadlocks.
+	 */
+	private void executeOnEventQueue(Runnable r) {
+		EventQueue.invokeLater(r);
+//		try {
+//			EventQueue.invokeAndWait(r);
+//		} catch (InterruptedException ex) {
+//			throw new RuntimeException(ex);
+//		} catch (java.lang.reflect.InvocationTargetException ex) {
+//			throw new RuntimeException(ex);
+//		}
+	}
+
+	void forwardEvents() {
+		for (StateChangeEvent event : this.events.drain()) {
+			this.listener.stateChanged(event);
+		}
+	}
+
+	@Override
+	public String toString() {
+		return "AWT(" + this.listener.toString() + ')';
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractCollectionValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractCollectionValueModel.java
new file mode 100644
index 0000000..5b3a3d9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractCollectionValueModel.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.ChangeSupport;
+import org.eclipse.persistence.tools.utility.model.SingleAspectChangeSupport;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+
+/**
+ * This abstract class provides the infrastructure for "lazily" adding listeners
+ * to an underlying model as necessary. Subclasses will need to engage and
+ * disegage the underlying model and fire the appropriate collection change
+ * events. Subclasses must implement the appropriate {@link CollectionValueModel}.
+ * <p>
+ * Subclasses must implement the following methods:<ul>
+ * <li>{@link #engageModel()}<p>
+ *     implement this method to add the appropriate listener to the underlying model
+ * <li>{@link #disengageModel()}<p>
+ *     implement this method to remove the appropriate listener from the underlying model
+ * </ul>
+ */
+public abstract class AbstractCollectionValueModel
+	extends AbstractModel
+{
+
+	// ********** constructor/initialization **********
+
+	protected AbstractCollectionValueModel() {
+		super();
+	}
+
+	@Override
+	protected ChangeSupport buildChangeSupport() {
+		return new SingleAspectChangeSupport(this, CollectionChangeListener.class, CollectionValueModel.VALUES);
+	}
+
+
+	// ********** extend change support **********
+
+	/**
+	 * Extend to start listening to the underlying model if necessary.
+	 */
+	@Override
+	public synchronized void addChangeListener(ChangeListener listener) {
+		if (this.hasNoListeners()) {
+			this.engageModel();
+		}
+		super.addChangeListener(listener);
+	}
+
+	/**
+	 * Extend to start listening to the underlying model if necessary.
+	 */
+	@Override
+	public synchronized void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) {
+		if (collectionName.equals(CollectionValueModel.VALUES) && this.hasNoListeners()) {
+			this.engageModel();
+		}
+		super.addCollectionChangeListener(collectionName, listener);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying model if necessary.
+	 */
+	@Override
+	public synchronized void removeChangeListener(ChangeListener listener) {
+		super.removeChangeListener(listener);
+		if (this.hasNoListeners()) {
+			this.disengageModel();
+		}
+	}
+
+	/**
+	 * Extend to stop listening to the underlying model if necessary.
+	 */
+	@Override
+	public synchronized void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) {
+		super.removeCollectionChangeListener(collectionName, listener);
+		if (collectionName.equals(CollectionValueModel.VALUES) && this.hasNoListeners()) {
+			this.disengageModel();
+		}
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * Return whether the model has no collection value listeners.
+	 */
+	protected boolean hasNoListeners() {
+		return ! this.hasListeners();
+	}
+
+	/**
+	 * Return whether the model has any collection value listeners.
+	 */
+	protected boolean hasListeners() {
+		return this.hasAnyCollectionChangeListeners(CollectionValueModel.VALUES);
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Engage the underlying model.
+	 */
+	protected abstract void engageModel();
+
+	/**
+	 * Stop listening to the underlying model.
+	 */
+	protected abstract void disengageModel();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractListValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractListValueModel.java
new file mode 100644
index 0000000..6a80416
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractListValueModel.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.ChangeSupport;
+import org.eclipse.persistence.tools.utility.model.SingleAspectChangeSupport;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+
+/**
+ * This abstract class provides the infrastructure for "lazily" adding listeners
+ * to an underlying model as necessary. Subclasses will need to engage and
+ * disegage the underlying model and fire the appropriate list change
+ * events. Subclasses must implement the appropriate {@link ListValueModel}.
+ * <p>
+ * Subclasses must implement the following methods:<ul>
+ * <li>{@link #engageModel()}<p>
+ *     implement this method to add the appropriate listener to the underlying model
+ * <li>{@link #disengageModel()}<p>
+ *     implement this method to remove the appropriate listener from the underlying model
+ * </ul>
+ */
+public abstract class AbstractListValueModel
+	extends AbstractModel
+{
+
+	// ********** constructor/initialization **********
+
+	protected AbstractListValueModel() {
+		super();
+	}
+
+	@Override
+	protected ChangeSupport buildChangeSupport() {
+		return new SingleAspectChangeSupport(this, ListChangeListener.class, ListValueModel.LIST_VALUES);
+	}
+
+
+	// ********** extend change support **********
+
+	/**
+	 * Extend to start listening to the underlying model if necessary.
+	 */
+	@Override
+	public void addChangeListener(ChangeListener listener) {
+		if (this.hasNoListeners()) {
+			this.engageModel();
+		}
+		super.addChangeListener(listener);
+	}
+
+	/**
+	 * Extend to start listening to the underlying model if necessary.
+	 */
+	@Override
+	public void addListChangeListener(String listName, ListChangeListener listener) {
+		if (listName.equals(ListValueModel.LIST_VALUES) && this.hasNoListeners()) {
+			this.engageModel();
+		}
+		super.addListChangeListener(listName, listener);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying model if necessary.
+	 */
+	@Override
+	public void removeChangeListener(ChangeListener listener) {
+		super.removeChangeListener(listener);
+		if (this.hasNoListeners()) {
+			this.disengageModel();
+		}
+	}
+
+	/**
+	 * Extend to stop listening to the underlying model if necessary.
+	 */
+	@Override
+	public void removeListChangeListener(String listName, ListChangeListener listener) {
+		super.removeListChangeListener(listName, listener);
+		if (listName.equals(ListValueModel.LIST_VALUES) && this.hasNoListeners()) {
+			this.disengageModel();
+		}
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * Return whether the model has no collection value listeners.
+	 */
+	protected boolean hasNoListeners() {
+		return ! this.hasListeners();
+	}
+
+	/**
+	 * Return whether the model has any collection value listeners.
+	 */
+	protected boolean hasListeners() {
+		return this.hasAnyListChangeListeners(ListValueModel.LIST_VALUES);
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Engage the underlying model.
+	 */
+	protected abstract void engageModel();
+
+	/**
+	 * Stop listening to the underlying model.
+	 */
+	protected abstract void disengageModel();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractPropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractPropertyValueModel.java
new file mode 100644
index 0000000..d3fbfca
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractPropertyValueModel.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.ChangeSupport;
+import org.eclipse.persistence.tools.utility.model.SingleAspectChangeSupport;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+
+/**
+ * This abstract class provides the infrastructure for "lazily" adding/removing
+ * listeners to/from an underlying model as <em>property</em> change
+ * listeners are added to/removed from itself.
+ * Subclasses will need to engage and disengage the underlying model
+ * appropriately and fire the appropriate <em>property</em>
+ * change events.
+ * <p>
+ * Subclasses must implement the appropriate {@link PropertyValueModel}.
+ * <p>
+ * Subclasses must implement the following methods:<ul>
+ * <li>{@link #engageModel()}<p>
+ *     implement this method to add the appropriate listener(s) to the
+ *     underlying model
+ * <li>{@link #disengageModel()}<p>
+ *     implement this method to remove the appropriate listener(s) from the
+ *     underlying model
+ * </ul>
+ */
+public abstract class AbstractPropertyValueModel
+	extends AbstractModel
+{
+	// ********** constructor/initialization **********
+
+	protected AbstractPropertyValueModel() {
+		super();
+	}
+
+	@Override
+	protected ChangeSupport buildChangeSupport() {
+		return new SingleAspectChangeSupport(this, PropertyChangeListener.class, PropertyValueModel.VALUE);
+	}
+
+
+	// ********** listeners **********
+
+	/**
+	 * Extend to start listening to the underlying model if necessary.
+	 */
+	@Override
+	public synchronized void addChangeListener(ChangeListener listener) {
+		if (this.hasNoListeners()) {
+			this.engageModel();
+		}
+		super.addChangeListener(listener);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying model if necessary.
+	 */
+	@Override
+	public synchronized void removeChangeListener(ChangeListener listener) {
+		super.removeChangeListener(listener);
+		if (this.hasNoListeners()) {
+			this.disengageModel();
+		}
+	}
+
+	/**
+	 * Extend to start listening to the underlying model if necessary.
+	 */
+	@Override
+	public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+		if (propertyName.equals(PropertyValueModel.VALUE) && this.hasNoListeners()) {
+			this.engageModel();
+		}
+		super.addPropertyChangeListener(propertyName, listener);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying model if necessary.
+	 */
+	@Override
+	public synchronized void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+		super.removePropertyChangeListener(propertyName, listener);
+		if (propertyName.equals(PropertyValueModel.VALUE) && this.hasNoListeners()) {
+			this.disengageModel();
+		}
+	}
+
+	/**
+	 * Return whether the model has no property value listeners.
+	 */
+	protected boolean hasNoListeners() {
+		return ! this.hasListeners();
+	}
+
+	/**
+	 * Return whether the model has any property value listeners.
+	 */
+	protected boolean hasListeners() {
+		return this.hasAnyPropertyChangeListeners(PropertyValueModel.VALUE);
+	}
+
+
+	// ********** subclass implementation **********
+
+	/**
+	 * Engage the underlying model.
+	 */
+	protected abstract void engageModel();
+
+	/**
+	 * Stop listening to the underlying model.
+	 */
+	protected abstract void disengageModel();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractPropertyValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractPropertyValueModelAdapter.java
new file mode 100644
index 0000000..be16c0e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractPropertyValueModelAdapter.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+/**
+ * This abstract class provides the infrastructure needed to wrap
+ * a model, "lazily" listen to it, and convert
+ * its change notifications into <em>property</em> value model change
+ * notifications.
+ * <p>
+ * Subclasses must implement:<ul>
+ * <li>{@link #buildValue()}<p>
+ *     to return the current property value, as derived from the
+ *     current state of the underlying model
+ * <li>{@link #engageModel_()}<p>
+ *     to start listening to the underlying (adapted) model
+ * <li>{@link #disengageModel_()}<p>
+ *     to stop listening to the underlying (adapted) model
+ * </ul>
+ * Subclasses can call {@link #propertyChanged()} whenever the calculated
+ * value of the property changes (as determined by the subclass).
+ *
+ * @param <V> the type of the model's value
+ */
+public abstract class AbstractPropertyValueModelAdapter<V>
+	extends AbstractPropertyValueModel
+	implements PropertyValueModel<V>
+{
+	/**
+	 * Cache the current value so we can pass an "old value" when
+	 * we fire a property change event.
+	 * We need this because the value may be calculated and we may
+	 * not able to derive the "old value" from any fired events.
+	 */
+	protected volatile V value;
+
+
+	// ********** constructor/initialization **********
+
+	protected AbstractPropertyValueModelAdapter() {
+		super();
+		// our value is null when we are not listening to the model
+		this.value = null;
+	}
+
+
+	// ********** PropertyValueModel implementation **********
+
+	/**
+	 * Return the cached value.
+	 */
+	@Override
+	public V getValue() {
+		return this.value;
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Start listening to the underlying model and build the value.
+	 */
+	@Override
+	protected void engageModel() {
+		this.engageModel_();
+		// sync our value *after* we start listening to the model,
+		// since the model's value might change when a listener is added
+		this.value = this.buildValue();
+	}
+
+	/**
+	 * Start listening to the underlying model.
+	 */
+	protected abstract void engageModel_();
+
+	/**
+	 * Build and return the current value, as derived from the
+	 * current state of the underlying model.
+	 */
+	protected abstract V buildValue();
+
+	/**
+	 * Stop listening to the underlying model and clear the value.
+	 */
+	@Override
+	protected void disengageModel() {
+		this.disengageModel_();
+		// clear out our value when we are not listening to the model
+		this.value = null;
+	}
+
+	/**
+	 * Stop listening to the underlying model.
+	 */
+	protected abstract void disengageModel_();
+
+	/**
+	 * The underlying model changed in some fashion.
+	 * Recalculate the model's value and notify listeners.
+	 */
+	protected void propertyChanged() {
+		Object old = this.value;
+		this.firePropertyChanged(VALUE, old, this.value = this.buildValue());
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.value);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractTreeNodeValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractTreeNodeValueModel.java
new file mode 100644
index 0000000..17b2cfb
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AbstractTreeNodeValueModel.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.ChainIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.ChangeSupport;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
+
+/**
+ * Subclasses need only implement the following methods:
+ *
+ * #value()
+ *	    return the user-determined "value" of the node,
+ *     i.e. the object "wrapped" by the node
+ *
+ * #setValue(Object)
+ *     set the user-determined "value" of the node,
+ *     i.e. the object "wrapped" by the node;
+ *     typically only overridden for nodes with "primitive" values
+ *
+ * #parent()
+ *     return the parent of the node, which should be another
+ *     TreeNodeValueModel
+ *
+ * #childrenModel()
+ *     return a ListValueModel for the node's children
+ *
+ * #engageValue() and #disengageValue()
+ *     override these methods to listen to the node's value if
+ *     it can change in a way that should be reflected in the tree
+ */
+public abstract class AbstractTreeNodeValueModel<T>
+	extends AbstractModel
+	implements TreeNodeValueModel<T>
+{
+
+
+	// ********** constructors **********
+
+	/**
+	 * Default constructor.
+	 */
+	protected AbstractTreeNodeValueModel() {
+		super();
+	}
+
+	@Override
+	protected ChangeSupport buildChangeSupport() {
+		// this model fires *both* "value property change" and "state change" events...
+//		return new SingleAspectChangeSupport(this, PropertyChangeListener.class, PropertyValueModel.VALUE);
+		return super.buildChangeSupport();
+	}
+
+
+	// ********** extend AbstractModel implementation **********
+
+	/**
+	 * Clients should be adding both "state change" and "value property change"
+	 * listeners.
+	 */
+	@Override
+	public void addStateChangeListener(StateChangeListener listener) {
+		if (this.hasNoStateChangeListeners()) {
+			this.engageValue();
+		}
+		super.addStateChangeListener(listener);
+	}
+
+	/**
+	 * Begin listening to the node's value's state. If the state of the node changes
+	 * in a way that should be reflected in the tree, fire a "state change" event.
+	 */
+	protected abstract void engageValue();
+
+	/**
+	 * @see #addStateChangeListener(StateChangeListener)
+	 */
+	@Override
+	public void removeStateChangeListener(StateChangeListener listener) {
+		super.removeStateChangeListener(listener);
+		if (this.hasNoStateChangeListeners()) {
+			this.disengageValue();
+		}
+	}
+
+	/**
+	 * Stop listening to the node's value.
+	 * @see #engageValue()
+	 */
+	protected abstract void disengageValue();
+
+
+	// ********** WritablePropertyValueModel implementation **********
+
+	@Override
+	public void setValue(T value) {
+		throw new UnsupportedOperationException();
+	}
+
+
+	// ********** TreeNodeValueModel implementation **********
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public TreeNodeValueModel<T>[] path() {
+		List<TreeNodeValueModel<T>> path = ListTools.reverse(ListTools.list(this.backPath()));
+		return path.toArray(new TreeNodeValueModel[path.size()]);
+	}
+
+	/**
+	 * Return an iterator that climbs up the node's path,
+	 * starting with, and including, the node
+	 * and up to, and including, the root node.
+	 */
+	protected Iterator<TreeNodeValueModel<T>> backPath() {
+		return new ChainIterator<TreeNodeValueModel<T>>(this) {
+			@Override
+			protected TreeNodeValueModel<T> nextLink(TreeNodeValueModel<T> currentLink) {
+				return currentLink.parent();
+			}
+		};
+	}
+
+	@Override
+	public TreeNodeValueModel<T> child(int index) {
+		return this.childrenModel().get(index);
+	}
+
+	@Override
+	public int childrenSize() {
+		return this.childrenModel().size();
+	}
+
+	@Override
+	public int indexOfChild(TreeNodeValueModel<T> child) {
+		ListValueModel<TreeNodeValueModel<T>> children = this.childrenModel();
+		int size = children.size();
+		for (int i = 0; i < size; i++) {
+			if (children.get(i) == child) {
+				return i;
+			}
+		}
+		return -1;
+	}
+
+	@Override
+	public boolean isLeaf() {
+		return this.childrenModel().size() == 0;
+	}
+
+
+	// ********** standard methods **********
+
+	/**
+	 * We implement #equals(Object) so that TreePaths containing these nodes
+	 * will resolve properly when the nodes contain the same values. This is
+	 * necessary because nodes are dropped and rebuilt willy-nilly when dealing
+	 * with a sorted list of children; and this allows us to save and restore
+	 * a tree's expanded paths. The nodes in the expanded paths that are
+	 * saved before any modification (e.g. renaming a node) will be different
+	 * from the nodes in the tree's paths after the modification, if the modification
+	 * results in a possible change in the node sort order.  ~bjv
+	 */
+	@Override
+	public boolean equals(Object o) {
+		if (o == null) {
+			return false;
+		}
+		if (o.getClass() != this.getClass()) {
+			return false;
+		}
+		@SuppressWarnings("unchecked")
+		AbstractTreeNodeValueModel<T> other = (AbstractTreeNodeValueModel<T>) o;
+		return this.getValue().equals(other.getValue());
+	}
+
+	@Override
+	public int hashCode() {
+		return this.getValue().hashCode();
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.getValue());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AspectAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AspectAdapter.java
new file mode 100644
index 0000000..a63a050
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AspectAdapter.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.EventListener;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.ChangeSupport;
+import org.eclipse.persistence.tools.utility.model.SingleAspectChangeSupport;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+
+/**
+ * This abstract extension of {@link AbstractModel} provides a base for adding
+ * change listeners (property change, collection change, list change, tree change)
+ * to a subject and converting the subject's change notifications into a single
+ * set of change notifications for a common aspect
+ * (e.g. {@link PropertyValueModel#VALUE}).
+ * <p>
+ * The adapter will only listen to the subject (and subject model) when the
+ * adapter itself actually has listeners. This will allow the adapter to be
+ * garbage collected when appropriate.
+ *
+ * @param <S> the type of the model's subject
+ * @param <A> the type of the subject's aspect
+ */
+public abstract class AspectAdapter<S, A>
+	extends AbstractModel
+{
+	/**
+	 * The subject that holds the aspect and fires
+	 * change notification when the aspect changes.
+	 * We need to hold on to this directly so we can
+	 * disengage it when it changes.
+	 */
+	protected volatile S subject;
+
+	/**
+	 * A value model that holds the {@link #subject}
+	 * that holds the aspect and provides change notification.
+	 * This is useful when there are a number of aspect adapters
+	 * that have the same subject and that subject can change.
+	 * All the aspect adapters can share the same subject model.
+	 * For now, this is can only be set upon construction and is
+	 * immutable.
+	 */
+	protected final PropertyValueModel<? extends S> subjectModel;
+
+	/** A listener that keeps us in sync with the subject model. */
+	protected final PropertyChangeListener subjectListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an aspect adapter for the specified subject.
+	 */
+	protected AspectAdapter(S subject) {
+		this(new StaticPropertyValueModel<S>(subject));
+	}
+
+	/**
+	 * Construct an aspect adapter for the specified subject model.
+	 * The subject model cannot be <code>null</code>.
+	 */
+	protected AspectAdapter(PropertyValueModel<? extends S> subjectModel) {
+		super();
+		if (subjectModel == null) {
+			throw new NullPointerException();
+		}
+		this.subjectModel = subjectModel;
+		this.subjectListener = this.buildSubjectListener();
+		// the subject is null when we are not listening to it
+		// this will typically result in our value being null
+		this.subject = null;
+	}
+
+
+	// ********** initialization **********
+
+	@Override
+	protected ChangeSupport buildChangeSupport() {
+		return new LocalChangeSupport(this, this.getListenerClass(), this.getListenerAspectName());
+	}
+
+	protected PropertyChangeListener buildSubjectListener() {
+		return new SubjectListener();
+	}
+
+	protected class SubjectListener
+		extends PropertyChangeAdapter
+	{
+		/**
+		 * The subject model's value has changed, keep our subject in sync.
+		 */
+		@Override
+		public void propertyChanged(PropertyChangeEvent event) {
+			AspectAdapter.this.subjectChanged();
+		}
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * The subject has changed.
+	 * Move our subject listener and
+	 * notify listeners that the value has changed.
+	 */
+	protected synchronized void subjectChanged() {
+		A old = this.getAspectValue();
+		boolean hasListeners = this.hasListeners();
+		if (hasListeners) {
+			this.disengageSubject();
+		}
+		this.subject = this.subjectModel.getValue();
+		if (hasListeners) {
+			this.engageSubject();
+			this.fireAspectChanged(old, this.getAspectValue());
+		}
+	}
+
+	/**
+	 * Return the aspect's current value.
+	 */
+	protected abstract A getAspectValue();
+
+	/**
+	 * Return the class of listener that is interested in the aspect adapter's
+	 * changes.
+	 */
+	protected abstract Class<? extends EventListener> getListenerClass();
+
+	/**
+	 * Return the name of the aspect adapter's aspect
+	 * (e.g. {@link PropertyValueModel#VALUE}).
+	 * This is the name of the aspect adapter's single aspect, not the
+	 * name of the subject's aspect(s) the aspect adapter is adapting.
+	 */
+	protected abstract String getListenerAspectName();
+
+	/**
+	 * Return whether there are any listeners for the aspect.
+	 */
+	protected abstract boolean hasListeners();
+
+	/**
+	 * Return whether there are no listeners for the aspect.
+	 */
+	protected boolean hasNoListeners() {
+		return ! this.hasListeners();
+	}
+
+	/**
+	 * The aspect has changed, notify listeners appropriately.
+	 */
+	protected abstract void fireAspectChanged(A oldValue, A newValue);
+
+
+	// ********** engage/disengage models **********
+
+	/**
+	 * Called by {@link LocalChangeSupport}
+	 */
+	protected void engageModels() {
+		this.engageSubjectHolder();
+		this.engageSubject();
+	}
+
+	protected void engageSubjectHolder() {
+		this.subjectModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.subjectListener);
+		// sync our subject *after* we start listening to the subject holder,
+		// since its value might change when a listener is added
+		this.subject = this.subjectModel.getValue();
+	}
+
+	protected void engageSubject() {
+		// check for nothing to listen to
+		if (this.subject != null) {
+			this.engageSubject_();
+		}
+	}
+
+	/**
+	 * The {@link #subject} is not <code>null</code> - add our listener.
+	 */
+	protected abstract void engageSubject_();
+
+	/**
+	 * Called by {@link LocalChangeSupport}
+	 */
+	protected void disengageModels() {
+		this.disengageSubject();
+		this.disengageSubjectHolder();
+	}
+
+	protected void disengageSubject() {
+		// check for nothing to listen to
+		if (this.subject != null) {
+			this.disengageSubject_();
+		}
+	}
+
+	/**
+	 * The {@link #subject} is not <code>null</code> - remove our listener.
+	 */
+	protected abstract void disengageSubject_();
+
+	protected void disengageSubjectHolder() {
+		this.subjectModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.subjectListener);
+		// clear out the subject when we are not listening to its holder
+		this.subject = null;
+	}
+
+
+	// ********** local change support **********
+
+	/**
+	 * Extend change support to start listening to the aspect adapter's
+	 * models (the subject holder and the subject itself) when the first
+	 * relevant listener is added.
+	 * Conversely, stop listening to the aspect adapter's models when the
+	 * last relevant listener is removed.
+	 * A relevant listener is a listener of the relevant type and aspect or a
+	 * general-purpose listener.
+	 */
+	protected class LocalChangeSupport
+		extends SingleAspectChangeSupport
+	{
+		private static final long serialVersionUID = 1L;
+
+		public LocalChangeSupport(AspectAdapter<S, A> source, Class<? extends EventListener> validListenerClass, String validAspectName) {
+			super(source, validListenerClass, validAspectName);
+		}
+
+		protected boolean hasNoListeners() {
+			return this.hasNoListeners(this.validListenerClass, this.validAspectName);
+		}
+
+
+		// ********** overrides **********
+
+		@Override
+		protected synchronized <T extends EventListener> void addListener(Class<T> listenerClass, T listener) {
+			if (this.hasNoListeners()) {
+				AspectAdapter.this.engageModels();
+			}
+			super.addListener(listenerClass, listener);
+		}
+
+		@Override
+		protected synchronized <T extends EventListener> void addListener(Class<T> listenerClass, String aspectName, T listener) {
+			if (this.hasNoListeners()) {
+				AspectAdapter.this.engageModels();
+			}
+			super.addListener(listenerClass, aspectName, listener);
+		}
+
+		@Override
+		protected synchronized <T extends EventListener> void removeListener(Class<T> listenerClass, T listener) {
+			super.removeListener(listenerClass, listener);
+			if (this.hasNoListeners()) {
+				AspectAdapter.this.disengageModels();
+			}
+		}
+
+		@Override
+		protected synchronized <T extends EventListener> void removeListener(Class<T> listenerClass, String aspectName, T listener) {
+			super.removeListener(listenerClass, aspectName, listener);
+			if (this.hasNoListeners()) {
+				AspectAdapter.this.disengageModels();
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AspectCollectionValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AspectCollectionValueModelAdapter.java
new file mode 100644
index 0000000..399867f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AspectCollectionValueModelAdapter.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Collection;
+import java.util.EventListener;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+
+/**
+ * This {@link AspectAdapter} provides basic collection change support.
+ * This converts an "aspect" (as defined by subclasses) into
+ * a single {@link #VALUES} collection.
+ * <p>
+ * The typical subclass will override the following methods:<ul>
+ * <li>{@link #engageSubject_()}<p>
+ *     implement this method to add the appropriate listener to the subject
+ * <li>{@link #disengageSubject_()}<p>
+ *     implement this method to remove the appropriate listener from the subject
+ * <li>{@link #getIterable()}<p>
+ *     at the very minimum, override this method to return an iterable containing the
+ *     subject's collection aspect; it does not need to be overridden if either
+ *     {@link #iterator_()} or {@link #iterator()} is overridden and its behavior changed
+ * <li>{@link #size_()}<p>
+ *     override this method to improve performance; it does not need to be overridden if
+ *     {@link #size()} is overridden and its behavior changed
+ * <li>{@link #iterator_()}<p>
+ *     override this method to return an iterator on the
+ *     subject's collection aspect if it is not possible to implement {@link #getIterable()};
+ *     it does not need to be overridden if
+ *     {@link #iterator()} is overridden and its behavior changed
+ * <li>{@link #iterator()}<p>
+ *     override this method only if returning an empty iterator when the
+ *     subject is null is unacceptable
+ * <li>{@link #size()}<p>
+ *     override this method only if returning a zero when the
+ *     subject is null is unacceptable
+ * </ul>
+ * To notify listeners, subclasses can call {@link #aspectChanged()}
+ * whenever the aspect has changed.
+ *
+ * @param <S> the type of the model's subject
+ * @param <E> the type of the subject's collection aspect's elements
+ */
+@SuppressWarnings("nls")
+public abstract class AspectCollectionValueModelAdapter<S, E>
+	extends AspectAdapter<S, Collection<E>>
+	implements CollectionValueModel<E>
+{
+	/**
+	 * Construct a collection value model adapter for an aspect of the
+	 * specified subject.
+	 */
+	protected AspectCollectionValueModelAdapter(PropertyValueModel<? extends S> subjectModel) {
+		super(subjectModel);
+	}
+
+
+	// ********** CollectionValueModel implementation **********
+
+	/**
+	 * Return the elements of the subject's collection aspect.
+	 */
+	@Override
+	public Iterator<E> iterator() {
+		return (this.subject == null) ? EmptyIterator.<E>instance() : this.iterator_();
+	}
+
+	/**
+	 * Return the elements of the subject's collection aspect.
+	 * At this point we can be sure the {@link #subject} is
+	 * <em>not</em> <code>null</code>.
+	 * @see #iterator()
+	 */
+	protected Iterator<E> iterator_() {
+		return this.getIterable().iterator();
+	}
+
+	/**
+	 * Return the elements of the subject's collection aspect.
+	 * At this point we can be sure the {@link #subject} is
+	 * <em>not</em> <code>null</code>.
+	 * @see #iterator_()
+	 */
+	protected Iterable<E> getIterable() {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+	/**
+	 * Return the size of the subject's collection aspect.
+	 */
+	@Override
+	public int size() {
+		return (this.subject == null) ? 0 : this.size_();
+	}
+
+	/**
+	 * Return the size of the subject's collection aspect.
+	 * At this point we can be sure the {@link #subject} is
+	 * <em>not</em> <code>null</code>.
+	 * @see #size()
+	 */
+	protected int size_() {
+		return IteratorTools.size(this.iterator());
+	}
+
+
+	// ********** AspectAdapter implementation **********
+
+	@Override
+	protected Collection<E> getAspectValue() {
+		return this.buildValueCollection();
+	}
+
+	@Override
+	protected Class<? extends EventListener> getListenerClass() {
+		return CollectionChangeListener.class;
+	}
+
+	@Override
+	protected String getListenerAspectName() {
+		return VALUES;
+	}
+
+	@Override
+	protected boolean hasListeners() {
+		return this.hasAnyCollectionChangeListeners(VALUES);
+	}
+
+	@Override
+	protected void fireAspectChanged(Collection<E> oldValue, Collection<E> newValue) {
+		this.fireCollectionChanged(VALUES, newValue);
+	}
+
+	protected void aspectChanged() {
+		this.fireCollectionChanged(VALUES, this.buildValueCollection());
+	}
+
+	protected Collection<E> buildValueCollection() {
+		return CollectionTools.collection(this.iterator());
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.buildValueCollection());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AspectListValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AspectListValueModelAdapter.java
new file mode 100644
index 0000000..e7ce7c7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AspectListValueModelAdapter.java
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.EventListener;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterator.EmptyListIterator;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+
+/**
+ * This {@link AspectAdapter} provides basic list change support.
+ * This converts an "aspect" (as defined by subclasses) into
+ * a single {@link #LIST_VALUES} list.
+ * <p>
+ * The typical subclass will override the following methods:<ul>
+ * <li>{@link #engageSubject_()}<p>
+ *     implement this method to add the appropriate listener to the subject
+ * <li>{@link #disengageSubject_()}<p>
+ *     implement this method to remove the appropriate listener from the subject
+ * <li>{@link #getListIterable()}<p>
+ *     at the very minimum, override this method to return a list iterable containing the
+ *     subject's list aspect; it does not need to be overridden if either
+ *     {@link #listIterator_()} or {@link #listIterator()} is overridden and its behavior changed
+ * <li>{@link #get(int)}<p>
+ *     override this method to improve performance
+ * <li>{@link #size_()}<p>
+ *     override this method to improve performance; it does not need to be overridden if
+ *     {@link #size()} is overridden and its behavior changed
+ * <li>{@link #toArray_()}<p>
+ *     override this method to improve performance; it does not need to be overridden if
+ *     {@link #toArray()} is overridden and its behavior changed
+ * <li>{@link #listIterator_()}<p>
+ *     override this method to return a list iterator on the subject's list
+ *     aspect if it is not possible to implement {@link #getListIterable()};
+ *     it does not need to be overridden if
+ *     {@link #listIterator()} is overridden and its behavior changed
+ * <li>{@link #listIterator()}<p>
+ *     override this method only if returning an empty list iterator when the
+ *     subject is null is unacceptable
+ * <li>{@link #size()}<p>
+ *     override this method only if returning a zero when the
+ *     subject is null is unacceptable
+ * <li>{@link #toArray()}<p>
+ *     override this method only if returning an empty array when the
+ *     subject is null is unacceptable
+ * </ul>
+ * To notify listeners, subclasses can call {@link #aspectChanged()}
+ * whenever the aspect has changed.
+ *
+ * @param <S> the type of the model's subject
+ * @param <E> the type of the subject's list aspect's elements
+ */
+@SuppressWarnings("nls")
+public abstract class AspectListValueModelAdapter<S, E>
+	extends AspectAdapter<S, List<E>>
+	implements ListValueModel<E>
+{
+	// ********** constructors **********
+
+	/**
+	 * Construct a list value model adapter for an aspect of the
+	 * specified subject.
+	 */
+	protected AspectListValueModelAdapter(PropertyValueModel<? extends S> subjectModel) {
+		super(subjectModel);
+	}
+
+
+	// ********** ListValueModel implementation **********
+
+	/**
+	 * Return the elements of the subject's list aspect.
+	 */
+	@Override
+	public ListIterator<E> iterator() {
+		return this.listIterator();
+	}
+
+	/**
+	 * Return the elements of the subject's list aspect.
+	 */
+	@Override
+	public ListIterator<E> listIterator() {
+		return (this.subject == null) ? EmptyListIterator.<E>instance() : this.listIterator_();
+	}
+
+	/**
+	 * Return the elements of the subject's list aspect.
+	 * At this point we can be sure the {@link #subject} is
+	 * <em>not</em> <code>null</code>.
+	 * @see #listIterator()
+	 */
+	protected ListIterator<E> listIterator_() {
+		return this.getListIterable().iterator();
+	}
+
+	/**
+	 * Return the elements of the subject's list aspect.
+	 * At this point we can be sure the {@link #subject} is
+	 * <em>not</em> <code>null</code>.
+	 * @see #listIterator_()
+	 */
+	protected ListIterable<E> getListIterable() {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+	/**
+	 * Return the element at the specified index of the subject's list aspect.
+	 */
+	@Override
+	public E get(int index) {
+		return IteratorTools.get(this.listIterator(), index);
+	}
+
+	/**
+	 * Return the size of the subject's list aspect.
+	 */
+	@Override
+	public int size() {
+		return this.subject == null ? 0 : this.size_();
+	}
+
+	/**
+	 * Return the size of the subject's list aspect.
+	 * At this point we can be sure the {@link #subject} is
+	 * <em>not</em> <code>null</code>.
+	 * @see #size()
+	 */
+	protected int size_() {
+		return IteratorTools.size(this.listIterator());
+	}
+
+	/**
+	 * Return an array manifestation of the subject's list aspect.
+	 */
+	@Override
+	public Object[] toArray() {
+		return this.subject == null ? ObjectTools.EMPTY_OBJECT_ARRAY : this.toArray_();
+	}
+
+	/**
+	 * Return an array manifestation of the subject's list aspect.
+	 * At this point we can be sure the subject is not null.
+	 * @see #toArray()
+	 */
+	protected Object[] toArray_() {
+		return ArrayTools.array(this.listIterator(), this.size());
+	}
+
+
+	// ********** AspectAdapter implementation **********
+
+	@Override
+	protected List<E> getAspectValue() {
+		return this.buildValueList();
+	}
+
+	@Override
+	protected Class<? extends EventListener> getListenerClass() {
+		return ListChangeListener.class;
+	}
+
+	@Override
+	protected String getListenerAspectName() {
+		return LIST_VALUES;
+	}
+
+	@Override
+	protected boolean hasListeners() {
+		return this.hasAnyListChangeListeners(LIST_VALUES);
+	}
+
+	@Override
+	protected void fireAspectChanged(List<E> oldValue, List<E> newValue) {
+		this.fireListChanged(LIST_VALUES, newValue);
+	}
+
+	protected void aspectChanged() {
+		this.fireListChanged(LIST_VALUES, this.buildValueList());
+	}
+
+	protected List<E> buildValueList() {
+		return ListTools.list(this.iterator());
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.buildValueList());
+	}
+}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AspectPropertyValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AspectPropertyValueModelAdapter.java
new file mode 100644
index 0000000..5bbb0d6
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/AspectPropertyValueModelAdapter.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.EventListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+
+/**
+ * This {@link AspectAdapter} provides basic property change support.
+ * This converts an "aspect" (as defined by subclasses) into
+ * a single {@link #VALUE} property.
+ * <p>
+ * The typical subclass will override the following methods:<ul>
+ * <li>{@link #engageSubject_()}<p>
+ *     implement this method to add the appropriate listener to the subject
+ * <li>{@link #disengageSubject_()}<p>
+ *     implement this method to remove the appropriate listener from the subject
+ * <li>{@link #buildValue_()}<p>
+ *     at the very minimum, override this method to return the value of the
+ *     subject's aspect (or "virtual" aspect); it does not need to be
+ *     overridden if {@link #buildValue()} is overridden and its behavior changed
+ * <li>{@link #setValue_(Object)}<p>
+ *     override this method if the client code needs to <em>set</em> the value of
+ *     the subject's aspect; oftentimes, though, the client code (e.g. UI)
+ *     will need only to <em>get</em> the value; it does not need to be
+ *     overridden if {@link #setValue(Object)} is overridden and its behavior changed
+ * <li>{@link #buildValue()}<p>
+ *     override this method only if returning a <code>null</code> value when
+ *     the subject is <code>null</code> is unacceptable
+ * <li>{@link #setValue(Object)}<p>
+ *     override this method only if something must be done when the subject
+ *     is <code>null</code> (e.g. throw an exception)
+ * </ul>
+ * To notify listeners, subclasses can call {@link #aspectChanged()}
+ * whenever the aspect has changed.
+ *
+ * @param <S> the type of the model's subject
+ * @param <V> the type of the subject's property aspect
+ */
+@SuppressWarnings("nls")
+public abstract class AspectPropertyValueModelAdapter<S, V>
+	extends AspectAdapter<S, V>
+	implements ModifiablePropertyValueModel<V>
+{
+	/**
+	 * Cache the current value of the aspect so we
+	 * can pass an "old value" when we fire a property change event.
+	 * We need this because the value may be calculated and may
+	 * not be in the property change event fired by the subject,
+	 * especially when dealing with multiple aspects.
+	 */
+	protected volatile V value;
+
+
+	// ********** constructor **********
+
+	/**
+	 * Construct a property value model adapter for an aspect of the
+	 * specified subject.
+	 * The subject model cannot be <code>null</code>.
+	 */
+	protected AspectPropertyValueModelAdapter(PropertyValueModel<? extends S> subjectModel) {
+		super(subjectModel);
+		// our value is null when we are not listening to the subject
+		this.value = null;
+	}
+
+
+	// ********** PropertyValueModel implementation **********
+
+	/**
+	 * Return the value of the subject's aspect.
+	 */
+	@Override
+	public final V getValue() {
+		return this.value;
+	}
+
+
+	// ********** WritablePropertyValueModel implementation **********
+
+	/**
+	 * Set the value of the subject's aspect.
+	 */
+	@Override
+	public void setValue(V value) {
+		if (this.subject != null) {
+			this.setValue_(value);
+		}
+	}
+
+	/**
+	 * Set the value of the subject's aspect.
+	 * At this point we can be sure the {@link #subject} is
+	 * <em>not</em> <code>null</code>.
+	 * @see #setValue(Object)
+	 */
+	protected void setValue_(@SuppressWarnings("unused") V value) {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+
+	// ********** AspectAdapter implementation **********
+
+	@Override
+	protected V getAspectValue() {
+		return this.value;
+	}
+
+	@Override
+	protected Class<? extends EventListener> getListenerClass() {
+		return PropertyChangeListener.class;
+	}
+
+	@Override
+	protected String getListenerAspectName() {
+		return VALUE;
+	}
+
+    @Override
+	protected boolean hasListeners() {
+		return this.hasAnyPropertyChangeListeners(VALUE);
+	}
+
+    @Override
+	protected void fireAspectChanged(V oldValue, V newValue) {
+		this.firePropertyChanged(VALUE, oldValue, newValue);
+	}
+
+    @Override
+	protected void engageSubject() {
+		super.engageSubject();
+		// sync our value *after* we start listening to the subject,
+		// since its value might change when a listener is added
+		this.value = this.buildValue();
+	}
+
+    @Override
+	protected void disengageSubject() {
+		super.disengageSubject();
+		// clear out our value when we are not listening to the subject
+		this.value = null;
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Return the aspect's value.
+	 * At this point the subject may be <code>null</code>.
+	 */
+	protected V buildValue() {
+		return (this.subject == null) ? null : this.buildValue_();
+	}
+
+	/**
+	 * Return the value of the subject's aspect.
+	 * At this point we can be sure the {@link #subject} is
+	 * <em>not</em> <code>null</code>.
+	 * @see #buildValue()
+	 */
+	protected V buildValue_() {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+	/**
+	 * This method can be called by subclasses whenever the subject's aspect
+	 * has changed; listeners will be notified appropriately.
+	 */
+	protected void aspectChanged() {
+		V old = this.value;
+		this.fireAspectChanged(old, this.value = this.buildValue());
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.value);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/BufferedModifiablePropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/BufferedModifiablePropertyValueModel.java
new file mode 100644
index 0000000..8e983e8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/BufferedModifiablePropertyValueModel.java
@@ -0,0 +1,402 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+
+/**
+ * A <code>BufferedModifiablePropertyValueModel</code> is used to hold a temporary
+ * copy of the value
+ * in another property value model (the "wrapped" value model). The application
+ * can modify this temporary copy, ad nauseam; but the temporary copy is only
+ * passed through to the "wrapped" value model when the trigger "accepts" the
+ * buffered value. Alternatively, the application can "reset" the buffered value
+ * to the original, "wrapped" value.
+ * <p>
+ * The trigger is another {@link PropertyValueModel} that holds a
+ * {@link Boolean} and the application changes the trigger's value to
+ * <code>true</code> on "accept", <code>false</code> on "reset".
+ * <p>
+ * Typically, in a dialog:<ul>
+ * <li>pressing the "OK" button will trigger an "accept" and close the dialog
+ * <li>pressing the "Cancel" button will simply close the dialog,
+ *     dropping the "buffered" values into the bit bucket
+ * <li>pressing the "Apply" button will trigger an "accept" and leave the
+ *     dialog open
+ * <li>pressing the "Restore" button will trigger a "reset" and leave the
+ *     dialog open
+ * </ul>
+ * A number of buffered property value models can wrap another set of
+ * property aspect adapters that adapt the various aspects of a single
+ * domain model. All the buffered property value models can be hooked to the
+ * same trigger, and that trigger is controlled by the application, typically
+ * via the "OK" button in a dialog.
+ *
+ * @param <V> the type of the model's value
+ * @see PropertyAspectAdapter
+ */
+@SuppressWarnings("nls")
+public class BufferedModifiablePropertyValueModel<V>
+	extends PropertyValueModelWrapper<V>
+	implements ModifiablePropertyValueModel<V>
+{
+	/**
+	 * We cache the value here until it is accepted and passed
+	 * through to the wrapped value model.
+	 */
+	protected volatile V bufferedValue;
+
+	/**
+	 * This is set to true when we are "accepting" the buffered value
+	 * and passing it through to the wrapped value model. This allows
+	 * us to ignore the property change event fired by the wrapped
+	 * value model.
+	 * (We can't stop listening to the wrapped value model, because
+	 * if we are the only listener that could "deactivate" the wrapped
+	 * value model.)
+	 */
+	protected volatile boolean accepting;
+
+	/**
+	 * This is the trigger that indicates whether the buffered value
+	 * should be accepted or reset.
+	 */
+	protected final PropertyValueModel<Boolean> triggerModel;
+
+	/** This listens to the trigger model. */
+	protected final PropertyChangeListener triggerListener;
+
+	/**
+	 * This flag indicates whether our buffered value has been assigned
+	 * a value and is possibly out of sync with the wrapped value.
+	 */
+	protected volatile boolean buffering;
+
+
+	// ********** constructor/initialization **********
+
+	/**
+	 * Construct a buffered property value model with the specified wrapped
+	 * property value model and trigger model.
+	 */
+	// TODO wrap the value model in a CachingPVMWrapper and get rid of accepting flag
+	public BufferedModifiablePropertyValueModel(ModifiablePropertyValueModel<V> valueModel, PropertyValueModel<Boolean> triggerModel) {
+		super(valueModel);
+		if (triggerModel == null) {
+			throw new NullPointerException();
+		}
+		this.triggerModel = triggerModel;
+		this.bufferedValue = null;
+		this.buffering = false;
+		this.accepting = false;
+		this.triggerListener = this.buildTriggerListener();
+	}
+
+	protected PropertyChangeListener buildTriggerListener() {
+		return new TriggerListener();
+	}
+
+	protected class TriggerListener
+		extends PropertyChangeAdapter
+	{
+		@Override
+		public void propertyChanged(PropertyChangeEvent event) {
+			BufferedModifiablePropertyValueModel.this.triggerChanged(event);
+		}
+	}
+
+
+	// ********** value **********
+
+	/**
+	 * If we are currently "buffering" a value, return that;
+	 * otherwise, return the wrapped value.
+	 */
+	@Override
+	public V getValue() {
+		return this.buffering ? this.bufferedValue : this.valueModel.getValue();
+	}
+
+	/**
+	 * Assign the new value to our "buffered" value.
+	 * It will be pushed to the wrapped value model
+	 * when the trigger is "accepted".
+	 */
+	@Override
+	public void setValue(V value) {
+		if (this.buffering) {
+			if (this.valuesAreEqual(value, this.valueModel.getValue())) {
+				// the buffered value is being set back to the original value
+				this.reset();
+			} else {
+				// the buffered value is being changed
+				Object old = this.bufferedValue;
+				this.bufferedValue = value;
+				this.firePropertyChanged(VALUE, old, value);
+			}
+		} else {
+			if (this.valuesAreEqual(value, this.valueModel.getValue())) {
+				// the buffered value is being set to the same value as the original value - ignore
+			} else {
+				// the buffered value is being set for the first time
+				Object old = this.valueModel.getValue();
+				this.bufferedValue = value;
+				this.buffering = true;
+				this.firePropertyChanged(VALUE, old, value);
+			}
+		}
+	}
+
+
+	// ********** PropertyValueModelWrapper extensions **********
+
+	/**
+	 * Extend to engage the trigger model also.
+	 */
+	@Override
+	protected void engageModel() {
+		super.engageModel();
+		this.triggerModel.addPropertyChangeListener(VALUE, this.triggerListener);
+	}
+
+	/**
+	 * Extend to disengage the trigger model also.
+	 */
+	@Override
+	protected void disengageModel() {
+		this.triggerModel.removePropertyChangeListener(VALUE, this.triggerListener);
+		super.disengageModel();
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * If we are currently "accepting" the value (i.e passing it on to the
+	 * "wrapped" model), ignore change notifications, since we caused
+	 * them and our own listeners are already aware of the change.
+	 */
+	@Override
+	protected void wrappedValueChanged(PropertyChangeEvent event) {
+		if ( ! this.accepting) {
+			this.wrappedValueChanged_(event);
+		}
+	}
+
+	/**
+	 * If we have a "buffered" value, check whether the "wrapped" value has
+	 * changed to be the same as the "buffered" value. If it has, stop "buffering";
+	 * if not, do nothing.
+	 * If we do not yet have a "buffered" value, simply propagate the
+	 * change notification with the buffered model as the source.
+	 */
+	protected void wrappedValueChanged_(PropertyChangeEvent event) {
+		if (this.buffering) {
+			if (this.valuesAreEqual(event.getNewValue(), this.bufferedValue)) {
+				// the buffered value is being set back to the original value
+				this.reset();
+			} else {
+				this.handleChangeConflict(event);
+			}
+		} else {
+			this.firePropertyChanged(event.clone(this));
+		}
+	}
+
+	/**
+	 * By default, if we have a "buffered" value and the "wrapped" value changes,
+	 * we simply ignore the new "wrapped" value and simply overlay it with the
+	 * "buffered" value if it is "accepted". ("Last One In Wins" concurrency model)
+	 * Subclasses can override this method to change that behavior with a
+	 * different concurrency model. For example, you could drop the "buffered" value
+	 * and replace it with the new "wrapped" value, or you could throw an
+	 * exception.
+	 */
+	protected void handleChangeConflict(@SuppressWarnings("unused") PropertyChangeEvent event) {
+		// the default is to do nothing
+	}
+
+	protected void triggerChanged(PropertyChangeEvent event) {
+		this.triggerChanged(((Boolean) event.getNewValue()).booleanValue());
+	}
+
+	/**
+	 * The trigger changed:<ul>
+	 * <li>If it is now <code>true</code>, "accept" the buffered value and push
+	 *     it to the wrapped value model.
+	 * <li>If it is now <code>false</code>, "reset" the buffered value to its
+	 *     original value.
+	 * </ul>
+	 */
+	protected void triggerChanged(boolean triggerValue) {
+		// if nothing has been "buffered", we don't need to do anything:
+		// nothing needs to be passed through; nothing needs to be reset;
+		if (this.buffering) {
+			if (triggerValue) {
+				this.accept();
+			} else {
+				this.reset();
+			}
+		}
+	}
+
+	protected void accept() {
+		// set the accepting flag so we ignore any events
+		// fired by the wrapped value model
+		this.accepting = true;
+		try {
+			this.getValueModel().setValue(this.bufferedValue);
+		} finally {
+			this.bufferedValue = null;
+			this.buffering = false;
+			// clear the flag once the "accept" is complete
+			this.accepting = false;
+		}
+	}
+
+	protected void reset() {
+		// notify our listeners that our value has been reset
+		Object old = this.bufferedValue;
+		this.bufferedValue = null;
+		this.buffering = false;
+		this.firePropertyChanged(VALUE, old, this.valueModel.getValue());
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.getValue());
+	}
+
+
+	// ********** misc **********
+
+	/**
+	 * Return whether the buffered model is currently "buffering"
+	 * a value.
+	 */
+	public boolean isBuffering() {
+		return this.buffering;
+	}
+
+	/**
+	 * Our constructor accepts only a {@link ModifiablePropertyValueModel}{@code<T>}.
+	 */
+	@SuppressWarnings("unchecked")
+	protected ModifiablePropertyValueModel<V> getValueModel() {
+		return (ModifiablePropertyValueModel<V>) this.valueModel;
+	}
+
+
+	// ********** trigger **********
+
+	/**
+	 * <code>Trigger</code> is a special property value model that only maintains its
+	 * value (of <code>true</code> or <code>false</code>) during the change notification caused by
+	 * {@link #setValue(Object)}. In other words, a <code>Trigger</code>
+	 * only has a valid value when it is being set.
+	 */
+	public static class Trigger
+		extends SimplePropertyValueModel<Boolean>
+	{
+		/**
+		 * Construct a trigger with a null value.
+		 */
+		public Trigger() {
+			super();
+		}
+
+
+		// ********** ValueModel implementation **********
+
+		/**
+		 * Extend so that this method can only be invoked during
+		 * change notification triggered by {@link #setValue(Object)}.
+		 */
+		@Override
+		public Boolean getValue() {
+			if (this.value == null) {
+				throw new IllegalStateException("The method Trigger.getValue() may only be called during change notification.");
+			}
+			return this.value;
+		}
+
+		/**
+		 * Extend to reset the value to <code>null</code> once all the
+		 * listeners have been notified.
+		 */
+		@Override
+		public void setValue(Boolean value) {
+			super.setValue(value);
+			this.value = null;
+		}
+
+
+		// ********** convenience methods **********
+
+		/**
+		 * Set the trigger's value:<ul>
+		 * 	<li><code>true</code> indicates "accept"
+		 * 	<li><code>false</code> indicates "reset"
+		 * </ul>
+		 */
+		public void setValue(boolean value) {
+			this.setValue(Boolean.valueOf(value));
+		}
+
+		/**
+		 * Return the trigger's value:<ul>
+		 * 	<li><code>true</code> indicates "accept"
+		 * 	<li><code>false</code> indicates "reset"
+		 * </ul>
+		 * This method can only be invoked during change notification.
+		 */
+		public boolean booleanValue() {
+			return this.getValue().booleanValue();
+		}
+
+		/**
+		 * Accept the trigger (i.e. set its value to <code>true</code>).
+		 */
+		public void accept() {
+			this.setValue(true);
+		}
+
+		/**
+		 * Return whether the trigger has been accepted
+		 * (i.e. its value was changed to <code>true</code>).
+		 * This method can only be invoked during change notification.
+		 */
+		public boolean isAccepted() {
+			return this.booleanValue();
+		}
+
+		/**
+		 * Reset the trigger (i.e. set its value to <code>false</code>).
+		 */
+		public void reset() {
+			this.setValue(false);
+		}
+
+		/**
+		 * Return whether the trigger has been reset
+		 * (i.e. its value was changed to <code>false</code>).
+		 * This method can only be invoked during change notification.
+		 */
+		public boolean isReset() {
+			return ! this.booleanValue();
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CachingPropertyValueModelWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CachingPropertyValueModelWrapper.java
new file mode 100644
index 0000000..3046bf5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CachingPropertyValueModelWrapper.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+/**
+ * Wrap a writable property value model and cache its value so any changes
+ * made via the wrapper model will not fire any events to its listeners.
+ * Thus, a client can modify and listen to the wrapper model and not receive
+ * a change event when the client modifies the wrapper model; but any changes
+ * made by other clients (directly to the original model) will fire events
+ * to the client.
+ *
+ * @param <V> the type of the model's value
+ */
+public class CachingPropertyValueModelWrapper<V>
+	extends PropertyValueModelWrapper<V>
+	implements ModifiablePropertyValueModel<V>
+{
+	/**
+	 * Cache the value so we ignore any property change events
+	 * we ourselves trigger.
+	 */
+	protected volatile V value;
+
+
+	/**
+	 * Construct a caching writable property value model with the specified
+	 * nested writable property value model.
+	 */
+	public CachingPropertyValueModelWrapper(ModifiablePropertyValueModel<V> valueModel) {
+		super(valueModel);
+	}
+
+	/**
+	 * Return the cached value, since it is up-to-date.
+	 */
+	@Override
+	public V getValue() {
+		return this.value;
+	}
+
+	/**
+	 * Cache the new value so we ignore the resulting property change event.
+	 */
+	@Override
+	public void setValue(V value) {
+		this.value = value;
+		this.getValueModel().setValue(value);
+	}
+
+	@Override
+	protected void wrappedValueChanged(V oldValue, V newValue) {
+		V old = this.value;
+		// the new event will be suppressed if it is the result of a new value
+		// forwarded from this wrapper (i.e. 'old' and 'newValue' are equal)
+		this.firePropertyChanged(VALUE, old, this.value = newValue);
+	}
+
+	/**
+	 * Our constructors accept only a
+	 * {@link ModifiablePropertyValueModel}{@code<V>},
+	 * so this cast should be safe.
+	 */
+	@SuppressWarnings("unchecked")
+	protected ModifiablePropertyValueModel<V> getValueModel() {
+		return (ModifiablePropertyValueModel<V>) this.valueModel;
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.value);
+	}
+
+
+	// ********** listeners **********
+
+	/**
+	 * We have listeners, cache the nested value.
+	 */
+	@Override
+	protected void engageModel() {
+		super.engageModel();
+		this.value = this.valueModel.getValue();
+	}
+
+	/**
+	 * We have no more listeners, clear the cached value.
+	 */
+	@Override
+	protected void disengageModel() {
+		this.value = null;
+		super.disengageModel();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ChangePropertyValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ChangePropertyValueModelAdapter.java
new file mode 100644
index 0000000..5468ba6
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ChangePropertyValueModelAdapter.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.ChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.AbstractChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+
+/**
+ * This abstract class provides the infrastructure needed to wrap
+ * a model, "lazily" listen to it, and convert
+ * its change notifications into property value model change
+ * notifications.
+ * <p>
+ * Subclasses must implement:<ul>
+ * <li>{@link #buildValue()}<p>
+ *     to return the current property value, as derived from the
+ *     current model
+ * </ul>
+ * Subclasses might want to override the following methods
+ * to improve performance (by not recalculating the value, if possible):<ul>
+ * <li>{@link #modelChanged(ChangeEvent event)}
+ * <li>{@link #buildChangeListener()}
+ * </ul>
+ */
+public abstract class ChangePropertyValueModelAdapter<T>
+	extends AbstractPropertyValueModelAdapter<T>
+{
+	/** The wrapped model. */
+	protected final Model model;
+
+	/** A listener that allows us to sync with changes to the wrapped collection model. */
+	protected final ChangeListener modelListener;
+
+
+	// ********** constructor/initialization **********
+
+	/**
+	 * Construct a property value model with the specified wrapped model.
+	 */
+	protected ChangePropertyValueModelAdapter(Model model) {
+		super();
+		if (model == null) {
+			throw new NullPointerException();
+		}
+		this.model = model;
+		this.modelListener = this.buildChangeListener();
+	}
+
+	protected ChangeListener buildChangeListener() {
+		return new ModelListener();
+	}
+
+	protected class ModelListener
+		extends AbstractChangeListener
+	{
+		@Override
+		protected void modelChanged(ChangeEvent event) {
+			ChangePropertyValueModelAdapter.this.modelChanged(event);
+		}
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Start listening to the model.
+	 */
+	@Override
+	protected void engageModel_() {
+		this.model.addChangeListener(this.modelListener);
+	}
+
+	/**
+	 * Stop listening to the model.
+	 */
+	@Override
+	protected void disengageModel_() {
+		this.model.removeChangeListener(this.modelListener);
+	}
+
+
+	// ********** change support **********
+
+	/**
+	 * The wrapped model has changed;
+	 * propagate the change notification appropriately.
+	 */
+	protected void modelChanged(@SuppressWarnings("unused") ChangeEvent event) {
+		// by default, simply recalculate the value and fire an event
+		this.propertyChanged();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionAspectAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionAspectAdapter.java
new file mode 100644
index 0000000..6dc631f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionAspectAdapter.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Collection;
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+
+/**
+ * This extension of {@link AspectCollectionValueModelAdapter} provides
+ * basic collection change support.
+ * This converts a set of one or more collections into
+ * a single {@link #VALUES} collection.
+ * <p>
+ * The typical subclass will override the following methods (see the descriptions
+ * in {@link AspectCollectionValueModelAdapter}):<ul>
+ * <li>{@link #getIterable()} - preferred
+ * <li>{@link #size_()} - semi-preferred
+ * <li>{@link #iterator_()}
+ * <li>{@link #iterator()}
+ * <li>{@link #size()}
+ * </ul>
+ *
+ * @param <S> the type of the adapter's subject
+ * @param <E> the type of the adapter's collection's elements
+ */
+public abstract class CollectionAspectAdapter<S extends Model, E>
+	extends AspectCollectionValueModelAdapter<S, E>
+{
+	/**
+	 * The name of the subject's collections that we use for the value.
+	 */
+	protected final String[] aspectNames;
+		protected static final String[] EMPTY_ASPECT_NAMES = new String[0];
+
+	/** A listener that listens to the subject's collection aspects. */
+	protected final CollectionChangeListener aspectChangeListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a collection aspect adapter for the specified subject
+	 * and collection aspect.
+	 */
+	protected CollectionAspectAdapter(String aspectName, S subject) {
+		this(new String[] {aspectName}, subject);
+	}
+
+	/**
+	 * Construct a collection aspect adapter for the specified subject
+	 * and collection aspects.
+	 */
+	protected CollectionAspectAdapter(String[] aspectNames, S subject) {
+		this(new StaticPropertyValueModel<S>(subject), aspectNames);
+	}
+
+	/**
+	 * Construct a collection aspect adapter for the specified subject model
+	 * and collection apects.
+	 */
+	protected CollectionAspectAdapter(PropertyValueModel<? extends S> subjectModel, String... aspectNames) {
+		super(subjectModel);
+		if (aspectNames == null) {
+			throw new NullPointerException();
+		}
+		this.aspectNames = aspectNames;
+		this.aspectChangeListener = this.buildAspectChangeListener();
+	}
+
+	/**
+	 * Construct a collection aspect adapter for the specified subject holder
+	 * and collection aspects.
+	 */
+	protected CollectionAspectAdapter(PropertyValueModel<? extends S> subjectModel, Collection<String> aspectNames) {
+		this(subjectModel, aspectNames.toArray(new String[aspectNames.size()]));
+	}
+
+	/**
+	 * Construct a collection aspect adapter for an "unchanging" collection in
+	 * the specified subject. This is useful for a collection aspect that does not
+	 * change for a particular subject; but the subject will change, resulting in
+	 * a new collection.
+	 */
+	protected CollectionAspectAdapter(PropertyValueModel<? extends S> subjectModel) {
+		this(subjectModel, EMPTY_ASPECT_NAMES);
+	}
+
+
+	// ********** initialization **********
+
+	protected CollectionChangeListener buildAspectChangeListener() {
+		return new AspectChangeListener();
+	}
+
+	/**
+	 * Transform the subject's collection change events into {@link #VALUES}
+	 * collection change events
+	 */
+	protected class AspectChangeListener
+		extends CollectionChangeAdapter
+	{
+		@Override
+		public void itemsAdded(CollectionAddEvent event) {
+			CollectionAspectAdapter.this.aspectItemsAdded(event);
+		}
+		@Override
+		public void itemsRemoved(CollectionRemoveEvent event) {
+			CollectionAspectAdapter.this.aspectItemsRemoved(event);
+		}
+		@Override
+		public void collectionCleared(CollectionClearEvent event) {
+			CollectionAspectAdapter.this.aspectCollectionCleared(event);
+		}
+		@Override
+		public void collectionChanged(CollectionChangeEvent event) {
+			CollectionAspectAdapter.this.aspectCollectionChanged(event);
+		}
+	}
+
+
+	// ********** AspectAdapter implementation **********
+
+	@Override
+	protected void engageSubject_() {
+    	for (String collectionName : this.aspectNames) {
+			this.subject.addCollectionChangeListener(collectionName, this.aspectChangeListener);
+		}
+	}
+
+	@Override
+	protected void disengageSubject_() {
+    	for (String collectionName : this.aspectNames) {
+			this.subject.removeCollectionChangeListener(collectionName, this.aspectChangeListener);
+		}
+	}
+
+
+	// ********** events **********
+
+	protected void aspectItemsAdded(CollectionAddEvent event) {
+		this.fireItemsAdded(event.clone(this, VALUES));
+	}
+
+	protected void aspectItemsRemoved(CollectionRemoveEvent event) {
+		this.fireItemsRemoved(event.clone(this, VALUES));
+	}
+
+	protected void aspectCollectionCleared(CollectionClearEvent event) {
+		this.fireCollectionCleared(event.clone(this, VALUES));
+	}
+
+	protected void aspectCollectionChanged(CollectionChangeEvent event) {
+		this.fireCollectionChanged(event.clone(this, VALUES));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionListValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionListValueModelAdapter.java
new file mode 100644
index 0000000..6cc4122
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionListValueModelAdapter.java
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyListIterator;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+
+/**
+ * An adapter that allows us to make a {@link CollectionValueModel} behave like
+ * a read-only {@link ListValueModel}, sorta.
+ * <p>
+ * To maintain a reasonably consistent appearance to client code, we
+ * keep an internal list somewhat in sync with the wrapped collection.
+ * <p>
+ * <strong>NB:</strong> Since we only listen to the wrapped collection when we have
+ * listeners ourselves and we can only stay in sync with the wrapped
+ * collection while we are listening to it, results to various methods
+ * (e.g. {@link #size()}, {@link #get(int)}) will be unpredictable whenever
+ * we do not have any listeners. This should not be too painful since,
+ * most likely, clients will also be listeners.
+ */
+@SuppressWarnings("nls")
+public class CollectionListValueModelAdapter<E>
+	extends AbstractListValueModel
+	implements ListValueModel<E>
+{
+	/** The wrapped collection value model. */
+	protected final CollectionValueModel<? extends E> collectionHolder;
+
+	/** A listener that forwards any events fired by the collection holder. */
+	protected final CollectionChangeListener collectionChangeListener;
+
+	/**
+	 * Our internal list, which holds the same elements as
+	 * the wrapped collection, but keeps them in order.
+	 */
+	// we declare this an ArrayList so we can use #clone() and #ensureCapacity(int)
+	protected final ArrayList<E> list;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Wrap the specified collection value model.
+	 */
+	public CollectionListValueModelAdapter(CollectionValueModel<? extends E> collectionHolder) {
+		super();
+		if (collectionHolder == null) {
+			throw new NullPointerException();
+		}
+		this.collectionHolder = collectionHolder;
+		this.collectionChangeListener = this.buildCollectionChangeListener();
+		this.list = new ArrayList<E>(collectionHolder.size());
+		// postpone building the list and listening to the underlying collection
+		// until we have listeners ourselves...
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * The wrapped collection has changed, forward an equivalent
+	 * list change event to our listeners.
+	 */
+	protected CollectionChangeListener buildCollectionChangeListener() {
+		return new CollectionChangeListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent event) {
+				CollectionListValueModelAdapter.this.itemsAdded(event);
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent event) {
+				CollectionListValueModelAdapter.this.itemsRemoved(event);
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent event) {
+				CollectionListValueModelAdapter.this.collectionCleared(event);
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent event) {
+				CollectionListValueModelAdapter.this.collectionChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "collection change listener";
+			}
+		};
+	}
+
+
+	// ********** ListValueModel implementation **********
+
+	@Override
+	public Iterator<E> iterator() {
+		return this.listIterator();
+	}
+
+	@Override
+	public ListIterator<E> listIterator() {
+		return new ReadOnlyListIterator<E>(this.list);
+	}
+
+	@Override
+	public E get(int index) {
+		return this.list.get(index);
+	}
+
+	@Override
+	public int size() {
+		return this.list.size();
+	}
+
+	@Override
+	public Object[] toArray() {
+		return this.list.toArray();
+	}
+
+
+	// ********** behavior **********
+
+	@Override
+	protected void engageModel() {
+		this.collectionHolder.addCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener);
+		// sync our list *after* we start listening to the collection model,
+		// since its value might change when a listener is added
+		this.buildList();
+	}
+
+	@Override
+	protected void disengageModel() {
+		this.collectionHolder.removeCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener);
+		// clear out the list when we are not listening to the collection holder
+		this.list.clear();
+	}
+
+	protected void buildList() {
+		// if the new collection is empty, do nothing
+		int size = this.collectionHolder.size();
+		if (size != 0) {
+			this.buildList(size);
+		}
+	}
+
+	protected void buildList(int size) {
+		this.list.ensureCapacity(size);
+		for (E each : this.collectionHolder) {
+			this.list.add(each);
+		}
+	}
+
+	protected void itemsAdded(CollectionAddEvent event) {
+		this.addItemsToList(this.indexToAddItems(), this.getItems(event), this.list, LIST_VALUES);
+	}
+
+	protected int indexToAddItems() {
+		return this.list.size();
+	}
+
+	// minimize scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getItems(CollectionAddEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+	protected void itemsRemoved(CollectionRemoveEvent event) {
+		this.removeItemsFromList(this.getItems(event), this.list, LIST_VALUES);
+	}
+
+	// minimize scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getItems(CollectionRemoveEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+	protected void collectionCleared(@SuppressWarnings("unused") CollectionClearEvent event) {
+		this.clearList(this.list, LIST_VALUES);
+	}
+
+	/**
+	 * synchronize our internal list with the wrapped collection
+	 * and fire the appropriate events
+	 */
+	protected void collectionChanged(@SuppressWarnings("unused") CollectionChangeEvent event) {
+		int size = this.collectionHolder.size();
+		if (size == 0) {
+			if (this.list.isEmpty()) {
+				// no change
+			} else {
+				this.clearList(this.list, LIST_VALUES);
+			}
+		} else {
+			if (this.list.isEmpty()) {
+				this.buildList(size);
+				this.fireItemsAdded(LIST_VALUES, 0, this.list);
+			} else {
+				this.synchronizeList(this.buildSyncList(), this.list, LIST_VALUES);
+			}
+		}
+	}
+
+	protected Iterable<? extends E> buildSyncList() {
+		return this.collectionHolder;
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.list);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionPropertyValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionPropertyValueModelAdapter.java
new file mode 100644
index 0000000..8090e86
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionPropertyValueModelAdapter.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+
+/**
+ * This abstract class provides the infrastructure needed to wrap
+ * a collection value model, "lazily" listen to it, and convert
+ * its change notifications into property value model change
+ * notifications.
+ * <p>
+ * Subclasses must override:<ul>
+ * <li>{@link #buildValue()}<p>
+ *     to return the current property value, as derived from the
+ *     current collection value
+ * </ul>
+ * Subclasses might want to override the following methods
+ * to improve performance (by not recalculating the value, if possible):<ul>
+ * <li>{@link #itemsAdded(CollectionAddEvent event)}
+ * <li>{@link #itemsAdded(Iterable)}
+ * <li>{@link #itemsRemoved(CollectionRemoveEvent event)}
+ * <li>{@link #itemsRemoved(Iterable)}
+ * <li>{@link #collectionCleared(CollectionClearEvent event)}
+ * <li>{@link #collectionChanged(CollectionChangeEvent event)}
+ * </ul>
+ *
+ * @param <V> the type of the model's value
+ * @param <E> the type of the wrapped collection value model's elements
+ */
+public abstract class CollectionPropertyValueModelAdapter<V, E>
+	extends AbstractPropertyValueModelAdapter<V>
+{
+	/** The wrapped collection value model. */
+	protected final CollectionValueModel<? extends E> collectionModel;
+
+	/** A listener that allows us to sync with changes to the wrapped collection model. */
+	protected final CollectionChangeListener collectionListener;
+
+
+	// ********** constructor/initialization **********
+
+	/**
+	 * Construct a property value model with the specified wrapped
+	 * collection value model.
+	 */
+	protected CollectionPropertyValueModelAdapter(CollectionValueModel<? extends E> collectionModel) {
+		super();
+		if (collectionModel == null) {
+			throw new NullPointerException();
+		}
+		this.collectionModel = collectionModel;
+		this.collectionListener = this.buildCollectionListener();
+	}
+
+	protected CollectionChangeListener buildCollectionListener() {
+		return new CollectionListener();
+	}
+
+	/**
+	 * Straightforward callbacks to the adapter.
+	 */
+	protected class CollectionListener
+		extends CollectionChangeAdapter
+	{
+		@Override
+		public void itemsAdded(CollectionAddEvent event) {
+			CollectionPropertyValueModelAdapter.this.itemsAdded(event);
+		}
+		@Override
+		public void itemsRemoved(CollectionRemoveEvent event) {
+			CollectionPropertyValueModelAdapter.this.itemsRemoved(event);
+		}
+		@Override
+		public void collectionCleared(CollectionClearEvent event) {
+			CollectionPropertyValueModelAdapter.this.collectionCleared(event);
+		}
+		@Override
+		public void collectionChanged(CollectionChangeEvent event) {
+			CollectionPropertyValueModelAdapter.this.collectionChanged(event);
+		}
+	}
+
+
+	// ********** listener **********
+
+	/**
+	 * Start listening to the collection holder.
+	 */
+	@Override
+	protected void engageModel_() {
+		this.collectionModel.addCollectionChangeListener(CollectionValueModel.VALUES, this.collectionListener);
+	}
+
+	/**
+	 * Stop listening to the collection holder.
+	 */
+	@Override
+	protected void disengageModel_() {
+		this.collectionModel.removeCollectionChangeListener(CollectionValueModel.VALUES, this.collectionListener);
+	}
+
+
+	// ********** collection change support **********
+
+	/**
+	 * Items were added to the wrapped collection holder;
+	 * propagate the change notification appropriately.
+	 */
+	protected void itemsAdded(CollectionAddEvent event) {
+		@SuppressWarnings("unchecked")
+		Iterable<E> items = (Iterable<E>) event.getItems();
+		this.itemsAdded(items);
+	}
+
+	/**
+	 * The specified items were added to the wrapped collection holder;
+	 * propagate the change notification appropriately.
+	 */
+	protected void itemsAdded(@SuppressWarnings("unused") Iterable<E> items) {
+		// by default, simply recalculate the value and fire an event
+		this.propertyChanged();
+	}
+
+	/**
+	 * Items were removed from the wrapped collection holder;
+	 * propagate the change notification appropriately.
+	 */
+	protected void itemsRemoved(CollectionRemoveEvent event) {
+		@SuppressWarnings("unchecked")
+		Iterable<E> items = (Iterable<E>) event.getItems();
+		this.itemsRemoved(items);
+	}
+
+	/**
+	 * The specified items were removed from the wrapped collection holder;
+	 * propagate the change notification appropriately.
+	 */
+	protected void itemsRemoved(@SuppressWarnings("unused") Iterable<E> items) {
+		// by default, simply recalculate the value and fire an event if necessary
+		this.propertyChanged();
+	}
+
+	/**
+	 * The wrapped collection holder was cleared;
+	 * propagate the change notification appropriately.
+	 */
+	protected void collectionCleared(@SuppressWarnings("unused") CollectionClearEvent event) {
+		// by default, simply recalculate the value and fire an event if necessary
+		this.propertyChanged();
+	}
+
+	/**
+	 * The value of the wrapped collection holder has changed;
+	 * propagate the change notification appropriately.
+	 */
+	protected void collectionChanged(@SuppressWarnings("unused") CollectionChangeEvent event) {
+		// by default, simply recalculate the value and fire an event if necessary
+		this.propertyChanged();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionValueModel.java
new file mode 100644
index 0000000..a62e759
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionValueModel.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.model.Model;
+
+/**
+ * Interface used to abstract collection accessing and
+ * change notification and make it more pluggable.
+ * <p>
+ * 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.
+ *
+ * @param <E> the type of values held by the model
+ */
+@SuppressWarnings("nls")
+public interface CollectionValueModel<E>
+	extends Model, Iterable<E>
+{
+
+	/**
+	 * Return the collection's values.
+	 */
+	@Override
+	Iterator<E> iterator();
+		String VALUES = "values";
+
+	/**
+	 * Return the size of the collection.
+	 */
+	int size();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionValueModelWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionValueModelWrapper.java
new file mode 100644
index 0000000..bc1e5bc
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CollectionValueModelWrapper.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+
+/**
+ * This abstract class provides the infrastructure needed to wrap
+ * another collection value model, "lazily" listen to it, and propagate
+ * its change notifications. Subclasses must implement the appropriate
+ * {@link CollectionValueModel}.
+ *
+ * @param <E> the type of elements held by the model
+ */
+@SuppressWarnings("nls")
+public abstract class CollectionValueModelWrapper<E>
+	extends AbstractCollectionValueModel
+{
+	/** The wrapped collection value model. */
+	protected final CollectionValueModel<? extends E> collectionModel;
+
+	/** A listener that allows us to sync with changes to the wrapped collection model. */
+	protected final CollectionChangeListener collectionChangeListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a collection value model with the specified wrapped
+	 * collection value model.
+	 */
+	protected CollectionValueModelWrapper(CollectionValueModel<? extends E> collectionModel) {
+		super();
+		if (collectionModel == null) {
+			throw new NullPointerException();
+		}
+		this.collectionModel = collectionModel;
+		this.collectionChangeListener = this.buildCollectionChangeListener();
+	}
+
+
+	// ********** initialization **********
+
+	protected CollectionChangeListener buildCollectionChangeListener() {
+		return new CollectionChangeListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent event) {
+				CollectionValueModelWrapper.this.itemsAdded(event);
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent event) {
+				CollectionValueModelWrapper.this.itemsRemoved(event);
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent event) {
+				CollectionValueModelWrapper.this.collectionCleared(event);
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent event) {
+				CollectionValueModelWrapper.this.collectionChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "collection change listener";
+			}
+		};
+	}
+
+
+	// ********** AbstractCollectionValueModel implementation **********
+
+	/**
+	 * Start listening to the collection holder.
+	 */
+	@Override
+	protected void engageModel() {
+		this.collectionModel.addCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener);
+	}
+
+	/**
+	 * Stop listening to the collection holder.
+	 */
+	@Override
+	protected void disengageModel() {
+		this.collectionModel.removeCollectionChangeListener(CollectionValueModel.VALUES, this.collectionChangeListener);
+	}
+
+
+	// ********** helper methods **********
+
+	// minimize scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getItems(CollectionAddEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+	// minimize scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getItems(CollectionRemoveEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+
+	// ********** collection change support **********
+
+	/**
+	 * Items were added to the wrapped collection holder;
+	 * propagate the change notification appropriately.
+	 */
+	protected abstract void itemsAdded(CollectionAddEvent event);
+
+	/**
+	 * Items were removed from the wrapped collection holder;
+	 * propagate the change notification appropriately.
+	 */
+	protected abstract void itemsRemoved(CollectionRemoveEvent event);
+
+	/**
+	 * The wrapped collection holder was cleared;
+	 * propagate the change notification appropriately.
+	 */
+	protected abstract void collectionCleared(CollectionClearEvent event);
+
+	/**
+	 * The value of the wrapped collection holder has changed;
+	 * propagate the change notification appropriately.
+	 */
+	protected abstract void collectionChanged(CollectionChangeEvent event);
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CompositeBooleanPropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CompositeBooleanPropertyValueModel.java
new file mode 100644
index 0000000..8678deb
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CompositeBooleanPropertyValueModel.java
@@ -0,0 +1,358 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Collection;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterable.TransformationIterable;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * A <code>CompositeBooleanPropertyValueModel</code> adapts a
+ * {@link CollectionValueModel} holding boolean {@link PropertyValueModel}s
+ * to a single boolean {@link PropertyValueModel}. The composite value is
+ * determined by the {@link CompositeBooleanPropertyValueModel.Adapter} provided
+ * at construction. Typically the composite will be either an AND or an OR of
+ * all the boolean values.
+ * <p>
+ * If there are <em>no</em> boolean {@link PropertyValueModel}s, the composite
+ * will return its default value; which, by default, is <code>null</code>.
+ * <p>
+ * <strong>NB:</strong> None of the wrapped boolean models can return a
+ * <code>null</code> value or this class will throw an exception. The assumption
+ * is that all the wrapped boolean models are configured with "default" values
+ * that determine the model's value (TRUE or FALSE) when <code>null</code>.
+ */
+@SuppressWarnings("nls")
+public class CompositeBooleanPropertyValueModel
+	extends CompositePropertyValueModel<Boolean, Boolean>
+{
+	/**
+	 * Calculation of the model's value is delegated to this adapter.
+	 */
+	protected final Adapter adapter;
+
+	/**
+	 * The default setting for the composite boolean property value model;
+	 * for when the underlying collection model is empty.
+	 * The default [default value] is <code>null</code>.
+	 */
+	private final Boolean defaultValue;
+
+
+	// ********** AND factory methods **********
+
+	/**
+	 * Construct a boolean property value model that is a composite AND of the
+	 * specified boolean property value models; i.e. the model's value is true
+	 * if all the contained models are true, otherwise its value is false.
+	 * The model's default value, when it contains no nested models, is
+	 * <code>null</code>.
+	 */
+	public static CompositeBooleanPropertyValueModel and(PropertyValueModel<Boolean>... array) {
+		return new CompositeBooleanPropertyValueModel(AND_ADAPTER, array);
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite AND of the
+	 * specified boolean property value models; i.e. the model's value is true
+	 * if all the contained models are true, otherwise its value is false.
+	 * When the model contains no nested models, its value will be the
+	 * specified default.
+	 */
+	public static CompositeBooleanPropertyValueModel and(Boolean defaultValue, PropertyValueModel<Boolean>... array) {
+		return new CompositeBooleanPropertyValueModel(AND_ADAPTER, defaultValue, array);
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite AND of the
+	 * specified boolean property value models; i.e. the model's value is true
+	 * if all the contained models are true, otherwise its value is false.
+	 * The model's default value, when it contains no nested models, is
+	 * <code>null</code>.
+	 */
+	public static <E extends PropertyValueModel<Boolean>> CompositeBooleanPropertyValueModel and(Collection<E> collection) {
+		return new CompositeBooleanPropertyValueModel(AND_ADAPTER, collection);
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite AND of the
+	 * specified boolean property value models; i.e. the model's value is true
+	 * if all the contained models are true, otherwise its value is false.
+	 * When the model contains no nested models, its value will be the
+	 * specified default.
+	 */
+	public static <E extends PropertyValueModel<Boolean>> CompositeBooleanPropertyValueModel and(Boolean defaultValue, Collection<E> collection) {
+		return new CompositeBooleanPropertyValueModel(AND_ADAPTER, defaultValue, collection);
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite AND of the
+	 * specified boolean property value models; i.e. the model's value is true
+	 * if all the contained models are true, otherwise its value is false.
+	 * The model's default value, when it contains no nested models, is
+	 * <code>null</code>.
+	 */
+	public static CompositeBooleanPropertyValueModel and(CollectionValueModel<? extends PropertyValueModel<Boolean>> collectionModel) {
+		return new CompositeBooleanPropertyValueModel(AND_ADAPTER, collectionModel);
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite AND of the
+	 * specified boolean property value models; i.e. the model's value is true
+	 * if all the contained models are true, otherwise its value is false.
+	 * When the model contains no nested models, its value will be the
+	 * specified default.
+	 */
+	public static CompositeBooleanPropertyValueModel and(Boolean defaultValue, CollectionValueModel<? extends PropertyValueModel<Boolean>> collectionModel) {
+		return new CompositeBooleanPropertyValueModel(AND_ADAPTER, defaultValue, collectionModel);
+	}
+
+
+	// ********** OR factory methods **********
+
+	/**
+	 * Construct a boolean property value model that is a composite OR of the
+	 * specified boolean property value models; i.e. the model's value is false
+	 * if all the contained models are false, otherwise its value is true.
+	 * The model's default value, when it contains no nested models, is
+	 * <code>null</code>.
+	 */
+	public static CompositeBooleanPropertyValueModel or(PropertyValueModel<Boolean>... array) {
+		return new CompositeBooleanPropertyValueModel(OR_ADAPTER, array);
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite OR of the
+	 * specified boolean property value models; i.e. the model's value is false
+	 * if all the contained models are false, otherwise its value is true.
+	 * When the model contains no nested models, its value will be the
+	 * specified default.
+	 */
+	public static CompositeBooleanPropertyValueModel or(Boolean defaultValue, PropertyValueModel<Boolean>... array) {
+		return new CompositeBooleanPropertyValueModel(OR_ADAPTER, defaultValue, array);
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite OR of the
+	 * specified boolean property value models; i.e. the model's value is false
+	 * if all the contained models are false, otherwise its value is true.
+	 * The model's default value, when it contains no nested models, is
+	 * <code>null</code>.
+	 */
+	public static <E extends PropertyValueModel<Boolean>> CompositeBooleanPropertyValueModel or(Collection<E> collection) {
+		return new CompositeBooleanPropertyValueModel(OR_ADAPTER, collection);
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite OR of the
+	 * specified boolean property value models; i.e. the model's value is false
+	 * if all the contained models are false, otherwise its value is true.
+	 * When the model contains no nested models, its value will be the
+	 * specified default.
+	 */
+	public static <E extends PropertyValueModel<Boolean>> CompositeBooleanPropertyValueModel or(Boolean defaultValue, Collection<E> collection) {
+		return new CompositeBooleanPropertyValueModel(OR_ADAPTER, defaultValue, collection);
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite OR of the
+	 * specified boolean property value models; i.e. the model's value is false
+	 * if all the contained models are false, otherwise its value is true.
+	 * The model's default value, when it contains no nested models, is
+	 * <code>null</code>.
+	 */
+	public static CompositeBooleanPropertyValueModel or(CollectionValueModel<? extends PropertyValueModel<Boolean>> collectionModel) {
+		return new CompositeBooleanPropertyValueModel(OR_ADAPTER, collectionModel);
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite OR of the
+	 * specified boolean property value models; i.e. the model's value is false
+	 * if all the contained models are false, otherwise its value is true.
+	 * When the model contains no nested models, its value will be the
+	 * specified default.
+	 */
+	public static CompositeBooleanPropertyValueModel or(Boolean defaultValue, CollectionValueModel<? extends PropertyValueModel<Boolean>> collectionModel) {
+		return new CompositeBooleanPropertyValueModel(OR_ADAPTER, defaultValue, collectionModel);
+	}
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a boolean property value model that is a composite of the specified
+	 * boolean property value models, as defined by the specified adapter.
+	 * The model's default value, when it contains no nested models, is
+	 * <code>null</code>.
+	 */
+	public CompositeBooleanPropertyValueModel(Adapter adapter, PropertyValueModel<Boolean>... array) {
+		this(adapter, null, array);
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite of the specified
+	 * boolean property value models, as defined by the specified adapter.
+	 * When the model contains no nested models, its value will be the
+	 * specified default.
+	 */
+	public CompositeBooleanPropertyValueModel(Adapter adapter, Boolean defaultValue, PropertyValueModel<Boolean>... array) {
+		super(array);
+		if (adapter == null) {
+			throw new NullPointerException();
+		}
+		this.adapter = adapter;
+		this.defaultValue = defaultValue;
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite of the specified
+	 * boolean property value models, as defined by the specified adapter.
+	 * The model's default value, when it contains no nested models, is
+	 * <code>null</code>.
+	 */
+	public <E extends PropertyValueModel<Boolean>> CompositeBooleanPropertyValueModel(Adapter adapter, Collection<E> collection) {
+		this(adapter, null, collection);
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite of the specified
+	 * boolean property value models, as defined by the specified adapter.
+	 * When the model contains no nested models, its value will be the
+	 * specified default.
+	 */
+	public <E extends PropertyValueModel<Boolean>> CompositeBooleanPropertyValueModel(Adapter adapter, Boolean defaultValue, Collection<E> collection) {
+		super(collection);
+		if (adapter == null) {
+			throw new NullPointerException();
+		}
+		this.adapter = adapter;
+		this.defaultValue = defaultValue;
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite of the specified
+	 * boolean property value models, as defined by the specified adapter.
+	 * The model's default value, when it contains no nested models, is
+	 * <code>null</code>.
+	 */
+	public CompositeBooleanPropertyValueModel(Adapter adapter, CollectionValueModel<? extends PropertyValueModel<Boolean>> collectionModel) {
+		this(adapter, null, collectionModel);
+	}
+
+	/**
+	 * Construct a boolean property value model that is a composite of the specified
+	 * boolean property value models, as defined by the specified adapter.
+	 * When the model contains no nested models, its value will be the
+	 * specified default.
+	 */
+	public CompositeBooleanPropertyValueModel(Adapter adapter, Boolean defaultValue, CollectionValueModel<? extends PropertyValueModel<Boolean>> collectionModel) {
+		super(collectionModel);
+		if (adapter == null) {
+			throw new NullPointerException();
+		}
+		this.adapter = adapter;
+		this.defaultValue = defaultValue;
+	}
+
+
+	// ********** implementation **********
+
+	/**
+	 * Return the {@link #defaultValue} if the collection is empty;
+	 * otherwise delegate to the {@link #adapter}.
+	 */
+	@Override
+	protected Boolean buildValue() {
+		return (this.collectionModel.size() == 0) ? this.defaultValue : this.buildValue_();
+	}
+
+	protected Boolean buildValue_() {
+		return this.adapter.buildValue(this.getBooleans());
+	}
+
+	protected Iterable<Boolean> getBooleans() {
+		return new TransformationIterable<PropertyValueModel<? extends Boolean>, Boolean>(this.collectionModel, BOOLEAN_TRANSFORMER);
+	}
+
+	protected static final Transformer<PropertyValueModel<? extends Boolean>, Boolean> BOOLEAN_TRANSFORMER = new BooleanTransformer();
+
+	protected static class BooleanTransformer
+		implements Transformer<PropertyValueModel<? extends Boolean>, Boolean>
+	{
+		@Override
+		public Boolean transform(PropertyValueModel<? extends Boolean> booleanModel) {
+			return booleanModel.getValue();
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+	}
+
+
+	// ********** adapter **********
+
+	/**
+	 * This adapter allows the {@link CompositeBooleanPropertyValueModel} to be
+	 * pluggable.
+	 */
+	public interface Adapter {
+		/**
+		 * Return the composite boolean value of the specified collection
+		 * of booleans.
+		 */
+		Boolean buildValue(Iterable<Boolean> booleans);
+	}
+
+	/**
+	 * Return <code>true</code> if all the booleans are <code>true</code>;
+	 * otherwise return <code>false</code>.
+	 */
+	public static final Adapter AND_ADAPTER = new Adapter() {
+		@Override
+		public Boolean buildValue(Iterable<Boolean> booleans) {
+			for (Boolean b : booleans) {
+				if ( ! b.booleanValue()) {
+					return Boolean.FALSE;
+				}
+			}
+			return Boolean.TRUE;
+		}
+		@Override
+		public String toString() {
+			return "AND_ADAPTER";
+		}
+	};
+
+	/**
+	 * Return <code>false</code> if all the booleans are <code>false</code>;
+	 * otherwise return <code>true</code>.
+	 */
+	public static final Adapter OR_ADAPTER = new Adapter() {
+		@Override
+		public Boolean buildValue(Iterable<Boolean> booleans) {
+			for (Boolean b : booleans) {
+				if (b.booleanValue()) {
+					return Boolean.TRUE;
+				}
+			}
+			return Boolean.FALSE;
+		}
+		@Override
+		public String toString() {
+			return "OR_ADAPTER";
+		}
+	};
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CompositeCollectionValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CompositeCollectionValueModel.java
new file mode 100644
index 0000000..24b860f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CompositeCollectionValueModel.java
@@ -0,0 +1,428 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.NullList;
+import org.eclipse.persistence.tools.utility.iterable.CompositeIterable;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * A <code>CompositeCollectionValueModel</code> wraps another
+ * {@link CollectionValueModel} and uses a {@link Transformer}
+ * to convert each item in the wrapped collection to yet another
+ * {@link CollectionValueModel}. This composite collection contains
+ * the combined items from all these component collections.
+ * <p>
+ * <strong>NB:</strong> The wrapped collection must be an "identity set" that does not
+ * contain the same item twice or this class will throw an exception.
+ * <p>
+ * Terminology:<ul>
+ * <li><em>sources</em> - the items in the wrapped collection value model; these
+ *    are converted into component CVMs by the transformer
+ * <li><em>component CVMs</em> - the component collection value models that are combined
+ *    by this composite collection value model
+ * <li><em>items</em> - the items held by the component CVMs
+ * </ul>
+ *
+ * @param <E1> the type of items held by the wrapped collection model;
+ *     each of these is transformed (by the {@link #transformer}) into a
+ *     collection model of <code>E2</code>s
+ * @param <E2> the type of items held by the composite collection model
+ */
+@SuppressWarnings("nls")
+public class CompositeCollectionValueModel<E1, E2>
+	extends CollectionValueModelWrapper<E1>
+	implements CollectionValueModel<E2>
+{
+	/**
+	 * This is the (optional) user-supplied object that transforms
+	 * the items in the wrapped collection to collection value models.
+	 */
+	private final Transformer<E1, ? extends CollectionValueModel<? extends E2>> transformer;
+
+	/**
+	 * Cache of the component collection value models that
+	 * were generated by the transformer; keyed by the item
+	 * in the wrapped collection that was passed to the transformer.
+	 */
+	private final IdentityHashMap<E1, CollectionValueModel<? extends E2>> componentCVMs =
+			new IdentityHashMap<E1, CollectionValueModel<? extends E2>>();
+
+	/**
+	 * Cache of the collections corresponding to the component
+	 * collection value models above; keyed by the component
+	 * collection value models.
+	 * Use {@link ArrayList}s so we can use {@link ArrayList}-specific methods
+	 * (e.g. {@link ArrayList#clone()} and {@link ArrayList#ensureCapacity(int)}).
+	 */
+	private final IdentityHashMap<CollectionValueModel<? extends E2>, ArrayList<E2>> collections =
+			new IdentityHashMap<CollectionValueModel<? extends E2>, ArrayList<E2>>();
+
+	/** Listener that listens to all the component collection value models. */
+	private final CollectionChangeListener componentCVMListener;
+
+	/** Cache the size of the composite collection. */
+	private int size;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a collection value model with the specified wrapped
+	 * list value model. The specified list model already contains other
+	 * collection value models.
+	 */
+	public static <E1 extends CollectionValueModel<? extends E2>, E2> CompositeCollectionValueModel<E1, E2> forModels(ListValueModel<E1> listModel) {
+		return forModels(new ListCollectionValueModelAdapter<E1>(listModel));
+	}
+
+	/**
+	 * Construct a collection value model with the specified wrapped collection.
+	 */
+	public static <E1 extends CollectionValueModel<? extends E2>, E2> CompositeCollectionValueModel<E1, E2> forModels(Collection<E1> collection) {
+		return forModels(new StaticCollectionValueModel<E1>(collection));
+	}
+
+	/**
+	 * Construct a collection value model with the specified wrapped collection.
+	 */
+	public static <E1 extends CollectionValueModel<? extends E2>, E2> CompositeCollectionValueModel<E1, E2> forModels(E1... collection) {
+		return forModels(new StaticCollectionValueModel<E1>(collection));
+	}
+
+	/**
+	 * Construct a collection value model with the specified wrapped
+	 * collection value model. The specified collection
+	 * model already contains other collection value models.
+	 */
+	public static <E1 extends CollectionValueModel<? extends E2>, E2> CompositeCollectionValueModel<E1, E2> forModels(CollectionValueModel<E1> collectionModel) {
+		return new CompositeCollectionValueModel<E1, E2>(collectionModel, Transformer.Non.<E1>instance());
+	}
+
+	/**
+	 * Construct a collection value model with the specified wrapped
+	 * list value model and transformer.
+	 */
+	public CompositeCollectionValueModel(ListValueModel<? extends E1> listModel, Transformer<E1, ? extends CollectionValueModel<? extends E2>> transformer) {
+		this(new ListCollectionValueModelAdapter<E1>(listModel), transformer);
+	}
+
+	/**
+	 * Construct a collection value model with the specified, unchanging, wrapped
+	 * collection and transformer.
+	 */
+	public CompositeCollectionValueModel(Collection<? extends E1> collection, Transformer<E1, ? extends CollectionValueModel<? extends E2>> transformer) {
+		this(new StaticCollectionValueModel<E1>(collection), transformer);
+	}
+
+	/**
+	 * Construct a collection value model with the specified, unchanging, wrapped
+	 * collection and transformer.
+	 */
+	public CompositeCollectionValueModel(E1[] collection, Transformer<E1, ? extends CollectionValueModel<? extends E2>> transformer) {
+		this(new StaticCollectionValueModel<E1>(collection), transformer);
+	}
+
+	/**
+	 * Construct a collection value model with the specified wrapped
+	 * collection value model and transformer.
+	 */
+	public CompositeCollectionValueModel(CollectionValueModel<? extends E1> collectionModel, Transformer<E1, ? extends CollectionValueModel<? extends E2>> transformer) {
+		super(collectionModel);
+		if (transformer == null) {
+			throw new NullPointerException();
+		}
+		this.transformer = transformer;
+		this.componentCVMListener = this.buildComponentListener();
+		this.size = 0;
+	}
+
+
+	// ********** initialization **********
+
+	protected CollectionChangeListener buildComponentListener() {
+		return new ComponentListener();
+	}
+
+	protected class ComponentListener
+		extends CollectionChangeAdapter
+	{
+		@Override
+		public void itemsAdded(CollectionAddEvent event) {
+			CompositeCollectionValueModel.this.componentItemsAdded(event);
+		}
+		@Override
+		public void itemsRemoved(CollectionRemoveEvent event) {
+			CompositeCollectionValueModel.this.componentItemsRemoved(event);
+		}
+		@Override
+		public void collectionCleared(CollectionClearEvent event) {
+			CompositeCollectionValueModel.this.componentCollectionCleared(event);
+		}
+		@Override
+		public void collectionChanged(CollectionChangeEvent event) {
+			CompositeCollectionValueModel.this.componentCollectionChanged(event);
+		}
+	}
+
+
+	// ********** CollectionValueModel implementation **********
+
+	@Override
+	public Iterator<E2> iterator() {
+		return this.buildCompositeIterable().iterator();
+	}
+
+	protected Iterable<E2> buildCompositeIterable() {
+		return new CompositeIterable<E2>(this.collections.values());
+	}
+
+	@Override
+	public int size() {
+		return this.size;
+	}
+
+
+	// ********** CollectionValueModelWrapper overrides/implementation **********
+
+	@Override
+	protected void engageModel() {
+		super.engageModel();
+		// sync our cache *after* we start listening to the wrapped collection,
+		// since its value might change when a listener is added
+		this.addAllComponentSources();
+	}
+
+	/**
+	 * Transform all the sources to collection value models
+	 * and add their items to our cache, with no event notification.
+	 */
+	protected void addAllComponentSources() {
+		for (E1 source : this.collectionModel) {
+			this.addComponentSource(source, NullList.<E2>instance());
+		}
+	}
+
+	@Override
+	protected void disengageModel() {
+		super.disengageModel();
+		// stop listening to the components...
+		for (CollectionValueModel<? extends E2> componentCVM : this.componentCVMs.values()) {
+			componentCVM.removeCollectionChangeListener(VALUES, this.componentCVMListener);
+		}
+		// ...and clear the cache
+		this.componentCVMs.clear();
+		this.collections.clear();
+		this.size = 0;
+	}
+
+	/**
+	 * Some component sources were added;
+	 * add their corresponding items to our cache.
+	 */
+	@Override
+	protected void itemsAdded(CollectionAddEvent event) {
+		ArrayList<E2> addedItems = new ArrayList<E2>();
+		for (E1 item : this.getItems(event)) {
+			this.addComponentSource(item, addedItems);
+		}
+		this.fireItemsAdded(VALUES, addedItems);
+	}
+
+	/**
+	 * Transform the specified source to a collection value model
+	 * and add its items to our cache and the "collecting parameter".
+	 */
+	protected void addComponentSource(E1 source, List<E2> addedItems) {
+		CollectionValueModel<? extends E2> componentCVM = this.transformer.transform(source);
+		if (this.componentCVMs.put(source, componentCVM) != null) {
+			throw new IllegalStateException("duplicate component: " + source);
+		}
+		componentCVM.addCollectionChangeListener(VALUES, this.componentCVMListener);
+		ArrayList<E2> componentCollection = new ArrayList<E2>(componentCVM.size());
+		if (this.collections.put(componentCVM, componentCollection) != null) {
+			throw new IllegalStateException("duplicate collection: " + source);
+		}
+		this.addComponentItems(componentCVM, componentCollection);
+		addedItems.addAll(componentCollection);
+	}
+
+	/**
+	 * Add the items in the specified component CVM to the specified component
+	 * collection.
+	 */
+	protected void addComponentItems(CollectionValueModel<? extends E2> componentCVM, ArrayList<E2> componentCollection) {
+		int itemsSize = componentCVM.size();
+		this.size += itemsSize;
+		componentCollection.ensureCapacity(componentCollection.size() + itemsSize);
+		CollectionTools.addAll(componentCollection, componentCVM);
+	}
+
+	/**
+	 * Some component sources were removed;
+	 * remove their corresponding items from our cache.
+	 */
+	@Override
+	protected void itemsRemoved(CollectionRemoveEvent event) {
+		ArrayList<E2> removedItems = new ArrayList<E2>();
+		for (E1 item : this.getItems(event)) {
+			this.removeComponentSource(item, removedItems);
+		}
+		this.fireItemsRemoved(VALUES, removedItems);
+	}
+
+	/**
+	 * Remove the items corresponding to the specified source
+	 * from our cache.
+	 */
+	protected void removeComponentSource(E1 source, List<E2> removedItems) {
+		CollectionValueModel<? extends E2> componentCVM = this.componentCVMs.remove(source);
+		if (componentCVM == null) {
+			throw new IllegalStateException("missing component: " + source);
+		}
+		componentCVM.removeCollectionChangeListener(VALUES, this.componentCVMListener);
+		ArrayList<E2> componentCollection = this.collections.remove(componentCVM);
+		if (componentCollection == null) {
+			throw new IllegalStateException("missing collection: " + source);
+		}
+		removedItems.addAll(componentCollection);
+		this.removeComponentItems(componentCollection);
+	}
+
+	/**
+	 * Update our size and collection cache.
+	 */
+	protected void removeComponentItems(ArrayList<E2> componentCollection) {
+		this.size -= componentCollection.size();
+		componentCollection.clear();
+	}
+
+	/**
+	 * The component sources cleared;
+	 * clear our cache.
+	 */
+	@Override
+	protected void collectionCleared(CollectionClearEvent event) {
+		this.removeAllComponentSources();
+		this.fireCollectionCleared(VALUES);
+	}
+
+	protected void removeAllComponentSources() {
+		// copy the keys so we don't eat our own tail
+		ArrayList<E1> copy = new ArrayList<E1>(this.componentCVMs.keySet());
+		for (E1 source : copy) {
+			this.removeComponentSource(source, NullList.<E2>instance());
+		}
+	}
+
+	/**
+	 * The component sources changed;
+	 * rebuild our cache.
+	 */
+	@Override
+	protected void collectionChanged(CollectionChangeEvent event) {
+		this.removeAllComponentSources();
+		this.addAllComponentSources();
+		this.fireCollectionChanged(VALUES, CollectionTools.collection(this.iterator()));
+	}
+
+
+	// ********** internal methods **********
+
+	/**
+	 * One of the component collections had items added;
+	 * synchronize our caches.
+	 */
+	protected void componentItemsAdded(CollectionAddEvent event) {
+		int itemsSize = event.getItemsSize();
+		this.size += itemsSize;
+
+		ArrayList<E2> componentCollection = this.collections.get(this.componentCVM(event));
+		componentCollection.ensureCapacity(componentCollection.size() + itemsSize);
+
+		this.addItemsToCollection(this.getComponentItems(event), componentCollection, VALUES);
+	}
+
+	/**
+	 * One of the component collections had items removed;
+	 * synchronize our caches.
+	 */
+	protected void componentItemsRemoved(CollectionRemoveEvent event) {
+		this.size -= event.getItemsSize();
+		ArrayList<E2> componentCollection = this.collections.get(this.componentCVM(event));
+		this.removeItemsFromCollection(this.getComponentItems(event), componentCollection, VALUES);
+	}
+
+	/**
+	 * One of the component collections was cleared;
+	 * synchronize our caches by clearing out the appropriate
+	 * collection.
+	 */
+	protected void componentCollectionCleared(CollectionClearEvent event) {
+		ArrayList<E2> componentCollection = this.collections.get(this.componentCVM(event));
+		ArrayList<E2> removedItems = new ArrayList<E2>(componentCollection);
+		this.removeComponentItems(componentCollection);
+		this.fireItemsRemoved(VALUES, removedItems);
+	}
+
+	/**
+	 * One of the component collections changed;
+	 * synchronize our caches by clearing out the appropriate
+	 * collection and then rebuilding it.
+	 */
+	protected void componentCollectionChanged(CollectionChangeEvent event) {
+		CollectionValueModel<E2> componentCVM = this.componentCVM(event);
+		ArrayList<E2> componentCollection = this.collections.get(componentCVM);
+		this.removeComponentItems(componentCollection);
+		this.addComponentItems(componentCVM, componentCollection);
+		this.fireCollectionChanged(VALUES, CollectionTools.collection(this.iterator()));
+	}
+
+	// minimize scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E2> getComponentItems(CollectionAddEvent event) {
+		return (Iterable<E2>) event.getItems();
+	}
+
+	// minimize scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E2> getComponentItems(CollectionRemoveEvent event) {
+		return (Iterable<E2>) event.getItems();
+	}
+
+	// minimize scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected CollectionValueModel<E2> componentCVM(CollectionEvent event) {
+		return (CollectionValueModel<E2>) event.getSource();
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		StringBuilderTools.append(sb, this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CompositeListValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CompositeListValueModel.java
new file mode 100644
index 0000000..41631b1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CompositeListValueModel.java
@@ -0,0 +1,708 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterable.ListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
+import org.eclipse.persistence.tools.utility.iterable.ReadOnlyCompositeListIterable;
+import org.eclipse.persistence.tools.utility.iterable.SingleElementIterable;
+import org.eclipse.persistence.tools.utility.iterable.TransformationListIterable;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+import org.eclipse.persistence.tools.utility.transformer.TransformerAdapter;
+
+/**
+ * A <code>CompositeListValueModel</code> wraps another
+ * {@link ListValueModel} and uses a {@link Transformer}
+ * to convert each item in the wrapped list to yet another
+ * {@link ListValueModel}. This composite list contains
+ * the combined items from all these component lists.
+ * <p>
+ * Terminology:<ul>
+ * <li><em>sources</em> - the items in the wrapped list value model; these
+ *    are converted into component LVMs by the transformer
+ * <li><em>component LVMs</em> - the component list value models that are combined
+ *    by this composite list value model
+ * <li><em>items</em> - the items held by the component LVMs
+ * </ul>
+ *
+ * @param <E1> the type of items held by the wrapped list model;
+ *     each of these is transformed (by the {@link #transformer}) into a
+ *     list model of <code>E2</code>s
+ * @param <E2> the type of items held by the composite list model
+ */
+@SuppressWarnings("nls")
+public class CompositeListValueModel<E1, E2>
+	extends ListValueModelWrapper<E1>
+	implements ListValueModel<E2>
+{
+	/**
+	 * This is the (optional) user-supplied object that transforms
+	 * the items in the wrapped list to list value models.
+	 */
+	private final Transformer<E1, ? extends ListValueModel<? extends E2>> transformer;
+
+	/**
+	 * Cache of the sources, component LVMs, lists.
+	 */
+	private final ArrayList<Info> infoList = new ArrayList<Info>();
+	protected class Info {
+		// the object passed to the transformer
+		final E1 source;
+		// the list value model generated by the transformer
+		final ListValueModel<? extends E2> componentLVM;
+		// cache of the items held by the component LVM
+		final ArrayList<E2> items;
+		// the component LVM's beginning index within the composite LVM
+		int begin;
+		protected Info(E1 source, ListValueModel<? extends E2> componentLVM, ArrayList<E2> items, int begin) {
+			super();
+			this.source = source;
+			this.componentLVM = componentLVM;
+			this.items = items;
+			this.begin = begin;
+		}
+	}
+
+	/** Listener that listens to all the component list value models. */
+	private final ListChangeListener componentLVMListener;
+
+	/** Cache the size of the composite list. */
+	private int size;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a list value model with the specified wrapped
+	 * collection value model. The specified collection model already contains other
+	 * list value models.
+	 */
+	public static <E1 extends ListValueModel<? extends E2>, E2> CompositeListValueModel<E1, E2> forModels(CollectionValueModel<E1> collectionModel) {
+		return forModels(new CollectionListValueModelAdapter<E1>(collectionModel));
+	}
+
+	/**
+	 * Construct a list value model with the specified wrapped list.
+	 */
+	public static <E1 extends ListValueModel<? extends E2>, E2> CompositeListValueModel<E1, E2> forModels(List<E1> list) {
+		return forModels(new StaticListValueModel<E1>(list));
+	}
+
+	/**
+	 * Construct a list value model with the specified wrapped list.
+	 */
+	public static <E1 extends ListValueModel<? extends E2>, E2> CompositeListValueModel<E1, E2> forModels(E1... list) {
+		return forModels(new StaticListValueModel<E1>(list));
+	}
+
+	/**
+	 * Construct a list value model with the specified wrapped
+	 * list value model. The specified list
+	 * model already contains other list value models.
+	 */
+	public static <E1 extends ListValueModel<? extends E2>, E2> CompositeListValueModel<E1, E2> forModels(ListValueModel<E1> listModel) {
+		return new CompositeListValueModel<E1, E2>(listModel, Transformer.Non.<E1>instance());
+	}
+
+	/**
+	 * Construct a list value model with the specified wrapped
+	 * collection value model and transformer.
+	 */
+	public CompositeListValueModel(CollectionValueModel<? extends E1> collectionModel, Transformer<E1, ? extends ListValueModel<? extends E2>> transformer) {
+		this(new CollectionListValueModelAdapter<E1>(collectionModel), transformer);
+	}
+
+	/**
+	 * Construct a list value model with the specified, unchanging, wrapped
+	 * list and transformer.
+	 */
+	public CompositeListValueModel(List<? extends E1> list, Transformer<E1, ? extends ListValueModel<? extends E2>> transformer) {
+		this(new StaticListValueModel<E1>(list), transformer);
+	}
+
+	/**
+	 * Construct a list value model with the specified, unchanging, wrapped
+	 * list and transformer.
+	 */
+	public CompositeListValueModel(E1[] list, Transformer<E1, ? extends ListValueModel<? extends E2>> transformer) {
+		this(new StaticListValueModel<E1>(list), transformer);
+	}
+
+	/**
+	 * Construct a list value model with the specified wrapped
+	 * list value model and transformer.
+	 */
+	public CompositeListValueModel(ListValueModel<? extends E1> listModel, Transformer<E1, ? extends ListValueModel<? extends E2>> transformer) {
+		super(listModel);
+		if (transformer == null) {
+			throw new NullPointerException();
+		}
+		this.transformer = transformer;
+		this.componentLVMListener = this.buildComponentLVMListener();
+		this.size = 0;
+	}
+
+
+	// ********** initialization **********
+
+	protected ListChangeListener buildComponentLVMListener() {
+		return new ComponentListener();
+	}
+
+	protected class ComponentListener
+		extends ListChangeAdapter
+	{
+		@Override
+		public void itemsAdded(ListAddEvent event) {
+			CompositeListValueModel.this.componentItemsAdded(event);
+		}
+		@Override
+		public void itemsRemoved(ListRemoveEvent event) {
+			CompositeListValueModel.this.componentItemsRemoved(event);
+		}
+		@Override
+		public void itemsReplaced(ListReplaceEvent event) {
+			CompositeListValueModel.this.componentItemsReplaced(event);
+		}
+		@Override
+		public void itemsMoved(ListMoveEvent event) {
+			CompositeListValueModel.this.componentItemsMoved(event);
+		}
+		@Override
+		public void listCleared(ListClearEvent event) {
+			CompositeListValueModel.this.componentListCleared(event);
+		}
+		@Override
+		public void listChanged(ListChangeEvent event) {
+			CompositeListValueModel.this.componentListChanged(event);
+		}
+	}
+
+
+	// ********** ListValueModel implementation **********
+
+	@Override
+	public E2 get(int index) {
+		if ((index < 0) || (index >= this.size)) {
+			throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + this.size);
+		}
+		// move backwards through the info list
+		for (int i = this.infoList.size(); i-- > 0; ) {
+			Info info = this.infoList.get(i);
+			if (index >= info.begin) {
+				return info.items.get(index - info.begin);
+			}
+		}
+		throw new IllegalStateException();  // something is wack
+	}
+
+	@Override
+	public Iterator<E2> iterator() {
+		return this.listIterator();
+	}
+
+	@Override
+	public ListIterator<E2> listIterator() {
+		return this.buildListIterable().iterator();
+	}
+
+	protected ListIterable<E2> buildListIterable() {
+		return new ReadOnlyCompositeListIterable<E2>(this.buildListsIterables());
+	}
+
+	protected ListIterable<ListIterable<E2>> buildListsIterables() {
+		return new TransformationListIterable<Info, ListIterable<E2>>(this.infoList, new InfoTransformer());
+	}
+
+	protected class InfoTransformer
+		extends TransformerAdapter<Info, ListIterable<E2>>
+	{
+		@Override
+		public ListIterable<E2> transform(Info info) {
+			return new ListListIterable<E2>(info.items);
+		}
+	}
+
+	@Override
+	public int size() {
+		return this.size;
+	}
+
+	@Override
+	public Object[] toArray() {
+		return ArrayTools.array(this.listIterator(), this.size);
+	}
+
+
+	// ********** ListValueModelWrapper overrides/implementation **********
+
+	@Override
+	protected void engageModel() {
+		super.engageModel();
+		// sync our cache *after* we start listening to the wrapped list,
+		// since its value might change when a listener is added
+		this.addComponentSources(0, this.listModel, this.listModel.size(), false);  // false = do not fire event
+	}
+
+	@Override
+	protected void disengageModel() {
+		super.disengageModel();
+		// stop listening to the component LVMs...
+		for (Info info : this.infoList) {
+			info.componentLVM.removeListChangeListener(LIST_VALUES, this.componentLVMListener);
+		}
+		// ...and clear the cache
+		this.infoList.clear();
+		this.size = 0;
+	}
+
+	/**
+	 * Some component sources were added; update our cache.
+	 */
+	@Override
+	protected void itemsAdded(ListAddEvent event) {
+		this.addComponentSources(event.getIndex(), this.getItems(event), event.getItemsSize(), true);  // true = fire event
+	}
+
+	/**
+	 * Add infos corresponding to the specified sources to our cache.
+	 * Fire the appropriate event if requested.
+	 */
+	protected void addComponentSources(int addedSourcesIndex, Iterable<? extends E1> addedSources, int addedSourcesSize, boolean fireEvent) {
+		ArrayList<Info> newInfoList = new ArrayList<Info>(addedSourcesSize);
+		// the 'items' are either tacked on to the end or
+		// at the 'begin' index of the first 'info' that is being pushed back
+		int newItemsIndex = (addedSourcesIndex == this.infoList.size()) ? this.size : this.infoList.get(addedSourcesIndex).begin;
+
+		int begin = newItemsIndex;
+		for (E1 source : addedSources) {
+			ListValueModel<? extends E2> componentLVM = this.transformer.transform(source);
+			componentLVM.addListChangeListener(LIST_VALUES, this.componentLVMListener);
+			ArrayList<E2> items = new ArrayList<E2>(componentLVM.size());
+			CollectionTools.addAll(items, componentLVM.listIterator());
+			newInfoList.add(new Info(source, componentLVM, items, begin));
+			begin += items.size();
+		}
+		this.infoList.addAll(addedSourcesIndex, newInfoList);
+		int newItemsSize = begin - newItemsIndex;
+		this.size += newItemsSize;
+
+		// bump the 'begin' index for all the infos that were pushed back by the insert
+		int movedInfosIndex = addedSourcesIndex + addedSourcesSize;
+		for (int i = movedInfosIndex; i < this.infoList.size(); i++) {
+			this.infoList.get(i).begin += newItemsSize;
+		}
+
+		if (fireEvent) {
+			ArrayList<E2> newItems = new ArrayList<E2>(newItemsSize);
+			for (int i = addedSourcesIndex; i < movedInfosIndex; i++) {
+				newItems.addAll(this.infoList.get(i).items);
+			}
+			this.fireItemsAdded(LIST_VALUES, newItemsIndex, newItems);
+		}
+	}
+
+	/**
+	 * Some component sources were removed; update our cache.
+	 */
+	@Override
+	protected void itemsRemoved(ListRemoveEvent event) {
+		this.removeComponentSources(event.getIndex(), event.getItemsSize(), true);  // true = fire event
+	}
+
+	/**
+	 * Remove the infos corresponding to the specified sources from our cache.
+	 */
+	protected void removeComponentSources(int removedSourcesIndex, int removedSourcesSize, boolean fireEvent) {
+		int removedItemsIndex = this.infoList.get(removedSourcesIndex).begin;
+		int movedSourcesIndex = removedSourcesIndex + removedSourcesSize;
+		int movedItemsIndex = (movedSourcesIndex == this.infoList.size()) ? this.size : this.infoList.get(movedSourcesIndex).begin;
+		int removedItemsSize = movedItemsIndex - removedItemsIndex;
+		this.size -= removedItemsSize;
+
+		List<Info> subList = this.infoList.subList(removedSourcesIndex, removedSourcesIndex + removedSourcesSize);
+		ArrayList<Info> removedInfoList = new ArrayList<Info>(subList);  // make a copy
+		subList.clear();
+
+		// decrement the 'begin' index for all the infos that were moved forward by the deletes
+		for (int i = removedSourcesIndex; i < this.infoList.size(); i++) {
+			this.infoList.get(i).begin -= removedItemsSize;
+		}
+
+		for (Info removedInfo : removedInfoList) {
+			removedInfo.componentLVM.removeListChangeListener(LIST_VALUES, this.componentLVMListener);
+		}
+
+		if (fireEvent) {
+			ArrayList<E2> removedItems = new ArrayList<E2>(removedItemsSize);
+			for (Info removedInfo : removedInfoList) {
+				removedItems.addAll(removedInfo.items);
+			}
+			this.fireItemsRemoved(LIST_VALUES, removedItemsIndex, removedItems);
+		}
+	}
+
+	/**
+	 * Some component sources were replaced; update our cache.
+	 */
+	@Override
+	protected void itemsReplaced(ListReplaceEvent event) {
+		this.replaceComponentSources(event.getIndex(), this.getNewItems(event), event.getItemsSize(), true);  // true = fire event
+	}
+
+	/**
+	 * Replaced component sources will not (typically) map to a set of replaced
+	 * items, so we remove and add the corresponding lists of items, resulting in
+	 * two events.
+	 */
+	protected void replaceComponentSources(int replacedSourcesIndex, Iterable<? extends E1> newSources, int replacedSourcesSize, boolean fireEvent) {
+		this.removeComponentSources(replacedSourcesIndex, replacedSourcesSize, fireEvent);
+		this.addComponentSources(replacedSourcesIndex, newSources, replacedSourcesSize, fireEvent);
+	}
+
+	/**
+	 * Some component sources were moved; update our cache.
+	 */
+	@Override
+	protected void itemsMoved(ListMoveEvent event) {
+		this.moveComponentSources(event.getTargetIndex(), event.getSourceIndex(), event.getLength(), true);  // true = fire event
+	}
+
+	protected void moveComponentSources(int targetSourcesIndex, int sourceSourcesIndex, int movedSourcesLength, boolean fireEvent) {
+		int sourceItemsIndex = this.infoList.get(sourceSourcesIndex).begin;
+
+		int nextSourceSourceIndex = sourceSourcesIndex + movedSourcesLength;
+		int nextSourceItemIndex = (nextSourceSourceIndex == this.infoList.size()) ? this.size : this.infoList.get(nextSourceSourceIndex).begin;
+		int moveItemsLength = nextSourceItemIndex - sourceItemsIndex;
+
+		int targetItemsIndex = -1;
+		if (sourceSourcesIndex > targetSourcesIndex) {
+			// move from high to low index
+			targetItemsIndex = this.infoList.get(targetSourcesIndex).begin;
+		} else {
+			// move from low to high index (higher items move down during move)
+			int nextTargetSourceIndex = targetSourcesIndex + movedSourcesLength;
+			targetItemsIndex = (nextTargetSourceIndex == this.infoList.size()) ? this.size : this.infoList.get(nextTargetSourceIndex).begin;
+			targetItemsIndex = targetItemsIndex - moveItemsLength;
+		}
+
+		ListTools.move(this.infoList, targetSourcesIndex, sourceSourcesIndex, movedSourcesLength);
+
+		// update the 'begin' indexes of all the affected 'infos'
+		int min = Math.min(targetSourcesIndex, sourceSourcesIndex);
+		int max = Math.max(targetSourcesIndex, sourceSourcesIndex) + movedSourcesLength;
+		int begin = Math.min(targetItemsIndex, sourceItemsIndex);
+		for (int i = min; i < max; i++) {
+			Info info = this.infoList.get(i);
+			info.begin = begin;
+			begin += info.componentLVM.size();
+		}
+
+		if (fireEvent) {
+			this.fireItemsMoved(LIST_VALUES, targetItemsIndex, sourceItemsIndex, moveItemsLength);
+		}
+	}
+
+	/**
+	 * The component sources were cleared; clear our cache.
+	 */
+	@Override
+	protected void listCleared(ListClearEvent event) {
+		this.clearComponentSources();
+	}
+
+	protected void clearComponentSources() {
+		this.removeComponentSources(0, this.infoList.size(), false);  // false = do not fire event
+		this.fireListCleared(LIST_VALUES);
+	}
+
+	/**
+	 * The component sources changed; rebuild our cache.
+	 */
+	@Override
+	protected void listChanged(ListChangeEvent event) {
+		int newSize = this.listModel.size();
+		if (newSize == 0) {
+			this.clearComponentSources();
+			return;
+		}
+
+		int oldSize = this.infoList.size();
+		if (oldSize == 0) {
+			this.addComponentSources(0, this.listModel, newSize, true);  // true = fire event
+			return;
+		}
+
+		int min = Math.min(newSize, oldSize);
+		// handle replaced sources individually so we don't fire events for unchanged sources
+		for (int i = 0; i < min; i++) {
+			E1 newSource = this.listModel.get(i);
+			E1 oldSource = this.infoList.get(i).source;
+			if (this.valuesAreDifferent(newSource, oldSource)) {
+				this.replaceComponentSources(i, new SingleElementIterable<E1>(newSource), 1, true);  // true = fire event
+			}
+		}
+
+		if (newSize == oldSize) {
+			return;
+		}
+
+		if (newSize < oldSize) {
+			this.removeComponentSources(min, oldSize - newSize, true);  // true = fire event
+			return;
+		}
+
+		// newSize > oldSize
+		this.addComponentSources(min, this.buildSubListHolder(min), newSize - oldSize, true);  // true = fire event
+	}
+
+	protected Iterable<? extends E1> buildSubListHolder(int fromIndex) {
+		int listModelSize = this.listModel.size();
+		return ListTools.list(this.listModel, listModelSize).subList(fromIndex, listModelSize);
+	}
+
+	protected Iterable<? extends E1> buildSubListHolder(int fromIndex, int toIndex) {
+		int listModelSize = this.listModel.size();
+		return ((fromIndex == 0) && (toIndex == listModelSize)) ?
+				this.listModel :
+				ListTools.list(this.listModel, listModelSize).subList(fromIndex, toIndex);
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		StringBuilderTools.append(sb, this);
+	}
+
+
+	// ********** internal methods **********
+
+	/**
+	 * Return the index of the specified component LVM.
+	 */
+	protected int indexOf(ListValueModel<E2> componentLVM) {
+		for (int i = 0; i < this.infoList.size(); i++) {
+			if (this.infoList.get(i).componentLVM == componentLVM) {
+				return i;
+			}
+		}
+		throw new IllegalArgumentException("invalid component LVM: " + componentLVM);
+	}
+
+	/**
+	 * Return the index of the specified event's component LVM.
+	 */
+	protected int indexFor(ListEvent event) {
+		return this.indexOf(this.getComponentLVM(event));
+	}
+
+	/**
+	 * Items were added to one of the component lists;
+	 * synchronize our cache.
+	 */
+	protected void componentItemsAdded(ListAddEvent event) {
+		int componentLVMIndex = this.indexFor(event);
+		this.addComponentItems(componentLVMIndex, this.infoList.get(componentLVMIndex), event.getIndex(), this.getComponentItems(event), event.getItemsSize());
+	}
+
+	protected void addComponentItems(int componentLVMIndex, Info info, int addedItemsIndex, Iterable<? extends E2> addedItems, int addedItemsSize) {
+		// update the affected 'begin' indices
+		for (int i = componentLVMIndex + 1; i < this.infoList.size(); i++) {
+			this.infoList.get(i).begin += addedItemsSize;
+		}
+		this.size += addedItemsSize;
+
+		// synchronize the cached list
+		ListTools.addAll(info.items, addedItemsIndex, addedItems, addedItemsSize);
+
+		// translate the event
+		this.fireItemsAdded(LIST_VALUES, info.begin + addedItemsIndex, info.items.subList(addedItemsIndex, addedItemsIndex + addedItemsSize));
+	}
+
+	/**
+	 * Items were removed from one of the component lists;
+	 * synchronize our cache.
+	 */
+	protected void componentItemsRemoved(ListRemoveEvent event) {
+		// update the affected 'begin' indices
+		int componentLVMIndex = this.indexFor(event);
+		int removedItemsSize = event.getItemsSize();
+		for (int i = componentLVMIndex + 1; i < this.infoList.size(); i++) {
+			this.infoList.get(i).begin -= removedItemsSize;
+		}
+		this.size -= removedItemsSize;
+
+		// synchronize the cached list
+		Info info = this.infoList.get(componentLVMIndex);
+		int itemIndex = event.getIndex();
+		info.items.subList(itemIndex, itemIndex + event.getItemsSize()).clear();
+
+		// translate the event
+		this.fireItemsRemoved(event.clone(this, LIST_VALUES, info.begin));
+	}
+
+	/**
+	 * Items were replaced in one of the component lists;
+	 * synchronize our cache.
+	 */
+	protected void componentItemsReplaced(ListReplaceEvent event) {
+		// no changes to the 'begin' indices or size
+
+		// synchronize the cached list
+		int componentLVMIndex = this.indexFor(event);
+		Info info = this.infoList.get(componentLVMIndex);
+		int i = event.getIndex();
+		for (E2 item : this.getComponentItems(event)) {
+			info.items.set(i++, item);
+		}
+
+		// translate the event
+		this.fireItemsReplaced(event.clone(this, LIST_VALUES, info.begin));
+	}
+
+	/**
+	 * Items were moved in one of the component lists;
+	 * synchronize our cache.
+	 */
+	protected void componentItemsMoved(ListMoveEvent event) {
+		// no changes to the 'begin' indices or size
+
+		// synchronize the cached list
+		int componentLVMIndex = this.indexFor(event);
+		Info info = this.infoList.get(componentLVMIndex);
+		ListTools.move(info.items, event.getTargetIndex(), event.getSourceIndex(), event.getLength());
+
+		// translate the event
+		this.fireItemsMoved(event.clone(this, LIST_VALUES, info.begin));
+	}
+
+	/**
+	 * One of the component lists was cleared;
+	 * synchronize our cache.
+	 */
+	protected void componentListCleared(ListClearEvent event) {
+		int componentLVMIndex = this.indexFor(event);
+		this.clearComponentList(componentLVMIndex, this.infoList.get(componentLVMIndex));
+	}
+
+	protected void clearComponentList(int componentLVMIndex, Info info) {
+		// update the affected 'begin' indices
+		int removedItemsSize = info.items.size();
+		if (removedItemsSize == 0) {
+			return;
+		}
+
+		for (int i = componentLVMIndex + 1; i < this.infoList.size(); i++) {
+			this.infoList.get(i).begin -= removedItemsSize;
+		}
+		this.size -= removedItemsSize;
+
+		// synchronize the cached list
+		ArrayList<E2> items = new ArrayList<E2>(info.items);  // make a copy
+		info.items.clear();
+
+		// translate the event
+		this.fireItemsRemoved(LIST_VALUES, info.begin, items);
+	}
+
+	/**
+	 * One of the component lists changed;
+	 * synchronize our cache by synchronizing the appropriate
+	 * list and firing the appropriate events.
+	 */
+	protected void componentListChanged(ListChangeEvent event) {
+		int componentLVMIndex = this.indexFor(event);
+		Info info = this.infoList.get(componentLVMIndex);
+
+		int newItemsSize = info.componentLVM.size();
+		if (newItemsSize == 0) {
+			this.clearComponentList(componentLVMIndex, info);
+			return;
+		}
+
+		int oldItemsSize = info.items.size();
+		if (oldItemsSize == 0) {
+			this.addComponentItems(componentLVMIndex, info, 0, info.componentLVM, newItemsSize);
+			return;
+		}
+
+		int min = Math.min(newItemsSize, oldItemsSize);
+		// handle replaced items individually so we don't fire events for unchanged items
+		for (int i = 0; i < min; i++) {
+			E2 newItem = info.componentLVM.get(i);
+			E2 oldItem = info.items.set(i, newItem);
+			this.fireItemReplaced(LIST_VALUES, info.begin + i, newItem, oldItem);
+		}
+
+		int delta = newItemsSize - oldItemsSize;
+		if (delta == 0) {  // newItemsSize == oldItemsSize
+			return;
+		}
+
+		for (int i = componentLVMIndex + 1; i < this.infoList.size(); i++) {
+			this.infoList.get(i).begin += delta;
+		}
+		this.size += delta;
+
+		if (delta < 0) {  // newItemsSize < oldItemsSize
+			List<E2> subList = info.items.subList(newItemsSize, oldItemsSize);
+			ArrayList<E2> removedItems = new ArrayList<E2>(subList);  // make a copy
+			subList.clear();
+			this.fireItemsRemoved(LIST_VALUES, info.begin + newItemsSize, removedItems);
+			return;
+		}
+
+		// newItemsSize > oldItemsSize
+		ArrayList<E2> addedItems = new ArrayList<E2>(delta);
+		for (int i = oldItemsSize; i < newItemsSize; i++) {
+			addedItems.add(info.componentLVM.get(i));
+		}
+		info.items.addAll(addedItems);
+		this.fireItemsAdded(LIST_VALUES, info.begin + oldItemsSize, addedItems);
+	}
+
+	// minimize scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E2> getComponentItems(ListAddEvent event) {
+		return (Iterable<E2>) event.getItems();
+	}
+
+	// minimize scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E2> getComponentItems(ListReplaceEvent event) {
+		return (Iterable<E2>) event.getNewItems();
+	}
+
+	// minimize scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected ListValueModel<E2> getComponentLVM(ListEvent event) {
+		return (ListValueModel<E2>) event.getSource();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CompositePropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CompositePropertyValueModel.java
new file mode 100644
index 0000000..220e71e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/CompositePropertyValueModel.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import org.eclipse.persistence.tools.utility.collection.IdentityHashBag;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+
+/**
+ * A <code>CompositePropertyValueModel</code> adapts a
+ * {@link CollectionValueModel} holding other {@link PropertyValueModel}s
+ * to a single {@link PropertyValueModel}.
+ * <p>
+ * Subclasses must implement:<ul>
+ * <li>{@link #buildValue()}<p>
+ *     to return the current property value, as derived from the
+ *     component values
+ * </ul>
+ * <strong>NB:</strong> The wrapped collection must not contain any duplicates
+ * or this class will throw an exception.
+ *
+ * @param <V> the type of the model's value
+ * @param <E> the type of the wrapped collection value model's
+ * property value model's values
+ */
+public abstract class CompositePropertyValueModel<V, E>
+	extends CollectionPropertyValueModelAdapter<V, PropertyValueModel<? extends E>>
+{
+	/**
+	 * Cache the component property value models so we can stop listening to
+	 * them when they are removed from the collection value model.
+	 */
+	protected final IdentityHashBag<PropertyValueModel<? extends E>> componentPVMs =
+			new IdentityHashBag<PropertyValueModel<? extends E>>();
+
+	/**
+	 * Listen to every property value model in the collection value model.
+	 * If one changes, we need to re-calculate our value.
+	 */
+	protected final PropertyChangeListener componentListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a property value model that is a composite of the specified
+	 * property value models.
+	 */
+	public CompositePropertyValueModel(PropertyValueModel<? extends E>... collection) {
+		this(Arrays.asList(collection));
+	}
+
+	/**
+	 * Construct a property value model that is a composite of the specified
+	 * property value models.
+	 */
+	public <P extends PropertyValueModel<? extends E>> CompositePropertyValueModel(Collection<? extends P> collection) {
+		this(new StaticCollectionValueModel<P>(collection));
+	}
+
+	/**
+	 * Construct a property value model that is a composite of the specified
+	 * property value models.
+	 */
+	public <P extends PropertyValueModel<? extends E>> CompositePropertyValueModel(CollectionValueModel<P> collectionModel) {
+		super(collectionModel);
+		this.componentListener = this.buildComponentListener();
+	}
+
+
+	// ********** initialization **********
+
+	protected PropertyChangeListener buildComponentListener() {
+		return new ComponentListener();
+	}
+
+	protected class ComponentListener
+		extends PropertyChangeAdapter
+	{
+		@Override
+		public void propertyChanged(PropertyChangeEvent event) {
+			CompositePropertyValueModel.this.componentChanged(event);
+		}
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Subclasses can override this method if the event can be used to improve
+	 * the performance of building a new value (e.g. some property changes may
+	 * not necessitate the re-calculation of the value).
+	 */
+	protected void componentChanged(@SuppressWarnings("unused") PropertyChangeEvent event) {
+		this.propertyChanged();
+	}
+
+
+	// ********** CollectionPropertyValueModelAdapter overrides **********
+
+	@Override
+	protected void engageModel_() {
+		super.engageModel_();
+		this.addComponentPVMs(this.collectionModel);
+	}
+
+	protected <P extends PropertyValueModel<? extends E>> void addComponentPVMs(Iterable<P> pvms) {
+		for (P each : pvms) {
+			this.componentPVMs.add(each);
+			each.addPropertyChangeListener(VALUE, this.componentListener);
+		}
+	}
+
+	@Override
+	protected void disengageModel_() {
+		this.removeComponentPVMs(this.collectionModel);
+		super.disengageModel_();
+	}
+
+	protected <P extends PropertyValueModel<? extends E>> void removeComponentPVMs(Iterable<P> pvms) {
+		for (P each : pvms) {
+			each.removePropertyChangeListener(VALUE, this.componentListener);
+			this.componentPVMs.remove(each);
+		}
+	}
+
+	@Override
+	protected void itemsAdded(CollectionAddEvent event) {
+		this.addComponentPVMs(this.getItems(event));
+		super.itemsAdded(event);
+	}
+
+	@Override
+	protected void itemsRemoved(CollectionRemoveEvent event) {
+		this.removeComponentPVMs(this.getItems(event));
+		super.itemsRemoved(event);
+	}
+
+	@Override
+	protected void collectionCleared(CollectionClearEvent event) {
+		this.removeAllComponentPVMs();
+		super.collectionCleared(event);
+	}
+
+	protected void removeAllComponentPVMs() {
+		// copy the list so we don't eat our own tail
+		ArrayList<PropertyValueModel<? extends E>> copy = new ArrayList<PropertyValueModel<? extends E>>(this.componentPVMs);
+		this.removeComponentPVMs(copy);
+	}
+
+	@Override
+	protected void collectionChanged(CollectionChangeEvent event) {
+		this.removeAllComponentPVMs();
+		this.addComponentPVMs(this.collectionModel);
+		super.collectionChanged(event);
+	}
+
+
+	// ********** convenience methods **********
+
+	/**
+	 * Our constructor accepts only a
+	 * {@link CollectionValueModel}{@code<? extends }{@link PropertyValueModel}{@code<? extends E>>}.
+	 */
+	// minimize scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<? extends PropertyValueModel<? extends E>> getItems(CollectionAddEvent event) {
+		return (Iterable<? extends PropertyValueModel<? extends E>>) event.getItems();
+	}
+
+	/**
+	 * Our constructor accepts only a
+	 * {@link CollectionValueModel}{@code<? extends }{@link PropertyValueModel}{@code<? extends E>>}.
+	 */
+	// minimize scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<? extends PropertyValueModel<? extends E>> getItems(CollectionRemoveEvent event) {
+		return (Iterable<? extends PropertyValueModel<? extends E>>) event.getItems();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/DoubleModifiablePropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/DoubleModifiablePropertyValueModel.java
new file mode 100644
index 0000000..e7978dd
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/DoubleModifiablePropertyValueModel.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+/**
+ * Add support for changing the double property value model.
+ *
+ * @param <V> the type of the both the <em>wrapped</em> and <em>wrapper</em>
+ * models' values
+ */
+public class DoubleModifiablePropertyValueModel<V>
+	extends DoublePropertyValueModel<V>
+	implements ModifiablePropertyValueModel<V>
+{
+	/**
+	 * Construct a double modifiable property value model for the specified
+	 * wrapped property value model model.
+	 */
+	public DoubleModifiablePropertyValueModel(PropertyValueModel<? extends ModifiablePropertyValueModel<V>> valueModel) {
+		super(valueModel);
+	}
+
+	@Override
+	public void setValue(V value) {
+		ModifiablePropertyValueModel<V> vmv = this.getValueModelValueModel();
+		if (vmv == null) {
+			this.setValue_(value);
+		} else {
+			vmv.setValue(value);
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	protected ModifiablePropertyValueModel<V> getValueModelValueModel() {
+		return (ModifiablePropertyValueModel<V>) this.valueModelValueModel;
+	}
+
+	/**
+	 * The wrapped value model model is missing. Handle the specified new value.
+	 */
+	protected void setValue_(@SuppressWarnings("unused") V value) {
+		// do nothing by default
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/DoublePropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/DoublePropertyValueModel.java
new file mode 100644
index 0000000..a857135
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/DoublePropertyValueModel.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+
+/**
+ * This property value model <em>wrapper</em> wraps another property value model
+ * and treats the <em>wrapped</em> model's value as the <em>wrapper</em>'s value.
+ * Any change events fired by the <em>wrapped</em> model are simply forwarded by
+ * the <em>wrapper</em> as its own.
+ * Similarly, changing the <em>wrapper</em>'s <em>wrapped</em> model can also
+ * trigger a change event
+ * (see {@link #wrappedValueChanged(PropertyValueModel, PropertyValueModel)}).
+ * That is, the <em>wrapped</em> model is held by yet another property value
+ * model!
+ * <p>
+ * <ul>
+ * <li>Double (<em>wrapper</em>) property value model - a client can listen to
+ *     this model and receive the same change notification whether the
+ *     <em>wrapped</em> model or the <em>wrapped</em> model's value changes;
+ *     much like an {@link PropertyAspectAdapter aspect adapter} whose subject
+ *     model is <em>not</em> another property value model
+ *     <ul>
+ *     <li><em>Wrapped</em> property value model - this model is built and
+ *         maintained by the server that also builds the <em>wrapper</em> model
+ *         (i.e. the server will monitor some other model that determines when
+ *         the <em>wrapped</em> model is changed)
+ *         <ul>
+ *         <li>Original property value model - this model is the "original"
+ *             model that contains the value of interest
+ *         </ul>
+ *     </ul>
+ * </ul>
+ * <p>
+ * This wrapper is useful when a change in the <em>wrapped</em> model is
+ * signaled by a non-value event and a third-party would like to change it.
+ *
+ * @param <V> the type of the both the <em>wrapped</em> and <em>wrapper</em>
+ * models' values
+ */
+public class DoublePropertyValueModel<V>
+	extends PropertyValueModelWrapper<PropertyValueModel<? extends V>>
+	implements PropertyValueModel<V>
+{
+	/**
+	 * The optionally present wrapped value model value; held by
+	 * {@link #valueModel}. This may be <code>null</code>.
+	 */
+	protected volatile PropertyValueModel<? extends V> valueModelValueModel;
+
+	/**
+	 * A listener that allows us to sync with changes to the wrapped value
+	 * model model.
+	 */
+	protected final PropertyChangeListener valueModelValueListener;
+
+
+	// ********** constructors/initialization **********
+
+	/**
+	 * Construct a double property value model for the specified
+	 * wrapped property value model model.
+	 */
+	public DoublePropertyValueModel(PropertyValueModel<? extends PropertyValueModel<? extends V>> valueModel) {
+		super(valueModel);
+		this.valueModelValueListener = this.buildValueModelValueListener();
+	}
+
+	protected PropertyChangeListener buildValueModelValueListener() {
+		return new ValueModelListener();
+	}
+
+	/* CU private */ class ValueModelListener
+		extends PropertyChangeAdapter
+	{
+		@Override
+		public void propertyChanged(PropertyChangeEvent event) {
+			DoublePropertyValueModel.this.wrappedValueModelValueChanged(event);
+		}
+	}
+
+
+	// ********** PropertyValueModel implementation **********
+
+	@Override
+	public V getValue() {
+		return (this.valueModelValueModel == null) ? null : this.valueModelValueModel.getValue();
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.getValue());
+	}
+
+
+	// ********** wrapped value model **********
+
+	/**
+	 * The value model has changed.
+	 * Move our value model listener and
+	 * notify listeners that the value has changed.
+	 */
+	@Override
+	protected void wrappedValueChanged(PropertyValueModel<? extends V> oldValue, PropertyValueModel<? extends V> newValue) {
+		if (this.hasListeners()) {
+			V old = this.getValue();
+			this.disengageValueModel();
+			this.engageValueModel();
+			this.firePropertyChanged(VALUE, old, this.getValue());
+		}
+	}
+
+
+	// ********** wrapped value model value **********
+
+	/**
+	 * The value of the wrapped value model's value model has changed.
+	 * Forward the event as our own.
+	 */
+    protected void wrappedValueModelValueChanged(PropertyChangeEvent event) {
+		this.firePropertyChanged(event.clone(this));
+	}
+
+	/**
+	 * Begin listening to the value model.
+	 */
+	@Override
+	protected void engageModel() {
+		super.engageModel();
+		this.engageValueModel();
+	}
+
+	protected void engageValueModel() {
+		this.valueModelValueModel = this.valueModel.getValue();
+		if (this.valueModelValueModel != null) {
+			this.valueModelValueModel.addPropertyChangeListener(VALUE, this.valueModelValueListener);
+		}
+	}
+
+	/**
+	 * Stop listening to the value model.
+	 */
+	@Override
+	protected void disengageModel() {
+		this.disengageValueModel();
+		super.disengageModel();
+	}
+
+	protected void disengageValueModel() {
+		if (this.valueModelValueModel != null) {
+			this.valueModelValueModel.removePropertyChangeListener(VALUE, this.valueModelValueListener);
+		}
+		this.valueModelValueModel = null;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ElementPropertyValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ElementPropertyValueModelAdapter.java
new file mode 100644
index 0000000..4c6cf48
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ElementPropertyValueModelAdapter.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+
+/**
+ * Adapt an element in a collection value model to a property value model.
+ * The property model's value is determined by whether the collection model
+ * contains the value: If the collection model contains the value,
+ * the property model's value is <em>that</em> element; otherwise, the property
+ * model's value is <code>null</code>. A {@link #predicate} is used to determine
+ * whether the collection model contains the relevant value.
+ * <p>
+ * This is useful for a client (e.g. a UI widget) that is longer-living than its
+ * underlying model. Obviously, the client must be prepared to handle a value of
+ * <code>null</code>.
+ *
+ * @param <V> the type of the both the model's value and
+ * the wrapped collection value model's elements
+ */
+public class ElementPropertyValueModelAdapter<V>
+	extends CollectionPropertyValueModelAdapter<V, V>
+{
+	/**
+	 * A predicate used to determine whether an element in the wrapped
+	 * collection model is the model's value.
+	 */
+	protected final Filter<V> predicate;
+
+
+	/**
+	 * Construct a property value model whose value depends on whether the
+	 * specified collection value model contains the value. The specified
+	 * filter is used to determine whether an element in the specified
+	 * collection model is the property value.
+	 */
+	public ElementPropertyValueModelAdapter(CollectionValueModel<? extends V> collectionModel, Filter<V> predicate) {
+		super(collectionModel);
+		if (predicate == null) {
+			throw new NullPointerException();
+		}
+		this.predicate = predicate;
+	}
+
+	/**
+	 * If the collection model contains the property model's {@link #value},
+	 * return that element; otherwise return <code>null</code>.
+	 */
+	@Override
+	protected V buildValue() {
+		for (V each : this.collectionModel) {
+			if (this.predicate.accept(each)) {
+				return each;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Check whether the wrapped collection model now contains the
+	 * {@link #value}.
+	 */
+	@Override
+	protected void itemsAdded(Iterable<V> items) {
+		if (this.value == null) {
+			this.itemsAdded_(items);
+		}
+	}
+
+	protected void itemsAdded_(Iterable<V> items) {
+		for (V each : items) {
+			if (this.predicate.accept(each)) {
+				this.firePropertyChanged(VALUE, null, this.value = each);
+				return;
+			}
+		}
+	}
+
+	/**
+	 * Check whether the wrapped collection model no longer contains the
+	 * {@link #value}.
+	 */
+	@Override
+	protected void itemsRemoved(Iterable<V> items) {
+		if (this.value != null) {
+			this.itemsRemoved_(items);
+		}
+	}
+
+	protected void itemsRemoved_(Iterable<V> items) {
+		for (V each : items) {
+			if (this.valuesAreEqual(each, this.value)) {
+				V old = this.value;
+				this.firePropertyChanged(VALUE, old, this.value = null);
+				return;
+			}
+		}
+	}
+
+	/**
+	 * The {@link #value} must now be <code>null</code>.
+	 */
+	@Override
+	protected void collectionCleared(CollectionClearEvent event) {
+		if (this.value != null) {
+			V old = this.value;
+			this.firePropertyChanged(VALUE, old, this.value = null);
+		}
+	}
+
+	/**
+	 * Re-calculate the {@link #value}.
+	 */
+	@Override
+	protected void collectionChanged(CollectionChangeEvent event) {
+		V old = this.value;
+		this.firePropertyChanged(VALUE, old, this.value = this.buildValue());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ExtendedListValueModelWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ExtendedListValueModelWrapper.java
new file mode 100644
index 0000000..fd16d28
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ExtendedListValueModelWrapper.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyCompositeListIterator;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyListIterator;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+
+/**
+ * This wrapper extends a {@link ListValueModel}
+ * (or {@link org.eclipse.jpt.common.utility.model.value.CollectionValueModel CollectionValueModel})
+ * with fixed collections of items on either end.
+ * <p>
+ * <strong>NB:</strong> Be careful using or wrapping this list value model, since the
+ * "extended" items may be unexpected by the client code or wrapper.
+ */
+public class ExtendedListValueModelWrapper<E>
+	extends ListValueModelWrapper<E>
+	implements ListValueModel<E>
+{
+	/** the items "prepended" to the wrapped list */
+	protected List<E> prefix;
+
+	/** the items "appended" to the wrapped list */
+	protected List<E> suffix;
+
+
+	// ********** lots o' constructors **********
+
+	/**
+	 * Extend the specified list with a prefix and suffix.
+	 */
+	public ExtendedListValueModelWrapper(List<? extends E> prefix, ListValueModel<? extends E> listHolder, List<? extends E> suffix) {
+		super(listHolder);
+		this.prefix = new ArrayList<E>(prefix);
+		this.suffix = new ArrayList<E>(suffix);
+	}
+
+	/**
+	 * Extend the specified list with a prefix and suffix.
+	 */
+	public ExtendedListValueModelWrapper(E prefix, ListValueModel<? extends E> listHolder, E suffix) {
+		super(listHolder);
+		this.prefix = Collections.singletonList(prefix);
+		this.suffix = Collections.singletonList(suffix);
+	}
+
+	/**
+	 * Extend the specified list with a prefix.
+	 */
+	public ExtendedListValueModelWrapper(List<? extends E> prefix, ListValueModel<? extends E> listHolder) {
+		super(listHolder);
+		this.prefix = new ArrayList<E>(prefix);
+		this.suffix = Collections.emptyList();
+	}
+
+	/**
+	 * Extend the specified list with a prefix.
+	 */
+	public ExtendedListValueModelWrapper(E prefix, ListValueModel<? extends E> listHolder) {
+		super(listHolder);
+		this.prefix = Collections.singletonList(prefix);
+		this.suffix = Collections.emptyList();
+	}
+
+	/**
+	 * Extend the specified list with a suffix.
+	 */
+	public ExtendedListValueModelWrapper(ListValueModel<? extends E> listHolder, List<? extends E> suffix) {
+		super(listHolder);
+		this.prefix = Collections.emptyList();
+		this.suffix = new ArrayList<E>(suffix);
+	}
+
+	/**
+	 * Extend the specified list with a suffix.
+	 */
+	public ExtendedListValueModelWrapper(ListValueModel<? extends E> listHolder, E suffix) {
+		super(listHolder);
+		this.prefix = Collections.emptyList();
+		this.suffix = Collections.singletonList(suffix);
+	}
+
+	/**
+	 * Extend the specified list with a prefix containing a single null item.
+	 */
+	public ExtendedListValueModelWrapper(ListValueModel<? extends E> listHolder) {
+		super(listHolder);
+		this.prefix = Collections.singletonList(null);
+		this.suffix = Collections.emptyList();
+	}
+
+
+	// ********** ListValueModel implementation **********
+
+	@Override
+	public Iterator<E> iterator() {
+		return this.listIterator();
+	}
+
+	@Override
+	public ListIterator<E> listIterator() {
+		return new ReadOnlyListIterator<E>(this.listIterator_());
+	}
+
+	@SuppressWarnings("unchecked")
+	protected ListIterator<E> listIterator_() {
+		return new ReadOnlyCompositeListIterator<E>(
+			this.prefix.listIterator(),
+			this.listModel.listIterator(),
+			this.suffix.listIterator()
+		);
+	}
+
+	@Override
+	public E get(int index) {
+		int prefixSize = this.prefix.size();
+		if (index < prefixSize) {
+			return this.prefix.get(index);
+		} else if (index >= prefixSize + this.listModel.size()) {
+			return this.suffix.get(index - (prefixSize + this.listModel.size()));
+		} else {
+			return this.listModel.get(index - prefixSize);
+		}
+	}
+
+	@Override
+	public int size() {
+		return this.prefix.size() + this.listModel.size() + this.suffix.size();
+	}
+
+	@Override
+	public Object[] toArray() {
+		ArrayList<E> list = new ArrayList<E>(this.size());
+		list.addAll(this.prefix);
+		CollectionTools.addAll(list, this.listModel.iterator());
+		list.addAll(this.suffix);
+		return list.toArray();
+	}
+
+
+	// ********** ListValueModelWrapper implementation/overrides **********
+
+	@Override
+	protected void itemsAdded(ListAddEvent event) {
+		this.fireItemsAdded(event.clone(this, LIST_VALUES, this.prefix.size()));
+	}
+
+	@Override
+	protected void itemsRemoved(ListRemoveEvent event) {
+		this.fireItemsRemoved(event.clone(this, LIST_VALUES, this.prefix.size()));
+	}
+
+	@Override
+	protected void itemsReplaced(ListReplaceEvent event) {
+		this.fireItemsReplaced(event.clone(this, LIST_VALUES, this.prefix.size()));
+	}
+
+	@Override
+	protected void itemsMoved(ListMoveEvent event) {
+		this.fireItemsMoved(event.clone(this, LIST_VALUES, this.prefix.size()));
+	}
+
+	@Override
+	protected void listCleared(ListClearEvent event) {
+		this.fireListChanged(LIST_VALUES, this.buildList());  // not "cleared"
+	}
+
+	@Override
+	protected void listChanged(ListChangeEvent event) {
+		this.fireListChanged(LIST_VALUES, this.buildList());
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		StringBuilderTools.append(sb, this);
+	}
+
+
+	// ********** miscellaneous **********
+
+	public void setPrefix(List<E> prefix) {
+		this.prefix = prefix;
+		this.fireListChanged(LIST_VALUES, this.buildList());
+	}
+
+	public void setSuffix(List<E> suffix) {
+		this.suffix = suffix;
+		this.fireListChanged(LIST_VALUES, this.buildList());
+	}
+
+	private List<E> buildList() {
+		return ListTools.list(this.listIterator_());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/FilteringCollectionValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/FilteringCollectionValueModel.java
new file mode 100644
index 0000000..7b120c5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/FilteringCollectionValueModel.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.iterable.FilteringIterable;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyIterator;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+
+/**
+ * A <code>FilteringCollectionValueModel</code> wraps another
+ * {@link CollectionValueModel} and uses a {@link Filter}
+ * to determine which items in the collection are returned by calls
+ * to {@link #iterator()}.
+ * <p>
+ * The filter can be changed at any time; allowing the same
+ * adapter to be used with different filter criteria (e.g. when the user
+ * wants to view a list of <code>.java</code> files).
+ * <p>
+ * <strong>NB:</strong> If the objects in the "filtered" collection can change in such a way
+ * that they should be removed from the "filtered" collection, you will
+ * need to wrap the original collection in an {@link ItemAspectListValueModelAdapter}.
+ * For example, if the filter only "accepts" items whose names begin
+ * with "X" and the names of the items can change, you will need to
+ * wrap the original list of unfiltered items with an
+ * {@link ItemPropertyListValueModelAdapter} that listens for changes to each
+ * item's name and fires the appropriate event whenever an item's name
+ * changes. The event will cause this wrapper to re-filter the changed
+ * item and add or remove it from the "filtered" collection as appropriate.
+ */
+public class FilteringCollectionValueModel<E>
+	extends CollectionValueModelWrapper<E>
+	implements CollectionValueModel<E>
+{
+	/** This filters the items in the nested collection. */
+	private Filter<E> filter;
+
+	/** Cache the items that were accepted by the filter */
+	private final ArrayList<E> filteredItems = new ArrayList<E>();
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a collection value model with the specified wrapped
+	 * collection value model and a filter that simply accepts every object.
+	 */
+	public FilteringCollectionValueModel(CollectionValueModel<? extends E> collectionModel) {
+		this(collectionModel, Filter.Transparent.<E>instance());
+	}
+
+	/**
+	 * Construct a collection value model with the specified wrapped
+	 * collection value model and filter.
+	 */
+	public FilteringCollectionValueModel(CollectionValueModel<? extends E> collectionModel, Filter<E> filter) {
+		super(collectionModel);
+		if (filter == null) {
+			throw new NullPointerException();
+		}
+		this.filter = filter;
+	}
+
+	/**
+	 * Construct a collection value model with the specified wrapped
+	 * list value model and a filter that simply accepts every object.
+	 */
+	public FilteringCollectionValueModel(ListValueModel<? extends E> listModel) {
+		this(new ListCollectionValueModelAdapter<E>(listModel));
+	}
+
+	/**
+	 * Construct a collection value model with the specified wrapped
+	 * list value model and filter.
+	 */
+	public FilteringCollectionValueModel(ListValueModel<? extends E> listModel, Filter<E> filter) {
+		this(new ListCollectionValueModelAdapter<E>(listModel), filter);
+	}
+
+
+	// ********** CollectionValueModel implementation **********
+
+	@Override
+	public Iterator<E> iterator() {
+		return new ReadOnlyIterator<E>(this.filteredItems);
+	}
+
+	@Override
+	public int size() {
+		return this.filteredItems.size();
+	}
+
+
+	// ********** CollectionValueModelWrapper overrides/implementation **********
+
+	@Override
+	protected void engageModel() {
+		super.engageModel();
+		// sync our cache *after* we start listening to the nested collection,
+		// since its value might change when a listener is added
+		CollectionTools.addAll(this.filteredItems, this.filter(this.collectionModel));
+	}
+
+	@Override
+	protected void disengageModel() {
+		super.disengageModel();
+		// clear out the cache when we are not listening to the nested collection
+		this.filteredItems.clear();
+	}
+
+	@Override
+	protected void itemsAdded(CollectionAddEvent event) {
+		// filter the values before propagating the change event
+		this.addItemsToCollection(this.filter(this.getItems(event)), this.filteredItems, VALUES);
+	}
+
+	@Override
+	protected void itemsRemoved(CollectionRemoveEvent event) {
+		// do *not* filter the values, because they may no longer be
+		// "accepted" and that might be why they were removed in the first place;
+		// anyway, any extraneous items are harmless
+		this.removeItemsFromCollection(event.getItems(), this.filteredItems, VALUES);
+	}
+
+	@Override
+	protected void collectionCleared(CollectionClearEvent event) {
+		this.clearCollection(this.filteredItems, VALUES);
+	}
+
+	@Override
+	protected void collectionChanged(CollectionChangeEvent event) {
+		this.rebuildFilteredItems();
+	}
+
+
+	// ********** miscellaneous **********
+
+	/**
+	 * Change the filter and rebuild the collection.
+	 */
+	public void setFilter(Filter<E> filter) {
+		this.filter = filter;
+		this.rebuildFilteredItems();
+	}
+
+	/**
+	 * Return an iterable that filters the specified iterable.
+	 */
+	protected Iterable<E> filter(Iterable<? extends E> items) {
+		return new FilteringIterable<E>(items, this.filter);
+	}
+
+	/**
+	 * Synchronize our cache with the wrapped collection.
+	 */
+	protected void rebuildFilteredItems() {
+		this.filteredItems.clear();
+		CollectionTools.addAll(this.filteredItems, this.filter(this.collectionModel));
+		this.fireCollectionChanged(VALUES, this.filteredItems);
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.filteredItems);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/FilteringModifiablePropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/FilteringModifiablePropertyValueModel.java
new file mode 100644
index 0000000..61b78da
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/FilteringModifiablePropertyValueModel.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.filter.Filter;
+
+/**
+ * A <code>FilteringModifiablePropertyValueModel</code> wraps another
+ * {@link ModifiablePropertyValueModel} and uses a pair of {@link Filter}s
+ * to determine when the wrapped value is to be returned by calls
+ * to {@link #getValue()} and modified by calls to
+ * {@link #setValue(Object) setValue(V)}.
+ * <p>
+ * One, possibly undesirable, side-effect of using this value model is that
+ * it must return <em>something</em> as the value. The default behavior is
+ * to return <code>null</code> whenever the wrapped value is not "accepted",
+ * which can be configured and/or overridden
+ * ({@link FilteringPropertyValueModel#getDefaultValue() getDefaultValue()}).
+ * <p>
+ * Another, possibly undesirable, side-effect of using this value model is that
+ * it will not fire an event if a new value is not "accepted", even if it is
+ * different than the current value.
+ * <p>
+ * Similarly, if an incoming value is not "reverse accepted", <em>nothing</em>
+ * will passed through to the wrapped value model, not even <code>null</code>.
+ *
+ * @param <V> the type of the model's <em>filtered</em> value
+ * @see Filter
+ */
+public class FilteringModifiablePropertyValueModel<V>
+	extends FilteringPropertyValueModel<V>
+	implements ModifiablePropertyValueModel<V>
+{
+	/**
+	 * The model sets the wrapped value to any value accepted by this filter
+	 * and does nothing with any value rejected by this filter.
+	 */
+	protected final Filter<V> setFilter;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a filtering property value model with the specified nested
+	 * property value model, <em>get</em> filter, and <em>set</em> filter.
+	 * The default value will be <code>null</code>.
+	 */
+	public FilteringModifiablePropertyValueModel(ModifiablePropertyValueModel<V> valueModel, Filter<V> getFilter, Filter<V> setFilter) {
+		this(valueModel, getFilter, setFilter, null);
+	}
+
+	/**
+	 * Construct a filtering property value model with the specified nested
+	 * property value model, <em>get</em> filter, <em>set</em> filter,
+	 * and default value.
+	 */
+	public FilteringModifiablePropertyValueModel(ModifiablePropertyValueModel<V> valueModel, Filter<V> getFilter, Filter<V> setFilter, V defaultValue) {
+		super(valueModel, getFilter, defaultValue);
+		if (setFilter == null) {
+			throw new NullPointerException();
+		}
+		this.setFilter = setFilter;
+	}
+
+
+	// ********** ModifiablePropertyValueModel implementation **********
+
+	@Override
+	public void setValue(V value) {
+		if (this.setFilter.accept(value)) {
+			this.getValueModel().setValue(value);
+		}
+	}
+
+	/**
+	 * Our constructor accepts only a {@link ModifiablePropertyValueModel}{@code<T>}.
+	 */
+	@SuppressWarnings("unchecked")
+	protected ModifiablePropertyValueModel<V> getValueModel() {
+		return (ModifiablePropertyValueModel<V>) this.valueModel;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/FilteringPropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/FilteringPropertyValueModel.java
new file mode 100644
index 0000000..f195c31
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/FilteringPropertyValueModel.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.filter.Filter;
+
+/**
+ * A <code>FilteringPropertyValueModel</code> wraps another
+ * {@link PropertyValueModel} and uses a {@link Filter}
+ * to determine when the wrapped value is to be returned by calls
+ * to {@link #getValue()}.
+ * <p>
+ * One, possibly undesirable, side-effect of using this value model is that
+ * it must return <em>something</em> as the value. The default behavior is
+ * to return <code>null</code> whenever the wrapped value is not "accepted",
+ * which can be configured and/or overridden ({@link #getDefaultValue()}).
+ *
+ * @param <V> the type of the model's <em>filtered</em> value
+ * @see Filter
+ */
+public class FilteringPropertyValueModel<V>
+	extends PropertyValueModelWrapper<V>
+	implements PropertyValueModel<V>
+{
+	/**
+	 * The model returns any wrapped value accepted by this filter and returns
+	 * the {@link #defaultValue} in place of any wrapped value rejected by this
+	 * filter.
+	 */
+	protected final Filter<V> filter;
+
+	/**
+	 * The value returned by the model if the wrapped value is reject by the
+	 * {@link #filter}.
+	 */
+	protected final V defaultValue;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a filtering property value model with the specified nested
+	 * property value model and filter.
+	 * The default value will be <code>null</code>.
+	 */
+	public FilteringPropertyValueModel(PropertyValueModel<? extends V> valueModel, Filter<V> filter) {
+		this(valueModel, filter, null);
+	}
+
+	/**
+	 * Construct a filtering property value model with the specified nested
+	 * property value model, filter, and default value.
+	 */
+	public FilteringPropertyValueModel(PropertyValueModel<? extends V> valueModel, Filter<V> filter, V defaultValue) {
+		super(valueModel);
+		if (filter == null) {
+			throw new NullPointerException();
+		}
+		this.filter = filter;
+		this.defaultValue = defaultValue;
+	}
+
+
+	// ********** PropertyValueModel implementation **********
+
+	@Override
+	public V getValue() {
+		return this.filterValue(this.valueModel.getValue());
+	}
+
+
+	// ********** PropertyValueModelWrapper implementation **********
+
+	@Override
+	protected void wrappedValueChanged(V oldValue, V newValue) {
+		// filter the values before propagating the change event
+		this.firePropertyChanged(VALUE, this.filterValue(oldValue), this.filterValue(newValue));
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * If the specified value is "accepted" simply return it,
+	 * otherwise return the default value.
+	 */
+	protected V filterValue(V value) {
+		return this.filter.accept(value) ? value : this.getDefaultValue();
+	}
+
+	/**
+	 * Return the object that should be returned if
+	 * the nested value was rejected by the filter.
+	 * The default is <code>null</code>.
+	 */
+	protected V getDefaultValue() {
+		return this.defaultValue;
+	}
+
+	/**
+	 * Print the filtered value.
+	 */
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.getValue());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemAspectListValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemAspectListValueModelAdapter.java
new file mode 100644
index 0000000..d6e77ae
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemAspectListValueModelAdapter.java
@@ -0,0 +1,280 @@
+/*******************************************************************************

+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.model.value;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.EventObject;

+import java.util.IdentityHashMap;

+import java.util.Iterator;

+import java.util.ListIterator;

+import org.eclipse.persistence.tools.utility.StringBuilderTools;

+import org.eclipse.persistence.tools.utility.collection.ListTools;

+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyListIterator;

+import org.eclipse.persistence.tools.utility.model.Model;

+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;

+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;

+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;

+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;

+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;

+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;

+import org.eclipse.persistence.tools.utility.reference.SimpleIntReference;

+

+/**

+ * Abstract list value model that provides behavior for wrapping a {@link ListValueModel}

+ * (or {@link CollectionValueModel}) and listening for changes to aspects of the

+ * <em>items</em> held by the list (or collection). Changes to the actual list

+ * (or collection) are also monitored.

+ *

+ * This is useful if you have a collection of items that can be modified by adding

+ * or removing items or the items themselves might change in a fashion that

+ * might change the list or collection's external appearance.

+ *

+ * Subclasses need to override two methods:<ul>

+ * <li>{@link #engageItem_(Model)}<p>

+ *     begin listening to the appropriate aspect of the specified item and call

+ *     {@link #itemAspectChanged(EventObject)} whenever the aspect changes

+ * <li>{@link #disengageItem_(Model)}<p>

+ *     stop listening to the appropriate aspect of the specified item

+ * </ul>

+ */

+@SuppressWarnings("nls")

+public abstract class ItemAspectListValueModelAdapter<E>

+	extends ListValueModelWrapper<E>

+	implements ListValueModel<E>

+{

+

+	/**

+	 * Maintain a counter for each of the items in the

+	 * wrapped list holder we are listening to.

+	 */

+	protected final IdentityHashMap<E, SimpleIntReference> counters;

+

+

+	// ********** constructors **********

+

+	/**

+	 * Constructor - the list holder is required.

+	 */

+	protected ItemAspectListValueModelAdapter(ListValueModel<? extends E> listHolder) {

+		super(listHolder);

+		this.counters = new IdentityHashMap<E, SimpleIntReference>();

+	}

+

+	/**

+	 * Constructor - the collection holder is required.

+	 */

+	protected ItemAspectListValueModelAdapter(CollectionValueModel<? extends E> collectionHolder) {

+		this(new CollectionListValueModelAdapter<E>(collectionHolder));

+	}

+

+

+	// ********** ListValueModel implementation **********

+

+	@Override

+	public Iterator<E> iterator() {

+		return this.listIterator();

+	}

+

+	@Override

+	public ListIterator<E> listIterator() {

+		return new ReadOnlyListIterator<E>(this.listModel.listIterator());

+	}

+

+	@Override

+	public E get(int index) {

+		return this.listModel.get(index);

+	}

+

+	@Override

+	public int size() {

+		return this.listModel.size();

+	}

+

+	@Override

+	public Object[] toArray() {

+		return this.listModel.toArray();

+	}

+

+

+	// ********** behavior **********

+

+	/**

+	 * Start listening to the list holder and the items in the list.

+	 */

+	@Override

+	protected void engageModel() {

+		super.engageModel();

+		this.engageAllItems();

+	}

+

+	protected void engageAllItems() {

+		this.engageItems(this.listModel);

+	}

+

+	protected void engageItems(Iterable<? extends E> items) {

+		for (E item : items) {

+			this.engageItem(item);

+		}

+	}

+

+	protected void engageItem(E item) {

+		// listen to each item only once

+		SimpleIntReference counter = this.counters.get(item);

+		if (counter == null) {

+			counter = new SimpleIntReference();

+			this.counters.put(item, counter);

+			this.engageItem_((Model) item);

+		}

+		counter.increment();

+	}

+

+	/**

+	 * Start listening to the specified item.

+	 */

+	protected abstract void engageItem_(Model item);

+

+	/**

+	 * Stop listening to the list holder and the items in the list.

+	 */

+	@Override

+	protected void disengageModel() {

+		this.disengageAllItems();

+		super.disengageModel();

+	}

+

+	protected void disengageAllItems() {

+		this.disengageItems(this.listModel);

+	}

+

+	protected void disengageItems(Iterable<? extends E> items) {

+		for (E item : items) {

+			this.disengageItem(item);

+		}

+	}

+

+	protected void disengageItem(E item) {

+		// stop listening to each item only once

+		SimpleIntReference counter = this.counters.get(item);

+		if (counter == null) {

+			// something is wrong if this happens...  ~bjv

+			throw new IllegalStateException("missing counter: " + item);

+		}

+		if (counter.decrement() == 0) {

+			this.counters.remove(item);

+			this.disengageItem_((Model) item);

+		}

+	}

+

+	/**

+	 * Stop listening to the specified item.

+	 */

+	protected abstract void disengageItem_(Model item);

+

+	@Override

+	public void toString(StringBuilder sb) {

+		StringBuilderTools.append(sb, this);

+	}

+

+

+	// ********** list change support **********

+

+	/**

+	 * Items were added to the wrapped list holder.

+	 * Forward the event and begin listening to the added items.

+	 */

+	@Override

+	protected void itemsAdded(ListAddEvent event) {

+		// re-fire event with the wrapper as the source

+		this.fireItemsAdded(event.clone(this, LIST_VALUES));

+		this.engageItems(this.getItems(event));

+	}

+

+	/**

+	 * Items were removed from the wrapped list holder.

+	 * Stop listening to the removed items and forward the event.

+	 */

+	@Override

+	protected void itemsRemoved(ListRemoveEvent event) {

+		this.disengageItems(this.getItems(event));

+		// re-fire event with the wrapper as the source

+		this.fireItemsRemoved(event.clone(this, LIST_VALUES));

+	}

+

+	/**

+	 * Items were replaced in the wrapped list holder.

+	 * Stop listening to the removed items, forward the event,

+	 * and begin listening to the added items.

+	 */

+	@Override

+	protected void itemsReplaced(ListReplaceEvent event) {

+		this.disengageItems(this.getOldItems(event));

+		// re-fire event with the wrapper as the source

+		this.fireItemsReplaced(event.clone(this, LIST_VALUES));

+		this.engageItems(this.getNewItems(event));

+	}

+

+	/**

+	 * Items were moved in the wrapped list holder.

+	 * No need to change any listeners; just forward the event.

+	 */

+	@Override

+	protected void itemsMoved(ListMoveEvent event) {

+		// re-fire event with the wrapper as the source

+		this.fireItemsMoved(event.clone(this, LIST_VALUES));

+	}

+

+	/**

+	 * The wrapped list holder was cleared.

+	 * Stop listening to the removed items and forward the event.

+	 */

+	@Override

+	protected void listCleared(ListClearEvent event) {

+		// we should only need to disengage each item once...

+		// make a copy to prevent a ConcurrentModificationException

+		Collection<E> keys = new ArrayList<E>(this.counters.keySet());

+		this.disengageItems(keys);

+		this.counters.clear();

+		// re-fire event with the wrapper as the source

+		this.fireListCleared(LIST_VALUES);

+	}

+

+	/**

+	 * The wrapped list holder has changed in some dramatic fashion.

+	 * Reconfigure our listeners and forward the event.

+	 */

+	@Override

+	protected void listChanged(ListChangeEvent event) {

+		// we should only need to disengage each item once...

+		// make a copy to prevent a ConcurrentModificationException

+		Collection<E> keys = new ArrayList<E>(this.counters.keySet());

+		this.disengageItems(keys);

+		this.counters.clear();

+		// re-fire event with the wrapper as the source

+		this.fireListChanged(event.clone(this));

+		this.engageAllItems();

+	}

+

+

+	// ********** item change support **********

+

+	/**

+	 * The specified item has a bound property that has changed.

+	 * Notify listeners of the change. The listeners will have to determine

+	 * whether the item aspect change is significant.

+	 */

+	protected void itemAspectChanged(@SuppressWarnings("unused") EventObject event) {

+		this.fireListChanged(LIST_VALUES, ListTools.list(this.listModel, this.listModel.size()));

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemChangeListValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemChangeListValueModelAdapter.java
new file mode 100644
index 0000000..ca70757
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemChangeListValueModelAdapter.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.ChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.AbstractChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+
+/**
+ * Extend {@link ItemAspectListValueModelAdapter} to listen to all of the changes
+ * of each item in the wrapped list model.
+ */
+public class ItemChangeListValueModelAdapter<E>
+	extends ItemAspectListValueModelAdapter<E>
+{
+	/** Listener that listens to all the items in the list. */
+	protected final ChangeListener itemChangeListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an adapter for the specified items.
+	 */
+	public ItemChangeListValueModelAdapter(ListValueModel<E> listHolder) {
+		super(listHolder);
+		this.itemChangeListener = this.buildItemChangeListener();
+	}
+
+
+	// ********** initialization **********
+
+	protected ChangeListener buildItemChangeListener() {
+		return new ItemChangeListener();
+	}
+
+	protected class ItemChangeListener
+		extends AbstractChangeListener
+	{
+		@Override
+		protected void modelChanged(ChangeEvent event) {
+			ItemChangeListValueModelAdapter.this.itemAspectChanged(event);
+		}
+	}
+
+
+	// ********** behavior **********
+
+	@Override
+	protected void engageItem_(Model item) {
+		item.addChangeListener(this.itemChangeListener);
+	}
+
+	@Override
+	protected void disengageItem_(Model item) {
+		item.removeChangeListener(this.itemChangeListener);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemCollectionListValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemCollectionListValueModelAdapter.java
new file mode 100644
index 0000000..f275ccf
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemCollectionListValueModelAdapter.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Arrays;
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+
+/**
+ * Extend {@link ItemAspectListValueModelAdapter} to listen to one or more collection
+ * aspects of each item in the wrapped list model.
+ */
+@SuppressWarnings("nls")
+public class ItemCollectionListValueModelAdapter<E>
+	extends ItemAspectListValueModelAdapter<E>
+{
+
+	/** The names of the items' collections that we listen to. */
+	protected final String[] collectionNames;
+
+	/** Listener that listens to all the items in the list. */
+	protected final CollectionChangeListener itemCollectionListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an adapter for the specified item Collections.
+	 */
+	public ItemCollectionListValueModelAdapter(ListValueModel<E> listHolder, String... collectionNames) {
+		super(listHolder);
+		if (collectionNames == null) {
+			throw new NullPointerException();
+		}
+		this.collectionNames = collectionNames;
+		this.itemCollectionListener = this.buildItemCollectionListener();
+	}
+
+	/**
+	 * Construct an adapter for the specified item Collections.
+	 */
+	public ItemCollectionListValueModelAdapter(CollectionValueModel<E> collectionHolder, String... collectionNames) {
+		this(new CollectionListValueModelAdapter<E>(collectionHolder), collectionNames);
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * All we really care about is the fact that a Collection aspect has
+	 * changed.  Do the same thing no matter which event occurs.
+	 */
+	protected CollectionChangeListener buildItemCollectionListener() {
+		return new CollectionChangeListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent event) {
+				ItemCollectionListValueModelAdapter.this.itemAspectChanged(event);
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent event) {
+				ItemCollectionListValueModelAdapter.this.itemAspectChanged(event);
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent event) {
+				ItemCollectionListValueModelAdapter.this.itemAspectChanged(event);
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent event) {
+				ItemCollectionListValueModelAdapter.this.itemAspectChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "item collection listener: " + Arrays.asList(ItemCollectionListValueModelAdapter.this.collectionNames);
+			}
+		};
+	}
+
+
+	// ********** behavior **********
+
+	@Override
+	protected void engageItem_(Model item) {
+		for (String collectionName : this.collectionNames) {
+			item.addCollectionChangeListener(collectionName, this.itemCollectionListener);
+		}
+	}
+
+	@Override
+	protected void disengageItem_(Model item) {
+		for (String collectionName : this.collectionNames) {
+			item.removeCollectionChangeListener(collectionName, this.itemCollectionListener);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemListListValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemListListValueModelAdapter.java
new file mode 100644
index 0000000..cfa288c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemListListValueModelAdapter.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Arrays;
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+
+/**
+ * Extend {@link ItemAspectListValueModelAdapter} to listen to one or more list
+ * aspects of each item in the wrapped list model.
+ */
+@SuppressWarnings("nls")
+public class ItemListListValueModelAdapter<E>
+	extends ItemAspectListValueModelAdapter<E>
+{
+
+	/** The names of the subject's lists that we listen to. */
+	protected final String[] listNames;
+
+	/** Listener that listens to all the items in the list. */
+	protected final ListChangeListener itemListListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an adapter for the specified item List aspects.
+	 */
+	public ItemListListValueModelAdapter(ListValueModel<E> listHolder, String... listNames) {
+		super(listHolder);
+		if (listNames == null) {
+			throw new NullPointerException();
+		}
+		this.listNames = listNames;
+		this.itemListListener = this.buildItemListListener();
+	}
+
+	/**
+	 * Construct an adapter for the specified item List aspects.
+	 */
+	public ItemListListValueModelAdapter(CollectionValueModel<E> collectionHolder, String... listNames) {
+		this(new CollectionListValueModelAdapter<E>(collectionHolder), listNames);
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * All we really care about is the fact that the List aspect has
+	 * changed.  Do the same thing no matter which event occurs.
+	 */
+	protected ListChangeListener buildItemListListener() {
+		return new ListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) {
+				ItemListListValueModelAdapter.this.itemAspectChanged(event);
+			}
+			@Override
+			public void itemsRemoved(ListRemoveEvent event) {
+				ItemListListValueModelAdapter.this.itemAspectChanged(event);
+			}
+			@Override
+			public void itemsReplaced(ListReplaceEvent event) {
+				ItemListListValueModelAdapter.this.itemAspectChanged(event);
+			}
+			@Override
+			public void itemsMoved(ListMoveEvent event) {
+				ItemListListValueModelAdapter.this.itemAspectChanged(event);
+			}
+			@Override
+			public void listCleared(ListClearEvent event) {
+				ItemListListValueModelAdapter.this.itemAspectChanged(event);
+			}
+			@Override
+			public void listChanged(ListChangeEvent event) {
+				ItemListListValueModelAdapter.this.itemAspectChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "item list listener: " + Arrays.asList(ItemListListValueModelAdapter.this.listNames);
+			}
+		};
+	}
+
+
+	// ********** behavior **********
+
+	@Override
+	protected void engageItem_(Model item) {
+		for (String listName : this.listNames) {
+			item.addListChangeListener(listName, this.itemListListener);
+		}
+	}
+
+	@Override
+	protected void disengageItem_(Model item) {
+		for (String listName : this.listNames) {
+			item.removeListChangeListener(listName, this.itemListListener);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemPropertyListValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemPropertyListValueModelAdapter.java
new file mode 100644
index 0000000..208fcf1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemPropertyListValueModelAdapter.java
@@ -0,0 +1,132 @@
+/*******************************************************************************

+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.model.value;

+

+import java.util.Arrays;

+import java.util.EventListener;

+import java.util.EventObject;

+import org.eclipse.persistence.tools.utility.iterable.IterableTools;

+import org.eclipse.persistence.tools.utility.model.ChangeSupport;

+import org.eclipse.persistence.tools.utility.model.Model;

+import org.eclipse.persistence.tools.utility.model.SingleAspectChangeSupport;

+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;

+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;

+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;

+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;

+

+/**

+ * Extend {@link ItemAspectListValueModelAdapter} to listen to one or more

+ * properties of each item in the wrapped list model.

+ */

+@SuppressWarnings("nls")

+public class ItemPropertyListValueModelAdapter<E>

+	extends ItemAspectListValueModelAdapter<E>

+{

+

+	/** The names of the items' properties that we listen to. */

+	protected final String[] propertyNames;

+

+	/** Listener that listens to all the items in the list. */

+	protected final PropertyChangeListener itemPropertyListener;

+

+

+	// ********** constructors **********

+

+	/**

+	 * Construct an adapter for the specified item properties.

+	 */

+	public ItemPropertyListValueModelAdapter(ListValueModel<E> listHolder, String... propertyNames) {

+		super(listHolder);

+		if (propertyNames == null) {

+			throw new NullPointerException();

+		}

+		this.propertyNames = propertyNames;

+		this.itemPropertyListener = this.buildItemPropertyListener();

+	}

+

+	/**

+	 * Construct an adapter for the specified item properties.

+	 */

+	public ItemPropertyListValueModelAdapter(CollectionValueModel<E> collectionHolder, String... propertyNames) {

+		this(new CollectionListValueModelAdapter<E>(collectionHolder), propertyNames);

+	}

+

+

+	// ********** initialization **********

+

+	protected PropertyChangeListener buildItemPropertyListener() {

+		return new PropertyChangeListener() {

+			@Override

+			public void propertyChanged(PropertyChangeEvent event) {

+				ItemPropertyListValueModelAdapter.this.itemAspectChanged(event);

+			}

+			@Override

+			public String toString() {

+				return "item property listener: " + Arrays.asList(ItemPropertyListValueModelAdapter.this.propertyNames);

+			}

+		};

+	}

+

+

+	// ********** behavior **********

+

+	@Override

+	protected void engageItem_(Model item) {

+		for (String propertyName : this.propertyNames) {

+			item.addPropertyChangeListener(propertyName, this.itemPropertyListener);

+		}

+	}

+

+	@Override

+	protected void disengageItem_(Model item) {

+		for (String propertyName : this.propertyNames) {

+			item.removePropertyChangeListener(propertyName, this.itemPropertyListener);

+		}

+	}

+

+	/**

+	 * bug 342171

+	 * Override to just fire an itemReplaced event instead of a listChanged event.

+	 * An aspect of the item has changed, so no reason to say that the entire list has changed.

+	 * Added a LocalChangeSupport so that I can fire a ListReplacedEvent for an old list

+	 * and new list containing the same item.

+	 */

+	@Override

+	protected void itemAspectChanged(EventObject event) {

+		Object item = event.getSource();

+		this.getChangeSupport().fireItemsReplaced(

+			new ListReplaceEvent(this, LIST_VALUES, IterableTools.indexOf(this.listModel, item), item, item));

+	}

+

+	@Override

+	protected ChangeSupport buildChangeSupport() {

+		return new LocalChangeSupport(this, ListChangeListener.class, ListValueModel.LIST_VALUES);

+	}

+

+	/* CU private */ class LocalChangeSupport extends SingleAspectChangeSupport {

+		private static final long serialVersionUID = 1L;

+		LocalChangeSupport(Model source, Class<? extends EventListener> validListenerClass, String validAspectName) {

+			super(source, validListenerClass, validAspectName);

+		}

+		@Override

+		public boolean fireItemsReplaced(ListReplaceEvent event) {

+			this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName());

+			if (event.getItemsSize() != 0) {

+				this.fireItemsReplaced_(event);

+				return true;

+			}

+			return false;

+		}

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemStateListValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemStateListValueModelAdapter.java
new file mode 100644
index 0000000..06ae92c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ItemStateListValueModelAdapter.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
+
+/**
+ * Extend {@link ItemAspectListValueModelAdapter} to listen to the
+ * "state" of each item in the wrapped list model.
+ */
+@SuppressWarnings("nls")
+public class ItemStateListValueModelAdapter<E>
+	extends ItemAspectListValueModelAdapter<E>
+{
+	/** Listener that listens to all the items in the list. */
+	protected final StateChangeListener itemStateListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an adapter for the item state.
+	 */
+	public ItemStateListValueModelAdapter(ListValueModel<E> listHolder) {
+		super(listHolder);
+		this.itemStateListener = this.buildItemStateListener();
+	}
+
+	/**
+	 * Construct an adapter for the item state.
+	 */
+	public ItemStateListValueModelAdapter(CollectionValueModel<E> collectionHolder) {
+		this(new CollectionListValueModelAdapter<E>(collectionHolder));
+	}
+
+
+	// ********** initialization **********
+
+	protected StateChangeListener buildItemStateListener() {
+		return new StateChangeListener() {
+			@Override
+			public void stateChanged(StateChangeEvent event) {
+				ItemStateListValueModelAdapter.this.itemAspectChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "item state listener";
+			}
+		};
+	}
+
+
+	// ********** behavior **********
+
+	@Override
+	protected void engageItem_(Model item) {
+		item.addStateChangeListener(this.itemStateListener);
+	}
+
+	@Override
+	protected void disengageItem_(Model item) {
+		item.removeStateChangeListener(this.itemStateListener);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListAspectAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListAspectAdapter.java
new file mode 100644
index 0000000..c4c1362
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListAspectAdapter.java
@@ -0,0 +1,192 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Collection;
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+
+/**
+ * This extension of {@link AspectListValueModelAdapter} provides
+ * basic list change support.
+ * This converts a set of one or more lists into
+ * a single {@link #LIST_VALUES} list.
+ * <p>
+ * The typical subclass will override the following methods (see the descriptions
+ * in {@link AspectListValueModelAdapter}):<ul>
+ * <li>{@link #listIterator_()}
+ * <li>{@link #get(int)}
+ * <li>{@link #size_()}
+ * <li>{@link #toArray_()}
+ * <li>{@link #listIterator()}
+ * <li>{@link #size()}
+ * <li>{@link #toArray()}
+ * </ul>
+ *
+ * @param <S> the type of the adapter's subject
+ * @param <E> the type of the adapter's list's elements
+ */
+public abstract class ListAspectAdapter<S extends Model, E>
+	extends AspectListValueModelAdapter<S, E>
+{
+	/**
+	 * The name of the subject's lists that we use for the value.
+	 */
+	protected final String[] aspectNames;
+		protected static final String[] EMPTY_ASPECT_NAMES = new String[0];
+
+	/** A listener that listens to the subject's list aspects. */
+	protected final ListChangeListener aspectChangeListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a list aspect adapter for the specified subject
+	 * and list aspect.
+	 */
+	protected ListAspectAdapter(String aspectName, S subject) {
+		this(new String[] {aspectName}, subject);
+	}
+
+	/**
+	 * Construct a list aspect adapter for the specified subject
+	 * and list aspects.
+	 */
+	protected ListAspectAdapter(String[] aspectNames, S subject) {
+		this(new StaticPropertyValueModel<S>(subject), aspectNames);
+	}
+
+	/**
+	 * Construct a list aspect adapter for the specified subject holder
+	 * and lists.
+	 */
+	protected ListAspectAdapter(PropertyValueModel<? extends S> subjectModel, String... aspectNames) {
+		super(subjectModel);
+		if (aspectNames == null) {
+			throw new NullPointerException();
+		}
+		this.aspectNames = aspectNames;
+		this.aspectChangeListener = this.buildAspectChangeListener();
+	}
+
+	/**
+	 * Construct a list aspect adapter for the specified subject holder
+	 * and lists.
+	 */
+	protected ListAspectAdapter(PropertyValueModel<? extends S> subjectModel, Collection<String> aspectNames) {
+		this(subjectModel, aspectNames.toArray(new String[aspectNames.size()]));
+	}
+
+	/**
+	 * Construct a list aspect adapter for an "unchanging" list in
+	 * the specified subject. This is useful for a list aspect that does not
+	 * change for a particular subject; but the subject will change, resulting in
+	 * a new list.
+	 */
+	protected ListAspectAdapter(PropertyValueModel<? extends S> subjectModel) {
+		this(subjectModel, EMPTY_ASPECT_NAMES);
+	}
+
+
+	// ********** initialization **********
+
+	protected ListChangeListener buildAspectChangeListener() {
+		return new AspectChangeListener();
+	}
+
+	/**
+	 * Transform the subject's list change events into {@link #LIST_VALUES}
+	 * list change events
+	 */
+	protected class AspectChangeListener
+		extends ListChangeAdapter
+	{
+		@Override
+		public void itemsAdded(ListAddEvent event) {
+			ListAspectAdapter.this.aspectItemsAdded(event);
+		}
+		@Override
+		public void itemsRemoved(ListRemoveEvent event) {
+			ListAspectAdapter.this.aspectItemsRemoved(event);
+		}
+		@Override
+		public void itemsReplaced(ListReplaceEvent event) {
+			ListAspectAdapter.this.aspectItemsReplaced(event);
+		}
+		@Override
+		public void itemsMoved(ListMoveEvent event) {
+			ListAspectAdapter.this.aspectItemsMoved(event);
+		}
+		@Override
+		public void listCleared(ListClearEvent event) {
+			ListAspectAdapter.this.aspectListCleared(event);
+		}
+		@Override
+		public void listChanged(ListChangeEvent event) {
+			ListAspectAdapter.this.aspectListChanged(event);
+		}
+	}
+
+
+	// ********** AspectAdapter implementation **********
+
+	@Override
+	protected void engageSubject_() {
+    	for (String listName : this.aspectNames) {
+			this.subject.addListChangeListener(listName, this.aspectChangeListener);
+		}
+	}
+
+	@Override
+	protected void disengageSubject_() {
+    	for (String listName : this.aspectNames) {
+			this.subject.removeListChangeListener(listName, this.aspectChangeListener);
+		}
+	}
+
+
+	// ********** behavior **********
+
+	protected void aspectItemsAdded(ListAddEvent event) {
+		this.fireItemsAdded(event.clone(this, LIST_VALUES));
+	}
+
+	protected void aspectItemsRemoved(ListRemoveEvent event) {
+		this.fireItemsRemoved(event.clone(this, LIST_VALUES));
+	}
+
+	protected void aspectItemsReplaced(ListReplaceEvent event) {
+		this.fireItemsReplaced(event.clone(this, LIST_VALUES));
+	}
+
+	protected void aspectItemsMoved(ListMoveEvent event) {
+		this.fireItemsMoved(event.clone(this, LIST_VALUES));
+	}
+
+	protected void aspectListCleared(ListClearEvent event) {
+		this.fireListCleared(event.clone(this, LIST_VALUES));
+	}
+
+	protected void aspectListChanged(ListChangeEvent event) {
+		this.fireListChanged(event.clone(this, LIST_VALUES));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListCollectionValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListCollectionValueModelAdapter.java
new file mode 100644
index 0000000..f58e2e1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListCollectionValueModelAdapter.java
@@ -0,0 +1,242 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyIterator;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+
+/**
+ * An adapter that allows us to make a {@link ListValueModel} behave like
+ * a read-only {@link CollectionValueModel}, sorta.
+ * <p>
+ * We keep an internal collection somewhat in sync with the wrapped list.
+ * <p>
+ * <strong>NB:</strong> Since we only listen to the wrapped list when we have
+ * listeners ourselves and we can only stay in sync with the wrapped
+ * list while we are listening to it, results to various methods
+ * (e.g. {@link #size()}, {@link #iterator()}) will be unpredictable whenever
+ * we do not have any listeners. This should not be too painful since,
+ * most likely, client objects will also be listeners.
+ */
+@SuppressWarnings("nls")
+public class ListCollectionValueModelAdapter<E>
+	extends AbstractCollectionValueModel
+	implements CollectionValueModel<E>
+{
+	/** The wrapped list value model. */
+	protected final ListValueModel<? extends E> listHolder;
+
+	/** A listener that forwards any events fired by the list holder. */
+	protected final ListChangeListener listChangeListener;
+
+	/**
+	 * Our internal collection, which holds the same elements as
+	 * the wrapped list.
+	 */
+	// we declare this an ArrayList so we can use #clone() and #ensureCapacity(int)
+	protected final ArrayList<E> collection;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Wrap the specified list value model.
+	 */
+	public ListCollectionValueModelAdapter(ListValueModel<? extends E> listHolder) {
+		super();
+		if (listHolder == null) {
+			throw new NullPointerException();
+		}
+		this.listHolder = listHolder;
+		this.listChangeListener = this.buildListChangeListener();
+		this.collection = new ArrayList<E>();
+		// postpone building the collection and listening to the underlying list
+		// until we have listeners ourselves...
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * The wrapped list has changed, forward an equivalent
+	 * collection change event to our listeners.
+	 */
+	protected ListChangeListener buildListChangeListener() {
+		return new ListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) {
+				ListCollectionValueModelAdapter.this.itemsAdded(event);
+			}
+			@Override
+			public void itemsRemoved(ListRemoveEvent event) {
+				ListCollectionValueModelAdapter.this.itemsRemoved(event);
+			}
+			@Override
+			public void itemsReplaced(ListReplaceEvent event) {
+				ListCollectionValueModelAdapter.this.itemsReplaced(event);
+			}
+			@Override
+			public void itemsMoved(ListMoveEvent event) {
+				ListCollectionValueModelAdapter.this.itemsMoved(event);
+			}
+			@Override
+			public void listCleared(ListClearEvent event) {
+				ListCollectionValueModelAdapter.this.listCleared(event);
+			}
+			@Override
+			public void listChanged(ListChangeEvent event) {
+				ListCollectionValueModelAdapter.this.listChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "list change listener";
+			}
+		};
+	}
+
+
+	// ********** CollectionValueModel implementation **********
+
+	@Override
+	public Iterator<E> iterator() {
+		// try to prevent backdoor modification of the list
+		return new ReadOnlyIterator<E>(this.collection);
+	}
+
+	@Override
+	public int size() {
+		return this.collection.size();
+	}
+
+
+	// ********** AbstractCollectionValueModel implementation **********
+
+	@Override
+	protected void engageModel() {
+		this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+		// sync our collection *after* we start listening to the list model,
+		// since its value might change when a listener is added
+		this.buildCollection();
+	}
+
+	@Override
+	protected void disengageModel() {
+		this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+		// clear out the collection when we are not listening to the list holder
+		this.collection.clear();
+	}
+
+
+	// ********** behavior **********
+
+	protected void itemsAdded(ListAddEvent event) {
+		this.addItemsToCollection(this.getItems(event), this.collection, VALUES);
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getItems(ListAddEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+	protected void itemsRemoved(ListRemoveEvent event) {
+		this.removeItemsFromCollection(this.getItems(event), this.collection, VALUES);
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getItems(ListRemoveEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+	protected void itemsReplaced(ListReplaceEvent event) {
+		this.removeItemsFromCollection(this.getOldItems(event), this.collection, VALUES);
+		this.addItemsToCollection(this.getNewItems(event), this.collection, VALUES);
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getOldItems(ListReplaceEvent event) {
+		return (Iterable<E>) event.getOldItems();
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getNewItems(ListReplaceEvent event) {
+		return (Iterable<E>) event.getNewItems();
+	}
+
+	protected void itemsMoved(@SuppressWarnings("unused") ListMoveEvent event) {
+		// do nothing? moving items in a list has no net effect on a collection...
+	}
+
+	protected void listCleared(@SuppressWarnings("unused") ListClearEvent event) {
+		// put in empty check so we don't fire events unnecessarily
+		if ( ! this.collection.isEmpty()) {
+			this.collection.clear();
+			this.fireCollectionCleared(VALUES);
+		}
+	}
+
+	/**
+	 * synchronize our internal collection with the wrapped list
+	 * and fire the appropriate events
+	 */
+	protected void listChanged(@SuppressWarnings("unused") ListChangeEvent event) {
+		if (this.listHolder.size() == 0) {
+			if (this.collection.isEmpty()) {
+				// no change
+			} else {
+				this.clearCollection(this.collection, VALUES);
+			}
+		} else {
+			if (this.collection.isEmpty()) {
+				this.buildCollection();
+				this.fireItemsAdded(VALUES, this.collection);
+			} else {
+				this.collection.clear();
+				this.buildCollection();
+				this.fireCollectionChanged(VALUES, this.collection);
+			}
+		}
+	}
+
+	protected void buildCollection() {
+		// if the new list is empty, do nothing
+		int size = this.listHolder.size();
+		if (size != 0) {
+			this.buildCollection(size);
+		}
+	}
+
+	protected void buildCollection(int size) {
+		this.collection.ensureCapacity(size);
+		for (E each : this.listHolder) {
+			this.collection.add(each);
+		}
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.collection);
+	}
+}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListCurator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListCurator.java
new file mode 100644
index 0000000..bd323b9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListCurator.java
@@ -0,0 +1,237 @@
+/*******************************************************************************

+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

+ * which accompanies this distribution.

+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ * http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *     Oracle - initial API and implementation

+ *

+ ******************************************************************************/

+package org.eclipse.persistence.tools.utility.model.value;

+

+import java.util.ArrayList;

+import java.util.EventListener;

+import java.util.Iterator;

+import java.util.List;

+import java.util.ListIterator;

+import org.eclipse.persistence.tools.utility.collection.CollectionTools;

+import org.eclipse.persistence.tools.utility.collection.ListTools;

+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyListIterator;

+import org.eclipse.persistence.tools.utility.model.Model;

+import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;

+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;

+import org.eclipse.persistence.tools.utility.model.listener.StateChangeAdapter;

+import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;

+

+/**

+ * This extension of {@link AspectAdapter} provides list change support

+ * by adapting a subject's state change events to a minimum set

+ * of list change events.

+ *

+ * @param <S> the type of the adapter's subject

+ * @param <E> the type of the adapter's list's elements

+ */

+public abstract class ListCurator<S extends Model, E>

+	extends AspectAdapter<S, List<E>>

+	implements ListValueModel<E>

+{

+	/** How the list looked before the last state change */

+	private final ArrayList<E> record;

+

+	/** A listener that listens for the subject's state to change */

+	private final StateChangeListener stateChangeListener;

+

+

+	// ********** constructors **********

+

+	/**

+	 * Construct a curator for the specified subject.

+	 */

+	protected ListCurator(S subject) {

+		this(new StaticPropertyValueModel<S>(subject));

+	}

+

+	/**

+	 * Construct a curator for the specified subject model.

+	 * The subject model cannot be <code>null</code>.

+	 */

+	protected ListCurator(PropertyValueModel<? extends S> subjectModel) {

+		super(subjectModel);

+		this.record = new ArrayList<E>();

+		this.stateChangeListener = this.buildStateChangeListener();

+	}

+

+

+	// ********** initialization **********

+

+	/**

+	 * The subject's state has changed, do inventory and report to listeners.

+	 */

+	protected StateChangeListener buildStateChangeListener() {

+		return new SubjectStateChangeListener();

+	}

+

+	protected class SubjectStateChangeListener

+		extends StateChangeAdapter

+	{

+		@Override

+		public void stateChanged(StateChangeEvent event) {

+			ListCurator.this.submitInventoryReport();

+		}

+	}

+

+

+	// ********** ListValueModel implementation **********

+

+	@Override

+	public ListIterator<E> iterator() {

+		return this.listIterator();

+	}

+

+	@Override

+	public ListIterator<E> listIterator() {

+		return new ReadOnlyListIterator<E>(this.record);

+	}

+

+	/**

+	 * Return the item at the specified index of the subject's list aspect.

+	 */

+	@Override

+	public E get(int index) {

+		return this.record.get(index);

+	}

+

+	/**

+	 * Return the size of the subject's list aspect.

+	 */

+	@Override

+	public int size() {

+		return this.record.size();

+	}

+

+	/**

+	 * Return an array manifestation of the subject's list aspect.

+	 */

+	@Override

+	public Object[] toArray() {

+		return this.record.toArray();

+	}

+

+

+	// ********** AspectAdapter implementation **********

+

+	@Override

+	protected List<E> getAspectValue() {

+		return this.record;

+	}

+

+	@Override

+	protected Class<? extends EventListener> getListenerClass() {

+		return ListChangeListener.class;

+	}

+

+	@Override

+	protected String getListenerAspectName() {

+		return LIST_VALUES;

+	}

+

+	@Override

+	protected boolean hasListeners() {

+		return this.hasAnyListChangeListeners(LIST_VALUES);

+	}

+

+	/**

+	 * The aspect has changed, notify listeners appropriately.

+	 */

+	@Override

+	protected void fireAspectChanged(List<E> oldValue, List<E> newValue) {

+		this.fireListChanged(LIST_VALUES, this.record);

+	}

+

+	/**

+	 * The subject is not null - add our listener.

+	 */

+	@Override

+	protected void engageSubject_() {

+		((Model) this.subject).addStateChangeListener(this.stateChangeListener);

+		// sync our list *after* we start listening to the subject,

+		// since its value might change when a listener is added

+		CollectionTools.addAll(this.record, this.iteratorForRecord());

+	}

+

+	/**

+	 * The subject is not null - remove our listener.

+	 */

+	@Override

+	protected void disengageSubject_() {

+		((Model) this.subject).removeStateChangeListener(this.stateChangeListener);

+		// clear out the list when we are not listening to the subject

+		this.record.clear();

+	}

+

+

+	// ********** ListCurator protocol **********

+

+	/**

+	 * This is intended to be different from {@link ListValueModel#iterator()}.

+	 * It is intended to be used only when the subject changes or the

+	 * subject's "state" changes (as signified by a state change event).

+	 */

+	protected abstract Iterator<E> iteratorForRecord();

+

+

+	// ********** behavior **********

+

+	void submitInventoryReport() {

+		List<E> newRecord = ListTools.list(this.iteratorForRecord());

+		int recordIndex = 0;

+

+		// add items from the new record

+		for (E newItem : newRecord) {

+			this.inventoryNewItem(recordIndex, newItem);

+			recordIndex++;

+		}

+

+		// clean out items that are no longer in the new record

+		for (recordIndex = 0; recordIndex < this.record.size(); ) {

+			E item = this.record.get(recordIndex);

+

+			if (newRecord.contains(item)) {

+				recordIndex++;

+			} else {

+				this.removeItemFromInventory(recordIndex, item);

+			}

+		}

+	}

+

+	private void inventoryNewItem(int recordIndex, E newItem) {

+		List<E> rec = new ArrayList<E>(this.record);

+

+		if ((recordIndex < rec.size()) && rec.get(recordIndex).equals(newItem)) {

+			return;

+		}

+		if (rec.contains(newItem)) {

+			this.removeItemFromInventory(recordIndex, rec.get(recordIndex));

+			this.inventoryNewItem(recordIndex, newItem);

+		} else {

+			this.addItemToInventory(recordIndex, newItem);

+		}

+	}

+

+	private void addItemToInventory(int index, E item) {

+		this.addItemToList(index, item, this.record, LIST_VALUES);

+	}

+

+	private void removeItemFromInventory(int index, @SuppressWarnings("unused") E item) {

+		this.removeItemFromList(index, this.record, LIST_VALUES);

+	}

+

+	@Override

+	public void toString(StringBuilder sb) {

+		sb.append(this.record);

+	}

+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListPropertyValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListPropertyValueModelAdapter.java
new file mode 100644
index 0000000..df85ae5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListPropertyValueModelAdapter.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+
+/**
+ * This abstract class provides the infrastructure needed to wrap
+ * a list value model, "lazily" listen to it, and convert
+ * its change notifications into property value model change
+ * notifications.
+ * <p>
+ * Subclasses must override:<ul>
+ * <li>{@link #buildValue()}<p>
+ *     to return the current property value, as derived from the
+ *     current list value
+ * </ul>
+ * Subclasses might want to override the following methods
+ * to improve performance (by not recalculating the value, if possible):<ul>
+ * <li>{@link #itemsAdded(ListAddEvent event)}
+ * <li>{@link #itemsRemoved(ListRemoveEvent event)}
+ * <li>{@link #itemsReplaced(ListReplaceEvent event)}
+ * <li>{@link #itemsMoved(ListMoveEvent event)}
+ * <li>{@link #listCleared(ListClearEvent event)}
+ * <li>{@link #listChanged(ListChangeEvent event)}
+ * </ul>
+ */
+public abstract class ListPropertyValueModelAdapter<T>
+	extends AbstractPropertyValueModelAdapter<T>
+{
+	/** The wrapped list value model. */
+	protected final ListValueModel<?> listModel;
+
+	/** A listener that allows us to sync with changes to the wrapped list model. */
+	protected final ListChangeListener listListener;
+
+
+	// ********** constructor/initialization **********
+
+	/**
+	 * Construct a property value model with the specified wrapped
+	 * list value model.
+	 */
+	protected ListPropertyValueModelAdapter(ListValueModel<?> listModel) {
+		super();
+		if (listModel == null) {
+			throw new NullPointerException();
+		}
+		this.listModel = listModel;
+		this.listListener = this.buildListListener();
+	}
+
+	protected ListChangeListener buildListListener() {
+		return new ListListener();
+	}
+
+	protected class ListListener
+		extends ListChangeAdapter
+	{
+		@Override
+		public void itemsAdded(ListAddEvent event) {
+			ListPropertyValueModelAdapter.this.itemsAdded(event);
+		}
+		@Override
+		public void itemsRemoved(ListRemoveEvent event) {
+			ListPropertyValueModelAdapter.this.itemsRemoved(event);
+		}
+		@Override
+		public void itemsReplaced(ListReplaceEvent event) {
+			ListPropertyValueModelAdapter.this.itemsReplaced(event);
+		}
+		@Override
+		public void itemsMoved(ListMoveEvent event) {
+			ListPropertyValueModelAdapter.this.itemsMoved(event);
+		}
+		@Override
+		public void listCleared(ListClearEvent event) {
+			ListPropertyValueModelAdapter.this.listCleared(event);
+		}
+		@Override
+		public void listChanged(ListChangeEvent event) {
+			ListPropertyValueModelAdapter.this.listChanged(event);
+		}
+	}
+
+
+	// ********** listener **********
+
+	/**
+	 * Start listening to the list holder.
+	 */
+	@Override
+	protected void engageModel_() {
+		this.listModel.addListChangeListener(ListValueModel.LIST_VALUES, this.listListener);
+	}
+
+	/**
+	 * Stop listening to the list holder.
+	 */
+	@Override
+	protected void disengageModel_() {
+		this.listModel.removeListChangeListener(ListValueModel.LIST_VALUES, this.listListener);
+	}
+
+
+	// ********** list change support **********
+
+	/**
+	 * Items were added to the wrapped list holder;
+	 * propagate the change notification appropriately.
+	 */
+	protected void itemsAdded(@SuppressWarnings("unused") ListAddEvent event) {
+		// by default, simply recalculate the value and fire an event
+		this.propertyChanged();
+	}
+
+	/**
+	 * Items were removed from the wrapped list holder;
+	 * propagate the change notification appropriately.
+	 */
+	protected void itemsRemoved(@SuppressWarnings("unused") ListRemoveEvent event) {
+		// by default, simply recalculate the value and fire an event
+		this.propertyChanged();
+	}
+
+	/**
+	 * Items were replaced in the wrapped list holder;
+	 * propagate the change notification appropriately.
+	 */
+	protected void itemsReplaced(@SuppressWarnings("unused") ListReplaceEvent event) {
+		// by default, simply recalculate the value and fire an event
+		this.propertyChanged();
+	}
+
+	/**
+	 * Items were moved in the wrapped list holder;
+	 * propagate the change notification appropriately.
+	 */
+	protected void itemsMoved(@SuppressWarnings("unused") ListMoveEvent event) {
+		// by default, simply recalculate the value and fire an event
+		this.propertyChanged();
+	}
+
+	/**
+	 * The wrapped list holder was cleared;
+	 * propagate the change notification appropriately.
+	 */
+	protected void listCleared(@SuppressWarnings("unused") ListClearEvent event) {
+		// by default, simply recalculate the value and fire an event
+		this.propertyChanged();
+	}
+
+	/**
+	 * The value of the wrapped list holder has changed;
+	 * propagate the change notification appropriately.
+	 */
+	protected void listChanged(@SuppressWarnings("unused") ListChangeEvent event) {
+		// by default, simply recalculate the value and fire an event
+		this.propertyChanged();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListValueModel.java
new file mode 100644
index 0000000..f433bbf
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListValueModel.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Iterator;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.model.Model;
+
+/**
+ * Interface used to abstract list accessing and
+ * change notification and make it more pluggable.
+ * <p>
+ * 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.
+ *
+ * @param <E> the type of values held by the list model
+ */
+@SuppressWarnings("nls")
+public interface ListValueModel<E>
+	extends Model, Iterable<E>
+{
+	/**
+	 * Return the list's values.
+	 */
+	@Override
+	Iterator<E> iterator();
+		String LIST_VALUES = "list values";
+
+	/**
+	 * Return the list's values.
+	 */
+	ListIterator<E> listIterator();
+
+	/**
+	 * Return the size of the list.
+	 */
+	int size();
+
+	/**
+	 * Return the item at the specified index of the list.
+	 */
+	E get(int index);
+
+	/**
+	 * Return the list's values.
+	 */
+	Object[] toArray();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListValueModelWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListValueModelWrapper.java
new file mode 100644
index 0000000..44e66fc
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ListValueModelWrapper.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+
+/**
+ * This abstract class provides the infrastructure needed to wrap
+ * another list value model, "lazily" listen to it, and propagate
+ * its change notifications. Subclasses must implement the appropriate
+ * {@link ListValueModel}.
+ */
+@SuppressWarnings("nls")
+public abstract class ListValueModelWrapper<E>
+	extends AbstractListValueModel
+{
+	/** The wrapped list value model. */
+	protected final ListValueModel<? extends E> listModel;
+
+	/** A listener that allows us to sync with changes to the wrapped list model. */
+	protected final ListChangeListener listChangeListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a list value model with the specified wrapped
+	 * list value model.
+	 */
+	protected ListValueModelWrapper(ListValueModel<? extends E> listModel) {
+		super();
+		if (listModel == null) {
+			throw new NullPointerException();
+		}
+		this.listModel = listModel;
+		this.listChangeListener = this.buildListChangeListener();
+	}
+
+
+	// ********** initialization **********
+
+	protected ListChangeListener buildListChangeListener() {
+		return new ListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) {
+				ListValueModelWrapper.this.itemsAdded(event);
+			}
+			@Override
+			public void itemsRemoved(ListRemoveEvent event) {
+				ListValueModelWrapper.this.itemsRemoved(event);
+			}
+			@Override
+			public void itemsReplaced(ListReplaceEvent event) {
+				ListValueModelWrapper.this.itemsReplaced(event);
+			}
+			@Override
+			public void itemsMoved(ListMoveEvent event) {
+				ListValueModelWrapper.this.itemsMoved(event);
+			}
+			@Override
+			public void listCleared(ListClearEvent event) {
+				ListValueModelWrapper.this.listCleared(event);
+			}
+			@Override
+			public void listChanged(ListChangeEvent event) {
+				ListValueModelWrapper.this.listChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "list change listener";
+			}
+		};
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Start listening to the list holder.
+	 */
+	@Override
+	protected void engageModel() {
+		this.listModel.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+	}
+
+	/**
+	 * Stop listening to the list holder.
+	 */
+	@Override
+	protected void disengageModel() {
+		this.listModel.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getItems(ListAddEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getItems(ListRemoveEvent event) {
+		return (Iterable<E>) event.getItems();
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getNewItems(ListReplaceEvent event) {
+		return (Iterable<E>) event.getNewItems();
+	}
+
+	// minimized scope of suppressed warnings
+	@SuppressWarnings("unchecked")
+	protected Iterable<E> getOldItems(ListReplaceEvent event) {
+		return (Iterable<E>) event.getOldItems();
+	}
+
+
+	// ********** list change support **********
+
+	/**
+	 * Items were added to the wrapped list holder;
+	 * propagate the change notification appropriately.
+	 */
+	protected abstract void itemsAdded(ListAddEvent event);
+
+	/**
+	 * Items were removed from the wrapped list holder;
+	 * propagate the change notification appropriately.
+	 */
+	protected abstract void itemsRemoved(ListRemoveEvent event);
+
+	/**
+	 * Items were replaced in the wrapped list holder;
+	 * propagate the change notification appropriately.
+	 */
+	protected abstract void itemsReplaced(ListReplaceEvent event);
+
+	/**
+	 * Items were moved in the wrapped list holder;
+	 * propagate the change notification appropriately.
+	 */
+	protected abstract void itemsMoved(ListMoveEvent event);
+
+	/**
+	 * The wrapped list holder was cleared;
+	 * propagate the change notification appropriately.
+	 */
+	protected abstract void listCleared(ListClearEvent event);
+
+	/**
+	 * The value of the wrapped list holder has changed;
+	 * propagate the change notification appropriately.
+	 */
+	protected abstract void listChanged(ListChangeEvent event);
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiableCollectionValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiableCollectionValueModel.java
new file mode 100644
index 0000000..50d8814
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiableCollectionValueModel.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+/**
+ * Extend {@link CollectionValueModel} to allow the setting of the
+ * collection's values.
+ * <p>
+ * 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.
+ *
+ * @param <E> the type of values held by the model
+ */
+public interface ModifiableCollectionValueModel<E>
+	extends CollectionValueModel<E>
+{
+	/**
+	 * Set the values and fire a collection change notification.
+	 * @see CollectionValueModel#VALUES
+	 */
+	void setValues(Iterable<E> values);
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiableListValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiableListValueModel.java
new file mode 100644
index 0000000..91fa945
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiableListValueModel.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+/**
+ * Extend {@link ListValueModel} to allow the setting of the
+ * list's values.
+ * <p>
+ * 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.
+ *
+ * @param <E> the type of values held by the model
+ */
+public interface ModifiableListValueModel<E>
+	extends ListValueModel<E>
+{
+	/**
+	 * Set the list values and fire a list change notification.
+	 * @see ListValueModel#LIST_VALUES
+	 */
+	void setListValues(Iterable<E> values);
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiablePropertyCollectionValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiablePropertyCollectionValueModelAdapter.java
new file mode 100644
index 0000000..c93e690
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiablePropertyCollectionValueModelAdapter.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Iterator;
+
+/**
+ * An adapter that allows us to make a {@link ModifiablePropertyValueModel} behave like
+ * a single-element {@link ModifiableCollectionValueModel}, sorta.
+ * <p>
+ * If the property's value is <code>null</code>, an empty iterator is returned
+ * (i.e. you can't have a collection with a <code>null</code> element).
+ * Also, only a single-element collection can be written to the adapter.
+ */
+@SuppressWarnings("nls")
+public class ModifiablePropertyCollectionValueModelAdapter<E>
+	extends PropertyCollectionValueModelAdapter<E>
+	implements ModifiableCollectionValueModel<E>
+{
+	// ********** constructor **********
+
+	/**
+	 * Convert the specified writable property value model to a writable
+	 * collection value model.
+	 */
+	public ModifiablePropertyCollectionValueModelAdapter(ModifiablePropertyValueModel<E> valueHolder) {
+		super(valueHolder);
+	}
+
+
+	// ********** WritableCollectionValueModel implementation **********
+
+	@Override
+	public void setValues(Iterable<E> values) {
+		Iterator<E> stream = values.iterator();
+		if (stream.hasNext()) {
+			E newValue = stream.next();
+			if (stream.hasNext()) {
+				throw new IllegalArgumentException("non-singleton collection: " + values);
+			}
+			this.getValueHolder().setValue(newValue);
+		} else {
+			this.getValueHolder().setValue(null);
+		}
+	}
+
+	// our constructor takes only writable property value models
+	@SuppressWarnings("unchecked")
+	protected ModifiablePropertyValueModel<E> getValueHolder() {
+		return (ModifiablePropertyValueModel<E>) this.valueHolder;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiablePropertyListValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiablePropertyListValueModelAdapter.java
new file mode 100644
index 0000000..6ad3f02
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiablePropertyListValueModelAdapter.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Iterator;
+
+/**
+ * An adapter that allows us to make a {@link ModifiablePropertyValueModel} behave like
+ * a single-element {@link ModifiableListValueModel}, sorta.
+ * <p>
+ * If the property's value is <code>null</code>, an empty iterator is returned
+ * (i.e. you can't have a list with a <code>null</code> element).
+ * Also, only a single-element list can be written to the adapter.
+ */
+@SuppressWarnings("nls")
+public class ModifiablePropertyListValueModelAdapter<E>
+	extends PropertyListValueModelAdapter<E>
+	implements ModifiableListValueModel<E>
+{
+	// ********** constructor **********
+
+	/**
+	 * Convert the specified writable property value model to a writable
+	 * collection value model.
+	 */
+	public ModifiablePropertyListValueModelAdapter(ModifiablePropertyValueModel<E> valueHolder) {
+		super(valueHolder);
+	}
+
+
+	// ********** WritableListValueModel implementation **********
+
+	@Override
+	public void setListValues(Iterable<E> listValues) {
+		Iterator<E> stream = listValues.iterator();
+		if (stream.hasNext()) {
+			E newValue = stream.next();
+			if (stream.hasNext()) {
+				throw new IllegalArgumentException("non-singleton list: " + listValues);
+			}
+			this.getValueHolder().setValue(newValue);
+		} else {
+			this.getValueHolder().setValue(null);
+		}
+	}
+
+	// our constructor takes only writable property value models
+	@SuppressWarnings("unchecked")
+	protected ModifiablePropertyValueModel<E> getValueHolder() {
+		return (ModifiablePropertyValueModel<E>) this.valueHolder;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiablePropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiablePropertyValueModel.java
new file mode 100644
index 0000000..12737d3
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ModifiablePropertyValueModel.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+/**
+ * Extend {@link PropertyValueModel} to allow the setting of the property's value.
+ * <p>
+ * 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.
+ *
+ * @param <V> the type of value held by the model
+ */
+public interface ModifiablePropertyValueModel<V>
+	extends PropertyValueModel<V>
+{
+	/**
+	 * Set the value and fire a property change notification.
+	 * @see PropertyValueModel#VALUE
+	 */
+	void setValue(V value);
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/NullCollectionValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/NullCollectionValueModel.java
new file mode 100644
index 0000000..54e6f16
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/NullCollectionValueModel.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+
+/**
+ * A read-only collection value model for when you
+ * don't need to support a collection. In particular, this
+ * is useful for the leaf nodes of a tree that never have
+ * children.
+ * <p>
+ * We don't use a singleton because we hold on to listeners.
+ */
+public final class NullCollectionValueModel<E>
+	extends AbstractModel
+	implements CollectionValueModel<E>, Serializable
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Default constructor.
+	 */
+	public NullCollectionValueModel() {
+		super();
+	}
+
+
+	// ********** CollectionValueModel implementation **********
+
+	@Override
+	public int size() {
+		return 0;
+	}
+
+	@Override
+	public Iterator<E> iterator() {
+		return EmptyIterator.instance();
+	}
+
+
+	// ********** Object overrides **********
+
+    @Override
+	public String toString() {
+    	return this.getClass().getSimpleName();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/NullListValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/NullListValueModel.java
new file mode 100644
index 0000000..742c26b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/NullListValueModel.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+import org.eclipse.persistence.tools.utility.iterator.EmptyListIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+
+/**
+ * An empty list value model for when you don't
+ * need to support a list.
+ * <p>
+ * We don't use a singleton because we hold on to listeners.
+ */
+@SuppressWarnings("nls")
+public final class NullListValueModel<E>
+	extends AbstractModel
+	implements ListValueModel<E>, Serializable
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Default constructor.
+	 */
+	public NullListValueModel() {
+		super();
+	}
+
+
+	// ********** ListValueModel implementation **********
+
+	@Override
+	public Iterator<E> iterator() {
+		return EmptyIterator.instance();
+	}
+
+	@Override
+	public ListIterator<E> listIterator() {
+		return EmptyListIterator.instance();
+	}
+
+	@Override
+	public int size() {
+		return 0;
+	}
+
+	@Override
+	public E get(int index) {
+		throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0");
+	}
+
+	@Override
+	public Object[] toArray() {
+		return ObjectTools.EMPTY_OBJECT_ARRAY;
+	}
+
+
+	// ********** Object overrides **********
+
+	@Override
+	public String toString() {
+		return this.getClass().getSimpleName();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/NullPropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/NullPropertyValueModel.java
new file mode 100644
index 0000000..138b384
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/NullPropertyValueModel.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+
+/**
+ * A property value model for when you
+ * don't need to support a value.
+ * <p>
+ * We don't use a singleton because we hold on to listeners.
+ */
+public final class NullPropertyValueModel<T>
+	extends AbstractModel
+	implements PropertyValueModel<T>, Serializable
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Default constructor.
+	 */
+	public NullPropertyValueModel() {
+		super();
+	}
+
+	@Override
+	public T getValue() {
+		return null;
+	}
+
+    @Override
+	public String toString() {
+		return this.getClass().getSimpleName();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyAspectAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyAspectAdapter.java
new file mode 100644
index 0000000..a805dea
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyAspectAdapter.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Collection;
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+
+/**
+ * This {@link AspectPropertyValueModelAdapter} provides basic property change support.
+ * This converts a set of one or more standard properties into
+ * a single {@link #VALUE} property.
+ * <p>
+ * The typical subclass will override the following methods (see the descriptions
+ * in {@link AspectPropertyValueModelAdapter}):<ul>
+ * <li>{@link #buildValue_()}
+ * <li>{@link #setValue_(Object)}
+ * <li>{@link #buildValue()}
+ * <li>{@link #setValue(Object)}
+ * </ul>
+ *
+ * @param <S> the type of the model's subject
+ * @param <V> the type of the subject's property aspect
+ */
+public abstract class PropertyAspectAdapter<S extends Model, V>
+	extends AspectPropertyValueModelAdapter<S, V>
+{
+	/** The name of the subject's properties that we use for the value. */
+	protected final String[] aspectNames;
+		protected static final String[] EMPTY_ASPECT_NAMES = new String[0];
+
+	/** A listener that listens to the appropriate properties of the subject. */
+	protected final PropertyChangeListener aspectChangeListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a property aspect adapter for the specified subject
+	 * and property aspect.
+	 */
+	protected PropertyAspectAdapter(String aspectName, S subject) {
+		this(new String[] {aspectName}, subject);
+	}
+
+	/**
+	 * Construct a property aspect adapter for the specified subject
+	 * and property aspects.
+	 */
+	protected PropertyAspectAdapter(String[] aspectNames, S subject) {
+		this(new StaticPropertyValueModel<S>(subject), aspectNames);
+	}
+
+	/**
+	 * Construct a property aspect adapter for the specified subject model
+	 * and property aspects.
+	 */
+	protected PropertyAspectAdapter(PropertyValueModel<? extends S> subjectModel, String... aspectNames) {
+		super(subjectModel);
+		if (aspectNames == null) {
+			throw new NullPointerException();
+		}
+		this.aspectNames = aspectNames;
+		this.aspectChangeListener = this.buildAspectChangeListener();
+	}
+
+	/**
+	 * Construct a property aspect adapter for the specified subject model
+	 * and property aspects.
+	 */
+	protected PropertyAspectAdapter(PropertyValueModel<? extends S> subjectModel, Collection<String> aspectNames) {
+		this(subjectModel, aspectNames.toArray(new String[aspectNames.size()]));
+	}
+
+	/**
+	 * Construct a property aspect adapter for an "unchanging" property aspect in
+	 * the specified subject. This is useful for a property aspect that does not
+	 * change for a particular subject; but the subject will change, resulting in
+	 * a new property. (A {@link TransformationPropertyValueModel} could also be
+	 * used in this situation.)
+	 */
+	protected PropertyAspectAdapter(PropertyValueModel<? extends S> subjectModel) {
+		this(subjectModel, EMPTY_ASPECT_NAMES);
+	}
+
+
+	// ********** initialization **********
+
+	protected PropertyChangeListener buildAspectChangeListener() {
+		return new AspectChangeListener();
+	}
+
+	/**
+	 * Transform the subject's property change events into
+	 * {@link #VALUE} property change events.
+	 */
+	protected class AspectChangeListener
+		extends PropertyChangeAdapter
+	{
+		@Override
+		public void propertyChanged(PropertyChangeEvent event) {
+			PropertyAspectAdapter.this.aspectChanged(event);
+		}
+	}
+
+
+	// ********** AspectAdapter implementation **********
+
+    @Override
+	protected void engageSubject_() {
+    	for (String propertyName : this.aspectNames) {
+			this.subject.addPropertyChangeListener(propertyName, this.aspectChangeListener);
+		}
+	}
+
+    @Override
+	protected void disengageSubject_() {
+    	for (String propertyName : this.aspectNames) {
+			this.subject.removePropertyChangeListener(propertyName, this.aspectChangeListener);
+		}
+	}
+
+	protected void aspectChanged(@SuppressWarnings("unused") PropertyChangeEvent event) {
+ 		//TODO we have multiple PropertyAspectAdapters that depend on the aspectChanged()
+    	//behavior because they do a transformation in the buildValue(). It would be
+    	//nice to use the new value from the event instead of rebuilding it.
+    	//this.fireAspectChanged((V) event.getOldValue(), this.value = (V) event.getNewValue());
+    	aspectChanged();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyCollectionValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyCollectionValueModelAdapter.java
new file mode 100644
index 0000000..ef8802d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyCollectionValueModelAdapter.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Collections;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+import org.eclipse.persistence.tools.utility.iterator.EmptyIterator;
+import org.eclipse.persistence.tools.utility.iterator.SingleElementIterator;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+
+/**
+ * An adapter that allows us to make a {@link PropertyValueModel} behave like
+ * a read-only, single-element {@link CollectionValueModel}, sorta.
+ * <p>
+ * If the property's value is null, an empty iterator is returned
+ * (i.e. you can't have a collection with a <code>null</code> element).
+ */
+@SuppressWarnings("nls")
+public class PropertyCollectionValueModelAdapter<E>
+	extends AbstractCollectionValueModel
+	implements CollectionValueModel<E>
+{
+	/** The wrapped property value model. */
+	protected final PropertyValueModel<? extends E> valueHolder;
+
+	/** A listener that forwards any events fired by the value holder. */
+	protected final PropertyChangeListener propertyChangeListener;
+
+	/** Cache the value. */
+	protected E value;
+
+
+	// ********** constructors/initialization **********
+
+	/**
+	 * Convert the specified property value model to a collection
+	 * value model.
+	 */
+	public PropertyCollectionValueModelAdapter(PropertyValueModel<? extends E> valueHolder) {
+		super();
+		if (valueHolder == null) {
+			throw new NullPointerException();
+		}
+		this.valueHolder = valueHolder;
+		this.propertyChangeListener = this.buildPropertyChangeListener();
+		this.value = null;
+		// postpone building the value and listening to the underlying value
+		// until we have listeners ourselves...
+	}
+
+	/**
+	 * The wrapped value has changed, forward an equivalent
+	 * collection change event to our listeners.
+	 */
+	protected PropertyChangeListener buildPropertyChangeListener() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent event) {
+				@SuppressWarnings("unchecked")
+				E eventNewValue = (E) event.getNewValue();
+				PropertyCollectionValueModelAdapter.this.valueChanged(eventNewValue);
+			}
+			@Override
+			public String toString() {
+				return "property change listener";
+			}
+		};
+	}
+
+
+	// ********** CollectionValueModel implementation **********
+
+	@Override
+	public Iterator<E> iterator() {
+		return (this.value == null) ? EmptyIterator.<E>instance() : this.iterator_();
+	}
+
+	protected Iterator<E> iterator_() {
+		return new SingleElementIterator<E>(this.value);
+	}
+
+	@Override
+	public int size() {
+		return (this.value == null) ? 0 : 1;
+	}
+
+
+	// ********** AbstractCollectionValueModel implementation **********
+
+	@Override
+	protected void engageModel() {
+		this.valueHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.propertyChangeListener);
+		// sync our value *after* we start listening to the value model,
+		// since its value might change when a listener is added
+		this.value = this.valueHolder.getValue();
+	}
+
+	@Override
+	protected void disengageModel() {
+		this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.propertyChangeListener);
+		// clear out the value when we are not listening to the value holder
+		this.value = null;
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * synchronize our internal value with the wrapped value
+	 * and fire the appropriate events
+	 */
+	protected void valueChanged(E newValue) {
+		E oldValue = this.value;
+		this.value = newValue;
+		if (oldValue == null) {
+			// we wouldn't get the event if the new value were null too
+			this.fireItemAdded(VALUES, newValue);
+		} else {
+			if (newValue == null) {
+				this.fireItemRemoved(VALUES, oldValue);
+			} else {
+				// we wouldn't get the event if the new value was the same as the old
+				this.fireCollectionChanged(VALUES, Collections.singleton(newValue));
+			}
+		}
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		StringBuilderTools.append(sb, this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyListValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyListValueModelAdapter.java
new file mode 100644
index 0000000..aa72cfb
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyListValueModelAdapter.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Iterator;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+import org.eclipse.persistence.tools.utility.iterator.EmptyListIterator;
+import org.eclipse.persistence.tools.utility.iterator.SingleElementListIterator;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+
+/**
+ * An adapter that allows us to make a {@link PropertyValueModel} behave like
+ * a read-only, single-element {@link ListValueModel}, sorta.
+ * <p>
+ * If the property's value is null, an empty iterator is returned
+ * (i.e. you can't have a collection with a <code>null</code> element).
+ */
+@SuppressWarnings("nls")
+public class PropertyListValueModelAdapter<E>
+	extends AbstractListValueModel
+	implements ListValueModel<E>
+{
+	/** The wrapped property value model. */
+	protected final PropertyValueModel<? extends E> valueHolder;
+
+	/** A listener that forwards any events fired by the value holder. */
+	protected final PropertyChangeListener propertyChangeListener;
+
+	/** Cache the value. */
+	protected E value;
+
+
+	// ********** constructors/initialization **********
+
+	/**
+	 * Convert the specified property value model to a list
+	 * value model.
+	 */
+	public PropertyListValueModelAdapter(PropertyValueModel<? extends E> valueHolder) {
+		super();
+		if (valueHolder == null) {
+			throw new NullPointerException();
+		}
+		this.valueHolder = valueHolder;
+		this.propertyChangeListener = this.buildPropertyChangeListener();
+		// postpone building the value and listening to the underlying value
+		// until we have listeners ourselves...
+	}
+
+	/**
+	 * The wrapped value has changed, forward an equivalent
+	 * list change event to our listeners.
+	 */
+	protected PropertyChangeListener buildPropertyChangeListener() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent event) {
+				@SuppressWarnings("unchecked")
+				E eventNewValue = (E) event.getNewValue();
+				PropertyListValueModelAdapter.this.valueChanged(eventNewValue);
+			}
+			@Override
+			public String toString() {
+				return "property change listener";
+			}
+		};
+	}
+
+
+	// ********** ListValueModel implementation **********
+
+	@Override
+	public Iterator<E> iterator() {
+		return this.listIterator();
+	}
+
+	@Override
+	public ListIterator<E> listIterator() {
+		return (this.value == null) ?
+					EmptyListIterator.<E>instance()
+				:
+					new SingleElementListIterator<E>(this.value);
+	}
+
+	@Override
+	public int size() {
+		return (this.value == null) ? 0 : 1;
+	}
+
+	@Override
+	public E get(int index) {
+		if (this.value == null) {
+			throw this.buildIOOBE(index, 0);
+		}
+		if (index > 0) {
+			throw this.buildIOOBE(index, 1);
+		}
+		return this.value;
+	}
+
+	@Override
+	public Object[] toArray() {
+		return (this.value == null) ? ObjectTools.EMPTY_OBJECT_ARRAY : new Object[] {this.value};
+	}
+
+
+	// ********** behavior **********
+
+	protected IndexOutOfBoundsException buildIOOBE(int index, int size) {
+		return new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
+	}
+
+	@Override
+	protected void engageModel() {
+		this.valueHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.propertyChangeListener);
+		// sync our value *after* we start listening to the value model,
+		// since its value might change when a listener is added
+		this.value = this.valueHolder.getValue();
+	}
+
+	@Override
+	protected void disengageModel() {
+		this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.propertyChangeListener);
+		// clear out the value when we are not listening to the value holder
+		this.value = null;
+	}
+
+	/**
+	 * synchronize our internal value with the wrapped value
+	 * and fire the appropriate events
+	 */
+	protected void valueChanged(E newValue) {
+		E oldValue = this.value;
+		this.value = newValue;
+		if (oldValue == null) {
+			this.fireItemAdded(LIST_VALUES, 0, newValue);
+		} else {
+			if (newValue == null) {
+				this.fireItemRemoved(LIST_VALUES, 0, oldValue);
+			} else {
+				this.fireItemReplaced(LIST_VALUES, 0, newValue, oldValue);
+			}
+		}
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		StringBuilderTools.append(sb, this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyValueModel.java
new file mode 100644
index 0000000..13ad260
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyValueModel.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.Model;
+
+/**
+ * Interface used to abstract property accessing and
+ * change notification and make it more pluggable.
+ * <p>
+ * 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.
+ *
+ * @param <V> the type of value held by the model
+ */
+@SuppressWarnings("nls")
+public interface PropertyValueModel<V>
+	extends Model
+{
+	/**
+	 * Return the model's value.
+	 */
+	V getValue();
+		String VALUE = "value";
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyValueModelWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyValueModelWrapper.java
new file mode 100644
index 0000000..86c7b01
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/PropertyValueModelWrapper.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+
+/**
+ * This abstract class provides the infrastructure needed to wrap
+ * another property value model, "lazily" listen to it, and propagate
+ * its change notifications. Subclasses must implement the appropriate
+ * {@link PropertyValueModel}.
+ * <p>
+ * Subclasses must implement one of the following methods:<ul>
+ * <li>{@link #wrappedValueChanged(PropertyChangeEvent)}<p>
+ *     implement this method to propagate the appropriate change notification
+ * <li>{@link #wrappedValueChanged(Object, Object) valueChanged(V, V)}<p>
+ *     implement this method to propagate the appropriate change notification
+ * </ul>
+ *
+ * @param <V> the type of the <em>wrapped</em> model's value
+ */
+@SuppressWarnings("nls")
+public abstract class PropertyValueModelWrapper<V>
+	extends AbstractPropertyValueModel
+{
+	/** The wrapped property value model. Never <code>null</code>. */
+	protected final PropertyValueModel<? extends V> valueModel;
+
+	/** A listener that allows us to sync with changes to the wrapped value model. */
+	protected final PropertyChangeListener valueListener;
+
+
+	// ********** constructors/initialization **********
+
+	/**
+	 * Construct a property value model with the specified wrapped
+	 * property value model.
+	 */
+	protected PropertyValueModelWrapper(PropertyValueModel<? extends V> valueModel) {
+		super();
+		if (valueModel == null) {
+			throw new NullPointerException();
+		}
+		this.valueModel = valueModel;
+		this.valueListener = this.buildValueListener();
+	}
+
+	protected PropertyChangeListener buildValueListener() {
+		return new ValueListener();
+	}
+
+	/* CU private */ class ValueListener
+		extends PropertyChangeAdapter
+	{
+		@Override
+		public void propertyChanged(PropertyChangeEvent event) {
+			PropertyValueModelWrapper.this.wrappedValueChanged(event);
+		}
+	}
+
+
+	// ********** listen to wrapped value model **********
+
+	/**
+	 * Begin listening to the value holder.
+	 */
+	@Override
+	protected void engageModel() {
+		this.valueModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.valueListener);
+	}
+
+	/**
+	 * Stop listening to the value holder.
+	 */
+	@Override
+	protected void disengageModel() {
+		this.valueModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.valueListener);
+	}
+
+
+	// ********** property change support **********
+
+	/**
+	 * The value of the wrapped value model has changed;
+	 * propagate the change notification appropriately.
+	 * @see #wrappedValueChanged(Object, Object)
+	 */
+	@SuppressWarnings("unchecked")
+	protected void wrappedValueChanged(PropertyChangeEvent event) {
+		this.wrappedValueChanged((V) event.getOldValue(), (V) event.getNewValue());
+	}
+
+	/**
+	 * The value of the wrapped value model has changed;
+	 * propagate the change notification appropriately.
+	 * @see #wrappedValueChanged(PropertyChangeEvent)
+	 */
+	protected void wrappedValueChanged(@SuppressWarnings("unused") V oldValue, @SuppressWarnings("unused") V newValue) {
+		throw new RuntimeException("This method was not overridden.");
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ReadOnlyModifiablePropertyValueModelWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ReadOnlyModifiablePropertyValueModelWrapper.java
new file mode 100644
index 0000000..2ae547e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ReadOnlyModifiablePropertyValueModelWrapper.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+
+/**
+ * A simple implementation of {@link ModifiablePropertyValueModel} that actually
+ * ... <em>isn't</em> ... modifiable.  It can however be used in places that require a
+ * {@link ModifiablePropertyValueModel} and where the developer is sure that no
+ * attempt will be made to write to it.
+ */
+public class ReadOnlyModifiablePropertyValueModelWrapper<T>
+	extends PropertyValueModelWrapper<T>
+	implements ModifiablePropertyValueModel<T>
+{
+	public ReadOnlyModifiablePropertyValueModelWrapper(PropertyValueModel<? extends T> valueModel) {
+		super(valueModel);
+	}
+
+
+	@Override
+	public T getValue() {
+		return this.valueModel.getValue();
+	}
+
+	@Override
+	public void setValue(T value) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	protected void wrappedValueChanged(PropertyChangeEvent event) {
+		this.firePropertyChanged(event.clone(this));
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.getValue());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SetCollectionValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SetCollectionValueModel.java
new file mode 100644
index 0000000..1ae7901
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SetCollectionValueModel.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.StringBuilderTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyIterator;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+
+/**
+ * A <code>SetCollectionValueModel</code> wraps another
+ * {@link CollectionValueModel} and returns the items in the collection
+ * only once.
+ */
+@SuppressWarnings("nls")
+public class SetCollectionValueModel<E>
+	extends CollectionValueModelWrapper<E>
+	implements CollectionValueModel<E>
+{
+	private final HashBag<E> bag = new HashBag<E>();
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a collection value model with the specified wrapped
+	 * collection value model and a filter that simply accepts every object.
+	 */
+	public SetCollectionValueModel(CollectionValueModel<? extends E> collectionHolder) {
+		super(collectionHolder);
+	}
+
+	/**
+	 * Construct a collection value model with the specified wrapped
+	 * list value model and a filter that simply accepts every object.
+	 */
+	public SetCollectionValueModel(ListValueModel<E> listHolder) {
+		this(new ListCollectionValueModelAdapter<E>(listHolder));
+	}
+
+
+	// ********** CollectionValueModel implementation **********
+
+	@Override
+	public Iterator<E> iterator() {
+		return new ReadOnlyIterator<E>(this.bag.uniqueIterator());
+	}
+
+	@Override
+	public int size() {
+		return this.bag.uniqueCount();
+	}
+
+
+	// ********** CollectionValueModelWrapper overrides/implementation **********
+
+	@Override
+	protected void engageModel() {
+		super.engageModel();
+		// sync our cache *after* we start listening to the nested collection,
+		// since its value might change when a listener is added
+		CollectionTools.addAll(this.bag, this.collectionModel);
+	}
+
+	@Override
+	protected void disengageModel() {
+		super.disengageModel();
+		// clear out the cache when we are not listening to the nested collection
+		this.bag.clear();
+	}
+
+	@Override
+	protected void itemsAdded(CollectionAddEvent event) {
+		ArrayList<E> addedItems = new ArrayList<E>(event.getItemsSize());
+		int uniqueCount = this.bag.uniqueCount();
+		for (E item : this.getItems(event)) {
+			this.bag.add(item);
+			if (this.bag.uniqueCount() > uniqueCount) {
+				uniqueCount = this.bag.uniqueCount();
+				addedItems.add(item);
+			}
+		}
+		this.fireItemsAdded(VALUES, addedItems);
+	}
+
+	@Override
+	protected void itemsRemoved(CollectionRemoveEvent event) {
+		ArrayList<E> removedItems = new ArrayList<E>(event.getItemsSize());
+		int uniqueCount = this.bag.uniqueCount();
+		for (E item : this.getItems(event)) {
+			if (this.bag.remove(item)) {
+				if (this.bag.uniqueCount() < uniqueCount) {
+					uniqueCount = this.bag.uniqueCount();
+					removedItems.add(item);
+				}
+			} else {
+				throw new IllegalStateException("missing item: " + item);
+			}
+		}
+		this.fireItemsRemoved(VALUES, removedItems);
+	}
+
+	@Override
+	protected void collectionCleared(CollectionClearEvent event) {
+		this.clearCollection(this.bag, VALUES);
+	}
+
+	@Override
+	protected void collectionChanged(CollectionChangeEvent event) {
+		this.bag.clear();
+		CollectionTools.addAll(this.bag, this.collectionModel);
+		this.fireCollectionChanged(VALUES, new HashSet<E>(this.bag));
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		StringBuilderTools.append(sb, this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SimpleCollectionValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SimpleCollectionValueModel.java
new file mode 100644
index 0000000..0b1bba0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SimpleCollectionValueModel.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Collection;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.HashBag;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.ChangeSupport;
+import org.eclipse.persistence.tools.utility.model.SingleAspectChangeSupport;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+
+/**
+ * Implementation of {@link ModifiableCollectionValueModel} and {@link Collection}
+ * that simply holds a collection and notifies listeners of any changes.
+ */
+public class SimpleCollectionValueModel<E>
+	extends AbstractModel
+	implements ModifiableCollectionValueModel<E>, Collection<E>
+{
+	/** The collection. */
+	protected final Collection<E> collection;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a collection value model for the specified collection.
+	 */
+	public SimpleCollectionValueModel(Collection<E> collection) {
+		super();
+		if (collection == null) {
+			throw new NullPointerException();
+		}
+		this.collection = collection;
+	}
+
+	/**
+	 * Construct a collection value model with an empty initial collection.
+	 */
+	public SimpleCollectionValueModel() {
+		this(new HashBag<E>());
+	}
+
+	@Override
+	protected ChangeSupport buildChangeSupport() {
+		return new SingleAspectChangeSupport(this, CollectionChangeListener.class, VALUES);
+	}
+
+
+	// ********** CollectionValueModel implementation **********
+
+	@Override
+	public Iterator<E> iterator() {
+		return new LocalIterator<E>(this.collection.iterator());
+	}
+
+	@Override
+	public int size() {
+		return this.collection.size();
+	}
+
+
+	// ********** WritableCollectionValueModel implementation **********
+
+	/**
+	 * Allow the collection's elements to be replaced.
+	 */
+	@Override
+	public void setValues(Iterable<E> values) {
+		if (values == null) {
+			throw new NullPointerException();
+		}
+		this.collection.clear();
+		CollectionTools.addAll(this.collection, values);
+		this.fireCollectionChanged(VALUES, this.collection);
+	}
+
+
+	// ********** Collection implementation **********
+
+	@Override
+	public boolean isEmpty() {
+		return this.collection.isEmpty();
+	}
+
+	@Override
+	public boolean contains(Object o) {
+		return this.collection.contains(o);
+	}
+
+	@Override
+	public Object[] toArray() {
+		return this.collection.toArray();
+	}
+
+	@Override
+	public <T extends Object> T[] toArray(T[] a) {
+		return this.collection.toArray(a);
+	}
+
+	@Override
+	public boolean add(E o) {
+		return this.addItemToCollection(o, this.collection, VALUES);
+	}
+
+	@Override
+	public boolean remove(Object o) {
+		return this.removeItemFromCollection(o, this.collection, VALUES);
+	}
+
+	@Override
+	public boolean containsAll(Collection<?> c) {
+		return this.collection.containsAll(c);
+	}
+
+	@Override
+	public boolean addAll(Collection<? extends E> c) {
+		return this.addItemsToCollection(c, this.collection, VALUES);
+	}
+
+	@Override
+	public boolean removeAll(Collection<?> c) {
+		return this.removeItemsFromCollection(c, this.collection, VALUES);
+	}
+
+	@Override
+	public boolean retainAll(Collection<?> c) {
+		return this.retainItemsInCollection(c, this.collection, VALUES);
+	}
+
+	@Override
+	public void clear() {
+		this.clearCollection(this.collection, VALUES);
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (o == this) {
+			return true;
+		}
+		if ((o instanceof Collection<?>) && (o instanceof CollectionValueModel<?>)) {
+			Collection<E> c1 = CollectionTools.collection(this.collection);
+			@SuppressWarnings("unchecked")
+			Collection<E> c2 = CollectionTools.collection(((Collection<E>) o).iterator());
+			return c1.equals(c2);
+		}
+		return false;
+	}
+
+	@Override
+	public int hashCode() {
+		return CollectionTools.collection(this.collection).hashCode();
+	}
+
+
+	// ********** miscellaneous **********
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.collection);
+	}
+
+
+	// ********** iterator **********
+
+	private class LocalIterator<T> implements Iterator<T> {
+		private final Iterator<T> iterator;
+		private T next;
+
+		LocalIterator(Iterator<T> iterator) {
+			super();
+			this.iterator = iterator;
+		}
+
+		@Override
+		public boolean hasNext() {
+			return this.iterator.hasNext();
+		}
+
+		@Override
+		public T next() {
+			return this.next = this.iterator.next();
+		}
+
+		@Override
+		@SuppressWarnings("synthetic-access")
+		public void remove() {
+			this.iterator.remove();
+			SimpleCollectionValueModel.this.fireItemRemoved(VALUES, this.next);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SimpleListValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SimpleListValueModel.java
new file mode 100644
index 0000000..294f807
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SimpleListValueModel.java
@@ -0,0 +1,358 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.ChangeSupport;
+import org.eclipse.persistence.tools.utility.model.SingleAspectChangeSupport;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+
+/**
+ * Implementation of {@link ListValueModel} and {@link List} that simply holds a
+ * list and notifies listeners of any changes.
+ */
+public class SimpleListValueModel<E>
+	extends AbstractModel
+	implements ModifiableListValueModel<E>, List<E>
+{
+	/** The list. */
+	protected List<E> list;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a list value model for the specified list.
+	 */
+	public SimpleListValueModel(List<E> list) {
+		super();
+		if (list == null) {
+			throw new NullPointerException();
+		}
+		this.list = list;
+	}
+
+	/**
+	 * Construct a list value model with an empty initial list.
+	 */
+	public SimpleListValueModel() {
+		this(new ArrayList<E>());
+	}
+
+	@Override
+	protected ChangeSupport buildChangeSupport() {
+		return new SingleAspectChangeSupport(this, ListChangeListener.class, LIST_VALUES);
+	}
+
+
+	// ********** ListValueModel implementation **********
+
+	@Override
+	public Iterator<E> iterator() {
+		return new LocalIterator<E>(this.list.iterator());
+	}
+
+	@Override
+	public ListIterator<E> listIterator() {
+		return new LocalListIterator<E>(this.list.listIterator());
+	}
+
+	@Override
+	public int size() {
+		return this.list.size();
+	}
+
+	@Override
+	public E get(int index) {
+		return this.list.get(index);
+	}
+
+
+	// ********** WritableListValueModel implementation **********
+
+	/**
+	 * Allow the list's elements to be replaced.
+	 */
+	@Override
+	public void setListValues(Iterable<E> list) {
+		if (list == null) {
+			throw new NullPointerException();
+		}
+		this.list.clear();
+		CollectionTools.addAll(this.list, list);
+		this.fireListChanged(LIST_VALUES, this.list);
+	}
+
+
+	// ********** List implementation **********
+
+	@Override
+	public boolean isEmpty() {
+		return this.list.isEmpty();
+	}
+
+	@Override
+	public boolean contains(Object o) {
+		return this.list.contains(o);
+	}
+
+	@Override
+	public Object[] toArray() {
+		return this.list.toArray();
+	}
+
+	@Override
+	public <T extends Object> T[] toArray(T[] a) {
+		return this.list.toArray(a);
+	}
+
+	@Override
+	public boolean add(E o) {
+		return this.addItemToList(o, this.list, LIST_VALUES);
+	}
+
+	@Override
+	public boolean remove(Object o) {
+		return this.removeItemFromList(o, this.list, LIST_VALUES);
+	}
+
+	@Override
+	public boolean containsAll(Collection<?> c) {
+		return this.list.containsAll(c);
+	}
+
+	@Override
+	public boolean addAll(Collection<? extends E> c) {
+		return this.addItemsToList(c, this.list, LIST_VALUES);
+	}
+
+	@Override
+	public boolean addAll(int index, Collection<? extends E> c) {
+		return this.addItemsToList(index, c, this.list, LIST_VALUES);
+	}
+
+	@Override
+	public boolean removeAll(Collection<?> c) {
+		return this.removeItemsFromList(c, this.list, LIST_VALUES);
+	}
+
+	@Override
+	public boolean retainAll(Collection<?> c) {
+		return this.retainItemsInList(c, this.list, LIST_VALUES);
+	}
+
+	@Override
+	public void clear() {
+		this.clearList(this.list, LIST_VALUES);
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (o == this) {
+			return true;
+		}
+		if ((o instanceof List<?>) && (o instanceof ListValueModel<?>)) {
+			List<E> l1 = ListTools.list(this.list);
+			@SuppressWarnings("unchecked")
+			List<E> l2 = ListTools.list(((List<E>) o).iterator());
+			return l1.equals(l2);
+		}
+		return false;
+	}
+
+	@Override
+	public int hashCode() {
+		return this.list.hashCode();
+	}
+
+	@Override
+	public E set(int index, E element) {
+		return this.setItemInList(index, element, this.list, LIST_VALUES);
+	}
+
+	@Override
+	public void add(int index, E element) {
+		this.addItemToList(index, element, this.list, LIST_VALUES);
+	}
+
+	@Override
+	public E remove(int index) {
+		return this.removeItemFromList(index, this.list, LIST_VALUES);
+	}
+
+	@Override
+	public int indexOf(Object o) {
+		return this.list.indexOf(o);
+	}
+
+	@Override
+	public int lastIndexOf(Object o) {
+		return this.list.lastIndexOf(o);
+	}
+
+	@Override
+	public ListIterator<E> listIterator(int index) {
+		return new LocalListIterator<E>(this.list.listIterator(index));
+	}
+
+	@Override
+	public List<E> subList(int fromIndex, int toIndex) {
+		// TODO hmmm  ~bjv
+		throw new UnsupportedOperationException();
+	}
+
+
+	// ********** additional behavior **********
+
+	/**
+	 * Move a single element.
+	 */
+	public void move(int targetIndex, int sourceIndex) {
+		this.moveItemInList(targetIndex, sourceIndex, this.list, LIST_VALUES);
+	}
+
+	/**
+	 * Move a sub-list of elements.
+	 */
+	public void move(int targetIndex, int sourceIndex, int length) {
+		this.moveItemsInList(targetIndex, sourceIndex, length, this.list, LIST_VALUES);
+	}
+
+	/**
+	 * Remove a range of elements.
+	 */
+	public void remove(int index, int length) {
+		this.removeItemsFromList(index, length, this.list, LIST_VALUES);
+	}
+
+	/**
+	 * Set a range of elements.
+	 */
+	public void set(int index, List<E> elements) {
+		this.setItemsInList(index, elements, this.list, LIST_VALUES);
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.list);
+	}
+
+
+	// ********** iterators **********
+
+	private class LocalIterator<T> implements Iterator<T> {
+		private final Iterator<T> iterator;
+		private int index = -1;
+		private T next;
+
+		LocalIterator(Iterator<T> iterator) {
+			super();
+			this.iterator = iterator;
+		}
+
+		@Override
+		public boolean hasNext() {
+			return this.iterator.hasNext();
+		}
+
+		@Override
+		public T next() {
+			this.next = this.iterator.next();
+			this.index++;
+			return this.next;
+		}
+
+		@Override
+		@SuppressWarnings("synthetic-access")
+		public void remove() {
+			this.iterator.remove();
+			SimpleListValueModel.this.fireItemRemoved(LIST_VALUES, this.index, this.next);
+		}
+
+	}
+
+	private class LocalListIterator<T> implements ListIterator<T> {
+		private final ListIterator<T> iterator;
+		private int last = -1;
+		private int next = 0;
+		private T current;
+
+		LocalListIterator(ListIterator<T> iterator) {
+			super();
+			this.iterator = iterator;
+		}
+
+		@Override
+		public boolean hasNext() {
+			return this.iterator.hasNext();
+		}
+
+		@Override
+		public T next() {
+			this.current = this.iterator.next();
+			this.last = this.next++;
+			return this.current;
+		}
+
+		@Override
+		public int nextIndex() {
+			return this.iterator.nextIndex();
+		}
+
+		@Override
+		public boolean hasPrevious() {
+			return this.iterator.hasPrevious();
+		}
+
+		@Override
+		public T previous() {
+			this.current = this.iterator.previous();
+			this.last = --this.next;
+			return this.current;
+		}
+
+		@Override
+		public int previousIndex() {
+			return this.iterator.previousIndex();
+		}
+
+		@Override
+		@SuppressWarnings("synthetic-access")
+		public void set(T o) {
+			this.iterator.set(o);
+			SimpleListValueModel.this.fireItemReplaced(LIST_VALUES, this.last, o, this.current);
+		}
+
+		@Override
+		@SuppressWarnings("synthetic-access")
+		public void add(T o) {
+			this.iterator.add(o);
+			SimpleListValueModel.this.fireItemAdded(LIST_VALUES, this.next, o);
+		}
+
+		@Override
+		@SuppressWarnings("synthetic-access")
+		public void remove() {
+			this.iterator.remove();
+			SimpleListValueModel.this.fireItemRemoved(LIST_VALUES, this.last, this.current);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SimplePropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SimplePropertyValueModel.java
new file mode 100644
index 0000000..e6a9aad
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SimplePropertyValueModel.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+import org.eclipse.persistence.tools.utility.model.ChangeSupport;
+import org.eclipse.persistence.tools.utility.model.SingleAspectChangeSupport;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+
+/**
+ * Implementation of {@link ModifiablePropertyValueModel} that simply holds on to
+ * an object, uses it as the value, and fires the appropriate event when the
+ * value changes.
+ *
+ * @param <V> the type of the model's value
+ */
+public class SimplePropertyValueModel<V>
+	extends AbstractModel
+	implements ModifiablePropertyValueModel<V>
+{
+	/** The value. */
+	protected V value;
+
+
+	/**
+	 * Construct a property value model for the specified value.
+	 */
+	public SimplePropertyValueModel(V value) {
+		super();
+		this.value = value;
+	}
+
+	/**
+	 * Construct a property value model with a value of <code>null</code>.
+	 */
+	public SimplePropertyValueModel() {
+		this(null);
+	}
+
+	@Override
+	protected ChangeSupport buildChangeSupport() {
+		return new SingleAspectChangeSupport(this, PropertyChangeListener.class, VALUE);
+	}
+
+
+	@Override
+	public V getValue() {
+		return this.value;
+	}
+
+	@Override
+	public void setValue(V value) {
+		V old = this.value;
+		this.value = value;
+		this.firePropertyChanged(VALUE, old, value);
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.value);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SortedListValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SortedListValueModelAdapter.java
new file mode 100644
index 0000000..a353744
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SortedListValueModelAdapter.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import org.eclipse.persistence.tools.utility.Range;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+
+/**
+ * An adapter that allows us to make a {@link CollectionValueModel}
+ * (or {@link org.eclipse.jpt.common.utility.model.value.ListValueModel ListValueModel})
+ * behave like a {@link org.eclipse.jpt.common.utility.model.value.ListValueModel ListValueModel}
+ * that keeps its contents sorted and notifies listeners appropriately.
+ * <p>
+ * The {@link Comparator} can be changed at any time; allowing the same
+ * adapter to be used with different sort criteria (e.g. when the user
+ * wants to sort a list of files first by name, then by date, then by size).
+ * <p>
+ * <strong>NB:</strong> Since we only listen to the wrapped collection when we have
+ * listeners ourselves and we can only stay in sync with the wrapped
+ * collection while we are listening to it, results to various methods
+ * (e.g. {@link #size()}, {@link #get(int)}) will be
+ * unpredictable whenever
+ * we do not have any listeners. This should not be too painful since,
+ * most likely, client objects will also be listeners.
+ *
+ * @see SortedListValueModelWrapper
+ */
+public class SortedListValueModelAdapter<E>
+	extends CollectionListValueModelAdapter<E>
+{
+	/**
+	 * A comparator used for sorting the elements;
+	 * if it is null, we use "natural ordering".
+	 */
+	protected Comparator<E> comparator;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Wrap the specified collection value model and sort its contents
+	 * using the specified comparator.
+	 */
+	public SortedListValueModelAdapter(CollectionValueModel<? extends E> collectionHolder, Comparator<E> comparator) {
+		super(collectionHolder);
+		this.comparator = comparator;
+	}
+
+	/**
+	 * Wrap the specified collection value model and sort its contents
+	 * based on the elements' "natural ordering".
+	 */
+	public SortedListValueModelAdapter(CollectionValueModel<? extends E> collectionHolder) {
+		this(collectionHolder, null);
+	}
+
+
+	// ********** accessors **********
+
+	public void setComparator(Comparator<E> comparator) {
+		this.comparator = comparator;
+		this.sortList();
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Sort the internal list before the superclass
+	 * sends out change notification.
+	 */
+	@Override
+	protected void buildList(int size) {
+		super.buildList(size);
+		Collections.sort(this.list, this.comparator);
+	}
+
+	/**
+	 * Sort the list after adding the items.
+	 */
+	@Override
+	protected void itemsAdded(CollectionAddEvent event) {
+		@SuppressWarnings("unchecked")
+		ArrayList<E> newList = (ArrayList<E>) this.list.clone();
+		newList.ensureCapacity(newList.size() + event.getItemsSize());
+		CollectionTools.addAll(newList, this.getItems(event));
+		Collections.sort(newList, this.comparator);
+		this.synchronizeList(newList, this.list, LIST_VALUES);
+	}
+
+	@Override
+	protected Iterable<? extends E> buildSyncList() {
+		return CollectionTools.sortedSet(this.collectionHolder, this.comparator, this.collectionHolder.size());
+	}
+
+	/**
+	 * sort the list and notify our listeners, if necessary;
+	 */
+	protected void sortList() {
+		// save the unsorted state of the sorted list so we can minimize the number of "replaced" items
+		@SuppressWarnings("unchecked")
+		ArrayList<E> unsortedList = (ArrayList<E>) this.list.clone();
+		Collections.sort(this.list, this.comparator);
+		Range diffRange = ListTools.identityDifferenceRange(unsortedList, this.list);
+		if (diffRange.size > 0) {
+			List<E> unsortedItems = unsortedList.subList(diffRange.start, diffRange.end + 1);
+			List<E> sortedItems = this.list.subList(diffRange.start, diffRange.end + 1);
+			this.fireItemsReplaced(LIST_VALUES, diffRange.start, sortedItems, unsortedItems);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SortedListValueModelWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SortedListValueModelWrapper.java
new file mode 100644
index 0000000..e333133
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/SortedListValueModelWrapper.java
@@ -0,0 +1,256 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.Range;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyListIterator;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+
+/**
+ * A wrapper that keeps the contents of a {@link ListValueModel} sorted
+ * and notifies listeners appropriately.
+ * <p>
+ * The {@link Comparator} can be changed at any time; allowing the same
+ * adapter to be used with different sort criteria (e.g. when the user
+ * wants to sort a list of files first by name, then by date, then by size).
+ * <p>
+ * <strong>NB:</strong> Since we only listen to the wrapped collection when we have
+ * listeners ourselves and we can only stay in sync with the wrapped
+ * collection while we are listening to it, results to various methods
+ * (e.g. {@link #size()}, {@link #get(int)}) will be unpredictable whenever
+ * we do not have any listeners. This should not be too painful since,
+ * most likely, client objects will also be listeners.
+ *
+ * @see SortedListValueModelAdapter
+ */
+public class SortedListValueModelWrapper<E>
+	extends ListValueModelWrapper<E>
+	implements ListValueModel<E>
+{
+	/**
+	 * A comparator used for sorting the elements;
+	 * if it is null, we use "natural ordering".
+	 */
+	protected Comparator<E> comparator;
+
+	/**
+	 * Our internal list, which holds the same elements as
+	 * the wrapped list, but keeps them sorted.
+	 */
+	// we declare this an ArrayList so we can use #clone() and #ensureCapacity(int)
+	protected final ArrayList<E> sortedList;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Wrap the specified list value model and sort its contents
+	 * using the specified comparator.
+	 */
+	public SortedListValueModelWrapper(ListValueModel<? extends E> listHolder, Comparator<E> comparator) {
+		super(listHolder);
+		this.comparator = comparator;
+		this.sortedList = new ArrayList<E>(listHolder.size());
+		// postpone building the sorted list and listening to the wrapped list
+		// until we have listeners ourselves...
+	}
+
+	/**
+	 * Wrap the specified list value model and sort its contents
+	 * based on the elements' "natural ordering".
+	 */
+	public SortedListValueModelWrapper(ListValueModel<? extends E> listHolder) {
+		this(listHolder, null);
+	}
+
+
+	// ********** ListValueModel implementation **********
+
+	@Override
+	public Iterator<E> iterator() {
+		return this.listIterator();
+	}
+
+	@Override
+	public ListIterator<E> listIterator() {
+		return new ReadOnlyListIterator<E>(this.sortedList);
+	}
+
+	@Override
+	public E get(int index) {
+		return this.sortedList.get(index);
+	}
+
+	@Override
+	public int size() {
+		return this.sortedList.size();
+	}
+
+	@Override
+	public Object[] toArray() {
+		return this.sortedList.toArray();
+	}
+
+
+	// ********** accessors **********
+
+	public void setComparator(Comparator<E> comparator) {
+		this.comparator = comparator;
+		this.sortList();
+	}
+
+
+	// ********** behavior **********
+
+    @Override
+	protected void engageModel() {
+		super.engageModel();
+		// sync the sorted list *after* we start listening to the wrapped list model,
+		// since its value might change when a listener is added
+		this.buildSortedList();
+	}
+
+    @Override
+	protected void disengageModel() {
+		super.disengageModel();
+		// clear out the sorted list when we are not listening to the wrapped list holder
+		this.sortedList.clear();
+	}
+
+	protected void buildSortedList() {
+		// if the new list is empty, do nothing
+		int size = this.listModel.size();
+		if (size != 0) {
+			this.buildSortedList(size);
+		}
+	}
+
+	protected void buildSortedList(int size) {
+		this.sortedList.ensureCapacity(size);
+		for (E each : this.listModel) {
+			this.sortedList.add(each);
+		}
+		Collections.sort(this.sortedList, this.comparator);
+	}
+
+
+	// ********** list change support **********
+
+	/**
+	 * Items were added to the wrapped list.
+	 */
+    @Override
+	protected void itemsAdded(ListAddEvent event) {
+		// first add the items and notify our listeners...
+		this.addItemsToList(this.getItems(event), this.sortedList, LIST_VALUES);
+		// ...then sort the list and notify our listeners
+		this.sortList();
+	}
+
+	/**
+	 * Items were removed from the wrapped list.
+	 */
+    @Override
+	protected void itemsRemoved(ListRemoveEvent event) {
+		this.removeItemsFromList(this.getItems(event), this.sortedList, LIST_VALUES);
+		// no sorting needed
+	}
+
+	/**
+	 * Items were replaced in the wrapped list.
+	 */
+    @Override
+	protected void itemsReplaced(ListReplaceEvent event) {
+		// first remove the old items and notify our listeners...
+		this.removeItemsFromList(this.getOldItems(event), this.sortedList, LIST_VALUES);
+		// then add the new items and notify our listeners...
+		this.addItemsToList(this.getNewItems(event), this.sortedList, LIST_VALUES);
+		// ...then sort the list and notify our listeners
+		this.sortList();
+	}
+
+	/**
+	 * Items were moved in the wrapped list.
+	 */
+    @Override
+	protected void itemsMoved(ListMoveEvent event) {
+    	// do nothing - sort order should remain unchanged
+	}
+
+	/**
+	 * The wrapped list was cleared.
+	 */
+    @Override
+	protected void listCleared(ListClearEvent event) {
+    	this.clearList(this.sortedList, LIST_VALUES);
+	}
+
+	/**
+	 * The wrapped list has changed in some dramatic fashion.
+	 * Rebuild our sorted list and notify our listeners.
+	 */
+    @Override
+	protected void listChanged(ListChangeEvent event) {
+		int size = this.listModel.size();
+		if (size == 0) {
+			if (this.sortedList.isEmpty()) {
+				// no change
+			} else {
+				this.clearList(this.sortedList, LIST_VALUES);
+			}
+		} else {
+			if (this.sortedList.isEmpty()) {
+				this.buildSortedList(size);
+				this.fireItemsAdded(LIST_VALUES, 0, this.sortedList);
+			} else {
+				this.sortedList.clear();
+				this.buildSortedList(size);
+				this.fireListChanged(LIST_VALUES, this.sortedList);
+			}
+		}
+	}
+
+	/**
+	 * sort the sorted list and notify our listeners, if necessary;
+	 */
+	protected void sortList() {
+		// save the unsorted state of the sorted list so we can minimize the number of "replaced" items
+		@SuppressWarnings("unchecked")
+		ArrayList<E> unsortedList = (ArrayList<E>) this.sortedList.clone();
+		Collections.sort(this.sortedList, this.comparator);
+		Range diffRange = ListTools.identityDifferenceRange(unsortedList, this.sortedList);
+		if (diffRange.size > 0) {
+			List<E> unsortedItems = unsortedList.subList(diffRange.start, diffRange.end + 1);
+			List<E> sortedItems = this.sortedList.subList(diffRange.start, diffRange.end + 1);
+			this.fireItemsReplaced(LIST_VALUES, diffRange.start, sortedItems, unsortedItems);
+		}
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.sortedList);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/StatePropertyValueModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/StatePropertyValueModelAdapter.java
new file mode 100644
index 0000000..e3ae8e7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/StatePropertyValueModelAdapter.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeAdapter;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
+
+/**
+ * This abstract class provides the infrastructure needed to wrap
+ * a model, "lazily" listen to it, and convert
+ * its state change notifications into property value model change
+ * notifications.
+ * <p>
+ * Subclasses must implement:<ul>
+ * <li>{@link #buildValue()}<p>
+ *     to return the current property value, as derived from the
+ *     current model
+ * </ul>
+ * Subclasses might want to override the following methods
+ * to improve performance (by not recalculating the value, if possible):<ul>
+ * <li>{@link #stateChanged(StateChangeEvent event)}
+ * </ul>
+ */
+public abstract class StatePropertyValueModelAdapter<T>
+	extends AbstractPropertyValueModelAdapter<T>
+{
+	/** The wrapped model. */
+	protected final Model model;
+
+	/** A listener that allows us to sync with changes to the wrapped model. */
+	protected final StateChangeListener stateListener;
+
+
+	// ********** constructor/initialization **********
+
+	/**
+	 * Construct a property value model with the specified wrapped model.
+	 */
+	protected StatePropertyValueModelAdapter(Model model) {
+		super();
+		if (model == null) {
+			throw new NullPointerException();
+		}
+		this.model = model;
+		this.stateListener = this.buildStateListener();
+	}
+
+	protected StateChangeListener buildStateListener() {
+		return new StateListener();
+	}
+
+	protected class StateListener
+		extends StateChangeAdapter
+	{
+		@Override
+		public void stateChanged(StateChangeEvent event) {
+			StatePropertyValueModelAdapter.this.stateChanged(event);
+		}
+	}
+
+
+	// ********** listener **********
+
+	/**
+	 * Start listening to the model.
+	 */
+	@Override
+	protected void engageModel_() {
+		this.model.addStateChangeListener(this.stateListener);
+	}
+
+	/**
+	 * Stop listening to the model.
+	 */
+	@Override
+	protected void disengageModel_() {
+		this.model.removeStateChangeListener(this.stateListener);
+	}
+
+
+	// ********** state change support **********
+
+	/**
+	 * The model's state changed;
+	 * propagate the change notification appropriately.
+	 */
+	protected void stateChanged(@SuppressWarnings("unused") StateChangeEvent event) {
+		// by default, simply recalculate the value and fire an event
+		this.propertyChanged();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/StaticCollectionValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/StaticCollectionValueModel.java
new file mode 100644
index 0000000..1cee3f7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/StaticCollectionValueModel.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Iterator;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.iterator.ArrayIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+
+/**
+ * Implementation of {@link CollectionValueModel} that can be used for
+ * returning an iterator on a static collection, but still allows listeners to be added.
+ * Listeners will <em>never</em> be notified of any changes, because there should be none.
+ */
+public class StaticCollectionValueModel<E>
+	extends AbstractModel
+	implements CollectionValueModel<E>, Serializable
+{
+	/** The elements. */
+	protected final Object[] elements;
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Construct a static collection value model for the specified array.
+	 */
+	public StaticCollectionValueModel(E... elements) {
+		super();
+		this.elements = elements.clone();
+	}
+
+	/**
+	 * Construct a static collection value model for the specified elements.
+	 */
+	public StaticCollectionValueModel(Iterable<? extends E> elements) {
+		super();
+		this.elements = ArrayTools.array(elements);
+	}
+
+
+	// ********** CollectionValueModel implementation **********
+
+	@Override
+	public int size() {
+		return this.elements.length;
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Iterator<E> iterator() {
+		// we can cast here since our constructors require the elements to be
+		// of type E and ArrayIterator is read-only
+		return (Iterator<E>) new ArrayIterator<Object>(this.elements);
+	}
+
+
+	// ********** Object overrides **********
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(Arrays.toString(this.elements));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/StaticListValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/StaticListValueModel.java
new file mode 100644
index 0000000..0f52dbe
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/StaticListValueModel.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.ArrayTools;
+import org.eclipse.persistence.tools.utility.iterator.ArrayIterator;
+import org.eclipse.persistence.tools.utility.iterator.ArrayListIterator;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+
+
+/**
+ * Implementation of {@link ListValueModel} that can be used for
+ * returning a list iterator on a static list, but still allows listeners to be added.
+ * Listeners will <em>never</em> be notified of any changes, because there should be none.
+ */
+public class StaticListValueModel<E>
+	extends AbstractModel
+	implements ListValueModel<E>, Serializable
+{
+	/** The elements. */
+	protected final Object[] elements;
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Construct a static list value model for the specified elements.
+	 */
+	public StaticListValueModel(E... elements) {
+		super();
+		this.elements = elements.clone();
+	}
+
+	/**
+	 * Construct a static list value model for the specified elements.
+	 */
+	public StaticListValueModel(Iterable<? extends E> elements) {
+		super();
+		this.elements = ArrayTools.array(elements);
+	}
+
+
+	// ********** ListValueModel implementation **********
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Iterator<E> iterator() {
+		// we can cast here since our constructors require the elements to be
+		// of type E and ArrayIterator is read-only
+		return (Iterator<E>) new ArrayIterator<Object>(this.elements);
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public ListIterator<E> listIterator() {
+		// we can cast here since our constructors require the elements to be
+		// of type E and ArrayListIterator is read-only
+		return (ListIterator<E>) new ArrayListIterator<Object>(this.elements);
+	}
+
+	@Override
+	public int size() {
+		return this.elements.length;
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public E get(int index) {
+		// we can cast here since our constructors require the elements to be
+		// of type E
+		return (E) this.elements[index];
+	}
+
+	@Override
+	public Object[] toArray() {
+		return this.elements.clone();
+	}
+
+
+	// ********** Object overrides **********
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(Arrays.toString(this.elements));
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/StaticPropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/StaticPropertyValueModel.java
new file mode 100644
index 0000000..635d086
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/StaticPropertyValueModel.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.model.AbstractModel;
+
+/**
+ * Implementation of {@link PropertyValueModel} that can be used for
+ * returning a static value, but still allows listeners to be added.
+ * Listeners will <em>never</em> be notified of any changes, because there should be none.
+ */
+public class StaticPropertyValueModel<T>
+	extends AbstractModel
+	implements PropertyValueModel<T>, Serializable
+{
+	/** The value. */
+	protected final T value;
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Construct a static property value model for the specified value.
+	 */
+	public StaticPropertyValueModel(T value) {
+		super();
+		this.value = value;
+	}
+
+
+	// ********** PropertyValueModel implementation **********
+
+	@Override
+	public T getValue() {
+		return this.value;
+	}
+
+
+	// ********** Object overrides **********
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.value);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/TransformationListValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/TransformationListValueModel.java
new file mode 100644
index 0000000..aefbe01
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/TransformationListValueModel.java
@@ -0,0 +1,322 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.persistence.tools.utility.iterator.ReadOnlyListIterator;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * An adapter that allows us to transform a {@link ListValueModel}
+ * (or adapted {@link CollectionValueModel}) into a read-only {@link ListValueModel}
+ * whose items are tranformations of the items in the wrapped
+ * {@link ListValueModel}. It will keep its contents in sync with
+ * the contents of the wrapped {@link ListValueModel} and notifies its
+ * listeners of any changes.
+ * <p>
+ * The {@link Transformer} can be changed at any time; allowing the same
+ * adapter to be used with different transformations.
+ * <p>
+ * As an alternative to building a {@link Transformer},
+ * a subclass of <code>TransformationListValueModelAdapter</code> can
+ * either override {@link #transformItem_(Object)} or,
+ * if something other than <code>null</code> should be returned when the
+ * wrapped item is <code>null</code>, override {@link #transformItem(Object)}.
+ * <p>
+ * <strong>NB:</strong> Since we only listen to the wrapped list when we have
+ * listeners ourselves and we can only stay in sync with the wrapped
+ * list while we are listening to it, results to various methods
+ * (e.g. {@link #size()}, {@link #get(int)}) will be unpredictable whenever
+ * we do not have any listeners. This should not be too painful since,
+ * most likely, clients will also be listeners.
+ *
+ * @see Transformer
+ */
+@SuppressWarnings("nls")
+public class TransformationListValueModel<E1, E2>
+	extends ListValueModelWrapper<E1>
+	implements ListValueModel<E2>
+{
+
+	/** This transforms the items, unless the subclass overrides {@link #transformItem(Object)}). */
+	protected Transformer<E1, E2> transformer;
+
+	/** The list of transformed items. */
+	protected final List<E2> transformedList;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a list value model with the specified nested
+	 * list value model and transformer.
+	 */
+	public TransformationListValueModel(ListValueModel<? extends E1> listHolder, Transformer<E1, E2> transformer) {
+		super(listHolder);
+		if (transformer == null) {
+			throw new NullPointerException();
+		}
+		this.transformer = transformer;
+		this.transformedList = new ArrayList<E2>();
+	}
+
+	/**
+	 * Construct a list value model with the specified nested
+	 * list value model and the default transformer.
+	 * Use this constructor if you want to override
+	 * {@link #transformItem_(Object)} or {@link #transformItem(Object)}
+	 * method instead of building a {@link Transformer}.
+	 */
+	public TransformationListValueModel(ListValueModel<? extends E1> listHolder) {
+		super(listHolder);
+		this.transformer = this.buildTransformer();
+		this.transformedList = new ArrayList<E2>();
+	}
+
+	/**
+	 * Construct a list value model with the specified nested
+	 * collection value model and transformer.
+	 */
+	public TransformationListValueModel(CollectionValueModel<? extends E1> collectionHolder, Transformer<E1, E2> transformer) {
+		this(new CollectionListValueModelAdapter<E1>(collectionHolder), transformer);
+	}
+
+	/**
+	 * Construct a list value model with the specified nested
+	 * collection value model and the default transformer.
+	 * Use this constructor if you want to override
+	 * {@link #transformItem_(Object)} or {@link #transformItem(Object)}
+	 * method instead of building a {@link Transformer}.
+	 */
+	public TransformationListValueModel(CollectionValueModel<? extends E1> collectionHolder) {
+		this(new CollectionListValueModelAdapter<E1>(collectionHolder));
+	}
+
+	protected Transformer<E1, E2> buildTransformer() {
+		return new DefaultTransformer();
+	}
+
+
+	// ********** ListValueModel implementation **********
+
+	@Override
+	public Iterator<E2> iterator() {
+		return this.listIterator();
+	}
+
+	@Override
+	public ListIterator<E2> listIterator() {
+		return new ReadOnlyListIterator<E2>(this.transformedList);
+	}
+
+	@Override
+	public E2 get(int index) {
+		return this.transformedList.get(index);
+	}
+
+	@Override
+	public int size() {
+		return this.transformedList.size();
+	}
+
+	@Override
+	public Object[] toArray() {
+		return this.transformedList.toArray();
+	}
+
+	// ********** behavior **********
+
+    @Override
+	protected void engageModel() {
+		super.engageModel();
+		// sync the transformed list *after* we start listening to the list model,
+		// since its value might change when a listener is added
+		this.transformedList.addAll(this.transformItems(this.listModel));
+	}
+
+    @Override
+	protected void disengageModel() {
+		super.disengageModel();
+		// clear out the list when we are not listening to the collection holder
+		this.transformedList.clear();
+	}
+
+	/**
+	 * Transform the items in the specified list value model.
+	 */
+	protected List<E2> transformItems(ListValueModel<? extends E1> lvm) {
+		return this.transformItems(lvm, lvm.size());
+	}
+
+	/**
+	 * Transform the items associated with the specified event.
+	 */
+	protected List<E2> transformItems(ListAddEvent event) {
+		return this.transformItems(this.getItems(event), event.getItemsSize());
+	}
+
+	/**
+	 * Transform the items associated with the specified event.
+	 */
+	protected List<E2> transformItems(ListRemoveEvent event) {
+		return this.transformItems(this.getItems(event), event.getItemsSize());
+	}
+
+	/**
+	 * Transform the new items associated with the specified event.
+	 */
+	protected List<E2> transformNewItems(ListReplaceEvent event) {
+		return this.transformItems(this.getNewItems(event), event.getItemsSize());
+	}
+
+	/**
+	 * Transform the old items associated with the specified event.
+	 */
+	protected List<E2> transformOldItems(ListReplaceEvent event) {
+		return this.transformItems(this.getOldItems(event), event.getItemsSize());
+	}
+
+	/**
+	 * Transform the specified items.
+	 */
+	protected List<E2> transformItems(Iterable<? extends E1> items, int size) {
+		List<E2> result = new ArrayList<E2>(size);
+		for (E1 item : items) {
+			result.add(this.transformItem(item));
+		}
+		return result;
+	}
+
+	/**
+	 * Transform the specified item.
+	 */
+	protected E2 transformItem(E1 item) {
+		return this.transformer.transform(item);
+	}
+
+	/**
+	 * Transform the specified, non-null, item and return the result.
+	 */
+	protected E2 transformItem_(@SuppressWarnings("unused") E1 item) {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+	/**
+	 * Change the transformer and rebuild the collection.
+	 */
+	public void setTransformer(Transformer<E1, E2> transformer) {
+		if (transformer == null) {
+			throw new NullPointerException();
+		}
+		this.transformer = transformer;
+		this.rebuildTransformedList();
+	}
+
+	/**
+	 * Synchronize our cache with the wrapped collection.
+	 */
+	protected void rebuildTransformedList() {
+		this.synchronizeList(this.transformItems(this.listModel), this.transformedList, LIST_VALUES);
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.transformedList);
+	}
+
+
+	// ********** list change support **********
+
+	/**
+	 * Items were added to the wrapped list holder.
+	 * Transform them, add them to our transformation list,
+	 * and notify our listeners.
+	 */
+    @Override
+	protected void itemsAdded(ListAddEvent event) {
+		this.addItemsToList(event.getIndex(), this.transformItems(event), this.transformedList, LIST_VALUES);
+	}
+
+	/**
+	 * Items were removed from the wrapped list holder.
+	 * Remove the corresponding items from our transformation list
+	 * and notify our listeners.
+	 */
+    @Override
+	protected void itemsRemoved(ListRemoveEvent event) {
+		this.removeItemsFromList(event.getIndex(), event.getItemsSize(), this.transformedList, LIST_VALUES);
+	}
+
+	/**
+	 * Items were replaced in the wrapped list holder.
+	 * Replace the corresponding items in our transformation list
+	 * and notify our listeners.
+	 */
+    @Override
+	protected void itemsReplaced(ListReplaceEvent event) {
+		this.setItemsInList(event.getIndex(), this.transformNewItems(event), this.transformedList, LIST_VALUES);
+	}
+
+	/**
+	 * Items were moved in the wrapped list holder.
+	 * Move the corresponding items in our transformation list
+	 * and notify our listeners.
+	 */
+    @Override
+	protected void itemsMoved(ListMoveEvent event) {
+    	this.moveItemsInList(event.getTargetIndex(), event.getSourceIndex(), event.getLength(), this.transformedList, LIST_VALUES);
+	}
+
+	/**
+	 * The wrapped list holder was cleared.
+	 * Clear our transformation list and notify our listeners.
+	 */
+    @Override
+	protected void listCleared(ListClearEvent event) {
+    	this.clearList(this.transformedList, LIST_VALUES);
+	}
+
+	/**
+	 * The wrapped list holder has changed in some dramatic fashion.
+	 * Rebuild our transformation list and notify our listeners.
+	 */
+    @Override
+	protected void listChanged(ListChangeEvent event) {
+		this.rebuildTransformedList();
+	}
+
+
+	// ********** default transformer **********
+
+	/**
+	 * The default transformer will return null if the wrapped item is null.
+	 * If the wrapped item is not null, it is transformed by a subclass
+	 * implementation of {@link TransformationListValueModel#transformItem_(Object)}.
+	 */
+	protected class DefaultTransformer implements Transformer<E1, E2> {
+		@Override
+		public E2 transform(E1 item) {
+			return (item == null) ? null : TransformationListValueModel.this.transformItem_(item);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/TransformationModifiablePropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/TransformationModifiablePropertyValueModel.java
new file mode 100644
index 0000000..48be14e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/TransformationModifiablePropertyValueModel.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * A <code>TransformationWritablePropertyValueModel</code> wraps another
+ * {@link ModifiablePropertyValueModel} and uses two {@link Transformer}s
+ * to:<ul>
+ * <li>transform the wrapped value before it is returned by {@link #getValue()}
+ * <li>"reverse-transform" the new value that comes in via
+ * {@link #setValue(Object)}
+ * </ul>
+ * <strong>NB:</strong> If the mapping between the wrapped values and the
+ * transformed values is not strictly one-to-one, the behavior of the
+ * transformation model may seem unpredictable; since the wrapped model's
+ * change events can cause the transformation model's value to change.
+ * For example: If the value is a string to be <em>transformed</em> to uppercase
+ * and <em>reverse-transformed</em> to lowercase; then mixed case values passed to
+ * the transformation model will be<ul>
+ * <li>unchanged if the transformation model has <em>no</em> listeners
+ * <li>changed to uppercase if the transformation model has any listeners
+ * ({@link #wrappedValueChanged(org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent)})
+ * </ul>
+ * As an alternative to building two {@link Transformer}s,
+ * a subclass of <code>TransformationWritablePropertyValueModel</code> can
+ * override {@link #transform_(Object)} and {@link #reverseTransform_(Object)};
+ * or, if something other than <code>null</code> should be returned when the
+ * wrapped value is <code>null</code> or the new value is <code>null</code>,
+ * override {@link #transform(Object)} and {@link #reverseTransform(Object)}.
+ *
+ * @param <V1> the type of the <em>wrapped</em> model's value
+ * @param <V2> the type of the model's <em>transformed</em> value
+ * @see Transformer
+ */
+@SuppressWarnings("nls")
+public class TransformationModifiablePropertyValueModel<V1, V2>
+	extends TransformationPropertyValueModel<V1, V2>
+	implements ModifiablePropertyValueModel<V2>
+{
+	protected final Transformer<V2, V1> reverseTransformer;
+
+
+	// ********** constructors/initialization **********
+
+	/**
+	 * Construct a writable property value model with the specified nested
+	 * writable property value model and the default transformers.
+	 * Use this constructor if you want to override the
+	 * {@link #transform_(Object)} and {@link #reverseTransform_(Object)}
+	 * (or {@link #transform(Object)} and {@link #reverseTransform(Object)})
+	 * methods instead of building {@link Transformer}s.
+	 */
+	public TransformationModifiablePropertyValueModel(ModifiablePropertyValueModel<V1> valueModel) {
+		super(valueModel);
+		this.reverseTransformer = this.buildReverseTransformer();
+	}
+
+	/**
+	 * Construct a writable property value model with the specified nested
+	 * writable property value model and transformers.
+	 */
+	public TransformationModifiablePropertyValueModel(ModifiablePropertyValueModel<V1> valueModel, Transformer<V1, V2> transformer, Transformer<V2, V1> reverseTransformer) {
+		super(valueModel, transformer);
+		if (reverseTransformer == null) {
+			throw new NullPointerException();
+		}
+		this.reverseTransformer = reverseTransformer;
+	}
+
+	protected Transformer<V2, V1> buildReverseTransformer() {
+		return new DefaultReverseTransformer();
+	}
+
+
+	// ********** WritablePropertyValueModel implementation **********
+
+	/**
+	 * Cache and "reverse-transform" the new value before passing it to the the
+	 * nested value model.
+	 * A side-effect of caching the new value is that the wrapper will
+	 * <em>not</em> fire an event when the wrapped model fires an event when
+	 * called from here.
+	 * @see #wrappedValueChanged(org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent)
+	 */
+	@Override
+	public void setValue(V2 value) {
+		this.value = value;
+		this.getValueModel().setValue(this.reverseTransform(value));
+	}
+
+
+	// ********** transformation **********
+
+	/**
+	 * "Reverse-transform" the specified value and return the result.
+	 * This is called by {@link #setValue(Object)}.
+	 */
+	protected V1 reverseTransform(V2 v) {
+		return this.reverseTransformer.transform(v);
+	}
+
+	/**
+	 * "Reverse-transform" the specified, non-<code>null</code>,
+	 * value and return the result.
+	 */
+	protected V1 reverseTransform_(@SuppressWarnings("unused") V2 v) {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * Our constructors accept only a {@link ModifiablePropertyValueModel}{@code<V>},
+	 * so this cast should be safe.
+	 */
+	@SuppressWarnings("unchecked")
+	protected ModifiablePropertyValueModel<V1> getValueModel() {
+		return (ModifiablePropertyValueModel<V1>) this.valueModel;
+	}
+
+
+	// ********** default reverse transformer **********
+
+	/**
+	 * The default reverse transformer will return <code>null</code>
+	 * if the new value is <code>null</code>.
+	 * If the new value is not <code>null</code>, it is reverse-transformed
+	 * by a subclass implementation of {@link #reverseTransform_(Object)}.
+	 */
+	protected class DefaultReverseTransformer
+		implements Transformer<V2, V1>
+	{
+		@Override
+		public V1 transform(V2 v) {
+			return (v == null) ? null : TransformationModifiablePropertyValueModel.this.reverseTransform_(v);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/TransformationPropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/TransformationPropertyValueModel.java
new file mode 100644
index 0000000..cc0453f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/TransformationPropertyValueModel.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * A <code>TransformationPropertyValueModel</code> wraps another
+ * {@link PropertyValueModel} and uses a {@link Transformer}
+ * to transform the wrapped value before it is returned by {@link #getValue()}.
+ * <p>
+ * The transformed value is calculated and cached during initialization and every
+ * time the wrapped value changes. This can be useful when the old value
+ * passed in to {@link #wrappedValueChanged(org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent)}
+ * can no longer be "transformed" because its state is no longer valid.
+ * This caching can also improve time performance in some situations.
+ * <p>
+ * As an alternative to building a {@link Transformer},
+ * a subclass of <code>TransformationPropertyValueModel</code> can
+ * either override {@link #transform_(Object)} or,
+ * if something other than <code>null</code> should be returned when the
+ * wrapped value is <code>null</code>, override {@link #transform(Object)}.
+ *
+ * @param <V1> the type of the <em>wrapped</em> model's value
+ * @param <V2> the type of the model's <em>transformed</em> value
+ * @see Transformer
+ */
+@SuppressWarnings("nls")
+public class TransformationPropertyValueModel<V1, V2>
+	extends PropertyValueModelWrapper<V1>
+	implements PropertyValueModel<V2>
+{
+	/**
+	 * Cache the transformed value so that during property change event
+	 * notification we do not have to transform the old value. It is possible
+	 * the old value is no longer be valid in the model; as a result,
+	 * transforming it would not be valid.
+	 */
+	protected volatile V2 value;
+
+	protected final Transformer<V1, V2> transformer;
+
+
+	// ********** constructors/initialization **********
+
+	/**
+	 * Construct a property value model with the specified nested
+	 * property value model and the default transformer.
+	 * Use this constructor if you want to override
+	 * {@link #transform_(Object)} or {@link #transform(Object)}
+	 * method instead of building a {@link Transformer}.
+	 */
+	public TransformationPropertyValueModel(PropertyValueModel<? extends V1> valueModel) {
+		super(valueModel);
+		this.transformer = this.buildTransformer();
+	}
+
+	/**
+	 * Construct a property value model with the specified nested
+	 * property value model and transformer. Depending on the nested model,
+	 * the transformer may be required to handle a <code>null</code> value.
+	 */
+	public TransformationPropertyValueModel(PropertyValueModel<? extends V1> valueModel, Transformer<V1, V2> transformer) {
+		super(valueModel);
+		if (transformer == null) {
+			throw new NullPointerException();
+		}
+		this.transformer = transformer;
+	}
+
+	protected Transformer<V1, V2> buildTransformer() {
+		return new DefaultTransformer();
+	}
+
+
+	// ********** PropertyValueModel implementation **********
+
+	/**
+	 * No need to transform the nested value, simply return the cached value,
+	 * which is already transformed.
+	 */
+	@Override
+	public V2 getValue() {
+		return this.value;
+	}
+
+
+	// ********** PropertyValueModelWrapper implementation **********
+
+	/**
+	 * Propagate the event with transformed values.
+	 */
+	@Override
+	protected void wrappedValueChanged(V1 oldValue, V1 newValue) {
+		V2 old = this.value;
+		this.firePropertyChanged(VALUE, old, this.value = this.transform(newValue));
+	}
+
+
+	// ********** transformation **********
+
+	/**
+	 * Transform the specified value and return the result.
+	 */
+	protected V2 transform(V1 v) {
+		return this.transformer.transform(v);
+	}
+
+	/**
+	 * Transform the specified, non-<code>null</code>, value and return the result.
+	 */
+	protected V2 transform_(@SuppressWarnings("unused") V1 v) {
+		throw new RuntimeException("This method was not overridden.");
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.value);
+	}
+
+
+	// ********** listeners **********
+
+	/**
+	 * We have listeners, transform the nested value and cache the result.
+	 */
+	@Override
+	protected void engageModel() {
+		super.engageModel();
+		this.value = this.transform(this.valueModel.getValue());
+	}
+
+	/**
+	 * We have no more listeners, clear the cached value.
+	 */
+	@Override
+	protected void disengageModel() {
+		this.value = null;
+		super.disengageModel();
+	}
+
+
+	// ********** default transformer **********
+
+	/**
+	 * The default transformer will return <code>null</code> if the wrapped
+	 * value is <code>null</code>. If the wrapped value is not
+	 * <code>null</code>, it is transformed by a subclass
+	 * implementation of {@link TransformationPropertyValueModel#transform_(Object)}.
+	 */
+	protected class DefaultTransformer
+		implements Transformer<V1, V2>
+	{
+		@Override
+		public V2 transform(V1 v) {
+			return (v == null) ? null : TransformationPropertyValueModel.this.transform_(v);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/TreeNodeValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/TreeNodeValueModel.java
new file mode 100644
index 0000000..107845e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/TreeNodeValueModel.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+/**
+ * Extend {@link ModifiablePropertyValueModel} to better support
+ * {@link org.eclipse.jpt.common.utility.internal.model.value.swing.TreeModelAdapter}.
+ * <p>
+ * Implementors of this interface should fire a "state change" event
+ * whenever the node's internal state changes in a way that the
+ * tree listeners should be notified.
+ * <p>
+ * Implementors of this interface should also fire a "value property change"
+ * event whenever the node's value changes. Typically, only nodes that
+ * hold "primitive" data will fire this event.
+ * <p>
+ * 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.
+ *
+ * @param <T> the type of values held by the model
+ *
+ * @see org.eclipse.jpt.common.utility.internal.model.value.AbstractTreeNodeValueModel
+ */
+public interface TreeNodeValueModel<T>
+	extends ModifiablePropertyValueModel<T>
+{
+
+	/**
+	 * Return the node's parent node; null if the node
+	 * is the root.
+	 */
+	TreeNodeValueModel<T> parent();
+
+	/**
+	 * Return the path to the node.
+	 */
+	TreeNodeValueModel<T>[] path();
+
+	/**
+	 * Return a list value model of the node's child nodes.
+	 */
+	ListValueModel<TreeNodeValueModel<T>> childrenModel();
+
+	/**
+	 * Return the node's child at the specified index.
+	 */
+	TreeNodeValueModel<T> child(int index);
+
+	/**
+	 * Return the size of the node's list of children.
+	 */
+	int childrenSize();
+
+	/**
+	 * Return the index in the node's list of children of the specified child.
+	 */
+	int indexOfChild(TreeNodeValueModel<T> child);
+
+	/**
+	 * Return whether the node is a leaf (i.e. it has no children)
+	 */
+	boolean isLeaf();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueAspectAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueAspectAdapter.java
new file mode 100644
index 0000000..50a3fc5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueAspectAdapter.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.ChangeSupport;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
+
+/**
+ * Abstract class that provides support for wrapping a {@link ModifiablePropertyValueModel}
+ * and listening for changes to <em>aspects</em> of the <em>value</em> held
+ * by the {@link ModifiablePropertyValueModel}. Changes to the
+ * {@link ModifiablePropertyValueModel}'s value are also monitored.
+ * <p>
+ * This is useful if you have a value that may change, but whose aspects can also
+ * change in a fashion that might be of interest to the client.
+ * <p>
+ * <strong>NB:</strong> Clients will need to listen for two different change
+ * notifications:<ul>
+ * <li>a property change event will be be fired when the <em>value</em> changes;
+ * <li>a state change event will be fired when an <em>aspect</em> of the value changes.
+ * </ul>
+ * Subclasses need to override two methods:<ul>
+ * <li>{@link #engageValue_()}<p>
+ *     begin listening to the appropriate aspect of the value and call
+ *     {@link #valueAspectChanged()} whenever the aspect changes
+ *     (this will fire a state change event)
+ * <li>{@link #disengageValue_()}<p>
+ *     stop listening to the appropriate aspect of the value
+ * </ul>
+ */
+public abstract class ValueAspectAdapter<V>
+	extends PropertyValueModelWrapper<V>
+	implements ModifiablePropertyValueModel<V>
+{
+	/** Cache the value so we can disengage. */
+	protected volatile V value;
+
+
+	// ********** constructors/initialization **********
+
+	/**
+	 * Constructor - the value model is required.
+	 */
+	protected ValueAspectAdapter(ModifiablePropertyValueModel<V> valueModel) {
+		super(valueModel);
+		this.value = null;
+	}
+
+	/**
+	 * Override to allow both property and state change listeners.
+	 */
+	@Override
+	protected ChangeSupport buildChangeSupport() {
+		return new ChangeSupport(this);
+	}
+
+
+	// ********** PropertyValueModel implementation **********
+
+	@Override
+	public V getValue() {
+		return this.value;
+	}
+
+
+	// ********** WritablePropertyValueModel implementation **********
+
+	@Override
+	public void setValue(V value) {
+		this.getValueModel().setValue(value);
+	}
+
+
+	// ********** PropertyValueModelWrapper implementation **********
+
+	@Override
+	protected void wrappedValueChanged(PropertyChangeEvent event) {
+		this.disengageValue();
+		this.engageValue();
+		this.firePropertyChanged(event.clone(this));
+	}
+
+
+	// ********** listeners **********
+
+	/**
+	 * Extend to start listening to the underlying model if necessary.
+	 */
+	@Override
+	public synchronized void addStateChangeListener(StateChangeListener listener) {
+		if (this.hasNoListeners()) {
+			this.engageModel();
+		}
+		super.addStateChangeListener(listener);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying model if necessary.
+	 */
+	@Override
+	public synchronized void removeStateChangeListener(StateChangeListener listener) {
+		super.removeStateChangeListener(listener);
+		if (this.hasNoListeners()) {
+			this.disengageModel();
+		}
+	}
+
+	/**
+	 * Extend to check for state change listeners.
+	 */
+	@Override
+	protected boolean hasListeners() {
+		return this.hasAnyStateChangeListeners() || super.hasListeners();
+	}
+
+	/**
+	 * Extend to engage an aspect of the value model's value.
+	 */
+	@Override
+	protected void engageModel() {
+		super.engageModel();
+		this.engageValue();
+	}
+
+	/**
+	 * Extend to disengage an aspect of the value model's value.
+	 */
+	@Override
+	protected void disengageModel() {
+		this.disengageValue();
+		super.disengageModel();
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Start listening to an aspect of the current value.
+	 */
+	protected void engageValue() {
+		this.value = this.valueModel.getValue();
+		if (this.value != null) {
+			this.engageValue_();
+		}
+	}
+
+	/**
+	 * Start listening to some aspect of the current value.
+	 * At this point we can be sure the value is not <code>null</code>.
+	 */
+	protected abstract void engageValue_();
+
+	/**
+	 * Stop listening to an aspect of the current value.
+	 */
+	protected void disengageValue() {
+		if (this.value != null) {
+			this.disengageValue_();
+			this.value = null;
+		}
+	}
+
+	/**
+	 * Stop listening to an aspect of the current value.
+	 * At this point we can be sure the value is not <code>null</code>.
+	 */
+	protected abstract void disengageValue_();
+
+	/**
+	 * Subclasses should call this method whenever the value's aspect changes.
+	 */
+	protected void valueAspectChanged() {
+		this.fireStateChanged();
+	}
+
+	/**
+	 * Our constructor accepts only a {@link ModifiablePropertyValueModel}{@code<V>}.
+	 */
+	@SuppressWarnings("unchecked")
+	protected ModifiablePropertyValueModel<V> getValueModel() {
+		return (ModifiablePropertyValueModel<V>) this.valueModel;
+	}
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.getValue());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueChangeAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueChangeAdapter.java
new file mode 100644
index 0000000..98f800b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueChangeAdapter.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.ChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.AbstractChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+
+/**
+ * Extend {@link ValueAspectAdapter} to listen to all the aspects
+ * of the value in the wrapped value model.
+ */
+public class ValueChangeAdapter<V extends Model>
+	extends ValueAspectAdapter<V>
+{
+	/** Listener that listens to the value. */
+	protected final ChangeListener valueAspectListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a change adapter for the specified value.
+	 */
+	public ValueChangeAdapter(ModifiablePropertyValueModel<V> valueHolder) {
+		super(valueHolder);
+		this.valueAspectListener = this.buildValueAspectListener();
+	}
+
+
+	// ********** initialization **********
+
+	protected ChangeListener buildValueAspectListener() {
+		return new ValueAspectListener();
+	}
+
+	protected class ValueAspectListener
+		extends AbstractChangeListener
+	{
+		@Override
+		protected void modelChanged(ChangeEvent event) {
+			ValueChangeAdapter.this.valueAspectChanged(event);
+		}
+	}
+
+
+	// ********** ValueAspectAdapter implementation **********
+
+	@Override
+	protected void engageValue_() {
+		this.value.addChangeListener(this.valueAspectListener);
+	}
+
+	@Override
+	protected void disengageValue_() {
+		this.value.removeChangeListener(this.valueAspectListener);
+	}
+
+
+	// ********** change events **********
+
+	protected void valueAspectChanged(@SuppressWarnings("unused") ChangeEvent event) {
+		this.valueAspectChanged();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueCollectionAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueCollectionAdapter.java
new file mode 100644
index 0000000..2a982d9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueCollectionAdapter.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Arrays;
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.CollectionAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.CollectionRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+
+/**
+ * Extend {@link ValueAspectAdapter} to listen to one or more collection
+ * aspects of the value in the wrapped value model.
+ */
+@SuppressWarnings("nls")
+public class ValueCollectionAdapter<V extends Model>
+	extends ValueAspectAdapter<V>
+{
+	/** The names of the value's collections that we listen to. */
+	protected final String[] collectionNames;
+
+	/** Listener that listens to the value. */
+	protected final CollectionChangeListener valueCollectionListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an adapter for the specified value collections.
+	 */
+	public ValueCollectionAdapter(ModifiablePropertyValueModel<V> valueHolder, String... collectionNames) {
+		super(valueHolder);
+		if (collectionNames == null) {
+			throw new NullPointerException();
+		}
+		this.collectionNames = collectionNames;
+		this.valueCollectionListener = this.buildValueCollectionListener();
+	}
+
+
+	// ********** initialization **********
+
+	protected CollectionChangeListener buildValueCollectionListener() {
+		return new CollectionChangeListener() {
+			@Override
+			public void itemsAdded(CollectionAddEvent event) {
+				ValueCollectionAdapter.this.itemsAdded(event);
+			}
+			@Override
+			public void itemsRemoved(CollectionRemoveEvent event) {
+				ValueCollectionAdapter.this.itemsRemoved(event);
+			}
+			@Override
+			public void collectionCleared(CollectionClearEvent event) {
+				ValueCollectionAdapter.this.collectionCleared(event);
+			}
+			@Override
+			public void collectionChanged(CollectionChangeEvent event) {
+				ValueCollectionAdapter.this.collectionChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "value collection listener: " + Arrays.asList(ValueCollectionAdapter.this.collectionNames);
+			}
+		};
+	}
+
+
+	// ********** ValueAspectAdapter implementation **********
+
+	@Override
+	protected void engageValue_() {
+		for (String collectionName : this.collectionNames) {
+			this.value.addCollectionChangeListener(collectionName, this.valueCollectionListener);
+		}
+	}
+
+	@Override
+	protected void disengageValue_() {
+		for (String collectionName : this.collectionNames) {
+			this.value.removeCollectionChangeListener(collectionName, this.valueCollectionListener);
+		}
+	}
+
+
+	// ********** change events **********
+
+	protected void itemsAdded(@SuppressWarnings("unused") CollectionAddEvent event) {
+		this.valueAspectChanged();
+	}
+
+	protected void itemsRemoved(@SuppressWarnings("unused") CollectionRemoveEvent event) {
+		this.valueAspectChanged();
+	}
+
+	protected void collectionCleared(@SuppressWarnings("unused") CollectionClearEvent event) {
+		this.valueAspectChanged();
+	}
+
+	protected void collectionChanged(@SuppressWarnings("unused") CollectionChangeEvent event) {
+		this.valueAspectChanged();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueListAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueListAdapter.java
new file mode 100644
index 0000000..12d6c88
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueListAdapter.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Arrays;
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+
+/**
+ * Extend {@link ValueAspectAdapter} to listen to one or more list
+ * aspects of the value in the wrapped value model.
+ */
+@SuppressWarnings("nls")
+public class ValueListAdapter<V extends Model>
+	extends ValueAspectAdapter<V>
+{
+	/** The names of the value's lists that we listen to. */
+	protected final String[] listNames;
+
+	/** Listener that listens to the value. */
+	protected final ListChangeListener valueListListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an adapter for the specified value lists.
+	 */
+	public ValueListAdapter(ModifiablePropertyValueModel<V> valueHolder, String... listNames) {
+		super(valueHolder);
+		if (listNames == null) {
+			throw new NullPointerException();
+		}
+		this.listNames = listNames;
+		this.valueListListener = this.buildValueListListener();
+	}
+
+
+	// ********** initialization **********
+
+	protected ListChangeListener buildValueListListener() {
+		return new ListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) {
+				ValueListAdapter.this.itemsAdded(event);
+			}
+			@Override
+			public void itemsRemoved(ListRemoveEvent event) {
+				ValueListAdapter.this.itemsRemoved(event);
+			}
+			@Override
+			public void itemsReplaced(ListReplaceEvent event) {
+				ValueListAdapter.this.itemsReplaced(event);
+			}
+			@Override
+			public void itemsMoved(ListMoveEvent event) {
+				ValueListAdapter.this.itemsMoved(event);
+			}
+			@Override
+			public void listCleared(ListClearEvent event) {
+				ValueListAdapter.this.listCleared(event);
+			}
+			@Override
+			public void listChanged(ListChangeEvent event) {
+				ValueListAdapter.this.listChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "value list listener: " + Arrays.asList(ValueListAdapter.this.listNames);
+			}
+		};
+	}
+
+
+	// ********** ValueAspectAdapter implementation **********
+
+	@Override
+	protected void engageValue_() {
+		for (String listName : this.listNames) {
+			this.value.addListChangeListener(listName, this.valueListListener);
+		}
+	}
+
+	@Override
+	protected void disengageValue_() {
+		for (String listName : this.listNames) {
+			this.value.removeListChangeListener(listName, this.valueListListener);
+		}
+	}
+
+
+	// ********** change events **********
+
+	protected void itemsAdded(@SuppressWarnings("unused") ListAddEvent event) {
+		this.valueAspectChanged();
+	}
+
+	protected void itemsRemoved(@SuppressWarnings("unused") ListRemoveEvent event) {
+		this.valueAspectChanged();
+	}
+
+	protected void itemsReplaced(@SuppressWarnings("unused") ListReplaceEvent event) {
+		this.valueAspectChanged();
+	}
+
+	protected void itemsMoved(@SuppressWarnings("unused") ListMoveEvent event) {
+		this.valueAspectChanged();
+	}
+
+	protected void listCleared(@SuppressWarnings("unused") ListClearEvent event) {
+		this.valueAspectChanged();
+	}
+
+	protected void listChanged(@SuppressWarnings("unused") ListChangeEvent event) {
+		this.valueAspectChanged();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValuePropertyAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValuePropertyAdapter.java
new file mode 100644
index 0000000..61985e1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValuePropertyAdapter.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import java.util.Arrays;
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+
+/**
+ * Extend {@link ValueAspectAdapter} to listen to one or more
+ * properties of the value in the wrapped value model.
+ */
+@SuppressWarnings("nls")
+public class ValuePropertyAdapter<V extends Model>
+	extends ValueAspectAdapter<V>
+{
+	/** The names of the value's properties we listen to. */
+	protected final String[] propertyNames;
+
+	/** Listener that listens to the value. */
+	protected final PropertyChangeListener valuePropertyListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an adapter for the specified value properties.
+	 */
+	public ValuePropertyAdapter(ModifiablePropertyValueModel<V> valueHolder, String... propertyNames) {
+		super(valueHolder);
+		if (propertyNames == null) {
+			throw new NullPointerException();
+		}
+		this.propertyNames = propertyNames;
+		this.valuePropertyListener = this.buildValuePropertyListener();
+	}
+
+
+	// ********** initialization **********
+
+	protected PropertyChangeListener buildValuePropertyListener() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent event) {
+				ValuePropertyAdapter.this.propertyChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "value property listener: " + Arrays.asList(ValuePropertyAdapter.this.propertyNames);
+			}
+		};
+	}
+
+
+	// ********** ValueAspectAdapter implementation **********
+
+	@Override
+	protected void engageValue_() {
+		for (String propertyName : this.propertyNames) {
+			this.value.addPropertyChangeListener(propertyName, this.valuePropertyListener);
+		}
+	}
+
+	@Override
+	protected void disengageValue_() {
+		for (String propertyName : this.propertyNames) {
+			this.value.removePropertyChangeListener(propertyName, this.valuePropertyListener);
+		}
+	}
+
+
+	// ********** change events **********
+
+	protected void propertyChanged(@SuppressWarnings("unused") PropertyChangeEvent event) {
+		this.valueAspectChanged();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueStateAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueStateAdapter.java
new file mode 100644
index 0000000..4bb0d18
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/ValueStateAdapter.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value;
+
+import org.eclipse.persistence.tools.utility.model.Model;
+import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
+
+/**
+ * Extend {@link ValueAspectAdapter} to listen to the
+ * "state" of the value in the wrapped value model.
+ */
+@SuppressWarnings("nls")
+public class ValueStateAdapter<V extends Model>
+	extends ValueAspectAdapter<V>
+{
+	/** Listener that listens to value. */
+	protected final StateChangeListener valueStateListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an adapter for the value state.
+	 */
+	public ValueStateAdapter(ModifiablePropertyValueModel<V> valueHolder) {
+		super(valueHolder);
+		this.valueStateListener = this.buildValueStateListener();
+	}
+
+
+	// ********** initialization **********
+
+	protected StateChangeListener buildValueStateListener() {
+		return new StateChangeListener() {
+			@Override
+			public void stateChanged(StateChangeEvent event) {
+				ValueStateAdapter.this.stateChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "value state listener";
+			}
+		};
+	}
+
+
+	// ********** ValueAspectAdapter implementation **********
+
+	@Override
+	protected void engageValue_() {
+		this.value.addStateChangeListener(this.valueStateListener);
+	}
+
+	@Override
+	protected void disengageValue_() {
+		this.value.removeStateChangeListener(this.valueStateListener);
+	}
+
+
+	// ********** change events **********
+
+	protected void stateChanged(@SuppressWarnings("unused") StateChangeEvent event) {
+		this.valueAspectChanged();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/prefs/PreferencePropertyValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/prefs/PreferencePropertyValueModel.java
new file mode 100644
index 0000000..aca673e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/prefs/PreferencePropertyValueModel.java
@@ -0,0 +1,409 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.prefs;
+
+import java.util.EventListener;
+import java.util.prefs.PreferenceChangeEvent;
+import java.util.prefs.PreferenceChangeListener;
+import java.util.prefs.Preferences;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.AspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.StaticPropertyValueModel;
+import org.eclipse.persistence.tools.utility.transformer.BooleanStringTransformer;
+import org.eclipse.persistence.tools.utility.transformer.IntegerStringTransformer;
+import org.eclipse.persistence.tools.utility.transformer.StringObjectTransformer;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * This adapter wraps a {@link Preferences} and converts it into a
+ * {@link PropertyValueModel}.
+ * It listens for the appropriate "preference" changes and converts them into
+ * {@link PropertyValueModel#VALUE} property changes. It also allows the
+ * specification of a default value
+ * for the {@link Preferences} , which, by default, is <code>null</code>
+ * (and is probably <em>not</em> a very good default).
+ * <p>
+ * You can configure whether the preference's value is returned,
+ * unchanged, as a string or as some other object (e.g. an <code>Integer</code>)
+ * by setting the adapter's converter. Internally, the preference's value
+ * is stored as the converted object; and the conversions take place
+ * when reading or writing from the preferences node or retrieving the
+ * value from an event fired by the preferences node.
+ * <p>
+ * This adapter is a bit different from most other adapters because the
+ * change events fired off by a {@link Preferences} node are asynchronous from
+ * the change itself.
+ * ({@link java.util.prefs.AbstractPreferences} uses an event dispatch daemon.)
+ * As a result, a client can set our value with {@link #setValue(Object)} and we
+ * will return from that method before we ever receive notification from
+ * the {@link Preferences} node that <em>it</em> has changed. This means we cannot
+ * rely on that event to keep our internally cached value in synch.
+ */
+@SuppressWarnings("nls")
+public class PreferencePropertyValueModel<P>
+	extends AspectAdapter<Preferences, P>
+	implements ModifiablePropertyValueModel<P>
+{
+	/** The key to the preference we use for the value. */
+	protected final String key;
+
+	/**
+	 * Cache the current (object) value of the preference so we
+	 * can pass an "old value" when we fire a property change event.
+	 */
+	protected P value;
+
+	/**
+	 * The default (object) value returned if there is no value
+	 * associated with the preference.
+	 */
+	protected final P defaultValue;
+
+	/**
+	 * This transformer is used to convert the preference's
+	 * string value to an object.
+	 */
+	protected final Transformer<String, P> stringTransformer;
+
+	/**
+	 * This transformer is used to convert an object
+	 * to the preference's string value.
+	 */
+	protected final Transformer<P, String> objectTransformer;
+
+	/** A listener that listens to the appropriate preference. */
+	protected final PreferenceChangeListener preferenceChangeListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an adapter for the specified preference with
+	 * the specified default value for the preference.
+	 */
+	public static PreferencePropertyValueModel<String> forString(Preferences preferences, String key, String defaultValue) {
+		return new PreferencePropertyValueModel<String>(
+				preferences,
+				key,
+				defaultValue,
+				Transformer.Non.<String>instance()
+			);
+	}
+
+	/**
+	 * Construct an adapter for the specified preference with
+	 * the specified default value for the preference.
+	 */
+	public static PreferencePropertyValueModel<String> forString(PropertyValueModel<? extends Preferences> preferencesModel, String key, String defaultValue) {
+		return new PreferencePropertyValueModel<String>(
+				preferencesModel,
+				key,
+				defaultValue,
+				Transformer.Non.<String>instance()
+			);
+	}
+
+	/**
+	 * Construct an adapter for the specified preference with
+	 * the specified default value for the preference.
+	 */
+	public static PreferencePropertyValueModel<Boolean> forBoolean(Preferences preferences, String key, boolean defaultValue) {
+		return new PreferencePropertyValueModel<Boolean>(
+				preferences,
+				key,
+				defaultValue ? Boolean.TRUE : Boolean.FALSE,
+				BooleanStringTransformer.instance()
+			);
+	}
+
+	/**
+	 * Construct an adapter for the specified preference with
+	 * the specified default value for the preference.
+	 */
+	public static PreferencePropertyValueModel<Boolean> forBoolean(PropertyValueModel<? extends Preferences> preferencesModel, String key, boolean defaultValue) {
+		return new PreferencePropertyValueModel<Boolean>(
+				preferencesModel,
+				key,
+				defaultValue ? Boolean.TRUE : Boolean.FALSE,
+				BooleanStringTransformer.instance()
+			);
+	}
+
+	/**
+	 * Construct an adapter for the specified preference with
+	 * the specified default value for the preference.
+	 */
+	public static PreferencePropertyValueModel<Integer> forInteger(Preferences preferences, String key, int defaultValue) {
+		return new PreferencePropertyValueModel<Integer>(
+				preferences,
+				key,
+				Integer.valueOf(defaultValue),
+				IntegerStringTransformer.instance()
+			);
+	}
+
+	/**
+	 * Construct an adapter for the specified preference with
+	 * the specified default value for the preference.
+	 */
+	public static PreferencePropertyValueModel<Integer> forInteger(PropertyValueModel<? extends Preferences> preferencesModel, String key, int defaultValue) {
+		return new PreferencePropertyValueModel<Integer>(
+				preferencesModel,
+				key,
+				Integer.valueOf(defaultValue),
+				IntegerStringTransformer.instance()
+			);
+	}
+
+	/**
+	 * Construct an adapter for the specified preference with
+	 * the specified default value for the preference.
+	 */
+	public PreferencePropertyValueModel(Preferences preferences, String key, P defaultValue, Transformer<String, P> stringTransformer) {
+		this(new StaticPropertyValueModel<Preferences>(preferences), key, defaultValue, stringTransformer);
+	}
+
+	/**
+	 * Construct an adapter for the specified preference with
+	 * the specified default value for the preference.
+	 */
+	public PreferencePropertyValueModel(
+			PropertyValueModel<? extends Preferences> preferencesModel,
+			String key,
+			P defaultValue,
+			Transformer<String, P> stringTransformer) {
+		this(preferencesModel, key, defaultValue, stringTransformer, StringObjectTransformer.<P>instance());
+	}
+
+	/**
+	 * Construct an adapter for the specified preference with
+	 * the specified default value for the preference.
+	 */
+	public PreferencePropertyValueModel(
+			PropertyValueModel<? extends Preferences> preferencesModel,
+			String key,
+			P defaultValue,
+			Transformer<String, P> stringTransformer,
+			Transformer<P, String> objectTransformer) {
+		super(preferencesModel);
+		if ((key == null) || (stringTransformer == null) || (objectTransformer == null)) {
+			throw new NullPointerException();
+		}
+		this.key = key;
+		this.defaultValue = defaultValue;
+		this.stringTransformer = stringTransformer;
+		this.objectTransformer = objectTransformer;
+		this.preferenceChangeListener = this.buildPreferenceChangeListener();
+		// our value is null when we are not listening to the preference
+		this.value = null;
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * A preference has changed, notify the listeners if necessary.
+	 */
+	protected PreferenceChangeListener buildPreferenceChangeListener() {
+		// transform the preference change events into VALUE property change events
+		return new PreferenceChangeListener() {
+			@Override
+			public void preferenceChange(PreferenceChangeEvent event) {
+				PreferencePropertyValueModel.this.preferenceChanged(event.getKey(), event.getNewValue());
+			}
+			@Override
+			public String toString() {
+				return "preference change listener";
+			}
+		};
+	}
+
+
+	// ********** ValueModel implementation **********
+
+	/**
+	 * Return the cached (converted) value.
+	 */
+	@Override
+	public synchronized P getValue() {
+		return this.value;
+	}
+
+
+	// ********** PropertyValueModel implementation **********
+
+	/**
+	 * Set the cached value, then set the appropriate preference value.
+	 */
+	@Override
+	public synchronized void setValue(P value) {
+		if (this.hasNoListeners()) {
+			return;		// no changes allowed when we have no listeners
+		}
+
+		Object old = this.value;
+		this.value = value;
+		this.fireAspectChanged(old, value);
+
+		if ((this.subject != null) && this.preferenceIsToBeSet(old, value)) {
+			this.setValue_(value);
+		}
+	}
+
+
+	// ********** AspectAdapter implementation **********
+
+	@Override
+	protected synchronized P getAspectValue() {
+		return this.value;
+	}
+
+	@Override
+	protected Class<? extends EventListener> getListenerClass() {
+		return PropertyChangeListener.class;
+	}
+
+	@Override
+	protected String getListenerAspectName() {
+		return VALUE;
+	}
+
+	@Override
+	protected boolean hasListeners() {
+		return this.hasAnyPropertyChangeListeners(VALUE);
+	}
+
+	@Override
+	protected void fireAspectChanged(Object oldValue, Object newValue) {
+		this.firePropertyChanged(VALUE, oldValue, newValue);
+	}
+
+	@Override
+	protected synchronized void engageSubject_() {
+		this.subject.addPreferenceChangeListener(this.preferenceChangeListener);
+		this.value = this.buildValue();
+	}
+
+	@Override
+	protected synchronized void disengageSubject_() {
+		try {
+			this.subject.removePreferenceChangeListener(this.preferenceChangeListener);
+		} catch (IllegalStateException ex) {
+			// for some odd reason, we are not allowed to remove a listener from a "dead"
+			// preferences node; so handle the exception that gets thrown here
+			if ( ! ex.getMessage().equals("Node has been removed.")) { //$NON-NLS-1$
+				// if it is not the expected exception, re-throw it
+				throw ex;
+			}
+		}
+		this.value = null;
+	}
+
+
+	// ********** AbstractModel implementation **********
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.key);
+		sb.append(" => ");
+		sb.append(this.value);
+	}
+
+
+	// ********** public API **********
+
+	/**
+	 * Return the preference's key.
+	 */
+	public String getKey() {
+		return this.key;
+	}
+
+
+	// ********** internal methods **********
+
+	/**
+	 * Return the preference's value.
+	 * At this point the subject may be null.
+	 */
+	protected P buildValue() {
+		return (this.subject == null) ? null : this.buildValue_();
+	}
+
+	/**
+	 * Return the appropriate preference, converted to the appropriate object.
+	 * At this point we can be sure that the subject is not null.
+	 */
+	protected P buildValue_() {
+		return this.convertToObject(this.subject.get(this.key, this.convertToString(this.defaultValue)));
+	}
+
+	/**
+	 * Set the appropriate preference after converting the value to a string.
+	 * At this point we can be sure that the subject is not null.
+	 */
+	protected void setValue_(P value) {
+		this.subject.put(this.key, this.convertToString(value));
+	}
+
+	/**
+	 * Return whether the specified new value should be passed
+	 * through to the preference. By default, only if the value has changed,
+	 * will it be passed through to the preference. This also has the
+	 * effect of not creating new preferences in the "backing store"
+	 * if the new value is the same as the default value.
+	 *
+	 * Subclasses can override this method to return true if they
+	 * would like to ALWAYS pass through the new value to the preference.
+	 */
+	protected boolean preferenceIsToBeSet(Object oldValue, Object newValue) {
+		return this.attributeValueHasChanged(oldValue, newValue);
+	}
+
+	/**
+	 * Convert the specified object to a string that can be stored as
+	 * the value of the preference.
+	 */
+	protected String convertToString(P o) {
+		return this.objectTransformer.transform(o);
+	}
+
+	/**
+	 * Convert the specified preference value string to an
+	 * appropriately-typed object to be returned to the client.
+	 */
+	protected P convertToObject(String s) {
+		return this.stringTransformer.transform(s);
+	}
+
+	protected void preferenceChanged(String prefKey, @SuppressWarnings("unused") String newValue) {
+		if (prefKey.equals(this.key)) {
+			this.preferenceChanged();
+		}
+	}
+
+	/**
+	 * The underlying preference changed; either because we changed it
+	 * in #setValue_(Object) or a third-party changed it.
+	 * If this is called because of our own change, the event will be
+	 * swallowed because the old and new values are the same.
+	 */
+	protected synchronized void preferenceChanged() {
+		Object old = this.value;
+		this.value = this.buildValue();
+		this.fireAspectChanged(old, this.value);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/prefs/PreferencesCollectionValueModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/prefs/PreferencesCollectionValueModel.java
new file mode 100644
index 0000000..d374941
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/prefs/PreferencesCollectionValueModel.java
@@ -0,0 +1,236 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.prefs;
+
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.PreferenceChangeEvent;
+import java.util.prefs.PreferenceChangeListener;
+import java.util.prefs.Preferences;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterable.ArrayIterable;
+import org.eclipse.persistence.tools.utility.iterable.TransformationIterable;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+import org.eclipse.persistence.tools.utility.model.value.AspectAdapter;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.StaticPropertyValueModel;
+import org.eclipse.persistence.tools.utility.transformer.TransformerAdapter;
+
+/**
+ * This adapter wraps a Preferences node and converts its preferences into a
+ * CollectionValueModel of PreferencePropertyValueModels. It listens for
+ * "preference" changes and converts them into VALUE collection changes.
+ */
+public class PreferencesCollectionValueModel<P>
+	extends AspectAdapter<Preferences, Object>
+	implements CollectionValueModel<PreferencePropertyValueModel<P>>
+{
+	/** Cache the current preferences, stored in models and keyed by name. */
+	protected final HashMap<String, PreferencePropertyValueModel<P>> preferenceModels = new HashMap<String, PreferencePropertyValueModel<P>>();
+
+	/** A listener that listens to the preferences node for added or removed preferences. */
+	protected final PreferenceChangeListener preferenceChangeListener;
+
+	/** Adapter to convert a preferences node into a property value model. */
+	protected final Adapter<P> adapter;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an adapter for the specified preferences node.
+	 */
+	public PreferencesCollectionValueModel(Preferences preferences, Adapter<P> adapter) {
+		this(new StaticPropertyValueModel<Preferences>(preferences), adapter);
+	}
+
+	/**
+	 * Construct an adapter for the specified preferences node.
+	 */
+	public PreferencesCollectionValueModel(PropertyValueModel<? extends Preferences> preferencesModel, Adapter<P> adapter) {
+		super(preferencesModel);
+		if (adapter == null) {
+			throw new NullPointerException();
+		}
+		this.preferenceChangeListener = this.buildPreferenceChangeListener();
+		this.adapter = adapter;
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * A preferences have changed, notify the listeners.
+	 */
+	protected PreferenceChangeListener buildPreferenceChangeListener() {
+		return new LocalPreferenceChangeListener();
+	}
+
+	protected class LocalPreferenceChangeListener
+		implements PreferenceChangeListener
+	{
+		/**
+		 * Transform the preference change events into <code>VALUE</code>
+		 * collection change events.
+		 */
+		@Override
+		public void preferenceChange(PreferenceChangeEvent event) {
+			PreferencesCollectionValueModel.this.preferenceChanged(event.getKey(), event.getNewValue());
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.toString(this);
+		}
+	}
+
+
+	// ********** CollectionValueModel implementation **********
+
+	/**
+	 * Return an iterator on the preference models.
+	 */
+	@Override
+	public synchronized Iterator<PreferencePropertyValueModel<P>> iterator() {
+		return this.preferenceModels.values().iterator();
+	}
+
+	@Override
+	public synchronized int size() {
+		return this.preferenceModels.size();
+	}
+
+
+	// ********** AspectAdapter implementation **********
+
+	@Override
+	protected Object getAspectValue() {
+		return this.iterator();
+	}
+
+	@Override
+	protected Class<? extends EventListener> getListenerClass() {
+		return CollectionChangeListener.class;
+	}
+
+	@Override
+	protected String getListenerAspectName() {
+		return VALUES;
+	}
+
+    @Override
+	protected boolean hasListeners() {
+		return this.hasAnyCollectionChangeListeners(VALUES);
+	}
+
+	@Override
+	protected void fireAspectChanged(Object oldValue, Object newValue) {
+    	@SuppressWarnings("unchecked") Iterator<PreferencePropertyValueModel<P>> iterator = (Iterator<PreferencePropertyValueModel<P>>) newValue;
+		this.fireCollectionChanged(VALUES, CollectionTools.collection(iterator));
+	}
+
+    @Override
+	protected void engageSubject_() {
+		this.subject.addPreferenceChangeListener(this.preferenceChangeListener);
+		for (PreferencePropertyValueModel<P> preferenceModel : this.getPreferenceModels()) {
+			this.preferenceModels.put(preferenceModel.getKey(), preferenceModel);
+		}
+	}
+
+    @Override
+	protected void disengageSubject_() {
+		try {
+			this.subject.removePreferenceChangeListener(this.preferenceChangeListener);
+		} catch (IllegalStateException ex) {
+			// for some odd reason, we are not allowed to remove a listener from a "dead"
+			// preferences node; so handle the exception that gets thrown here
+			if ( ! ex.getMessage().equals("Node has been removed.")) { //$NON-NLS-1$
+				// if it is not the expected exception, re-throw it
+				throw ex;
+			}
+		}
+		this.preferenceModels.clear();
+	}
+
+
+	// ********** AbstractModel implementation **********
+
+	@Override
+	public void toString(StringBuilder sb) {
+		sb.append(this.subject);
+	}
+
+
+	// ********** internal methods **********
+
+	/**
+	 * Return the preference models.
+	 * At this point we can be sure that the subject is not <code>null</code>.
+	 */
+	protected Iterable<PreferencePropertyValueModel<P>> getPreferenceModels() {
+		return new TransformationIterable<String, PreferencePropertyValueModel<P>>(this.getPreferenceKeys(), new PreferenceKeyTransformer());
+	}
+
+	protected Iterable<String> getPreferenceKeys() {
+		return new ArrayIterable<String>(this.getPreferenceKeys_());
+	}
+
+	protected String[] getPreferenceKeys_() {
+		try {
+			return this.subject.keys();
+		} catch (BackingStoreException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+	protected class PreferenceKeyTransformer
+		extends TransformerAdapter<String, PreferencePropertyValueModel<P>>
+	{
+		@Override
+		public PreferencePropertyValueModel<P> transform(String key) {
+			return PreferencesCollectionValueModel.this.buildPreferenceModel(key);
+		}
+	}
+
+	/**
+	 * Override this method to tweak the model used to wrap the
+	 * specified preference (e.g. to customize the model's converter).
+	 */
+	protected PreferencePropertyValueModel<P> buildPreferenceModel(String key) {
+		return this.adapter.buildPreferenceModel(this.subjectModel, key);
+//		return new PreferencePropertyValueModel<P>(this.subjectModel, key, null, Transformer.Null.<P>instance());
+	}
+
+	protected synchronized void preferenceChanged(String key, String newValue) {
+		if (newValue == null) {
+			// a preference was removed
+			PreferencePropertyValueModel<P> preferenceModel = this.preferenceModels.remove(key);
+			this.fireItemRemoved(VALUES, preferenceModel);
+		} else if ( ! this.preferenceModels.containsKey(key)) {
+			// a preference was added
+			PreferencePropertyValueModel<P> preferenceModel = this.buildPreferenceModel(key);
+			this.preferenceModels.put(key, preferenceModel);
+			this.fireItemAdded(VALUES, preferenceModel);
+		} else {
+			// a preference's value changed - do nothing
+		}
+	}
+
+	public interface Adapter<P> {
+		PreferencePropertyValueModel<P> buildPreferenceModel(PropertyValueModel<? extends Preferences> preferencesModel, String key);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/AbstractTreeModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/AbstractTreeModel.java
new file mode 100644
index 0000000..c288417
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/AbstractTreeModel.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import java.io.Serializable;
+import javax.swing.event.EventListenerList;
+import javax.swing.event.TreeModelEvent;
+import javax.swing.event.TreeModelListener;
+import javax.swing.tree.TreeModel;
+
+/**
+ * Abstract class that should have been provided by the JDK
+ * (a la {@link javax.swing.AbstractListModel}). This class provides:<ul>
+ * <li>support for a collection of listeners
+ * <li>a number of convenience methods for firing events for those listeners
+ * </ul>
+ */
+public abstract class AbstractTreeModel
+	implements TreeModel, Serializable
+{
+	/** Our listeners. */
+	protected final EventListenerList listenerList;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors/initialization **********
+
+	protected AbstractTreeModel() {
+		super();
+		this.listenerList = new EventListenerList();
+	}
+
+
+	// ********** partial TreeModel implementation **********
+
+	@Override
+	public void addTreeModelListener(TreeModelListener l) {
+		this.listenerList.add(TreeModelListener.class, l);
+	}
+
+	@Override
+	public void removeTreeModelListener(TreeModelListener l) {
+		this.listenerList.remove(TreeModelListener.class, l);
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * Return the model's current collection of listeners.
+	 * (There seems to be a pattern of making this type of method public;
+	 * although it should probably be protected....)
+	 */
+	public TreeModelListener[] treeModelListeners() {
+ 		return this.listenerList.getListeners(TreeModelListener.class);
+	}
+
+	/**
+	 * Return whether this model has no listeners.
+	 */
+	protected boolean hasNoTreeModelListeners() {
+		return this.listenerList.getListenerCount(TreeModelListener.class) == 0;
+	}
+
+	/**
+	 * Return whether this model has any listeners.
+	 */
+	protected boolean hasTreeModelListeners() {
+		return ! this.hasNoTreeModelListeners();
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Notify listeners of a model change.
+	 * A significant property of the nodes changed, but the nodes themselves
+	 * are still the same objects.
+	 * @see javax.swing.event.TreeModelEvent
+	 * @see javax.swing.event.TreeModelListener
+	 */
+	protected void fireTreeNodesChanged(Object[] path, int[] childIndices, Object[] children) {
+		// guaranteed to return a non-null array
+		Object[] listeners = this.listenerList.getListenerList();
+		TreeModelEvent event = null;
+		// process the listeners last to first, notifying
+		// those that are interested in this event
+		for (int i = listeners.length-2; i>=0; i-=2) {
+			if (listeners[i]==TreeModelListener.class) {
+				// lazily create the event
+				if (event == null) {
+					event = new TreeModelEvent(this, path, childIndices, children);
+				}
+				((TreeModelListener) listeners[i+1]).treeNodesChanged(event);
+			}
+		}
+	}
+
+
+	/**
+	 * Notify listeners of a model change.
+	 * A significant property of the node changed, but the node itself is the same object.
+	 * @see javax.swing.event.TreeModelEvent
+	 * @see javax.swing.event.TreeModelListener
+	 */
+	protected void fireTreeNodeChanged(Object[] path, int childIndex, Object child) {
+		this.fireTreeNodesChanged(path, new int[] {childIndex}, new Object[] {child});
+	}
+
+	/**
+	 * Notify listeners of a model change.
+	 * A significant property of the root changed, but the root itself is the same object.
+	 * @see javax.swing.event.TreeModelEvent
+	 * @see javax.swing.event.TreeModelListener
+	 */
+	protected void fireTreeRootChanged(Object root) {
+		this.fireTreeNodesChanged(new Object[] {root}, null, null);
+	}
+
+	/**
+	 * Notify listeners of a model change.
+	 * @see javax.swing.event.TreeModelEvent
+	 * @see javax.swing.event.TreeModelListener
+	 */
+	protected void fireTreeNodesInserted(Object[] path, int[] childIndices, Object[] children) {
+		// guaranteed to return a non-null array
+		Object[] listeners = this.listenerList.getListenerList();
+		TreeModelEvent event = null;
+		// process the listeners last to first, notifying
+		// those that are interested in this event
+		for (int i = listeners.length-2; i>=0; i-=2) {
+			if (listeners[i]==TreeModelListener.class) {
+				// lazily create the event
+				if (event == null) {
+					event = new TreeModelEvent(this, path, childIndices, children);
+				}
+				((TreeModelListener) listeners[i+1]).treeNodesInserted(event);
+			}
+		}
+	}
+
+	/**
+	 * Notify listeners of a model change.
+	 * @see javax.swing.event.TreeModelEvent
+	 * @see javax.swing.event.TreeModelListener
+	 */
+	protected void fireTreeNodeInserted(Object[] path, int childIndex, Object child) {
+		this.fireTreeNodesInserted(path, new int[] {childIndex}, new Object[] {child});
+	}
+
+	/**
+	 * Notify listeners of a model change.
+	 * @see javax.swing.event.TreeModelEvent
+	 * @see javax.swing.event.TreeModelListener
+	 */
+	protected void fireTreeNodesRemoved(Object[] path, int[] childIndices, Object[] children) {
+		// guaranteed to return a non-null array
+		Object[] listeners = this.listenerList.getListenerList();
+		TreeModelEvent event = null;
+		// process the listeners last to first, notifying
+		// those that are interested in this event
+		for (int i = listeners.length-2; i>=0; i-=2) {
+			if (listeners[i]==TreeModelListener.class) {
+				// lazily create the event
+				if (event == null) {
+					event = new TreeModelEvent(this, path, childIndices, children);
+				}
+				((TreeModelListener) listeners[i+1]).treeNodesRemoved(event);
+			}
+		}
+	}
+
+	/**
+	 * Notify listeners of a model change.
+	 * @see javax.swing.event.TreeModelEvent
+	 * @see javax.swing.event.TreeModelListener
+	 */
+	protected void fireTreeNodeRemoved(Object[] path, int childIndex, Object child) {
+		this.fireTreeNodesRemoved(path, new int[] {childIndex}, new Object[] {child});
+	}
+
+	/**
+	 * Notify listeners of a model change.
+	 * @see javax.swing.event.TreeModelEvent
+	 * @see javax.swing.event.TreeModelListener
+	 */
+	protected void fireTreeStructureChanged(Object[] path) {
+		// guaranteed to return a non-null array
+		Object[] listeners = this.listenerList.getListenerList();
+		TreeModelEvent event = null;
+		// process the listeners last to first, notifying
+		// those that are interested in this event
+		for (int i = listeners.length-2; i>=0; i-=2) {
+			if (listeners[i]==TreeModelListener.class) {
+				// lazily create the event
+				if (event == null) {
+					event = new TreeModelEvent(this, path);
+				}
+				((TreeModelListener) listeners[i+1]).treeStructureChanged(event);
+			}
+		}
+	}
+
+	/**
+	 * Notify listeners of a model change.
+	 * @see javax.swing.event.TreeModelEvent
+	 * @see javax.swing.event.TreeModelListener
+	 */
+	protected void fireTreeRootReplaced(Object newRoot) {
+		this.fireTreeStructureChanged(new Object[] {newRoot});
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/CheckBoxModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/CheckBoxModelAdapter.java
new file mode 100644
index 0000000..e39c77a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/CheckBoxModelAdapter.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+
+/**
+ * This javax.swing.ButtonModel can be used to keep a listener
+ * (e.g. a JCheckBox) in synch with a PropertyValueModel that
+ * holds a boolean.
+ *
+ * Maybe not the richest class in our toolbox, but it was the
+ * victim of refactoring....  ~bjv
+ */
+public class CheckBoxModelAdapter
+	extends ToggleButtonModelAdapter
+{
+	private static final long serialVersionUID = 1L;
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the boolean holder is required.
+	 */
+	public CheckBoxModelAdapter(ModifiablePropertyValueModel<Boolean> booleanHolder, boolean defaultValue) {
+		super(booleanHolder, defaultValue);
+	}
+
+	/**
+	 * Constructor - the boolean holder is required.
+	 * The default value will be false.
+	 */
+	public CheckBoxModelAdapter(ModifiablePropertyValueModel<Boolean> booleanHolder) {
+		super(booleanHolder);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ComboBoxModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ComboBoxModelAdapter.java
new file mode 100644
index 0000000..e8add59
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ComboBoxModelAdapter.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import javax.swing.ComboBoxModel;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.awt.AWTPropertyChangeListenerWrapper;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+
+/**
+ * This javax.swing.ComboBoxModel can be used to keep a ListDataListener
+ * (e.g. a JComboBox) in synch with a ListValueModel (or a CollectionValueModel).
+ * For combo boxes, the model object that holds the current selection is
+ * typically a different model object than the one that holds the collection
+ * of choices.
+ *
+ * For example, a MWReference (the selectionOwner) has an attribute
+ * "sourceTable" (the collectionOwner)
+ * which holds on to a collection of MWDatabaseFields. When the selection
+ * is changed this model will keep the listeners aware of the changes.
+ * The inherited list model will keep its listeners aware of changes to the
+ * collection model
+ *
+ * In addition to the collection holder required by the superclass,
+ * an instance of this ComboBoxModel must be supplied with a
+ * selection holder, which is a PropertyValueModel that provides access
+ * to the selection (typically a PropertyAspectAdapter).
+ */
+@SuppressWarnings("nls")
+public class ComboBoxModelAdapter
+	extends ListModelAdapter
+	implements ComboBoxModel
+{
+	protected final ModifiablePropertyValueModel<Object> selectionHolder;
+	protected final PropertyChangeListener selectionListener;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the list holder and selection holder are required;
+	 */
+	public ComboBoxModelAdapter(ListValueModel<?> listHolder, ModifiablePropertyValueModel<Object> selectionHolder) {
+		super(listHolder);
+		if (selectionHolder == null) {
+			throw new NullPointerException();
+		}
+		this.selectionHolder = selectionHolder;
+		this.selectionListener = this.buildSelectionListener();
+	}
+
+	/**
+	 * Constructor - the collection holder and selection holder are required;
+	 */
+	public ComboBoxModelAdapter(CollectionValueModel<?> collectionHolder, ModifiablePropertyValueModel<Object> selectionHolder) {
+		super(collectionHolder);
+		if (selectionHolder == null) {
+			throw new NullPointerException();
+		}
+		this.selectionHolder = selectionHolder;
+		this.selectionListener = this.buildSelectionListener();
+	}
+
+
+	// ********** initialization **********
+
+	protected PropertyChangeListener buildSelectionListener() {
+		return new AWTPropertyChangeListenerWrapper(this.buildSelectionListener_());
+	}
+
+	protected PropertyChangeListener buildSelectionListener_() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent event) {
+				// notify listeners that the selection has changed
+				ComboBoxModelAdapter.this.fireSelectionChanged();
+			}
+			@Override
+			public String toString() {
+				return "selection listener";
+			}
+		};
+	}
+
+
+	// ********** ComboBoxModel implementation **********
+
+	@Override
+	public Object getSelectedItem() {
+		return this.selectionHolder.getValue();
+	}
+
+	@Override
+	public void setSelectedItem(Object selectedItem) {
+		this.selectionHolder.setValue(selectedItem);
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Extend to engage the selection holder.
+	 */
+	@Override
+	protected void engageModel() {
+		super.engageModel();
+		this.selectionHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.selectionListener);
+	}
+
+	/**
+	 * Extend to disengage the selection holder.
+	 */
+	@Override
+	protected void disengageModel() {
+		this.selectionHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.selectionListener);
+		super.disengageModel();
+	}
+
+	/**
+	 * Notify the listeners that the selection has changed.
+	 */
+	protected void fireSelectionChanged() {
+		// I guess this will work...
+		this.fireContentsChanged(this, -1, -1);
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.selectionHolder + ":" + this.listHolder);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/DateSpinnerModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/DateSpinnerModelAdapter.java
new file mode 100644
index 0000000..bb8822f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/DateSpinnerModelAdapter.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import java.util.Calendar;
+import java.util.Date;
+import javax.swing.SpinnerDateModel;
+import javax.swing.event.ChangeListener;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.awt.AWTPropertyChangeListenerWrapper;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+
+/**
+ * This javax.swing.SpinnerDateModel can be used to keep a ChangeListener
+ * (e.g. a JSpinner) in synch with a PropertyValueModel that holds a date.
+ *
+ * This class must be a sub-class of SpinnerDateModel because of some
+ * crappy jdk code....  ~bjv
+ * @see javax.swing.JSpinner#createEditor(javax.swing.SpinnerModel)
+ *
+ * If this class needs to be modified, it would behoove us to review the
+ * other, similar classes:
+ * @see ListSpinnerModelAdapter
+ * @see NumberSpinnerModelAdapter
+ */
+@SuppressWarnings("nls")
+public class DateSpinnerModelAdapter
+	extends SpinnerDateModel
+{
+	/**
+	 * The default spinner value; used when the underlying model date value is null.
+	 * The default is the current date.
+	 */
+	private final Date defaultValue;
+
+	/** A value model on the underlying date. */
+	private final ModifiablePropertyValueModel<Object> dateHolder;
+
+	/** A listener that allows us to synchronize with changes made to the underlying date. */
+	private final PropertyChangeListener dateChangeListener;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the date holder is required.
+	 * The default spinner value is the current date.
+	 */
+	public DateSpinnerModelAdapter(ModifiablePropertyValueModel<Object> dateHolder) {
+		this(dateHolder, new Date());
+	}
+
+	/**
+	 * Constructor - the date holder and default value are required.
+	 */
+	public DateSpinnerModelAdapter(ModifiablePropertyValueModel<Object> dateHolder, Date defaultValue) {
+		this(dateHolder, null, null, Calendar.DAY_OF_MONTH, defaultValue);
+	}
+
+	/**
+	 * Constructor - the date holder is required.
+	 * The default spinner value is the current date.
+	 */
+	public DateSpinnerModelAdapter(ModifiablePropertyValueModel<Object> dateHolder, Comparable<?> start, Comparable<?> end, int calendarField) {
+		this(dateHolder, start, end, calendarField, new Date());
+	}
+
+	/**
+	 * Constructor - the date holder is required.
+	 */
+	public DateSpinnerModelAdapter(ModifiablePropertyValueModel<Object> dateHolder, Comparable<?> start, Comparable<?> end, int calendarField, Date defaultValue) {
+		super(dateHolder.getValue() == null ? defaultValue : (Date) dateHolder.getValue(), start, end, calendarField);
+		this.dateHolder = dateHolder;
+		this.dateChangeListener = this.buildDateChangeListener();
+		// postpone listening to the underlying date
+		// until we have listeners ourselves...
+		this.defaultValue = defaultValue;
+	}
+
+
+	// ********** initialization **********
+
+	protected PropertyChangeListener buildDateChangeListener() {
+		return new AWTPropertyChangeListenerWrapper(this.buildDateChangeListener_());
+	}
+
+	protected PropertyChangeListener buildDateChangeListener_() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent event) {
+				DateSpinnerModelAdapter.this.synchronize(event.getNewValue());
+			}
+			@Override
+			public String toString() {
+				return "date listener";
+			}
+		};
+	}
+
+
+	// ********** SpinnerModel implementation **********
+
+	/**
+	 * Extend to check whether this method is being called before we
+	 * have any listeners.
+	 * This is necessary because some crappy jdk code gets the value
+	 * from the model *before* listening to the model.  ~bjv
+	 * @see javax.swing.JSpinner.DefaultEditor#DefaultEditor(javax.swing.JSpinner)
+	 */
+    @Override
+	public Object getValue() {
+		if (this.getChangeListeners().length == 0) {
+			// sorry about this "lateral" call to super  ~bjv
+			super.setValue(this.spinnerValueOf(this.dateHolder.getValue()));
+		}
+		return super.getValue();
+	}
+
+	/**
+	 * Extend to update the underlying date directly.
+	 * The resulting event will be ignored: @see #synchronize(Object).
+	 */
+	@Override
+	public void setValue(Object value) {
+		super.setValue(value);
+		this.dateHolder.setValue(value);
+	}
+
+	/**
+	 * Extend to start listening to the underlying date if necessary.
+	 */
+	@Override
+	public void addChangeListener(ChangeListener listener) {
+		if (this.getChangeListeners().length == 0) {
+			this.dateHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.dateChangeListener);
+			this.synchronize(this.dateHolder.getValue());
+		}
+		super.addChangeListener(listener);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying date if appropriate.
+	 */
+    @Override
+	public void removeChangeListener(ChangeListener listener) {
+		super.removeChangeListener(listener);
+		if (this.getChangeListeners().length == 0) {
+			this.dateHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.dateChangeListener);
+		}
+	}
+
+
+	// ********** queries **********
+
+	protected Date getDefaultValue() {
+		return this.defaultValue;
+	}
+
+	/**
+	 * Convert to a non-null value.
+	 */
+	protected Object spinnerValueOf(Object value) {
+		return (value == null) ? this.getDefaultValue() : value;
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Set the spinner value if it has changed.
+	 */
+	void synchronize(Object value) {
+		Object newValue = this.spinnerValueOf(value);
+		// check to see whether the spinner date has already been synchronized
+		// (via #setValue())
+		if ( ! this.getValue().equals(newValue)) {
+			this.setValue(newValue);
+		}
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.dateHolder);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/DocumentAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/DocumentAdapter.java
new file mode 100644
index 0000000..63c60d4
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/DocumentAdapter.java
@@ -0,0 +1,405 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.util.EventObject;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.event.EventListenerList;
+import javax.swing.event.UndoableEditEvent;
+import javax.swing.event.UndoableEditListener;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.Element;
+import javax.swing.text.PlainDocument;
+import javax.swing.text.Position;
+import javax.swing.text.Segment;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.awt.AWTPropertyChangeListenerWrapper;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+
+/**
+ * This javax.swing.text.Document can be used to keep a DocumentListener
+ * (e.g. a JTextField) in synch with a PropertyValueModel that holds a string.
+ *
+ * NB: This model should only be used for "small" documents;
+ * i.e. documents used by text fields, not text panes.
+ * @see #synchronizeDelegate(String)
+ */
+@SuppressWarnings("nls")
+public class DocumentAdapter
+	implements Document, Serializable
+{
+	/** The delegate document whose behavior we "enhance". */
+	protected final Document delegate;
+
+	/** A listener that allows us to forward any changes made to the delegate document. */
+	protected final CombinedListener delegateListener;
+
+	/** A value model on the underlying model string. */
+	protected final ModifiablePropertyValueModel<String> stringHolder;
+
+	/** A listener that allows us to synchronize with changes made to the underlying model string. */
+	protected transient PropertyChangeListener stringListener;
+
+    /** The event listener list for the document. */
+    protected final EventListenerList listenerList = new EventListenerList();
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the string holder is required.
+	 * Wrap the specified document.
+	 */
+	public DocumentAdapter(ModifiablePropertyValueModel<String> stringHolder, Document delegate) {
+		super();
+		if (stringHolder == null || delegate == null) {
+			throw new NullPointerException();
+		}
+		this.stringHolder = stringHolder;
+		// postpone listening to the underlying model string
+		// until we have listeners ourselves...
+		this.delegate = delegate;
+		this.stringListener = this.buildStringListener();
+		this.delegateListener = this.buildDelegateListener();
+	}
+
+	/**
+	 * Constructor - the string holder is required.
+	 * Wrap a plain document.
+	 */
+	public DocumentAdapter(ModifiablePropertyValueModel<String> stringHolder) {
+		this(stringHolder, new PlainDocument());
+	}
+
+
+	// ********** initialization **********
+
+	protected PropertyChangeListener buildStringListener() {
+		return new AWTPropertyChangeListenerWrapper(this.buildStringListener_());
+	}
+
+	protected PropertyChangeListener buildStringListener_() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent event) {
+				DocumentAdapter.this.stringChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "string listener";
+			}
+		};
+	}
+
+	protected CombinedListener buildDelegateListener() {
+		return new InternalListener();
+	}
+
+
+	// ********** Document implementation **********
+
+	@Override
+	public int getLength() {
+		return this.delegate.getLength();
+	}
+
+	/**
+	 * Extend to start listening to the underlying models if necessary.
+	 */
+	@Override
+	public void addDocumentListener(DocumentListener listener) {
+		if (this.listenerList.getListenerCount(DocumentListener.class) == 0) {
+			this.delegate.addDocumentListener(this.delegateListener);
+			this.engageStringHolder();
+		}
+		this.listenerList.add(DocumentListener.class, listener);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying models if appropriate.
+	 */
+	@Override
+	public void removeDocumentListener(DocumentListener listener) {
+		this.listenerList.remove(DocumentListener.class, listener);
+		if (this.listenerList.getListenerCount(DocumentListener.class) == 0) {
+			this.disengageStringHolder();
+			this.delegate.removeDocumentListener(this.delegateListener);
+		}
+	}
+
+	/**
+	 * Extend to start listening to the delegate document if necessary.
+	 */
+	@Override
+	public void addUndoableEditListener(UndoableEditListener listener) {
+		if (this.listenerList.getListenerCount(UndoableEditListener.class) == 0) {
+			this.delegate.addUndoableEditListener(this.delegateListener);
+		}
+		this.listenerList.add(UndoableEditListener.class, listener);
+	}
+
+	/**
+	 * Extend to stop listening to the delegate document if appropriate.
+	 */
+	@Override
+	public void removeUndoableEditListener(UndoableEditListener listener) {
+		this.listenerList.remove(UndoableEditListener.class, listener);
+		if (this.listenerList.getListenerCount(UndoableEditListener.class) == 0) {
+			this.delegate.removeUndoableEditListener(this.delegateListener);
+		}
+	}
+
+	@Override
+	public Object getProperty(Object key) {
+		return this.delegate.getProperty(key);
+	}
+
+	@Override
+	public void putProperty(Object key, Object value) {
+		this.delegate.putProperty(key, value);
+	}
+
+	/**
+	 * Extend to update the underlying model string directly.
+	 * The resulting event will be ignored: @see #synchronizeDelegate(String).
+	 */
+	@Override
+	public void remove(int offset, int len) throws BadLocationException {
+		this.delegate.remove(offset, len);
+		this.stringHolder.setValue(this.delegate.getText(0, this.delegate.getLength()));
+	}
+
+	/**
+	 * Extend to update the underlying model string directly.
+	 * The resulting event will be ignored: @see #synchronizeDelegate(String).
+	 */
+	@Override
+	public void insertString(int offset, String insertedString, AttributeSet a) throws BadLocationException {
+		this.delegate.insertString(offset, insertedString, a);
+		this.stringHolder.setValue(this.delegate.getText(0, this.delegate.getLength()));
+	}
+
+	@Override
+	public String getText(int offset, int length) throws BadLocationException {
+		return this.delegate.getText(offset, length);
+	}
+
+	@Override
+	public void getText(int offset, int length, Segment txt) throws BadLocationException {
+		this.delegate.getText(offset, length, txt);
+	}
+
+	@Override
+	public Position getStartPosition() {
+		return this.delegate.getStartPosition();
+	}
+
+	@Override
+	public Position getEndPosition() {
+		return this.delegate.getEndPosition();
+	}
+
+	@Override
+	public Position createPosition(int offs) throws BadLocationException {
+		return this.delegate.createPosition(offs);
+	}
+
+	@Override
+	public Element[] getRootElements() {
+		return this.delegate.getRootElements();
+	}
+
+	@Override
+	public Element getDefaultRootElement() {
+		return this.delegate.getDefaultRootElement();
+	}
+
+	@Override
+	public void render(Runnable r) {
+		this.delegate.render(r);
+	}
+
+
+	// ********** queries **********
+
+	public DocumentListener[] documentListeners() {
+		return this.listenerList.getListeners(DocumentListener.class);
+	}
+
+	public UndoableEditListener[] undoableEditListeners() {
+		return this.listenerList.getListeners(UndoableEditListener.class);
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * A third party has modified the underlying model string.
+	 * Synchronize the delegate document accordingly.
+	 */
+	protected void stringChanged(PropertyChangeEvent event) {
+		this.synchronizeDelegate((String) event.getNewValue());
+	}
+
+	/**
+	 * Replace the document's entire text string with the new string.
+	 */
+	protected void synchronizeDelegate(String s) {
+		try {
+			int len = this.delegate.getLength();
+			// check to see whether the delegate has already been synchronized
+			// (via #insertString() or #remove())
+			if ( ! this.delegate.getText(0, len).equals(s)) {
+				this.delegate.remove(0, len);
+				this.delegate.insertString(0, s, null);
+			}
+		} catch (BadLocationException ex) {
+			throw new IllegalStateException(ex.getMessage());	// this should not happen...
+		}
+	}
+
+	protected void engageStringHolder() {
+		this.stringHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.stringListener);
+		this.synchronizeDelegate(this.stringHolder.getValue());
+	}
+
+	protected void disengageStringHolder() {
+		this.stringHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.stringListener);
+	}
+
+	protected void delegateChangedUpdate(DocumentEvent event) {
+		// no need to lazy-initialize the event;
+		// we wouldn't get here if we did not have listeners...
+		DocumentEvent ee = new InternalDocumentEvent(this, event);
+		DocumentListener[] listeners = this.documentListeners();
+		for (int i = listeners.length; i-- > 0; ) {
+			listeners[i].changedUpdate(ee);
+		}
+	}
+
+	protected void delegateInsertUpdate(DocumentEvent event) {
+		// no need to lazy-initialize the event;
+		// we wouldn't get here if we did not have listeners...
+		DocumentEvent ee = new InternalDocumentEvent(this, event);
+		DocumentListener[] listeners = this.documentListeners();
+		for (int i = listeners.length; i-- > 0; ) {
+			listeners[i].insertUpdate(ee);
+		}
+	}
+
+	protected void delegateRemoveUpdate(DocumentEvent event) {
+		// no need to lazy-initialize the event;
+		// we wouldn't get here if we did not have listeners...
+		DocumentEvent ee = new InternalDocumentEvent(this, event);
+		DocumentListener[] listeners = this.documentListeners();
+		for (int i = listeners.length; i-- > 0; ) {
+			listeners[i].removeUpdate(ee);
+		}
+	}
+
+	protected void delegateUndoableEditHappened(UndoableEditEvent event) {
+		// no need to lazy-initialize the event;
+		// we wouldn't get here if we did not have listeners...
+		UndoableEditEvent ee = new UndoableEditEvent(this, event.getEdit());
+		UndoableEditListener[] listeners = this.undoableEditListeners();
+		for (int i = listeners.length; i-- > 0; ) {
+			listeners[i].undoableEditHappened(ee);
+		}
+	}
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.stringHolder);
+	}
+
+	private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
+		// read in any hidden stuff
+		s.defaultReadObject();
+		this.stringListener = this.buildStringListener();
+	}
+
+
+// ********** inner class **********
+
+	protected interface CombinedListener extends DocumentListener, UndoableEditListener, Serializable {
+		// just consolidate the two interfaces
+	}
+
+	protected class InternalListener implements CombinedListener {
+		private static final long serialVersionUID = 1L;
+		@Override
+		public void changedUpdate(DocumentEvent event) {
+			DocumentAdapter.this.delegateChangedUpdate(event);
+		}
+		@Override
+		public void insertUpdate(DocumentEvent event) {
+			DocumentAdapter.this.delegateInsertUpdate(event);
+		}
+		@Override
+		public void removeUpdate(DocumentEvent event) {
+			DocumentAdapter.this.delegateRemoveUpdate(event);
+		}
+		@Override
+		public void undoableEditHappened(UndoableEditEvent event) {
+			DocumentAdapter.this.delegateUndoableEditHappened(event);
+		}
+	}
+
+	protected static class InternalDocumentEvent
+		extends EventObject
+		implements DocumentEvent
+	{
+		protected DocumentEvent delegate;
+
+		private static final long serialVersionUID = 1L;
+
+		protected InternalDocumentEvent(Document document, DocumentEvent delegate) {
+			super(document);
+			this.delegate = delegate;
+		}
+		@Override
+		public ElementChange getChange(Element elem) {
+			return this.delegate.getChange(elem);
+		}
+		@Override
+		public Document getDocument() {
+			return (Document) this.source;
+		}
+		@Override
+		public int getLength() {
+			return this.delegate.getLength();
+		}
+		@Override
+		public int getOffset() {
+			return this.delegate.getOffset();
+		}
+		@Override
+		public EventType getType() {
+			return this.delegate.getType();
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ListModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ListModelAdapter.java
new file mode 100644
index 0000000..b1089b1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ListModelAdapter.java
@@ -0,0 +1,305 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import javax.swing.AbstractListModel;
+import javax.swing.event.ListDataListener;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.awt.AWTListChangeListenerWrapper;
+import org.eclipse.persistence.tools.utility.model.value.CollectionListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+
+/**
+ * This javax.swing.ListModel can be used to keep a ListDataListener
+ * (e.g. a JList) in synch with a ListValueModel (or a CollectionValueModel).
+ *
+ * An instance of this ListModel *must* be supplied with a value model,
+ * which is a ListValueModel on the bound list or a CollectionValueModel
+ * on the bound collection. This is required - the list (or collection)
+ * itself can be null, but the value model that holds it cannot.
+ */
+@SuppressWarnings("nls")
+public class ListModelAdapter
+	extends AbstractListModel
+{
+	/** A value model on the underlying model list. */
+	protected ListValueModel<?> listHolder;
+
+	/**
+	 * Cache the size of the list for "dramatic" changes.
+	 * @see #listChanged()
+	 */
+	protected int listSize;
+
+	/** A listener that allows us to forward changes made to the underlying model list. */
+	protected final ListChangeListener listChangeListener;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Default constructor - initialize stuff.
+	 */
+	private ListModelAdapter() {
+		super();
+		this.listSize = 0;
+		this.listChangeListener = this.buildListChangeListener();
+	}
+
+	/**
+	 * Constructor - the list holder is required.
+	 */
+	public ListModelAdapter(ListValueModel<?> listHolder) {
+		this();
+		this.setModel(listHolder);
+	}
+
+	/**
+	 * Constructor - the collection holder is required.
+	 */
+	public ListModelAdapter(CollectionValueModel<?> collectionHolder) {
+		this();
+		this.setModel(collectionHolder);
+	}
+
+
+	// ********** initialization **********
+
+	protected ListChangeListener buildListChangeListener() {
+		return new AWTListChangeListenerWrapper(this.buildListChangeListener_());
+	}
+
+	protected ListChangeListener buildListChangeListener_() {
+		return new ListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) {
+				ListModelAdapter.this.itemsAdded(event);
+			}
+			@Override
+			public void itemsRemoved(ListRemoveEvent event) {
+				ListModelAdapter.this.itemsRemoved(event);
+			}
+			@Override
+			public void itemsReplaced(ListReplaceEvent event) {
+				ListModelAdapter.this.itemsReplaced(event);
+			}
+			@Override
+			public void itemsMoved(ListMoveEvent event) {
+				ListModelAdapter.this.itemsMoved(event);
+			}
+			@Override
+			public void listCleared(ListClearEvent event) {
+				ListModelAdapter.this.listCleared();
+			}
+			@Override
+			public void listChanged(ListChangeEvent event) {
+				ListModelAdapter.this.listChanged();
+			}
+			@Override
+			public String toString() {
+				return "list listener";
+			}
+		};
+	}
+
+
+	// ********** ListModel implementation **********
+
+	@Override
+	public int getSize() {
+		return this.listHolder.size();
+	}
+
+	@Override
+	public Object getElementAt(int index) {
+		return this.listHolder.get(index);
+	}
+
+	/**
+	 * Extend to start listening to the underlying model list if necessary.
+	 */
+    @Override
+	public void addListDataListener(ListDataListener l) {
+		if (this.hasNoListDataListeners()) {
+			this.engageModel();
+			this.listSize = this.listHolder.size();
+		}
+		super.addListDataListener(l);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying model list if appropriate.
+	 */
+    @Override
+	public void removeListDataListener(ListDataListener l) {
+		super.removeListDataListener(l);
+		if (this.hasNoListDataListeners()) {
+			this.disengageModel();
+			this.listSize = 0;
+		}
+	}
+
+
+	// ********** public API **********
+
+	/**
+	 * Return the underlying list model.
+	 */
+	public ListValueModel<?> model() {
+		return this.listHolder;
+	}
+
+	/**
+	 * Set the underlying list model.
+	 */
+	public void setModel(ListValueModel<?> listHolder) {
+		if (listHolder == null) {
+			throw new NullPointerException();
+		}
+		boolean hasListeners = this.hasListDataListeners();
+		if (hasListeners) {
+			this.disengageModel();
+		}
+		this.listHolder = listHolder;
+		if (hasListeners) {
+			this.engageModel();
+			this.listChanged();
+		}
+	}
+
+	/**
+	 * Set the underlying collection model.
+	 */
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public void setModel(CollectionValueModel<?> collectionHolder) {
+		this.setModel(new CollectionListValueModelAdapter(collectionHolder));
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * Return whether this model has no listeners.
+	 */
+	protected boolean hasNoListDataListeners() {
+		return this.getListDataListeners().length == 0;
+	}
+
+	/**
+	 * Return whether this model has any listeners.
+	 */
+	protected boolean hasListDataListeners() {
+		return ! this.hasNoListDataListeners();
+	}
+
+
+	// ********** behavior **********
+
+	protected void engageModel() {
+		this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+	}
+
+	protected void disengageModel() {
+		this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+	}
+
+
+
+	// ********** list change support **********
+
+	/**
+	 * Items were added to the underlying model list.
+	 * Notify listeners of the changes.
+	 */
+	protected void itemsAdded(ListAddEvent event) {
+		int start = event.getIndex();
+		int end = start + event.getItemsSize() - 1;
+		this.fireIntervalAdded(this, start, end);
+		this.listSize += event.getItemsSize();
+	}
+
+	/**
+	 * Items were removed from the underlying model list.
+	 * Notify listeners of the changes.
+	 */
+	protected void itemsRemoved(ListRemoveEvent event) {
+		int start = event.getIndex();
+		int end = start + event.getItemsSize() - 1;
+		this.fireIntervalRemoved(this, start, end);
+		this.listSize -= event.getItemsSize();
+	}
+
+	/**
+	 * Items were replaced in the underlying model list.
+	 * Notify listeners of the changes.
+	 */
+	protected void itemsReplaced(ListReplaceEvent event) {
+		int start = event.getIndex();
+		int end = start + event.getItemsSize() - 1;
+		this.fireContentsChanged(this, start, end);
+	}
+
+	/**
+	 * Items were moved in the underlying model list.
+	 * Notify listeners of the changes.
+	 */
+	protected void itemsMoved(ListMoveEvent event) {
+		int start = Math.min(event.getSourceIndex(), event.getTargetIndex());
+		int end = Math.max(event.getSourceIndex(), event.getTargetIndex()) + event.getLength() - 1;
+		this.fireContentsChanged(this, start, end);
+	}
+
+	/**
+	 * The underlying model list was cleared.
+	 * Notify listeners of the changes.
+	 */
+	protected void listCleared() {
+		if (this.listSize != 0) {
+			this.fireIntervalRemoved(this, 0, this.listSize - 1);
+			this.listSize = 0;
+		}
+	}
+
+	/**
+	 * The underlying model list has changed "dramatically".
+	 * Notify listeners of the changes.
+	 */
+	protected void listChanged() {
+		if (this.listSize != 0) {
+			this.fireIntervalRemoved(this, 0, this.listSize - 1);
+		}
+		this.listSize = this.listHolder.size();
+		if (this.listSize != 0) {
+			this.fireIntervalAdded(this, 0, this.listSize - 1);
+		}
+	}
+
+
+	// ********** Object overrides **********
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.listHolder);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ListSpinnerModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ListSpinnerModelAdapter.java
new file mode 100644
index 0000000..37cc11e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ListSpinnerModelAdapter.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import java.util.Arrays;
+import java.util.List;
+import javax.swing.SpinnerListModel;
+import javax.swing.event.ChangeListener;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.awt.AWTPropertyChangeListenerWrapper;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+
+/**
+ * This javax.swing.SpinnerListModel can be used to keep a ChangeListener
+ * (e.g. a JSpinner) in synch with a PropertyValueModel that holds a value
+ * in the list.
+ *
+ * This class must be a sub-class of SpinnerListModel because of some
+ * crappy jdk code....  ~bjv
+ * @see javax.swing.JSpinner#createEditor(javax.swing.SpinnerModel)
+ *
+ * NB: This model should only be used for values that have a reasonably
+ * inexpensive #equals() implementation.
+ * @see #synchronize(Object)
+ *
+ * If this class needs to be modified, it would behoove us to review the
+ * other, similar classes:
+ * @see DateSpinnerModelAdapter
+ * @see NumberSpinnerModelAdapter
+ */
+@SuppressWarnings("nls")
+public class ListSpinnerModelAdapter
+	extends SpinnerListModel
+{
+	/**
+	 * The default spinner value; used when the underlying model value is null.
+	 * The default is the first item on the list.
+	 */
+	private final Object defaultValue;
+
+	/** A value model on the underlying value. */
+	private final ModifiablePropertyValueModel<Object> valueHolder;
+
+	/** A listener that allows us to synchronize with changes made to the underlying value. */
+	private final PropertyChangeListener valueChangeListener;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the value holder is required.
+	 * Use the model value itself as the default spinner value.
+	 */
+	public ListSpinnerModelAdapter(ModifiablePropertyValueModel<Object> valueHolder) {
+		this(valueHolder, valueHolder.getValue());
+	}
+
+	/**
+	 * Constructor - the value holder is required.
+	 */
+	public ListSpinnerModelAdapter(ModifiablePropertyValueModel<Object> valueHolder, Object defaultValue) {
+		this(valueHolder, new Object[] {defaultValue}, defaultValue);
+	}
+
+	/**
+	 * Constructor - the value holder is required.
+	 * Use the first item in the list of values as the default spinner value.
+	 */
+	public ListSpinnerModelAdapter(ModifiablePropertyValueModel<Object> valueHolder, Object[] values) {
+		this(valueHolder, values, values[0]);
+	}
+
+	/**
+	 * Constructor - the value holder is required.
+	 */
+	public ListSpinnerModelAdapter(ModifiablePropertyValueModel<Object> valueHolder, Object[] values, Object defaultValue) {
+		this(valueHolder, Arrays.asList(values), defaultValue);
+	}
+
+	/**
+	 * Constructor - the value holder is required.
+	 * Use the first item in the list of values as the default spinner value.
+	 */
+	public ListSpinnerModelAdapter(ModifiablePropertyValueModel<Object> valueHolder, List<Object> values) {
+		this(valueHolder, values, values.get(0));
+	}
+
+	/**
+	 * Constructor - the value holder is required.
+	 */
+	public ListSpinnerModelAdapter(ModifiablePropertyValueModel<Object> valueHolder, List<Object> values, Object defaultValue) {
+		super(values);
+		this.valueHolder = valueHolder;
+		this.valueChangeListener = this.buildValueChangeListener();
+		// postpone listening to the underlying value
+		// until we have listeners ourselves...
+		this.defaultValue = defaultValue;
+	}
+
+
+	// ********** initialization **********
+
+	protected PropertyChangeListener buildValueChangeListener() {
+		return new AWTPropertyChangeListenerWrapper(this.buildValueChangeListener_());
+	}
+
+	protected PropertyChangeListener buildValueChangeListener_() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent event) {
+				ListSpinnerModelAdapter.this.synchronize(event.getNewValue());
+			}
+			@Override
+			public String toString() {
+				return "value listener";
+			}
+		};
+	}
+
+
+	// ********** SpinnerModel implementation **********
+
+	/**
+	 * Extend to check whether this method is being called before we
+	 * have any listeners.
+	 * This is necessary because some crappy jdk code gets the value
+	 * from the model *before* listening to the model.  ~bjv
+	 * @see javax.swing.JSpinner.DefaultEditor#DefaultEditor(javax.swing.JSpinner)
+	 */
+    @Override
+	public Object getValue() {
+		if (this.getChangeListeners().length == 0) {
+			// sorry about this "lateral" call to super  ~bjv
+			super.setValue(this.spinnerValueOf(this.valueHolder.getValue()));
+		}
+		return super.getValue();
+	}
+
+	/**
+	 * Extend to update the underlying value directly.
+	 * The resulting event will be ignored: @see #synchronize(Object).
+	 */
+    @Override
+	public void setValue(Object value) {
+		super.setValue(value);
+		this.valueHolder.setValue(value);
+	}
+
+	/**
+	 * Extend to start listening to the underlying value if necessary.
+	 */
+    @Override
+	public void addChangeListener(ChangeListener listener) {
+		if (this.getChangeListeners().length == 0) {
+			this.valueHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.valueChangeListener);
+			this.synchronize(this.valueHolder.getValue());
+		}
+		super.addChangeListener(listener);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying value if appropriate.
+	 */
+    @Override
+	public void removeChangeListener(ChangeListener listener) {
+		super.removeChangeListener(listener);
+		if (this.getChangeListeners().length == 0) {
+			this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.valueChangeListener);
+		}
+	}
+
+
+	// ********** queries **********
+
+	protected Object getDefaultValue() {
+		return this.defaultValue;
+	}
+
+	/**
+	 * Convert to a non-null value.
+	 */
+	protected Object spinnerValueOf(Object value) {
+		return (value == null) ? this.getDefaultValue() : value;
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Set the spinner value if it has changed.
+	 */
+	void synchronize(Object value) {
+		Object newValue = this.spinnerValueOf(value);
+		// check to see whether the spinner value has already been synchronized
+		// (via #setValue())
+		if ( ! this.getValue().equals(newValue)) {
+			this.setValue(newValue);
+		}
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.valueHolder);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/NumberSpinnerModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/NumberSpinnerModelAdapter.java
new file mode 100644
index 0000000..366c2dc
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/NumberSpinnerModelAdapter.java
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import javax.swing.SpinnerNumberModel;
+import javax.swing.event.ChangeListener;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.awt.AWTPropertyChangeListenerWrapper;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+
+/**
+ * This javax.swing.SpinnerNumberModel can be used to keep a ChangeListener
+ * (e.g. a JSpinner) in synch with a PropertyValueModel that holds a number.
+ *
+ * This class must be a sub-class of SpinnerNumberModel because of some
+ * crappy jdk code....  ~bjv
+ * @see javax.swing.JSpinner#createEditor(javax.swing.SpinnerModel)
+ *
+ * If this class needs to be modified, it would behoove us to review the
+ * other, similar classes:
+ * @see DateSpinnerModelAdapter
+ * @see ListSpinnerModelAdapter
+ */
+@SuppressWarnings("nls")
+public class NumberSpinnerModelAdapter
+	extends SpinnerNumberModel
+{
+	/**
+	 * The default spinner value; used when the
+	 * underlying model number value is null.
+	 */
+	private final Number defaultValue;
+
+	/** A value model on the underlying number. */
+	private final ModifiablePropertyValueModel<Number> numberHolder;
+
+	/**
+	 * A listener that allows us to synchronize with
+	 * changes made to the underlying number.
+	 */
+	private final PropertyChangeListener numberChangeListener;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the number holder is required.
+	 * The default spinner value is zero.
+	 * The step size is one.
+	 */
+	public NumberSpinnerModelAdapter(ModifiablePropertyValueModel<Number> numberHolder) {
+		this(numberHolder, 0);
+	}
+
+	/**
+	 * Constructor - the number holder is required.
+	 * The step size is one.
+	 */
+	public NumberSpinnerModelAdapter(ModifiablePropertyValueModel<Number> numberHolder, int defaultValue) {
+		this(numberHolder, null, null, Integer.valueOf(1), Integer.valueOf(defaultValue));
+	}
+
+	/**
+	 * Constructor - the number holder is required.
+	 * Use the minimum value as the default spinner value.
+	 */
+	public NumberSpinnerModelAdapter(ModifiablePropertyValueModel<Number> numberHolder, int minimum, int maximum, int stepSize) {
+		this(numberHolder, minimum, maximum, stepSize, minimum);
+	}
+
+	/**
+	 * Constructor - the number holder is required.
+	 */
+	public NumberSpinnerModelAdapter(ModifiablePropertyValueModel<Number> numberHolder, int minimum, int maximum, int stepSize, int defaultValue) {
+		this(numberHolder, Integer.valueOf(minimum), Integer.valueOf(maximum), Integer.valueOf(stepSize), Integer.valueOf(defaultValue));
+	}
+
+	/**
+	 * Constructor - the number holder is required.
+	 * Use the minimum value as the default spinner value.
+	 */
+	public NumberSpinnerModelAdapter(ModifiablePropertyValueModel<Number> numberHolder, double minimum, double maximum, double stepSize) {
+		this(numberHolder, minimum, maximum, stepSize, minimum);
+	}
+
+	/**
+	 * Constructor - the number holder is required.
+	 */
+	public NumberSpinnerModelAdapter(ModifiablePropertyValueModel<Number> numberHolder, double minimum, double maximum, double stepSize, double defaultValue) {
+		this(numberHolder, Double.valueOf(minimum), Double.valueOf(maximum), Double.valueOf(stepSize), Double.valueOf(defaultValue));
+	}
+
+	/**
+	 * Constructor - the number holder is required.
+	 */
+	public NumberSpinnerModelAdapter(ModifiablePropertyValueModel<Number> numberHolder, Comparable<?> minimum, Comparable<?> maximum, Number stepSize, Number defaultValue) {
+		super(numberHolder.getValue() == null ? defaultValue : (Number) numberHolder.getValue(), minimum, maximum, stepSize);
+		this.numberHolder = numberHolder;
+		this.numberChangeListener = this.buildNumberChangeListener();
+		// postpone listening to the underlying number
+		// until we have listeners ourselves...
+		this.defaultValue = defaultValue;
+	}
+
+
+	// ********** initialization **********
+
+	protected PropertyChangeListener buildNumberChangeListener() {
+		return new AWTPropertyChangeListenerWrapper(this.buildNumberChangeListener_());
+	}
+
+	protected PropertyChangeListener buildNumberChangeListener_() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent event) {
+				NumberSpinnerModelAdapter.this.synchronize(event.getNewValue());
+			}
+			@Override
+			public String toString() {
+				return "number listener";
+			}
+		};
+	}
+
+
+	// ********** SpinnerModel implementation **********
+
+	/**
+	 * Extend to check whether this method is being called before we
+	 * have any listeners.
+	 * This is necessary because some crappy jdk code gets the value
+	 * from the model *before* listening to the model.  ~bjv
+	 * @see javax.swing.JSpinner.DefaultEditor#DefaultEditor(javax.swing.JSpinner)
+	 */
+    @Override
+	public Object getValue() {
+		if (this.getChangeListeners().length == 0) {
+			// sorry about this "lateral" call to super  ~bjv
+			super.setValue(this.spinnerValueOf(this.numberHolder.getValue()));
+		}
+		return super.getValue();
+	}
+
+	/**
+	 * Extend to update the underlying number directly.
+	 * The resulting event will be ignored: @see #synchronizeDelegate(Object).
+	 */
+    @Override
+	public void setValue(Object value) {
+		super.setValue(value);
+		this.numberHolder.setValue((Number) value);
+	}
+
+	/**
+	 * Extend to start listening to the underlying number if necessary.
+	 */
+    @Override
+	public void addChangeListener(ChangeListener listener) {
+		if (this.getChangeListeners().length == 0) {
+			this.numberHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.numberChangeListener);
+			this.synchronize(this.numberHolder.getValue());
+		}
+		super.addChangeListener(listener);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying number if appropriate.
+	 */
+    @Override
+	public void removeChangeListener(ChangeListener listener) {
+		super.removeChangeListener(listener);
+		if (this.getChangeListeners().length == 0) {
+			this.numberHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.numberChangeListener);
+		}
+	}
+
+
+	// ********** queries **********
+
+	protected Number getDefaultValue() {
+		return this.defaultValue;
+	}
+
+	/**
+	 * Convert to a non-null value.
+	 */
+	protected Object spinnerValueOf(Object value) {
+		return (value == null) ? this.getDefaultValue() : value;
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Set the spinner value if it has changed.
+	 */
+	void synchronize(Object value) {
+		Object newValue = this.spinnerValueOf(value);
+		// check to see whether the date has already been synchronized
+		// (via #setValue())
+		if ( ! this.getValue().equals(newValue)) {
+			this.setValue(newValue);
+		}
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.numberHolder);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ObjectListSelectionModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ObjectListSelectionModel.java
new file mode 100644
index 0000000..b41b388
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ObjectListSelectionModel.java
@@ -0,0 +1,437 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import javax.swing.DefaultListSelectionModel;
+import javax.swing.ListModel;
+import javax.swing.event.ListDataEvent;
+import javax.swing.event.ListDataListener;
+import javax.swing.event.ListSelectionListener;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterator.IteratorTools;
+
+/**
+ * This ListSelectionModel is aware of the ListModel and
+ * provides convenience methods to access and set the
+ * selected *objects*, as opposed to the selected *indexes*.
+ */
+@SuppressWarnings("nls")
+public class ObjectListSelectionModel
+	extends DefaultListSelectionModel
+{
+	/** The list model referenced by the list selection model. */
+	private final ListModel listModel;
+
+	/** A listener that allows us to clear the selection when the list model has changed. */
+	private final ListDataListener listDataListener;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a list selection model for the specified list model.
+	 */
+	public ObjectListSelectionModel(ListModel listModel) {
+		super();
+		this.listModel = listModel;
+		this.listDataListener = this.buildListDataListener();
+	}
+
+
+	// ********** initialization **********
+
+	private ListDataListener buildListDataListener() {
+		return new ListDataListener() {
+			@Override
+			public void intervalAdded(ListDataEvent event) {
+				// this does not affect the selection
+			}
+			@Override
+			public void intervalRemoved(ListDataEvent event) {
+				// this does not affect the selection
+			}
+			@Override
+			public void contentsChanged(ListDataEvent event) {
+				ObjectListSelectionModel.this.listModelContentsChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "list data listener";
+			}
+		};
+	}
+
+	/**
+	 * Typically, the selection does not need to be cleared when the
+	 * contents of the list have changed. Most of the time this just
+	 * means an item has changed in a way that affects its display string
+	 * or icon. We typically only use the class for edits involving
+	 * single selection.
+	 * A subclass can override this method if the selection
+	 * should be cleared because a change could mean the selection is invalid.
+	 */
+	protected void listModelContentsChanged(@SuppressWarnings("unused") ListDataEvent event) {
+		/**this.clearSelection();*/
+	}
+
+
+	// ********** ListSelectionModel implementation **********
+
+	@Override
+	public void addListSelectionListener(ListSelectionListener l) {
+		if (this.hasNoListSelectionListeners()) {
+			this.listModel.addListDataListener(this.listDataListener);
+		}
+		super.addListSelectionListener(l);
+	}
+
+	@Override
+	public void removeListSelectionListener(ListSelectionListener l) {
+		super.removeListSelectionListener(l);
+		if (this.hasNoListSelectionListeners()) {
+			this.listModel.removeListDataListener(this.listDataListener);
+		}
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * Return whether this model has no listeners.
+	 */
+	protected boolean hasNoListSelectionListeners() {	// private-protected
+		return this.getListSelectionListeners().length == 0;
+	}
+
+	/**
+	 * Return the list model referenced by the list selection model.
+	 */
+	public ListModel getListModel() {
+		return this.listModel;
+	}
+
+	public int selectedValuesSize() {
+		int min = this.getMinSelectionIndex();
+		int max = this.getMaxSelectionIndex();
+
+		if ((min < 0) || (max < 0)) {
+			return 0;
+		}
+
+		int n = 0;
+		int count = this.getListModel().getSize();
+		for (int i = min; i <= max; i++) {
+			if (this.isSelectedIndex(i) && (i < count)) {
+				n++;
+			}
+		}
+		return n;
+	}
+
+	/**
+	 * Return the first selected value.
+	 * Return null if the selection is empty.
+	 */
+	public Object selectedValue() {
+		int index = this.getMinSelectionIndex();
+		if (index == -1) {
+			return null;
+		}
+		if (this.getListModel().getSize() <= index) {
+			return null;
+		}
+		return this.getListModel().getElementAt(index);
+	}
+
+	/**
+	 * Return an array of the selected values.
+	 */
+	public Object[] selectedValues() {
+		int min = this.getMinSelectionIndex();
+		int max = this.getMaxSelectionIndex();
+
+		if ((min < 0) || (max < 0)) {
+			return ObjectTools.EMPTY_OBJECT_ARRAY;
+		}
+
+		int maxSize = (max - min) + 1;
+		Object[] temp = new Object[maxSize];
+		int n = 0;
+		int count = this.getListModel().getSize();
+		for (int i = min; i <= max; i++) {
+			if (this.isSelectedIndex(i) && (i < count)) {
+				temp[n++] = this.getListModel().getElementAt(i);
+			}
+		}
+		if (n == maxSize) {
+			// all the elements in the range were selected
+			return temp;
+		}
+		// only some of the elements in the range were selected
+		Object[] result = new Object[n];
+		System.arraycopy(temp, 0, result, 0, n);
+		return result;
+	}
+
+	/**
+	 * Return an array of the selected indices in order.
+	 */
+	public int[] selectedIndices() {
+		int min = this.getMinSelectionIndex();
+		int max = this.getMaxSelectionIndex();
+
+		if ((min < 0) || (max < 0)) {
+			return new int[0];
+		}
+
+		int maxSize = (max - min) + 1;
+		int[] temp = new int[maxSize];
+		int n = 0;
+		int count = this.getListModel().getSize();
+		for (int i = min; i <= max; i++) {
+			if (this.isSelectedIndex(i) && (i < count)) {
+				temp[n++] = i;
+			}
+		}
+		if (n == maxSize) {
+			// all the elements in the range were selected
+			Arrays.sort(temp);
+			return temp;
+		}
+		// only some of the elements in the range were selected
+		int[] result = new int[n];
+		System.arraycopy(temp, 0, result, 0, n);
+		Arrays.sort(result);
+		return result;
+	}
+
+	/**
+	 * Set the selected value.
+	 */
+	public void setSelectedValue(Object object) {
+		this.setSelectedValues(IteratorTools.singletonIterator(object));
+	}
+
+	/**
+	 * Set the current set of selected objects to the specified objects.
+	 * @see javax.swing.ListSelectionModel#setSelectionInterval(int, int)
+	 */
+	public void setSelectedValues(Iterator<?> objects) {
+		this.setValueIsAdjusting(true);
+		this.clearSelection();
+		this.addSelectedValuesInternal(objects);
+		this.setValueIsAdjusting(false);
+	}
+
+	/**
+	 * Set the current set of selected objects to the specified objects.
+	 * @see javax.swing.ListSelectionModel#setSelectionInterval(int, int)
+	 */
+	public void setSelectedValues(Collection<?> objects) {
+		this.setSelectedValues(objects.iterator());
+	}
+
+	/**
+	 * Set the current set of selected objects to the specified objects.
+	 * @see javax.swing.ListSelectionModel#setSelectionInterval(int, int)
+	 */
+	public void setSelectedValues(Object[] objects) {
+		this.setSelectedValues(IteratorTools.iterator(objects));
+	}
+
+	/**
+	 * Add the specified object to the current set of selected objects.
+	 * @see javax.swing.ListSelectionModel#addSelectionInterval(int, int)
+	 */
+	public void addSelectedValue(Object object) {
+		this.addSelectedValues(IteratorTools.singletonIterator(object));
+	}
+
+	/**
+	 * Add the specified objects to the current set of selected objects.
+	 * @see javax.swing.ListSelectionModel#addSelectionInterval(int, int)
+	 */
+	public void addSelectedValues(Iterator<?> objects) {
+		this.setValueIsAdjusting(true);
+		this.addSelectedValuesInternal(objects);
+		this.setValueIsAdjusting(false);
+	}
+
+	/**
+	 * Add the specified objects to the current set of selected objects.
+	 * @see javax.swing.ListSelectionModel#addSelectionInterval(int, int)
+	 */
+	public void addSelectedValues(Collection<?> objects) {
+		this.addSelectedValues(objects.iterator());
+	}
+
+	/**
+	 * Add the specified objects to the current set of selected objects.
+	 * @see javax.swing.ListSelectionModel#addSelectionInterval(int, int)
+	 */
+	public void addSelectedValues(Object[] objects) {
+		this.addSelectedValues(IteratorTools.iterator(objects));
+	}
+
+	/**
+	 * Remove the specified object from the current set of selected objects.
+	 * @see javax.swing.ListSelectionModel#removeSelectionInterval(int, int)
+	 */
+	public void removeSelectedValue(Object object) {
+		this.removeSelectedValues(IteratorTools.singletonIterator(object));
+	}
+
+	/**
+	 * Remove the specified objects from the current set of selected objects.
+	 * @see javax.swing.ListSelectionModel#removeSelectionInterval(int, int)
+	 */
+	public void removeSelectedValues(Iterator<?> objects) {
+		this.setValueIsAdjusting(true);
+		ListModel lm = this.getListModel();
+		int lmSize = lm.getSize();
+		while (objects.hasNext()) {
+			int index = this.indexOf(objects.next(), lm, lmSize);
+			this.removeSelectionInterval(index, index);
+		}
+		this.setValueIsAdjusting(false);
+	}
+
+	/**
+	 * Remove the specified objects from the current set of selected objects.
+	 * @see javax.swing.ListSelectionModel#removeSelectionInterval(int, int)
+	 */
+	public void removeSelectedValues(Collection<?> objects) {
+		this.removeSelectedValues(objects.iterator());
+	}
+
+	/**
+	 * Remove the specified objects from the current set of selected objects.
+	 * @see javax.swing.ListSelectionModel#removeSelectionInterval(int, int)
+	 */
+	public void removeSelectedValues(Object[] objects) {
+		this.removeSelectedValues(IteratorTools.iterator(objects));
+	}
+
+	/**
+	 * @see javax.swing.ListSelectionModel#getAnchorSelectionIndex()
+	 * Return null if the anchor selection is empty.
+	 */
+	public Object getAnchorSelectedValue() {
+		int index = this.getAnchorSelectionIndex();
+		if (index == -1) {
+			return null;
+		}
+		return this.getListModel().getElementAt(index);
+	}
+
+	/**
+	 * @see javax.swing.ListSelectionModel#setAnchorSelectionIndex(int)
+	 */
+	public void setAnchorSelectedValue(Object object) {
+		this.setAnchorSelectionIndex(this.indexOf(object));
+	}
+
+	/**
+	 * @see javax.swing.ListSelectionModel#getLeadSelectionIndex()
+	 * Return null if the lead selection is empty.
+	 */
+	public Object getLeadSelectedValue() {
+		int index = this.getLeadSelectionIndex();
+		if (index == -1) {
+			return null;
+		}
+		return this.getListModel().getElementAt(index);
+	}
+
+	/**
+	 * @see javax.swing.ListSelectionModel#setLeadSelectionIndex(int)
+	 */
+	public void setLeadSelectedValue(Object object) {
+		this.setLeadSelectionIndex(this.indexOf(object));
+	}
+
+	/**
+	 * @see javax.swing.ListSelectionModel#getMaxSelectionIndex()
+	 * Return null if the max selection is empty.
+	 */
+	public Object getMaxSelectedValue() {
+		int index = this.getMaxSelectionIndex();
+		if (index == -1) {
+			return null;
+		}
+		return this.getListModel().getElementAt(index);
+	}
+
+	/**
+	 * @see javax.swing.ListSelectionModel#getMinSelectionIndex()
+	 * Return null if the min selection is empty.
+	 */
+	public Object getMinSelectedValue() {
+		int index = this.getMinSelectionIndex();
+		if (index == -1) {
+			return null;
+		}
+		return this.getListModel().getElementAt(index);
+	}
+
+	/**
+	 * @see javax.swing.ListSelectionModel#isSelectedIndex(int)
+	 */
+	public boolean valueIsSelected(Object object) {
+		return this.isSelectedIndex(this.indexOf(object));
+	}
+
+	/**
+	 * Add the specified objects to the current set of selected objects,
+	 * without wrapping the actions in "adjusting" events.
+	 */
+	private void addSelectedValuesInternal(Iterator<?> objects) {
+		ListModel lm = this.getListModel();
+		int listModelSize = lm.getSize();
+		while (objects.hasNext()) {
+			int index = this.indexOf(objects.next(), lm, listModelSize);
+			this.addSelectionInterval(index, index);
+		}
+	}
+
+	/**
+	 * Return the index in the list model of the specified object.
+	 * Return -1 if the object is not in the list model.
+	 */
+	private int indexOf(Object object) {
+		ListModel lm = this.getListModel();
+		return this.indexOf(object, lm, lm.getSize());
+	}
+
+	/**
+	 * Return the index in the list model of the specified object.
+	 * Return -1 if the object is not in the list model.
+	 */
+	// we're just jerking around with performance optimizations here
+	// (in memory of Phil...);
+	// call this method inside loops that do not modify the listModel
+	private int indexOf(Object object, ListModel lm, int listModelSize) {
+		for (int i = listModelSize; i-- > 0; ) {
+			if (lm.getElementAt(i).equals(object)) {
+				return i;
+			}
+		}
+		return -1;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/PrimitiveListTreeModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/PrimitiveListTreeModel.java
new file mode 100644
index 0000000..6ec072d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/PrimitiveListTreeModel.java
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import javax.swing.event.TreeModelListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.MutableTreeNode;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.awt.AWTListChangeListenerWrapper;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+
+/**
+ * This TreeModel implementation provides a tree with a "null" root that
+ * has a set of "primitive" children. These "primitive" children do not have
+ * children themselves, making the tree a maximum of 2 levels deep.
+ * This model automatically synchronizes the root's children with a
+ * ListValueModel that holds a collection of primitive (non-model) objects
+ * (e.g. Strings).
+ *
+ * This is useful for providing an "editable" list of primitives. Since the JDK
+ * does not provide us with an editable listbox, we must use an editable tree.
+ * We wrap everything in DefaultMutableTreeNodes.
+ *
+ * Subclasses must implement #primitiveChanged(int, Object) and update
+ * the model appropriately. This method is called when the user edits the
+ * list directly and presses <Enter>.
+ *
+ * The JTree using this model must be configured as "editable":
+ * 	tree.setEditable(true);
+ */
+// TODO convert to use an adapter instead of requiring subclass
+public abstract class PrimitiveListTreeModel
+	extends DefaultTreeModel
+{
+	/** a model on the list of primitives */
+	private final ListValueModel<?> listHolder;
+
+	/** a listener that handles the adding, removing, and replacing of the primitives */
+	private final ListChangeListener listChangeListener;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Public constructor - the list holder is required
+	 */
+	public PrimitiveListTreeModel(ListValueModel<?> listHolder) {
+		super(new DefaultMutableTreeNode(null, true));  // true = the root can have children
+		if (listHolder == null) {
+			throw new NullPointerException();
+		}
+		this.listHolder = listHolder;
+		this.listChangeListener = this.buildListChangeListener();
+		// postpone listening to the model until we have listeners ourselves
+	}
+
+	protected ListChangeListener buildListChangeListener() {
+		return new AWTListChangeListenerWrapper(this.buildListChangeListener_());
+	}
+
+	protected ListChangeListener buildListChangeListener_() {
+		return new PrimitiveListChangeListener();
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Subclasses should override this method to update the
+	 * model appropriately. The primitive at the specified index was
+	 * edited directly by the user and the new value is as specified.
+	 * Convert the value appropriately and place it in the model.
+	 */
+	protected abstract void primitiveChanged(int index, Object newValue);
+
+
+	// ********** TreeModel implementation **********
+
+	/**
+	 * Override to change the underlying model instead of changing the node directly.
+	 */
+    @Override
+	public void valueForPathChanged(TreePath path, Object newValue) {
+		TreeNode node = (TreeNode) path.getLastPathComponent();
+		int index = ((TreeNode) this.getRoot()).getIndex(node);
+		this.primitiveChanged(index, newValue);
+	}
+
+	/**
+	 * Extend to start listening to the underlying model if necessary.
+	 */
+    @Override
+	public void addTreeModelListener(TreeModelListener l) {
+		if (this.getTreeModelListeners().length == 0) {
+			this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+			this.synchronizeList();
+		}
+		super.addTreeModelListener(l);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying model if appropriate.
+	 */
+    @Override
+	public void removeTreeModelListener(TreeModelListener l) {
+		super.removeTreeModelListener(l);
+		if (this.getTreeModelListeners().length == 0) {
+			this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+		}
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Synchronize our list of nodes with the list of primitives
+	 */
+	void synchronizeList() {
+		this.clearList();
+		this.buildList();
+	}
+
+	void clearList() {
+		int childcount = this.root.getChildCount();
+		for (int i = childcount - 1; i >= 0; i--) {
+			this.removeNodeFromParent((MutableTreeNode)this.root.getChildAt(i));
+		}
+	}
+
+	private void buildList() {
+		for (Iterator<?> stream = this.listHolder.iterator(); stream.hasNext(); ) {
+			this.addPrimitive(stream.next());
+		}
+	}
+
+	/**
+	 * Add the specified primitive to the end of the list.
+	 */
+	private void addPrimitive(Object primitive) {
+		this.insertPrimitive(this.root.getChildCount(), primitive);
+	}
+
+	/**
+	 * Create a node for the specified primitive
+	 * and insert it as a child of the root.
+	 */
+	void insertPrimitive(int index, Object primitive) {
+		DefaultMutableTreeNode node = new DefaultMutableTreeNode(primitive, false); // don't allow children on the child node
+		this.insertNodeInto(node, (MutableTreeNode) this.root, index);
+	}
+
+	/**
+	 * Remove node at the specified index.
+	 */
+	MutableTreeNode removeNode(int index) {
+		MutableTreeNode node = (MutableTreeNode) this.root.getChildAt(index);
+		this.removeNodeFromParent(node);
+		return node;
+	}
+
+	/**
+	 * Replace the user object of the node at childIndex.
+	 */
+	void replacePrimitive(int index, Object primitive) {
+		MutableTreeNode node = (MutableTreeNode) this.root.getChildAt(index);
+		node.setUserObject(primitive);
+		this.nodeChanged(node);
+	}
+
+
+	// ********** inner class **********
+
+	private class PrimitiveListChangeListener implements ListChangeListener {
+		PrimitiveListChangeListener() {
+			super();
+		}
+
+		@Override
+		public void itemsAdded(ListAddEvent event) {
+			int i = event.getIndex();
+			for (Object item : event.getItems()) {
+				PrimitiveListTreeModel.this.insertPrimitive(i++, item);
+			}
+		}
+
+		@Override
+		public void itemsRemoved(ListRemoveEvent event) {
+			for (int i = 0; i < event.getItemsSize(); i++) {
+				PrimitiveListTreeModel.this.removeNode(event.getIndex());
+			}
+		}
+
+		@Override
+		public void itemsReplaced(ListReplaceEvent event) {
+			int i = event.getIndex();
+			for (Object item : event.getNewItems()) {
+				PrimitiveListTreeModel.this.replacePrimitive(i++, item);
+			}
+		}
+
+		@Override
+		public void itemsMoved(ListMoveEvent event) {
+			ArrayList<MutableTreeNode> temp = new ArrayList<MutableTreeNode>(event.getLength());
+			for (int i = 0; i < event.getLength(); i++) {
+				temp.add(PrimitiveListTreeModel.this.removeNode(event.getSourceIndex()));
+			}
+			int i = event.getTargetIndex();
+			for (MutableTreeNode node : temp) {
+				PrimitiveListTreeModel.this.insertPrimitive(i++, node);
+			}
+		}
+
+		@Override
+		public void listCleared(ListClearEvent event) {
+			PrimitiveListTreeModel.this.clearList();
+		}
+
+		@Override
+		public void listChanged(ListChangeEvent event) {
+			PrimitiveListTreeModel.this.synchronizeList();
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/RadioButtonModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/RadioButtonModelAdapter.java
new file mode 100644
index 0000000..9ca700c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/RadioButtonModelAdapter.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import org.eclipse.persistence.tools.utility.filter.Filter;
+import org.eclipse.persistence.tools.utility.model.value.FilteringModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.TransformationModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * This {@link javax.swing.ButtonModel} can be used to keep a listener
+ * (e.g. a {@link javax.swing.JRadioButton}) in synch with a (typically shared)
+ * {@link org.eclipse.jpt.common.utility.model.value.PropertyValueModel}
+ * that holds one value out of a set of values.
+ * <p>
+ * <strong>NB:</strong> Do <em>not</em> use this model with a
+ * {@link javax.swing.ButtonGroup}, since the
+ * shared value holder and the wrappers built by this adapter will
+ * keep the appropriate radio button checked. Also, this allows
+ * us to uncheck all the radio buttons in a group when the shared
+ * value is <code>null</code>.
+ */
+public class RadioButtonModelAdapter
+	extends ToggleButtonModelAdapter
+{
+	private static final long serialVersionUID = 1L;
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the value holder is required.
+	 */
+	public RadioButtonModelAdapter(ModifiablePropertyValueModel<Object> valueHolder, Object buttonValue, boolean defaultValue) {
+		super(buildBooleanHolder(valueHolder, buttonValue), defaultValue);
+	}
+
+	/**
+	 * Constructor - the value holder is required.
+	 * The default value will be false.
+	 */
+	public RadioButtonModelAdapter(ModifiablePropertyValueModel<Object> valueHolder, Object buttonValue) {
+		super(buildBooleanHolder(valueHolder, buttonValue));
+	}
+
+
+	// ********** static methods **********
+
+	/**
+	 * Build up a set of wrappers that will convert the
+	 * specified value holder and button value to/from a boolean.
+	 *
+	 * If the value holder's value matches the button value,
+	 * the wrapper will return true. Likewise, if the value holder's
+	 * value is set to true, the wrapper will set the value holder's
+	 * value to the button value.
+	 */
+	public static ModifiablePropertyValueModel<Boolean> buildBooleanHolder(ModifiablePropertyValueModel<Object> valueHolder, Object buttonValue) {
+		ModifiablePropertyValueModel<Object> filteringPVM = new FilteringModifiablePropertyValueModel<Object>(valueHolder, Filter.Transparent.instance(), new SetRadioButtonFilter(buttonValue));
+		return new TransformationModifiablePropertyValueModel<Object, Boolean>(filteringPVM, new RadioButtonTransformer(buttonValue), new ReverseRadioButtonTransformer(buttonValue));
+	}
+
+
+	// ********** overrides **********
+
+	/**
+	 * The user cannot de-select a radio button - the user
+	 * can only *select* a radio button. Only the model can
+	 * cause a radio button to be de-selected. We use the
+	 * ARMED flag to indicate whether we are being de-selected
+	 * by the user.
+	 */
+    @Override
+	public void setSelected(boolean b) {
+		// do not allow the user to de-select a radio button
+		// radio buttons can
+		if ((b == false) && this.isArmed()) {
+			return;
+		}
+		super.setSelected(b);
+	}
+
+
+	// ********** filters **********
+
+	/**
+	 * This filter will only pass through a new value to the wrapped
+	 * value model when it matches the configured button value.
+	 */
+	public static class SetRadioButtonFilter
+		implements Filter<Object>
+	{
+		private Object buttonValue;
+
+		public SetRadioButtonFilter(Object buttonValue) {
+			super();
+			this.buttonValue = buttonValue;
+		}
+
+		/**
+		 * pass through the value to the wrapped property value model
+		 * *only* when it matches our button value
+		 */
+		@Override
+		public boolean accept(Object value) {
+			return (value != null) && value.equals(this.buttonValue);
+		}
+	}
+
+
+	// ********** transformers **********
+
+	/**
+	 * This transformer will convert a value to {@link Boolean#TRUE}
+	 * when it matches the configured button value.
+	 */
+	public static class RadioButtonTransformer
+		implements Transformer<Object, Boolean>
+	{
+		private Object buttonValue;
+
+		public RadioButtonTransformer(Object buttonValue) {
+			super();
+			this.buttonValue = buttonValue;
+		}
+
+		/**
+		 * If the specified value matches the button value return {@link Boolean#TRUE},
+		 * if it is some other value return {@link Boolean#FALSE};
+		 * but if it is <code>null</code> simply pass it through because it will
+		 * cause the button model's default value to be used
+		 */
+		@Override
+		public Boolean transform(Object value) {
+			return (value == null) ? null : Boolean.valueOf(value.equals(this.buttonValue));
+		}
+	}
+
+	/**
+	 * This transformer will convert {@link Boolean#TRUE} to the configured
+	 * button value and {@link Boolean#FALSE} to <code>null</code>.
+	 */
+	public static class ReverseRadioButtonTransformer
+		implements Transformer<Boolean, Object>
+	{
+		private Object buttonValue;
+
+		public ReverseRadioButtonTransformer(Object buttonValue) {
+			super();
+			this.buttonValue = buttonValue;
+		}
+
+		/**
+		 * If the specified value is {@link Boolean#TRUE},
+		 * pass through the our button value;
+		 * otherwise pass through <code>null</code>.
+		 */
+		@Override
+		public Object transform (Boolean value) {
+			return (value.booleanValue()) ? this.buttonValue : null;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/SpinnerModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/SpinnerModelAdapter.java
new file mode 100644
index 0000000..180f629
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/SpinnerModelAdapter.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import javax.swing.AbstractSpinnerModel;
+import javax.swing.SpinnerModel;
+import javax.swing.SpinnerNumberModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.awt.AWTPropertyChangeListenerWrapper;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+
+/**
+ * This javax.swing.SpinnerModel can be used to keep a ChangeListener
+ * (e.g. a JSpinner) in synch with a PropertyValueModel that holds a value.
+ *
+ * Note: it is likely you want to use one of the following classes instead of
+ * this one:
+ *     DateSpinnerModelAdapter
+ *     NumberSpinnerModelAdapter
+ *     ListSpinnerModelAdapter
+ *
+ * NB: This model should only be used for values that have a fairly
+ * inexpensive #equals() implementation.
+ * @see #synchronizeDelegate(Object)
+ */
+@SuppressWarnings("nls")
+public class SpinnerModelAdapter
+	extends AbstractSpinnerModel
+{
+	/** The delegate spinner model whose behavior we "enhance". */
+	protected final SpinnerModel delegate;
+
+	/** A listener that allows us to forward any changes made to the delegate spinner model. */
+	protected final ChangeListener delegateListener;
+
+	/** A value model on the underlying value. */
+	protected final ModifiablePropertyValueModel<Object> valueHolder;
+
+	/** A listener that allows us to synchronize with changes made to the underlying value. */
+	protected final PropertyChangeListener valueListener;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the value holder and delegate are required.
+	 */
+	public SpinnerModelAdapter(ModifiablePropertyValueModel<Object> valueHolder, SpinnerModel delegate) {
+		super();
+		if (valueHolder == null || delegate == null) {
+			throw new NullPointerException();
+		}
+		this.valueHolder = valueHolder;
+		this.delegate = delegate;
+		// postpone listening to the underlying value
+		// until we have listeners ourselves...
+		this.valueListener = this.buildValueListener();
+		this.delegateListener = this.buildDelegateListener();
+	}
+
+	/**
+	 * Constructor - the value holder is required.
+	 * This will wrap a simple number spinner model.
+	 */
+	public SpinnerModelAdapter(ModifiablePropertyValueModel<Object> valueHolder) {
+		this(valueHolder, new SpinnerNumberModel());
+	}
+
+
+	// ********** initialization **********
+
+	protected PropertyChangeListener buildValueListener() {
+		return new AWTPropertyChangeListenerWrapper(this.buildValueListener_());
+	}
+
+	protected PropertyChangeListener buildValueListener_() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent event) {
+				SpinnerModelAdapter.this.valueChanged(event);
+			}
+			@Override
+			public String toString() {
+				return "value listener";
+			}
+		};
+	}
+
+	/**
+	 * expand access a bit for inner class
+	 */
+	@Override
+	protected void fireStateChanged() {
+		super.fireStateChanged();
+	}
+
+	protected ChangeListener buildDelegateListener() {
+		return new ChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent event) {
+				// forward the event, with this as the source
+				SpinnerModelAdapter.this.fireStateChanged();
+			}
+			@Override
+			public String toString() {
+				return "delegate listener";
+			}
+		};
+	}
+
+
+	// ********** SpinnerModel implementation **********
+
+	@Override
+	public Object getValue() {
+		return this.delegate.getValue();
+	}
+
+	/**
+	 * Extend to update the underlying value directly.
+	 * The resulting event will be ignored: @see #synchronizeDelegate(Object).
+	 */
+	@Override
+	public void setValue(Object value) {
+		this.delegate.setValue(value);
+		this.valueHolder.setValue(value);
+	}
+
+	@Override
+	public Object getNextValue() {
+		return this.delegate.getNextValue();
+	}
+
+	@Override
+	public Object getPreviousValue() {
+		return this.delegate.getPreviousValue();
+	}
+
+	/**
+	 * Extend to start listening to the underlying value if necessary.
+	 */
+    @Override
+	public void addChangeListener(ChangeListener listener) {
+		if (this.listenerList.getListenerCount(ChangeListener.class) == 0) {
+			this.delegate.addChangeListener(this.delegateListener);
+			this.engageValueHolder();
+		}
+		super.addChangeListener(listener);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying value if appropriate.
+	 */
+    @Override
+	public void removeChangeListener(ChangeListener listener) {
+		super.removeChangeListener(listener);
+		if (this.listenerList.getListenerCount(ChangeListener.class) == 0) {
+			this.disengageValueHolder();
+			this.delegate.removeChangeListener(this.delegateListener);
+		}
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * A third party has modified the underlying value.
+	 * Synchronize the delegate model accordingly.
+	 */
+	protected void valueChanged(PropertyChangeEvent event) {
+		this.synchronizeDelegate(event.getNewValue());
+	}
+
+	/**
+	 * Set the delegate's value if it has changed.
+	 */
+	protected void synchronizeDelegate(Object value) {
+		// check to see whether the delegate has already been synchronized
+		// (via #setValue())
+		if ( ! this.delegate.getValue().equals(value)) {
+			this.delegate.setValue(value);
+		}
+	}
+
+	protected void engageValueHolder() {
+		this.valueHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.valueListener);
+		this.synchronizeDelegate(this.valueHolder.getValue());
+	}
+
+	protected void disengageValueHolder() {
+		this.valueHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.valueListener);
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.valueHolder);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/TableModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/TableModelAdapter.java
new file mode 100644
index 0000000..171289f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/TableModelAdapter.java
@@ -0,0 +1,470 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.AbstractTableModel;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.awt.AWTListChangeListenerWrapper;
+import org.eclipse.persistence.tools.utility.model.listener.awt.AWTPropertyChangeListenerWrapper;
+import org.eclipse.persistence.tools.utility.model.value.CollectionListValueModelAdapter;
+import org.eclipse.persistence.tools.utility.model.value.CollectionValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+
+/**
+ * This TableModel can be used to keep a TableModelListener (e.g. a JTable)
+ * in synch with a ListValueModel that holds a collection of model objects,
+ * each of which corresponds to a row in the table.
+ * Typically, each column of the table will be bound to a different aspect
+ * of the contained model objects.
+ *
+ * For example, a MWTable has an attribute 'databaseFields' that holds
+ * a collection of MWDatabaseFields that would correspond to the rows of
+ * a JTable; and each MWDatabaseField has a number
+ * of attributes (e.g. name, type, size) that can be bound to the columns of
+ * a row in the JTable. As these database fields are added, removed, and
+ * changed, this model will keep the listeners aware of the changes.
+ *
+ * An instance of this TableModel must be supplied with a
+ * list holder (e.g. the 'databaseFields'), which is a value
+ * model on the bound collection This is required - the
+ * collection itself can be null, but the list value model that
+ * holds it is required. Typically this list will be sorted (@see
+ * SortedListValueModelAdapter).
+ *
+ * This TableModel must also be supplied with a ColumnAdapter that
+ * will be used to configure the headers, renderers, editors, and contents
+ * of the various columns.
+ *
+ * Design decision:
+ * Cell listener options (from low space/high time to high space/low time):
+ * 	- 1 cell listener listening to every cell (this is the current implementation)
+ * 	- 1 cell listener per row
+ * 	- 1 cell listener per cell
+ */
+@SuppressWarnings("nls")
+public class TableModelAdapter<E>
+	extends AbstractTableModel
+{
+	/**
+	 * a list of user objects that are converted to
+	 * rows via the column adapter
+	 */
+	private ListValueModel<? extends E> listHolder;
+	private final ListChangeListener listChangeListener;
+
+	/**
+	 * each row is an array of cell models
+	 */
+	// declare as ArrayList so we can use #ensureCapacity(int)
+	private final ArrayList<ModifiablePropertyValueModel<Object>[]> rows;
+
+	/**
+	 * client-supplied adapter that provides with the various column
+	 * settings and converts the objects in the LVM
+	 * into an array of cell models
+	 */
+	private final ColumnAdapter columnAdapter;
+
+	/**
+	 * the single listener that listens to every cell's model
+	 */
+	private final PropertyChangeListener cellListener;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a table model adapter for the specified objects
+	 * and adapter.
+	 */
+	public TableModelAdapter(ListValueModel<? extends E> listHolder, ColumnAdapter columnAdapter) {
+		super();
+		if (listHolder == null) {
+			throw new NullPointerException();
+		}
+		this.listHolder = listHolder;
+		this.columnAdapter = columnAdapter;
+		this.listChangeListener = this.buildListChangeListener();
+		this.rows = new ArrayList<ModifiablePropertyValueModel<Object>[]>();
+		this.cellListener = this.buildCellListener();
+	}
+
+	/**
+	 * Construct a table model adapter for the specified objects
+	 * and adapter.
+	 */
+	public TableModelAdapter(CollectionValueModel<? extends E> collectionHolder, ColumnAdapter columnAdapter) {
+		this(new CollectionListValueModelAdapter<E>(collectionHolder), columnAdapter);
+	}
+
+
+	// ********** initialization **********
+
+	protected ListChangeListener buildListChangeListener() {
+		return new AWTListChangeListenerWrapper(this.buildListChangeListener_());
+	}
+
+	protected ListChangeListener buildListChangeListener_() {
+		return new ListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) {
+				TableModelAdapter.this.addRows(event.getIndex(), event.getItemsSize(), this.getItems(event));
+			}
+			@Override
+			public void itemsRemoved(ListRemoveEvent event) {
+				TableModelAdapter.this.removeRows(event.getIndex(), event.getItemsSize());
+			}
+			@Override
+			public void itemsReplaced(ListReplaceEvent event) {
+				TableModelAdapter.this.replaceRows(event.getIndex(), this.getNewItems(event));
+			}
+			@Override
+			public void itemsMoved(ListMoveEvent event) {
+				TableModelAdapter.this.moveRows(event.getTargetIndex(), event.getSourceIndex(), event.getLength());
+			}
+			@Override
+			public void listCleared(ListClearEvent event) {
+				TableModelAdapter.this.clearTable();
+			}
+			@Override
+			public void listChanged(ListChangeEvent event) {
+				TableModelAdapter.this.rebuildTable();
+			}
+			// minimized scope of suppressed warnings
+			@SuppressWarnings("unchecked")
+			protected Iterable<Object> getItems(ListAddEvent event) {
+				return (Iterable<Object>) event.getItems();
+			}
+			// minimized scope of suppressed warnings
+			@SuppressWarnings("unchecked")
+			protected Iterable<Object> getNewItems(ListReplaceEvent event) {
+				return (Iterable<Object>) event.getNewItems();
+			}
+			@Override
+			public String toString() {
+				return "list listener";
+			}
+		};
+	}
+
+
+	protected PropertyChangeListener buildCellListener() {
+		return new AWTPropertyChangeListenerWrapper(this.buildCellListener_());
+	}
+
+	protected PropertyChangeListener buildCellListener_() {
+		return new PropertyChangeListener() {
+			@Override
+			@SuppressWarnings("unchecked")
+			public void propertyChanged(PropertyChangeEvent event) {
+				TableModelAdapter.this.cellChanged((ModifiablePropertyValueModel<Object>) event.getSource());
+			}
+			@Override
+			public String toString() {
+				return "cell listener";
+			}
+		};
+	}
+
+
+	// ********** TableModel implementation **********
+
+	@Override
+	public int getColumnCount() {
+		return this.columnAdapter.columnCount();
+	}
+
+	@Override
+	public int getRowCount() {
+		return this.rows.size();
+	}
+
+    @Override
+	public String getColumnName(int column) {
+		return this.columnAdapter.columnName(column);
+	}
+
+    @Override
+	public Class<?> getColumnClass(int columnIndex) {
+		return this.columnAdapter.columnClass(columnIndex);
+	}
+
+    @Override
+	public boolean isCellEditable(int rowIndex, int columnIndex) {
+		return this.columnAdapter.columnIsEditable(columnIndex);
+	}
+
+	@Override
+	public Object getValueAt(int rowIndex, int columnIndex) {
+		ModifiablePropertyValueModel<Object>[] row = this.rows.get(rowIndex);
+		return row[columnIndex].getValue();
+	}
+
+	@Override
+	public void setValueAt(Object value, int rowIndex, int columnIndex) {
+		ModifiablePropertyValueModel<Object>[] row = this.rows.get(rowIndex);
+		row[columnIndex].setValue(value);
+	}
+
+	/**
+	 * Extend to start listening to the underlying model if necessary.
+	 */
+    @Override
+	public void addTableModelListener(TableModelListener l) {
+		if (this.hasNoTableModelListeners()) {
+			this.engageModel();
+		}
+		super.addTableModelListener(l);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying model if necessary.
+	 */
+    @Override
+	public void removeTableModelListener(TableModelListener l) {
+		super.removeTableModelListener(l);
+		if (this.hasNoTableModelListeners()) {
+			this.disengageModel();
+		}
+	}
+
+
+	// ********** public API **********
+
+	/**
+	 * Return the underlying list model.
+	 */
+	public ListValueModel<? extends E> getModel() {
+		return this.listHolder;
+	}
+
+	/**
+	 * Set the underlying list model.
+	 */
+	public void setModel(ListValueModel<E> listHolder) {
+		if (listHolder == null) {
+			throw new NullPointerException();
+		}
+		boolean hasListeners = this.hasTableModelListeners();
+		if (hasListeners) {
+			this.disengageModel();
+		}
+		this.listHolder = listHolder;
+		if (hasListeners) {
+			this.engageModel();
+			this.fireTableDataChanged();
+		}
+	}
+
+	/**
+	 * Set the underlying collection model.
+	 */
+	public void setModel(CollectionValueModel<E> collectionHolder) {
+		this.setModel(new CollectionListValueModelAdapter<E>(collectionHolder));
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * Return whether this model has no listeners.
+	 */
+	protected boolean hasNoTableModelListeners() {
+		return this.listenerList.getListenerCount(TableModelListener.class) == 0;
+	}
+
+	/**
+	 * Return whether this model has any listeners.
+	 */
+	protected boolean hasTableModelListeners() {
+		return ! this.hasNoTableModelListeners();
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Start listening to the list of objects and the various aspects
+	 * of the objects that make up the rows.
+	 */
+	private void engageModel() {
+		this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+		this.engageAllCells();
+	}
+
+	/**
+	 * Convert the objects into rows and listen to the cells.
+	 */
+	private void engageAllCells() {
+		this.rows.ensureCapacity(this.listHolder.size());
+		for (Iterator<? extends E> stream = this.listHolder.iterator(); stream.hasNext(); ) {
+			ModifiablePropertyValueModel<Object>[] row = this.columnAdapter.cellModels(stream.next());
+			this.engageRow(row);
+			this.rows.add(row);
+		}
+	}
+
+	/**
+	 * Listen to the cells in the specified row.
+	 */
+	private void engageRow(ModifiablePropertyValueModel<Object>[] row) {
+		for (int i = row.length; i-- > 0; ) {
+			row[i].addPropertyChangeListener(PropertyValueModel.VALUE, this.cellListener);
+		}
+	}
+
+	/**
+	 * Stop listening.
+	 */
+	private void disengageModel() {
+		this.disengageAllCells();
+		this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
+	}
+
+	private void disengageAllCells() {
+		for (ModifiablePropertyValueModel<Object>[] row : this.rows) {
+			this.disengageRow(row);
+		}
+		this.rows.clear();
+	}
+
+	private void disengageRow(ModifiablePropertyValueModel<Object>[] row) {
+		for (int i = row.length; i-- > 0; ) {
+			row[i].removePropertyChangeListener(PropertyValueModel.VALUE, this.cellListener);
+		}
+	}
+
+	/**
+	 * brute-force search for the cell(s) that changed...
+	 */
+	void cellChanged(ModifiablePropertyValueModel<Object> cellHolder) {
+		for (int i = this.rows.size(); i-- > 0; ) {
+			ModifiablePropertyValueModel<Object>[] row = this.rows.get(i);
+			for (int j = row.length; j-- > 0; ) {
+				if (row[j] == cellHolder) {
+					this.fireTableCellUpdated(i, j);
+				}
+			}
+		}
+	}
+
+	/**
+	 * convert the items to rows
+	 */
+	void addRows(int index, int size, Iterable<Object> items) {
+		List<ModifiablePropertyValueModel<Object>[]> newRows = new ArrayList<ModifiablePropertyValueModel<Object>[]>(size);
+		for (Object item : items) {
+			ModifiablePropertyValueModel<Object>[] row = this.columnAdapter.cellModels(item);
+			this.engageRow(row);
+			newRows.add(row);
+		}
+		this.rows.addAll(index, newRows);
+		this.fireTableRowsInserted(index, index + size - 1);
+	}
+
+	void removeRows(int index, int size) {
+		for (int i = 0; i < size; i++) {
+			this.disengageRow(this.rows.remove(index));
+		}
+		this.fireTableRowsDeleted(index, index + size - 1);
+	}
+
+	void replaceRows(int index, Iterable<Object> items) {
+		int i = index;
+		for (Object item : items) {
+			ModifiablePropertyValueModel<Object>[] row = this.rows.get(i);
+			this.disengageRow(row);
+			row = this.columnAdapter.cellModels(item);
+			this.engageRow(row);
+			this.rows.set(i, row);
+			i++;
+		}
+		this.fireTableRowsUpdated(index, i - 1);
+	}
+
+	void moveRows(int targetIndex, int sourceIndex, int length) {
+		ArrayList<ModifiablePropertyValueModel<Object>[]> temp = new ArrayList<ModifiablePropertyValueModel<Object>[]>(length);
+		for (int i = 0; i < length; i++) {
+			temp.add(this.rows.remove(sourceIndex));
+		}
+		this.rows.addAll(targetIndex, temp);
+
+		int start = Math.min(targetIndex, sourceIndex);
+		int end = Math.max(targetIndex, sourceIndex) + length - 1;
+		this.fireTableRowsUpdated(start, end);
+	}
+
+	void clearTable() {
+		this.disengageAllCells();
+		this.fireTableDataChanged();
+	}
+
+	void rebuildTable() {
+		this.disengageAllCells();
+		this.engageAllCells();
+		this.fireTableDataChanged();
+	}
+
+
+	/**
+	 * This adapter is used by the table model adapter to
+	 * convert a model object into the models used for each of
+	 * the cells for the object's corresponding row in the table.
+	 */
+	public interface ColumnAdapter {
+		/**
+		 * Return the number of columns in the table.
+		 * Typically this is static.
+		 */
+		int columnCount();
+
+		/**
+		 * Return the name of the specified column.
+		 */
+		String columnName(int index);
+
+		/**
+		 * Return the class of the specified column.
+		 */
+		Class<?> columnClass(int index);
+
+		/**
+		 * Return whether the specified column is editable.
+		 * Typically this is the same for every row.
+		 */
+		boolean columnIsEditable(int index);
+
+		/**
+		 * Return the cell models for the specified subject
+		 * that corresponds to a single row in the table.
+		 */
+		ModifiablePropertyValueModel<Object>[] cellModels(Object subject);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ToggleButtonModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ToggleButtonModelAdapter.java
new file mode 100644
index 0000000..bf22de0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/ToggleButtonModelAdapter.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import java.awt.event.ActionListener;
+import java.awt.event.ItemListener;
+import javax.swing.JToggleButton.ToggleButtonModel;
+import javax.swing.event.ChangeListener;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.awt.AWTPropertyChangeListenerWrapper;
+import org.eclipse.persistence.tools.utility.model.value.ModifiablePropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+
+/**
+ * This javax.swing.ButtonModel can be used to keep a listener
+ * (e.g. a JCheckBox or a JRadioButton) in synch with a PropertyValueModel
+ * on a boolean.
+ */
+@SuppressWarnings("nls")
+public class ToggleButtonModelAdapter
+	extends ToggleButtonModel
+{
+	/**
+	 * The default setting for the toggle button; for when the underlying model is null.
+	 * The default [default value] is false (i.e. the toggle button is unchecked/empty).
+	 */
+	protected final boolean defaultValue;
+
+	/** A value model on the underlying model boolean. */
+	protected final ModifiablePropertyValueModel<Boolean> booleanHolder;
+
+	/**
+	 * A listener that allows us to synchronize with
+	 * changes made to the underlying model boolean.
+	 */
+	protected final PropertyChangeListener booleanChangeListener;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Constructor - the boolean holder is required.
+	 */
+	public ToggleButtonModelAdapter(ModifiablePropertyValueModel<Boolean> booleanHolder, boolean defaultValue) {
+		super();
+		if (booleanHolder == null) {
+			throw new NullPointerException();
+		}
+		this.booleanHolder = booleanHolder;
+		this.booleanChangeListener = this.buildBooleanChangeListener();
+		// postpone listening to the underlying model
+		// until we have listeners ourselves...
+		this.defaultValue = defaultValue;
+	}
+
+	/**
+	 * Constructor - the boolean holder is required.
+	 * The default value will be false.
+	 */
+	public ToggleButtonModelAdapter(ModifiablePropertyValueModel<Boolean> booleanHolder) {
+		this(booleanHolder, false);
+	}
+
+
+	// ********** initialization **********
+
+	protected PropertyChangeListener buildBooleanChangeListener() {
+		return new AWTPropertyChangeListenerWrapper(this.buildBooleanChangeListener_());
+	}
+
+	protected PropertyChangeListener buildBooleanChangeListener_() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent event) {
+				ToggleButtonModelAdapter.this.booleanChanged(event);
+			}
+		    @Override
+			public String toString() {
+				return "boolean listener";
+			}
+		};
+	}
+
+
+	// ********** ButtonModel implementation **********
+
+	/**
+	 * Extend to update the underlying model if necessary.
+	 */
+    @Override
+	public void setSelected(boolean b) {
+		if (this.isSelected() != b) {	// stop the recursion!
+			super.setSelected(b);//put the super call first, otherwise the following gets called twice
+			this.booleanHolder.setValue(Boolean.valueOf(b));
+		}
+	}
+
+	/**
+	 * Extend to start listening to the underlying model if necessary.
+	 */
+    @Override
+	public void addActionListener(ActionListener l) {
+		if (this.hasNoListeners()) {
+			this.engageModel();
+		}
+		super.addActionListener(l);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying model if appropriate.
+	 */
+    @Override
+	public void removeActionListener(ActionListener l) {
+		super.removeActionListener(l);
+		if (this.hasNoListeners()) {
+			this.disengageModel();
+		}
+	}
+
+	/**
+	 * Extend to start listening to the underlying model if necessary.
+	 */
+    @Override
+	public void addItemListener(ItemListener l) {
+		if (this.hasNoListeners()) {
+			this.engageModel();
+		}
+		super.addItemListener(l);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying model if appropriate.
+	 */
+    @Override
+	public void removeItemListener(ItemListener l) {
+		super.removeItemListener(l);
+		if (this.hasNoListeners()) {
+			this.disengageModel();
+		}
+	}
+
+	/**
+	 * Extend to start listening to the underlying model if necessary.
+	 */
+    @Override
+	public void addChangeListener(ChangeListener l) {
+		if (this.hasNoListeners()) {
+			this.engageModel();
+		}
+		super.addChangeListener(l);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying model if appropriate.
+	 */
+    @Override
+	public void removeChangeListener(ChangeListener l) {
+		super.removeChangeListener(l);
+		if (this.hasNoListeners()) {
+			this.disengageModel();
+		}
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * Return whether we have no listeners at all.
+	 */
+	protected boolean hasNoListeners() {
+		return this.listenerList.getListenerCount() == 0;
+	}
+
+	protected boolean getDefaultValue() {
+		return this.defaultValue;
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Synchronize with the specified value.
+	 * If it is null, use the default value (which is typically false).
+	 */
+	protected void setSelected(Boolean value) {
+		if (value == null) {
+			this.setSelected(this.getDefaultValue());
+		} else {
+			this.setSelected(value.booleanValue());
+		}
+	}
+
+	/**
+	 * The underlying model has changed - synchronize accordingly.
+	 */
+	protected void booleanChanged(PropertyChangeEvent event) {
+		this.setSelected((Boolean) event.getNewValue());
+	}
+
+	protected void engageModel() {
+		this.booleanHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.booleanChangeListener);
+		this.setSelected(this.booleanHolder.getValue());
+	}
+
+	protected void disengageModel() {
+		this.booleanHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.booleanChangeListener);
+	}
+
+
+	// ********** standard methods **********
+
+    @Override
+	public String toString() {
+		return ObjectTools.toString(this, this.booleanHolder);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/TreeModelAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/TreeModelAdapter.java
new file mode 100644
index 0000000..f65bde0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/model/value/swing/TreeModelAdapter.java
@@ -0,0 +1,934 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.model.value.swing;
+
+import java.util.ArrayList;
+import java.util.IdentityHashMap;
+import java.util.List;
+import javax.swing.event.TreeModelListener;
+import javax.swing.tree.TreePath;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.model.event.ListAddEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListClearEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListMoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListRemoveEvent;
+import org.eclipse.persistence.tools.utility.model.event.ListReplaceEvent;
+import org.eclipse.persistence.tools.utility.model.event.PropertyChangeEvent;
+import org.eclipse.persistence.tools.utility.model.event.StateChangeEvent;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.awt.AWTListChangeListenerWrapper;
+import org.eclipse.persistence.tools.utility.model.listener.awt.AWTPropertyChangeListenerWrapper;
+import org.eclipse.persistence.tools.utility.model.listener.awt.AWTStateChangeListenerWrapper;
+import org.eclipse.persistence.tools.utility.model.value.ListValueModel;
+import org.eclipse.persistence.tools.utility.model.value.PropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.StaticPropertyValueModel;
+import org.eclipse.persistence.tools.utility.model.value.TreeNodeValueModel;
+
+/**
+ * This javax.swing.tree.TreeModel can be used to keep a TreeModelListener
+ * (e.g. a JTree) in synch with a tree of TreeNodeValueModel objects. Unlike
+ * javax.swing.tree.DefaultTreeModel, you do not add and remove nodes with
+ * methods implemented here. You can add and remove nodes by adding and
+ * removing them directly to/from the nodes (or, more typically, the domain
+ * objects the nodes are wrapping and listening to).
+ *
+ * Due to limitations in JTree, the root of the tree can never be null,
+ * which, typically, should not be a problem. (If you want to display an empty
+ * tree you can set the JTree's treeModel to null.)
+ */
+@SuppressWarnings("nls")
+public class TreeModelAdapter<T>
+	extends AbstractTreeModel
+{
+	/**
+	 * A value model on the underlying tree's root node and its
+	 * corresponding listener. This allows clients to swap out
+	 * the entire tree. Due to limitations in JTree, the root should
+	 * never be set to null while we have listeners.
+	 */
+	private final PropertyValueModel<TreeNodeValueModel<T>> rootHolder;
+	private final PropertyChangeListener rootListener;
+
+	/**
+	 * A listener that notifies us when a node's internal
+	 * "state" changes (as opposed to the node's value or list of
+	 * children), allowing us to forward notification to our listeners.
+	 */
+	private final StateChangeListener nodeStateListener;
+
+	/**
+	 * A listener that notifies us when a node's "value"
+	 * changes (as opposed to the node's state or list of
+	 * children), allowing us to forward notification to our listeners.
+	 * Typically, this will only happen with nodes that hold
+	 * primitive data.
+	 */
+	private final PropertyChangeListener nodeValueListener;
+
+	/**
+	 * A listener that notifies us when an underlying node's
+	 * "list" of children changes, allowing us to keep our
+	 * internal tree in synch with the underlying tree model.
+	 */
+	private final ListChangeListener childrenListener;
+
+	/* these attributes make up our internal tree */
+	/**
+	 * The root cannot be null while we have listeners, which is
+	 * most of the time. The root is cached so we can disengage
+	 * from it when it has been swapped out.
+	 */
+	private TreeNodeValueModel<T> root;
+
+	/**
+	 * Map the nodes to their lists of children.
+	 * We cache these so we can swap out the entire list of children
+	 * when we receive a #listChanged() event (which does not include
+	 * the items that were affected).
+	 * @see ChangeEventChangePolicy#rebuildChildren()
+	 */
+	final IdentityHashMap<TreeNodeValueModel<T>, List<TreeNodeValueModel<T>>> childrenLists;
+
+	/**
+	 * Map the children models to their parents.
+	 * We cache these so we can figure out the "real" source of the
+	 * list change events (the parent).
+	 * @see EventChangePolicy#parent()
+	 */
+	final IdentityHashMap<ListValueModel<TreeNodeValueModel<T>>, TreeNodeValueModel<T>> parents;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a tree model for the specified root.
+	 */
+	public TreeModelAdapter(PropertyValueModel<TreeNodeValueModel<T>> rootHolder) {
+		super();
+		if (rootHolder == null) {
+			throw new NullPointerException();
+		}
+		this.rootHolder = rootHolder;
+		this.rootListener = this.buildRootListener();
+		this.nodeStateListener = this.buildNodeStateListener();
+		this.nodeValueListener = this.buildNodeValueListener();
+		this.childrenListener = this.buildChildrenListener();
+		this.childrenLists = new IdentityHashMap<TreeNodeValueModel<T>, List<TreeNodeValueModel<T>>>();
+		this.parents = new IdentityHashMap<ListValueModel<TreeNodeValueModel<T>>, TreeNodeValueModel<T>>();
+	}
+
+	/**
+	 * Construct a tree model for the specified root.
+	 */
+	public TreeModelAdapter(TreeNodeValueModel<T> root) {
+		this(new StaticPropertyValueModel<TreeNodeValueModel<T>>(root));
+	}
+
+
+	// ********** initialization **********
+
+	protected PropertyChangeListener buildRootListener() {
+		return new AWTPropertyChangeListenerWrapper(this.buildRootListener_());
+	}
+
+	protected PropertyChangeListener buildRootListener_() {
+		return new PropertyChangeListener() {
+			@Override
+			public void propertyChanged(PropertyChangeEvent event) {
+				TreeModelAdapter.this.rootChanged();
+			}
+			@Override
+			public String toString() {
+				return "root listener";
+			}
+		};
+	}
+
+	protected PropertyChangeListener buildNodeValueListener() {
+		return new AWTPropertyChangeListenerWrapper(this.buildNodeValueListener_());
+	}
+
+	protected PropertyChangeListener buildNodeValueListener_() {
+		return new PropertyChangeListener() {
+			@Override
+			@SuppressWarnings("unchecked")
+			public void propertyChanged(PropertyChangeEvent event) {
+				TreeModelAdapter.this.nodeChanged((TreeNodeValueModel<T>) event.getSource());
+			}
+			@Override
+			public String toString() {
+				return "node value listener";
+			}
+		};
+	}
+
+	protected StateChangeListener buildNodeStateListener() {
+		return new AWTStateChangeListenerWrapper(this.buildNodeStateListener_());
+	}
+
+	protected StateChangeListener buildNodeStateListener_() {
+		return new StateChangeListener() {
+			@Override
+			@SuppressWarnings("unchecked")
+			public void stateChanged(StateChangeEvent event) {
+				TreeModelAdapter.this.nodeChanged((TreeNodeValueModel<T>) event.getSource());
+			}
+			@Override
+			public String toString() {
+				return "node state listener";
+			}
+		};
+	}
+
+	protected ListChangeListener buildChildrenListener() {
+		return new AWTListChangeListenerWrapper(this.buildChildrenListener_());
+	}
+
+	protected ListChangeListener buildChildrenListener_() {
+		return new ListChangeListener() {
+			@Override
+			public void itemsAdded(ListAddEvent event) {
+				new AddEventChangePolicy(event).addChildren();
+			}
+			@Override
+			public void itemsRemoved(ListRemoveEvent event) {
+				new RemoveEventChangePolicy(event).removeChildren();
+			}
+			@Override
+			public void itemsReplaced(ListReplaceEvent event) {
+				new ReplaceEventChangePolicy(event).replaceChildren();
+			}
+			@Override
+			public void itemsMoved(ListMoveEvent event) {
+				new MoveEventChangePolicy(event).moveChildren();
+			}
+			@Override
+			public void listCleared(ListClearEvent event) {
+				new ClearEventChangePolicy(event).clearChildren();
+			}
+			@Override
+			public void listChanged(ListChangeEvent event) {
+				new ChangeEventChangePolicy(event).rebuildChildren();
+			}
+			@Override
+			public String toString() {
+				return "children listener";
+			}
+		};
+	}
+
+
+	// ********** TreeModel implementation **********
+
+	@Override
+	public Object getRoot() {
+		return this.root;
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Object getChild(Object parent, int index) {
+		return ((TreeNodeValueModel<T>) parent).child(index);
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public int getChildCount(Object parent) {
+		return ((TreeNodeValueModel<T>) parent).childrenSize();
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public boolean isLeaf(Object node) {
+		return ((TreeNodeValueModel<T>) node).isLeaf();
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public void valueForPathChanged(TreePath path, Object newValue) {
+		((TreeNodeValueModel<T>) path.getLastPathComponent()).setValue((T) newValue);
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public int getIndexOfChild(Object parent, Object child) {
+		return ((TreeNodeValueModel<T>) parent).indexOfChild((TreeNodeValueModel<T>) child);
+	}
+
+	/**
+	 * Extend to start listening to the underlying model if necessary.
+	 */
+    @Override
+	public void addTreeModelListener(TreeModelListener l) {
+		if (this.hasNoTreeModelListeners()) {
+			this.engageModel();
+		}
+		super.addTreeModelListener(l);
+	}
+
+	/**
+	 * Extend to stop listening to the underlying model if appropriate.
+	 */
+    @Override
+	public void removeTreeModelListener(TreeModelListener l) {
+		super.removeTreeModelListener(l);
+		if (this.hasNoTreeModelListeners()) {
+			this.disengageModel();
+		}
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * Listen to the root and all the other nodes
+	 * in the underlying tree model.
+	 */
+	private void engageModel() {
+		this.rootHolder.addPropertyChangeListener(PropertyValueModel.VALUE, this.rootListener);
+		this.root = this.rootHolder.getValue();
+		if (this.root == null) {
+			throw new NullPointerException();	// the root cannot be null while we have listeners
+		}
+		this.engageNode(this.root);
+		this.addRoot();
+	}
+
+	/**
+	 * Add the root and all of the nodes to the underlying tree.
+	 */
+	private void addRoot() {
+		this.addNode(0, this.root);
+	}
+
+	/**
+	 * Stop listening to the root and all the other
+	 * nodes in the underlying tree model.
+	 */
+	private void disengageModel() {
+		this.removeRoot();
+		this.disengageNode(this.root);
+		this.root = null;
+		this.rootHolder.removePropertyChangeListener(PropertyValueModel.VALUE, this.rootListener);
+	}
+
+	/**
+	 * Remove the root and all of the nodes from the underlying tree.
+	 */
+	private void removeRoot() {
+		this.removeNode(0, this.root);
+	}
+
+	/**
+	 * The root has been swapped.
+	 * This method is a bit gnarly because the API for notifying listeners
+	 * that the root has changed is a bit inconsistent with that used for
+	 * non-root nodes.
+	 */
+	void rootChanged() {
+		TreeNodeValueModel<T> newRoot = this.rootHolder.getValue();
+		if (newRoot == null) {
+			throw new NullPointerException();	// the root cannot be null while we have listeners
+		}
+		// remove all the current root's children from the tree
+		// and remove the it from the internal tree
+		this.removeRoot();
+
+		// save the old root and swap in the new root
+		TreeNodeValueModel<T> oldRoot = this.root;
+		this.root = newRoot;
+
+		// we must be listening to both the old and new roots when we fire the event
+		// because their values can be affected by whether they have listeners
+		this.engageNode(this.root);
+		this.fireTreeRootReplaced(this.root);
+		// now we can stop listening to the old root
+		this.disengageNode(oldRoot);
+
+		// add the new root to the internal tree and
+		// add all its children to the tree also
+		this.addRoot();
+	}
+
+	/**
+	 * Either the "value" or the "state" of the specified node has changed,
+	 * forward notification to our listeners.
+	 */
+	void nodeChanged(TreeNodeValueModel<T> node) {
+		TreeNodeValueModel<T> parent = node.parent();
+		if (parent == null) {
+			this.fireTreeRootChanged(node);
+		} else {
+			this.fireTreeNodeChanged(parent.path(), parent.indexOfChild(node), node);
+		}
+	}
+
+	/**
+	 * Listen to the nodes, notify our listeners that the nodes were added,
+	 * and then add the nodes to our internal tree.
+	 * We must listen to the nodes before notifying anybody, because
+	 * adding a listener can change the value of a node.
+	 */
+	void addChildren(TreeNodeValueModel<T>[] path, int[] childIndices, TreeNodeValueModel<T>[] children) {
+		int len = childIndices.length;
+		for (int i = 0; i < len; i++) {
+			this.engageNode(children[i]);
+		}
+		this.fireTreeNodesInserted(path, childIndices, children);
+		for (int i = 0; i < len; i++) {
+			this.addNode(childIndices[i], children[i]);
+		}
+	}
+
+	/**
+	 * Listen to the node and its children model.
+	 */
+	private void engageNode(TreeNodeValueModel<T> node) {
+		node.addStateChangeListener(this.nodeStateListener);
+		node.addPropertyChangeListener(PropertyValueModel.VALUE, this.nodeValueListener);
+		node.childrenModel().addListChangeListener(ListValueModel.LIST_VALUES, this.childrenListener);
+	}
+
+	/**
+	 * Add the node to our internal tree;
+	 * then recurse down through the node's children,
+	 * adding them to the internal tree also.
+	 */
+	private void addNode(int index, TreeNodeValueModel<T> node) {
+		this.addNodeToInternalTree(node.parent(), index, node, node.childrenModel());
+		new NodeChangePolicy(node).addChildren();
+	}
+
+	/**
+	 * Add the specified node to our internal tree.
+	 */
+	private void addNodeToInternalTree(TreeNodeValueModel<T> parent, int index, TreeNodeValueModel<T> node, ListValueModel<TreeNodeValueModel<T>> childrenModel) {
+		List<TreeNodeValueModel<T>> siblings = this.childrenLists.get(parent);
+		if (siblings == null) {
+			siblings = new ArrayList<TreeNodeValueModel<T>>();
+			this.childrenLists.put(parent, siblings);
+		}
+		siblings.add(index, node);
+
+		this.parents.put(childrenModel, node);
+	}
+
+	/**
+	 * Remove nodes from our internal tree, notify our listeners that the
+	 * nodes were removed, then stop listening to the nodes.
+	 * We must listen to the nodes until after notifying anybody, because
+	 * removing a listener can change the value of a node.
+	 */
+	void removeChildren(TreeNodeValueModel<T>[] path, int[] childIndices, TreeNodeValueModel<T>[] children) {
+		int len = childIndices.length;
+		for (int i = 0; i < len; i++) {
+			// the indices slide down a notch each time we remove a child
+			this.removeNode(childIndices[i] - i, children[i]);
+		}
+		this.fireTreeNodesRemoved(path, childIndices, children);
+		for (int i = 0; i < len; i++) {
+			this.disengageNode(children[i]);
+		}
+	}
+
+	/**
+	 * First, recurse down through the node's children,
+	 * removing them from our internal tree;
+	 * then remove the node itself from our internal tree.
+	 */
+	private void removeNode(int index, TreeNodeValueModel<T> node) {
+		new NodeChangePolicy(node).removeChildren();
+		this.removeNodeFromInternalTree(node.parent(), index, node.childrenModel());
+	}
+
+	/**
+	 * Remove the specified node from our internal tree.
+	 */
+	private void removeNodeFromInternalTree(TreeNodeValueModel<T> parent, int index, ListValueModel<TreeNodeValueModel<T>> childrenModel) {
+		this.parents.remove(childrenModel);
+
+		List<TreeNodeValueModel<T>> siblings = this.childrenLists.get(parent);
+		siblings.remove(index);
+		if (siblings.isEmpty()) {
+			this.childrenLists.remove(parent);
+		}
+	}
+
+	/**
+	 * Stop listening to the node and its children model.
+	 */
+	private void disengageNode(TreeNodeValueModel<T> node) {
+		node.childrenModel().removeListChangeListener(ListValueModel.LIST_VALUES, this.childrenListener);
+		node.removePropertyChangeListener(PropertyValueModel.VALUE, this.nodeValueListener);
+		node.removeStateChangeListener(this.nodeStateListener);
+	}
+
+	void moveChildren(TreeNodeValueModel<T> parent, int targetIndex, int sourceIndex, int length) {
+		List<TreeNodeValueModel<T>> childrenList = this.childrenLists.get(parent);
+		ArrayList<TreeNodeValueModel<T>> temp = new ArrayList<TreeNodeValueModel<T>>(length);
+		for (int i = 0; i < length; i++) {
+			temp.add(childrenList.remove(sourceIndex));
+		}
+		childrenList.addAll(targetIndex, temp);
+
+		this.fireTreeStructureChanged(parent.path());
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.root);
+	}
+
+
+	// ********** inner classes **********
+
+	/**
+	 * Coalesce some of the common change policy behavior.
+	 */
+	abstract class ChangePolicy {
+
+		ChangePolicy() {
+			super();
+		}
+
+		/**
+		 * Add the current set of children.
+		 */
+		void addChildren() {
+			TreeModelAdapter.this.addChildren(this.parent().path(), this.childIndices(), this.childArray());
+		}
+
+		/**
+		 * Remove the current set of children.
+		 */
+		void removeChildren() {
+			TreeModelAdapter.this.removeChildren(this.parent().path(), this.childIndices(), this.childArray());
+		}
+
+		/**
+		 * Return an array of the indices of the current set of children,
+		 * which should be contiguous.
+		 */
+		int[] childIndices() {
+			return this.buildIndices(this.childrenStartIndex(), this.childrenSize());
+		}
+
+		/**
+		 * Return an array of the current set of children.
+		 */
+		TreeNodeValueModel<T>[] childArray() {
+			return this.buildArray(this.getChildren(), this.childrenSize());
+		}
+
+		/**
+		 * Build an array to hold the elements in the specified iterator.
+		 * If they are different sizes, something is screwed up...
+		 */
+		TreeNodeValueModel<T>[] buildArray(Iterable<TreeNodeValueModel<T>> elements, int size) {
+			@SuppressWarnings("unchecked")
+			TreeNodeValueModel<T>[] array = new TreeNodeValueModel[size];
+			int i = 0;
+			for (TreeNodeValueModel<T> element : elements) {
+				array[i++] = element;
+			}
+			return array;
+		}
+
+		/**
+		 * Return a set of indices, starting at zero and
+		 * continuing for the specified size.
+		 */
+		int[] buildIndices(int size) {
+			return buildIndices(0, size);
+		}
+
+		/**
+		 * Return a set of indices, starting at the specified index and
+		 * continuing for the specified size.
+		 */
+		int[] buildIndices(int start, int size) {
+			int[] indices = new int[size];
+			int index = start;
+			for (int i = 0; i < size; i++) {
+				indices[i] = index++;
+			}
+			return indices;
+		}
+
+		/**
+		 * Return the parent of the current set of children.
+		 */
+		abstract TreeNodeValueModel<T> parent();
+
+		/**
+		 * Return the starting index for the current set of children.
+		 */
+		abstract int childrenStartIndex();
+
+		/**
+		 * Return the size of the current set of children.
+		 */
+		abstract int childrenSize();
+
+		/**
+		 * Return the current set of children.
+		 */
+		abstract Iterable<TreeNodeValueModel<T>> getChildren();
+	}
+
+
+	/**
+	 * Wraps a ListEvent for adding, removing, replacing,
+	 * and changing children.
+	 */
+	/* CU private */ abstract class EventChangePolicy
+		extends ChangePolicy
+	{
+		final ListEvent event;
+
+		EventChangePolicy(ListEvent event) {
+			super();
+			this.event = event;
+		}
+
+		/**
+		 * Map the ListChangeEvent's source to the corresponding parent.
+		 */
+		@Override
+		TreeNodeValueModel<T> parent() {
+			return TreeModelAdapter.this.parents.get(this.event.getSource());
+		}
+	}
+
+
+	/**
+	 * Wraps a ListAddEvent for adding children.
+	 */
+	/* CU private */ class AddEventChangePolicy
+		extends EventChangePolicy
+	{
+		AddEventChangePolicy(ListAddEvent event) {
+			super(event);
+		}
+
+		private ListAddEvent getEvent() {
+			return (ListAddEvent) this.event;
+		}
+
+		/**
+		 * The ListAddEvent's item index is the children start index.
+		 */
+		@Override
+		int childrenStartIndex() {
+			return this.getEvent().getIndex();
+		}
+
+		/**
+		 * The ListAddEvent's size is the children size.
+		 */
+		@Override
+		int childrenSize() {
+			return this.getEvent().getItemsSize();
+		}
+
+		/**
+		 * The ListAddEvent's items are the children.
+		 */
+		@Override
+		@SuppressWarnings("unchecked")
+		Iterable<TreeNodeValueModel<T>> getChildren() {
+			return (Iterable<TreeNodeValueModel<T>>) this.getEvent().getItems();
+		}
+	}
+
+
+	/**
+	 * Wraps a ListRemoveEvent for adding children.
+	 */
+	/* CU private */ class RemoveEventChangePolicy
+		extends EventChangePolicy
+	{
+		RemoveEventChangePolicy(ListRemoveEvent event) {
+			super(event);
+		}
+
+		private ListRemoveEvent getEvent() {
+			return (ListRemoveEvent) this.event;
+		}
+
+		/**
+		 * The ListRemoveEvent's item index is the children start index.
+		 */
+		@Override
+		int childrenStartIndex() {
+			return this.getEvent().getIndex();
+		}
+
+		/**
+		 * The ListRemoveEvent's size is the children size.
+		 */
+		@Override
+		int childrenSize() {
+			return this.getEvent().getItemsSize();
+		}
+
+		/**
+		 * The ListRemoveEvent's items are the children.
+		 */
+		@Override
+		@SuppressWarnings("unchecked")
+		Iterable<TreeNodeValueModel<T>> getChildren() {
+			return (Iterable<TreeNodeValueModel<T>>) this.getEvent().getItems();
+		}
+	}
+
+
+	/**
+	 * Wraps a ListReplaceEvent for replacing children.
+	 */
+	/* CU private */ class ReplaceEventChangePolicy
+		extends EventChangePolicy
+	{
+		ReplaceEventChangePolicy(ListReplaceEvent event) {
+			super(event);
+		}
+
+		private ListReplaceEvent getEvent() {
+			return (ListReplaceEvent) this.event;
+		}
+
+		/**
+		 * The ListReplaceEvent's item index is the children start index.
+		 */
+		@Override
+		int childrenStartIndex() {
+			return this.getEvent().getIndex();
+		}
+
+		/**
+		 * The ListReplaceEvent's size is the children size.
+		 */
+		@Override
+		int childrenSize() {
+			return this.getEvent().getItemsSize();
+		}
+
+		/**
+		 * The ListReplaceEvent's items are the children.
+		 */
+		@Override
+		@SuppressWarnings("unchecked")
+		Iterable<TreeNodeValueModel<T>> getChildren() {
+			return (Iterable<TreeNodeValueModel<T>>) this.getEvent().getNewItems();
+		}
+
+		/**
+		 * Remove the old nodes and add the new ones.
+		 */
+		void replaceChildren() {
+			TreeNodeValueModel<T>[] parentPath = this.parent().path();
+			int[] childIndices = this.childIndices();
+			TreeModelAdapter.this.removeChildren(parentPath, childIndices, this.getOldChildren());
+			TreeModelAdapter.this.addChildren(parentPath, childIndices, this.childArray());
+		}
+
+		TreeNodeValueModel<T>[] getOldChildren() {
+			return this.buildArray(this.getOldItems(), this.getEvent().getItemsSize());
+		}
+
+		// minimized scope of suppressed warnings
+		@SuppressWarnings("unchecked")
+		protected Iterable<TreeNodeValueModel<T>> getOldItems() {
+			return (Iterable<TreeNodeValueModel<T>>) this.getEvent().getOldItems();
+		}
+	}
+
+
+	/**
+	 * Wraps a ListMoveEvent for moving children.
+	 */
+	/* CU private */ class MoveEventChangePolicy
+		extends EventChangePolicy
+	{
+		MoveEventChangePolicy(ListMoveEvent event) {
+			super(event);
+		}
+
+		private ListMoveEvent getEvent() {
+			return (ListMoveEvent) this.event;
+		}
+
+		void moveChildren() {
+			TreeModelAdapter.this.moveChildren(this.parent(), this.getEvent().getTargetIndex(), this.getEvent().getSourceIndex(), this.getEvent().getLength());
+		}
+
+		@Override
+		int childrenStartIndex() {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		int childrenSize() {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		Iterable<TreeNodeValueModel<T>> getChildren() {
+			throw new UnsupportedOperationException();
+		}
+	}
+
+
+	/**
+	 * Wraps a ListClearEvent for clearing children.
+	 */
+	/* CU private */ class ClearEventChangePolicy
+		extends EventChangePolicy
+	{
+		ClearEventChangePolicy(ListClearEvent event) {
+			super(event);
+		}
+
+		/**
+		 * Clear all the nodes.
+		 */
+		void clearChildren() {
+			TreeNodeValueModel<T> parent = this.parent();
+			TreeNodeValueModel<T>[] parentPath = parent.path();
+			List<TreeNodeValueModel<T>> childrenList = TreeModelAdapter.this.childrenLists.get(parent);
+			int[] childIndices = this.buildIndices(childrenList.size());
+			TreeNodeValueModel<T>[] childArray = this.buildArray(childrenList, childrenList.size());
+			TreeModelAdapter.this.removeChildren(parentPath, childIndices, childArray);
+		}
+
+		@Override
+		int childrenStartIndex() {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		int childrenSize() {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		Iterable<TreeNodeValueModel<T>> getChildren() {
+			throw new UnsupportedOperationException();
+		}
+	}
+
+
+	/**
+	 * Wraps a ListChangeEvent for clearing children.
+	 */
+	/* CU private */ class ChangeEventChangePolicy
+		extends EventChangePolicy
+	{
+		ChangeEventChangePolicy(ListChangeEvent event) {
+			super(event);
+		}
+
+		/**
+		 * Remove all the old nodes and add all the new nodes.
+		 */
+		void rebuildChildren() {
+			TreeNodeValueModel<T> parent = this.parent();
+			TreeNodeValueModel<T>[] parentPath = parent.path();
+			List<TreeNodeValueModel<T>> childrenList = TreeModelAdapter.this.childrenLists.get(parent);
+			int[] childIndices = this.buildIndices(childrenList.size());
+			TreeNodeValueModel<T>[] childArray = this.buildArray(childrenList, childrenList.size());
+			TreeModelAdapter.this.removeChildren(parentPath, childIndices, childArray);
+
+			childIndices = this.buildIndices(parent.childrenModel().size());
+			childArray = this.buildArray(parent.childrenModel(), parent.childrenSize());
+			TreeModelAdapter.this.addChildren(parentPath, childIndices, childArray);
+		}
+
+		@Override
+		int childrenStartIndex() {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		int childrenSize() {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		Iterable<TreeNodeValueModel<T>> getChildren() {
+			throw new UnsupportedOperationException();
+		}
+	}
+
+
+	/**
+	 * Wraps a TreeNodeValueModel for adding and removing its children.
+	 */
+	/* CU private */ class NodeChangePolicy
+		extends ChangePolicy
+	{
+		private final TreeNodeValueModel<T> node;
+
+		NodeChangePolicy(TreeNodeValueModel<T> node) {
+			super();
+			this.node = node;
+		}
+
+		/**
+		 * The node itself is the parent.
+		 */
+		@Override
+		TreeNodeValueModel<T> parent() {
+			return this.node;
+		}
+
+		/**
+		 * Since we will always be dealing with all of the node's
+		 * children, the children start index is always zero.
+		 */
+		@Override
+		int childrenStartIndex() {
+			return 0;
+		}
+
+		/**
+		 * Since we will always be dealing with all of the node's
+		 * children, the children size is always equal to the size
+		 * of the children model.
+		 */
+		@Override
+		int childrenSize() {
+			return this.node.childrenModel().size();
+		}
+
+		/**
+		 * Since we will always be dealing with all of the node's
+		 * children, the children are all the objects held by
+		 * the children model.
+		 */
+		@Override
+		Iterable<TreeNodeValueModel<T>> getChildren() {
+			return this.node.childrenModel();
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/AbstractNode.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/AbstractNode.java
index 6b9cc86..6b5c641 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/AbstractNode.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/AbstractNode.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -22,46 +22,48 @@
 import java.util.ListIterator;
 import java.util.Set;
 import java.util.Vector;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
-import org.eclipse.persistence.tools.utility.iterators.CloneListIterator;
-import org.eclipse.persistence.tools.utility.iterators.FilteringIterator;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.iterator.CloneIterator;
+import org.eclipse.persistence.tools.utility.iterator.CloneListIterator;
+import org.eclipse.persistence.tools.utility.iterator.FilteringIterator;
 import org.eclipse.persistence.tools.utility.model.AbstractModel;
 import org.eclipse.persistence.tools.utility.model.AspectChangeSupport;
 import org.eclipse.persistence.tools.utility.model.ChangeSupport;
 
 /**
- * Base class for Node classes.
- * Provides support for the following:
- *     initialization
- *     enforced object identity wrt #equals()/#hashCode()
- *     containment hierarchy (parent/child)
- *     user comment
- *     dirty flag
- *     problems
- *     sorting
- *
- * Typically, subclasses should consider implementing the following methods:
- *     the appropriate constructors
- *         (with the appropriately-restrictive type declaration for parent)
- *     #initialize()
- *     #initialize(Node parentNode)
- *     #checkParent(Node parentNode)
- *     #addChildrenTo(List list)
- *     #nodeRemoved(Node)
- *     #validator()
- *     #transientAspectNames() or
- *         #addTransientAspectNamesTo(Set transientAspectNames)
- *     #addProblemsTo(List currentProblems)
- *     #nonValidatedAspectNames()
- *         #addNonValidatedAspectNamesTo(Set nonValidatedAspectNames)
- *     #displayString()
- *     #toString(StringBuilder sb)
+ * Base class for {@link Node} classes.
+ * Provides support for the following:<ul>
+ * <li>initialization
+ * <li>enforced object identity wrt #equals()/#hashCode()
+ * <li>containment hierarchy (parent/child)
+ * <li>user comment
+ * <li>dirty flag
+ * <li>problems
+ * <li>sorting
+ * </ul>
+ * Typically, subclasses should consider implementing the following methods:<ul>
+ * <li>the appropriate constructors
+ *     (with the appropriately-restrictive type declaration for parent)
+ * <li>{@link #initialize()}
+ * <li>{@link #initialize(Node)}
+ * <li>{@link #checkParent(Node)}
+ * <li>{@link #addChildrenTo(List)}
+ * <li>{@link #nodeRemoved(Node)}
+ * <li>{@link #getValidator()}
+ * <li>{@link #transientAspectNames()} or
+ *     {@link #addTransientAspectNamesTo(Set)}
+ * <li>{@link #addProblemsTo(List)}
+ * <li>{@link #nonValidatedAspectNames()}
+ * <li>{@link #addNonValidatedAspectNamesTo(Set)}
+ * <li>{@link #displayString()}
+ * <li>{@link #toString(StringBuilder)}
+ * </ul>
  */
 @SuppressWarnings("nls")
-public abstract class AbstractNode extends AbstractModel
-                                   implements Node {
+public abstract class AbstractNode
+	extends AbstractModel
+	implements Node
+{
 
 	/** Containment hierarchy. */
 	private Node parent;  // pseudo-final
@@ -76,7 +78,6 @@
 	 * allowing for asynchronous modification from another thread.
 	 */
 	private Vector<Problem> problems;		// pseudo-final
-		private static final Object[] EMPTY_PROBLEM_MESSAGE_ARGUMENTS = new Object[0];
 
 	/**
 	 * Cache the node's "branch" problems, as calculated during validation.
@@ -90,6 +91,7 @@
 	/** User comment. */
 	private volatile String comment;
 
+
 	// ********** static fields **********
 
 	/**
@@ -104,6 +106,7 @@
 	 */
 	private static final HashMap<Class<? extends AbstractNode>, HashSet<String>> nonValidatedAspectNameSets = new HashMap<Class<? extends AbstractNode>, HashSet<String>>();
 
+
 	// ********** constructors **********
 
 	/**
@@ -125,7 +128,7 @@
 	 * @see #initialize(Node)
 	 */
 	protected void initialize() {
-		this.comment = StringTools.EMPTY_STRING;
+		this.comment = "";
 
 		// a new object is dirty, by definition
 		this.dirty = true;
@@ -191,7 +194,7 @@
 
 	/**
 	 * INTRA-TREE API?
-	 * Returns the node's parent in the containment hierarchy.
+	 * Return the node's parent in the containment hierarchy.
 	 * Most nodes must have a parent.
 	 * @see #children()
 	 */
@@ -215,7 +218,7 @@
 
 	/**
 	 * INTRA-TREE API?
-	 * Returns the node's children, which are also nodes.
+	 * Return the node's children, which are also nodes.
 	 * Do NOT override this method.
 	 * Override #addChildrenTo(List).
 	 * @see #getParent()
@@ -241,7 +244,7 @@
 
 	/**
 	 * INTRA-TREE API?
-	 * Returns the containment hierarchy's root node.
+	 * Return the containment hierarchy's root node.
 	 * Most nodes must have a root.
 	 * @see #getParent()
 	 * NB: Assume the root has no parent.
@@ -253,7 +256,7 @@
 	}
 
 	/**
-	 * Returns whether the node is a descendant of the specified node.
+	 * Return whether the node is a descendant of the specified node.
 	 * By definition, a node is a descendant of itself.
 	 */
 	@Override
@@ -266,7 +269,7 @@
 	}
 
 	/**
-	 * Returns a collection holding all the node's "references", and all
+	 * Return a collection holding all the node's "references", and all
 	 * the node's descendants' "references". "References" are
 	 * objects that are "referenced" by another object, as opposed
 	 * to "owned" by another object.
@@ -285,7 +288,7 @@
 	 * to "owned" by another object.
 	 * This method is of particular concern to Handles, since most
 	 * (hopefully all) "references" are held by Handles.
-	 * @see Reference
+	 * @see org.eclipse.jpt.common.utility.node.Node.Reference
 	 * @see #children()
 	 */
 	@Override
@@ -297,7 +300,7 @@
 	}
 
 	/**
-	 * Returns all the nodes in the object's branch of the tree,
+	 * Return all the nodes in the object's branch of the tree,
 	 * including the node itself. The nodes will probably returned
 	 * in "depth-first" order.
 	 * Only really used for testing and debugging.
@@ -347,7 +350,7 @@
 
 	/**
 	 * convenience method
-	 * Returns whether node1 is a descendant of node2;
+	 * return whether node1 is a descendant of node2;
 	 * node1 can be null
 	 */
 	protected boolean nodeIsDescendantOf(Node node1, Node node2) {
@@ -377,7 +380,7 @@
 	// ********** user comment **********
 
 	/**
-	 * Returns the object's user comment.
+	 * Return the object's user comment.
 	 */
 	@Override
 	public final String comment() {
@@ -419,7 +422,7 @@
 
 	/**
 	 * INTRA-TREE API
-	 * Returns a validator that will be invoked whenever a
+	 * Return a validator that will be invoked whenever a
 	 * "validated" aspect of the node tree changes.
 	 * Typically only the root node directly holds a validator.
 	 * NB: Root node model implementations will need to override this method.
@@ -450,7 +453,7 @@
 	// ********** dirty flag support **********
 
 	/**
-	 * Returns whether any persistent aspects of the object
+	 * Return whether any persistent aspects of the object
 	 * have changed since the object was last read or saved.
 	 * This does NOT include changes to the object's descendants.
 	 */
@@ -459,7 +462,7 @@
 	}
 
 	/**
-	 * Returns whether any persistent aspects of the object,
+	 * Return whether any persistent aspects of the object,
 	 * or any of its descendants, have changed since the object and
 	 * its descendants were last read or saved.
 	 */
@@ -469,7 +472,7 @@
 	}
 
 	/**
-	 * Returns whether the object is unmodified
+	 * Return whether the object is unmodified
 	 * since it was last read or saved.
 	 * This does NOT include changes to the object's descendants.
 	 */
@@ -478,7 +481,7 @@
 	}
 
 	/**
-	 * Returns whether the object and all of its descendants
+	 * Return whether the object and all of its descendants
 	 * are unmodified since the object and
 	 * its descendants were last read or saved.
 	 */
@@ -620,7 +623,7 @@
 	}
 
 	/**
-	 * Returns a set of the object's transient aspect names.
+	 * Return a set of the object's transient aspect names.
 	 * These are the aspects that, when they change, will NOT cause the
 	 * object to be marked dirty.
 	 * If you need instance-based calculation of your transient aspects,
@@ -656,7 +659,7 @@
 	}
 
 	/**
-	 * Returns the dirty nodes in the object's branch of the tree,
+	 * Return the dirty nodes in the object's branch of the tree,
 	 * including the node itself (if appropriate).
 	 * Only really used for testing and debugging.
 	 */
@@ -673,7 +676,7 @@
 	// ********** problems **********
 
 	/**
-	 * Returns the node's problems.
+	 * Return the node's problems.
 	 * This does NOT include the problems of the node's descendants.
 	 * @see #branchProblems()
 	 */
@@ -682,7 +685,7 @@
 	}
 
 	/**
-	 * Returns the size of the node's problems.
+	 * Return the size of the node's problems.
 	 * This does NOT include the problems of the node's descendants.
 	 * @see #branchProblemsSize()
 	 */
@@ -691,7 +694,7 @@
 	}
 
 	/**
-	 * Returns whether the node has problems
+	 * Return whether the node has problems
 	 * This does NOT include the problems of the node's descendants.
 	 * @see #hasBranchProblems()
 	 */
@@ -700,7 +703,7 @@
 	}
 
 	/**
-	 * Returns all the node's problems along with all the
+	 * Return all the node's problems along with all the
 	 * node's descendants' problems.
 	 */
 	@Override
@@ -709,7 +712,7 @@
 	}
 
 	/**
-	 * Returns the size of all the node's problems along with all the
+	 * Return the size of all the node's problems along with all the
 	 * node's descendants' problems.
 	 */
 	@Override
@@ -718,7 +721,7 @@
 	}
 
 	/**
-	 * Returns whether the node or any of its descendants have problems.
+	 * Return whether the node or any of its descendants have problems.
 	 */
 	@Override
 	public final boolean hasBranchProblems() {
@@ -735,7 +738,7 @@
 	}
 
 	protected final Problem buildProblem(String messageKey, int messageType) {
-		return this.buildProblem(messageKey, messageType, EMPTY_PROBLEM_MESSAGE_ARGUMENTS);
+		return this.buildProblem(messageKey, messageType, ObjectTools.EMPTY_OBJECT_ARRAY);
 	}
 
 	/**
@@ -763,7 +766,7 @@
 	 * INTRA-TREE API
 	 * Validate the node and all of its descendants,
 	 * and update their sets of "branch" problems.
-	 * Returns true if the collection of "branch" problems has changed.
+	 * Return true if the collection of "branch" problems has changed.
 	 * This method is for internal use only; it is not for
 	 * client use.
 	 */
@@ -772,7 +775,7 @@
 		// rebuild "branch" problems in children first
 		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
 			Node child = stream.next();		// pull out the child to ease debugging
-			// * Returns value because we are going to rebuild our "branch"
+			// ignore the return value because we are going to rebuild our "branch"
 			// problems no matter what, to see if they have changed
 			child.validateBranchInternal();
 		}
@@ -801,7 +804,7 @@
 	}
 
 	/**
-	 * Returns whether they have
+	 * Rebuild the "branch" problems and return whether they have
 	 * changed.
 	 * NB: The entire collection of "branch" problems must be re-calculated
 	 * with EVERY "significant" change - we cannot keep it in sync via
@@ -880,7 +883,7 @@
 	 * INTRA-TREE API
 	 * Clear the node's "branch" problems and the "branch"
 	 * problems of all of its descendants.
-	 * Returns true if the collection of "branch" problems has changed.
+	 * Return true if the collection of "branch" problems has changed.
 	 * This method is for internal use only; it is not for
 	 * client use.
 	 */
@@ -891,7 +894,7 @@
 		}
 		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
 			Node child = stream.next();		// pull out the child to ease debugging
-			// * Returns value because we are going to clear our "branch"
+			// ignore the return value because we are going to clear our "branch"
 			// problems no matter what
 			child.clearAllBranchProblemsInternal();
 		}
@@ -903,7 +906,7 @@
 	}
 
 	/**
-	 * Returns whether a change to specified aspect requires a re-validation
+	 * Return whether a change to specified aspect requires a re-validation
 	 * of the node's tree.
 	 */
 	private boolean aspectChangeRequiresValidation(String aspectName) {
@@ -915,7 +918,7 @@
 	}
 
 	/**
-	 * Returns a set of the object's "non-validated" aspect names.
+	 * Return a set of the object's "non-validated" aspect names.
 	 * These are the aspects that, when they change, will NOT cause the
 	 * object (or its containing tree) to be validated, i.e. checked for problems.
 	 * If you need instance-based calculation of your "non-validated" aspects,
@@ -955,7 +958,7 @@
 	// ********** display methods **********
 
 	/**
-	 * Returns a developer-friendly String. If you want something useful for
+	 * Return a developer-friendly String. If you want something useful for
 	 * displaying in a user interface, use #displayString().
 	 * If you want to give more information in your #toString(),
 	 * override #toString(StringBuilder sb).
@@ -967,4 +970,4 @@
 	public final String toString() {
 		return super.toString();
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/AsynchronousValidator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/AsynchronousValidator.java
index 0c336b9..2e9ad82 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/AsynchronousValidator.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/AsynchronousValidator.java
@@ -1,24 +1,24 @@
 /*******************************************************************************
- * Copyright (c) 2007 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.node;
 
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.SynchronizedBoolean;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.reference.SynchronizedBoolean;
 
 /**
- * This implementation of the PluggableValidator.Delegate interface
- * simply sets a shared "validate" flag to true. This should trigger a
+ * This implementation of the {@link PluggableValidator.Delegate} interface
+ * simply sets a shared "validate" flag to <code>true</code>. This should trigger a
  * separate "validation" thread to begin validating the appropriate
  * branch of nodes.
  */
@@ -34,6 +34,9 @@
 	 */
 	public AsynchronousValidator(SynchronizedBoolean validateFlag) {
 		super();
+		if (validateFlag == null) {
+			throw new NullPointerException();
+		}
 		this.validateFlag = validateFlag;
 	}
 
@@ -49,7 +52,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.validateFlag);
+		return ObjectTools.toString(this, this.validateFlag);
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/DefaultProblem.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/DefaultProblem.java
index 1949c9d..a1a77c3 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/DefaultProblem.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/DefaultProblem.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2008 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
@@ -14,11 +14,10 @@
 package org.eclipse.persistence.tools.utility.node;
 
 import java.util.Arrays;
-
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
- * This class is a straightforward implementation of the Problem interface.
+ * This class is a straightforward implementation of the {@link Problem} interface.
  */
 public class DefaultProblem
 	implements Problem
@@ -28,8 +27,12 @@
 	private final int messageType;
 	private final Object[] messageArguments;
 
+
 	DefaultProblem(Node source, String messageKey, int messageType, Object[] messageArguments) {
 		super();
+		if ((source == null) || (messageKey == null) || (messageArguments == null)) {
+			throw new NullPointerException();
+		}
 		this.source = source;
 		this.messageKey = messageKey;
 		this.messageType = messageType;
@@ -87,7 +90,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.messageKey);
+		return ObjectTools.toString(this, this.messageKey);
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/Node.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/Node.java
index 17271c1..f99ee52 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/Node.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/Node.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -17,18 +17,23 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
-
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.model.Model;
 
 /**
  * This interface defines the methods that must be implemented
  * by any class whose instances are to be part of a containment hierarchy
  * that supports a "dirty" state and validation "problems".
- *
- * Note: Methods marked "INTRA-TREE API" are typically only used by
+ * <p>
+ * <strong>NB:</strong> Methods marked "INTRA-TREE API" are typically only used by
  * the nodes themselves, as opposed to clients of the nodes. These
  * methods are called by a node on either its parent or its children.
+ * <p>
+ * 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.
  */
 @SuppressWarnings("nls")
 public interface Node extends Model {
@@ -38,7 +43,8 @@
 
 	/**
 	 * INTRA-TREE API?
-	 * Returns the node's parent in the containment hierarchy.
+	 * <p>
+	 * Return the node's parent in the containment hierarchy.
 	 * Most nodes must have a parent. The parent is immutable.
 	 * @see #children()
 	 */
@@ -46,27 +52,30 @@
 
 	/**
 	 * INTRA-TREE API?
-	 * Returns the node's children, which are also nodes.
+	 * <p>
+	 * Return the node's children, which are also nodes.
 	 * @see #getParent()
 	 */
 	Iterator<Node> children();
 
 	/**
 	 * INTRA-TREE API?
-	 * Returns the containment hierarchy's root node.
+	 * <p>
+	 * Return the containment hierarchy's root node.
 	 * Most nodes must have a root.
 	 * @see #getParent()
 	 */
 	Node root();
 
 	/**
-	 * Returns whether the node is a descendant of the specified node.
+	 * Return whether the node is a descendant of the specified node.
 	 * By definition, a node is a descendant of itself.
 	 */
 	boolean isDescendantOf(Node node);
 
 	/**
 	 * INTRA-TREE API
+	 * <p>
 	 * Add the node's "references", and all the node's descendants'
 	 * "references", to the specified collection. "References" are
 	 * objects that are "referenced" by another object, as opposed
@@ -80,16 +89,19 @@
 
 	/**
 	 * INTRA-TREE API?
+	 * <p>
 	 * Add all the nodes in the object's branch of the tree,
 	 * including the node itself, to the specified collection.
 	 * Only really used for testing and debugging.
 	 */
 	void addAllNodesTo(Collection<Node> nodes);
 
+
 	// ********** model synchronization support **********
 
 	/**
 	 * INTRA-TREE API
+	 * <p>
 	 * This is a general notification that the specified node has been
 	 * removed from the tree. The node receiving this notification
 	 * should perform any necessary updates to remain in synch
@@ -101,6 +113,7 @@
 
 	/**
 	 * INTRA-TREE API
+	 * <p>
 	 * This is a general notification that the specified node has been
 	 * renamed. The node receiving this notification should mark its
 	 * branch dirty if necessary (i.e. it references the renamed node
@@ -114,7 +127,7 @@
 	// ********** dirty flag support **********
 
 	/**
-	 * Returns whether any persistent aspects of the node,
+	 * Return whether any persistent aspects of the node,
 	 * or any of its descendants, have changed since the node and
 	 * its descendants were last read or saved.
 	 */
@@ -123,6 +136,7 @@
 
 	/**
 	 * INTRA-TREE API
+	 * <p>
 	 * Mark the node and its parent as dirty branches.
 	 * This message is propagated up the containment
 	 * tree when a particular node becomes dirty.
@@ -140,6 +154,7 @@
 
 	/**
 	 * INTRA-TREE API
+	 * <p>
 	 * A child node's branch has been marked clean. If the node
 	 * itself is clean and if all of its children are also clean, the
 	 * node's branch can be marked clean. Then, if the node's
@@ -151,6 +166,7 @@
 
 	/**
 	 * INTRA-TREE API
+	 * <p>
 	 * Mark the node and all its descendants as clean.
 	 * Typically used when the node has just been
 	 * read in or written out.
@@ -160,11 +176,13 @@
 	 */
 	void cascadeMarkEntireBranchClean();
 
+
 	// ********** problems **********
 
 	/**
 	 * INTRA-TREE API
-	 * Returns a validator that will be invoked whenever a
+	 * <p>
+	 * Return a validator that will be invoked whenever a
 	 * "validated" aspect of the node tree changes.
 	 * Typically only the root node directly holds a validator.
 	 */
@@ -180,9 +198,10 @@
 	/**
 	 * Validate the node and its descendants.
 	 * This is an explicit request invoked by a client; and it will
-	 * typically be followed by a call to one of the following methods:
-	 * 	#branchProblems()
-	 * 	#hasBranchProblems()
+	 * typically be followed by a call to one of the following methods:<ul>
+	 * <li>{@link #branchProblems()}
+	 * <li>{@link #hasBranchProblems()}
+	 * </ul>
 	 * Whether the node maintains its problems on the fly
 	 * or waits until this method is called is determined by the
 	 * implementation.
@@ -192,46 +211,49 @@
 
 	/**
 	 * INTRA-TREE API
+	 * <p>
 	 * Validate the node and all of its descendants,
 	 * and update their sets of "branch" problems.
-	 * Returns true if the collection of "branch" problems has changed.
+	 * Return true if the collection of "branch" problems has changed.
 	 * This method is for internal use only; it is not for
 	 * client use.
 	 */
 	boolean validateBranchInternal();
 
 	/**
-	 * Returns all the node's problems along with all the
+	 * Return all the node's problems along with all the
 	 * node's descendants' problems.
 	 */
 	ListIterator<Problem> branchProblems();
 		String BRANCH_PROBLEMS_LIST = "branchProblems";
 
 	/**
-	 * Returns the size of all the node's problems along with all the
+	 * Return the size of all the node's problems along with all the
 	 * node's descendants' problems.
 	 */
 	int branchProblemsSize();
 
 	/**
-	 * Returns whether the node or any of its descendants have problems.
+	 * Return whether the node or any of its descendants have problems.
 	 */
 	boolean hasBranchProblems();
 		String HAS_BRANCH_PROBLEMS_PROPERTY = "hasBranchProblems";
 
 	/**
-	 * Returns whether the node contains the specified branch problem.
+	 * Return whether the node contains the specified branch problem.
 	 */
 	boolean containsBranchProblem(Problem problem);
 
 	/**
 	 * INTRA-TREE API
+	 * <p>
 	 * Something changed, rebuild the node's collection of branch problems.
 	 */
 	void rebuildBranchProblems();
 
 	/**
 	 * INTRA-TREE API
+	 * <p>
 	 * Add the node's problems, and all the node's descendants'
 	 * problems, to the specified list.
 	 * A call to this method should be immediately preceded by a call to
@@ -249,18 +271,20 @@
 
 	/**
 	 * INTRA-TREE API
+	 * <p>
 	 * Clear the node's "branch" problems and the "branch"
 	 * problems of all of its descendants.
-	 * Returns true if the collection of "branch" problems has changed.
+	 * Return true if the collection of "branch" problems has changed.
 	 * This method is for internal use only; it is not for
 	 * client use.
 	 */
 	boolean clearAllBranchProblemsInternal();
 
+
 	// ********** comment **********
 
 	/**
-	 * Returns the user comment concerning the node.
+	 * Return the user comment concerning the node.
 	 */
 	String comment();
 		String COMMENT_PROPERTY = "comment";
@@ -270,13 +294,15 @@
 	 */
 	void setComment(String comment);
 
+
 	// ********** displaying/sorting **********
 
 	/**
-	 * Returns a string representation of the model, suitable for sorting.
+	 * Return a string representation of the model, suitable for sorting.
 	 */
 	String displayString();
 
+
 	// ********** sub-interfaces **********
 
 	/**
@@ -284,31 +310,29 @@
 	 * @see Node#addBranchReferencesTo(java.util.Collection)
 	 */
 	interface Reference {
-
 		/**
-		 * Returns the "source" node of the reference, i.e. the node that
+		 * Return the "source" node of the reference, i.e. the node that
 		 * references the "target" node.
 		 */
 		Node source();
 
 		/**
-		 * Returns the "target" node of the reference, i.e. the node that
+		 * Return the "target" node of the reference, i.e. the node that
 		 * is referenced by the "source" node.
 		 */
 		Node target();
-
 	}
 
 
 	/**
 	 * A validator will validate a node as appropriate.
-	 * Typically the validation will
-	 * 	- occur whenever a node has changed
-	 * 	- encompass the entire tree containing the node
-	 * 	- execute asynchronously
+	 * Typically the validation will<ul>
+	 * <li>occur whenever a node has changed
+	 * <li>encompass the entire tree containing the node
+	 * <li>execute asynchronously
+	 * </ul>
 	 */
 	interface Validator {
-
 		/**
 		 * A "significant" aspect has changed;
 		 * validate the node as appropriate
@@ -329,17 +353,18 @@
 		 * called after a matching call to #pause().
 		 */
 		void resume();
-
 	}
 
 
 	// ********** helper implementations **********
 
 	/**
-	 * Straightforward implementation of the Reference interface
+	 * Straightforward implementation of the {@link Reference} interface
 	 * defined above.
 	 */
-	public class SimpleReference implements Reference {
+	public class SimpleReference
+		implements Reference
+	{
 		private Node source;
 		private Node target;
 		public SimpleReference(Node source, Node target) {
@@ -360,7 +385,7 @@
 		}
 		@Override
 		public String toString() {
-			return StringTools.buildToStringFor(this, this.source + " => " + this.target);
+			return ObjectTools.toString(this, this.source + " => " + this.target);
 		}
 	}
 
@@ -375,5 +400,4 @@
 				return "Node.NULL_VALIDATOR";
 			}
 		};
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/PluggableValidator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/PluggableValidator.java
index e0d8ba8..a93a3d3 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/PluggableValidator.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/PluggableValidator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,12 +14,12 @@
 package org.eclipse.persistence.tools.utility.node;
 
 import java.io.Serializable;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.SynchronizedBoolean;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.reference.SynchronizedBoolean;
 
 /**
- * This implementation of the Validator interface implements the
+ * This implementation of the {@link org.eclipse.jpt.common.utility.node.Node.Validator}
+ * interface implements the
  * pause/resume portion of the protocol, but delegates the actual
  * validation to a "pluggable" delegate.
  */
@@ -31,6 +31,7 @@
 	private boolean validateOnResume;
 	private final Delegate delegate;
 
+
 	/**
 	 * Convenience factory method.
 	 */
@@ -50,6 +51,9 @@
 	 */
 	public PluggableValidator(Delegate delegate) {
 		super();
+		if (delegate == null) {
+			throw new NullPointerException();
+		}
 		this.pause = false;
 		this.validateOnResume = false;
 		this.delegate = delegate;
@@ -87,7 +91,7 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.delegate);
+		return ObjectTools.toString(this, this.delegate);
 	}
 
 
@@ -103,6 +107,7 @@
 		 */
 		void validate();
 
+
 		/**
 		 * This delegate does nothing.
 		 */
@@ -123,7 +128,7 @@
 			}
 			@Override
 			public String toString() {
-				return StringTools.buildSingletonToString(this);
+				return ObjectTools.singletonToString(this);
 			}
 			private static final long serialVersionUID = 1L;
 			private Object readResolve() {
@@ -132,4 +137,4 @@
 			}
 		}
 	}
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/Problem.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/Problem.java
index 3d0584f..8887d22 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/Problem.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/Problem.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -14,32 +14,38 @@
 package org.eclipse.persistence.tools.utility.node;
 
 /**
- * Define an interface describing the problems associated with a node.
+ * Define an interface describing the problems associated with a {@link Node}.
+ * <p>
+ * 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 Problem {
 
 	/**
-	 * Returns the node most closely associated with the problem.
+	 * Return the node most closely associated with the problem.
 	 */
 	Node source();
 
 	/**
-	 * Returns a key that can be used to uniquely identify the problem's message.
+	 * Return a key that can be used to uniquely identify the problem's message.
 	 */
 	String messageKey();
 
 	/**
-	 * Returns the arguments associate with the problem's message.
+	 * Return the arguments associate with the problem's message.
 	 */
 	Object[] messageArguments();
 
 	/**
-	 * Returns the type of the identified problem's message
+	 * Return the type of the identified problem's message
 	 */
 	int messageType();
 
 	/**
-	 * Returns whether the problem is equal to the specified object.
+	 * Return whether the problem is equal to the specified object.
 	 * It is equal if the specified object is a implementation of the
 	 * Problem interface and its source, message key, and message
 	 * arguments are all equal to this problem's.
@@ -48,7 +54,7 @@
 	boolean equals(Object o);
 
 	/**
-	 * Returns the problem's hash code, which should calculated as an
+	 * Return the problem's hash code, which should calculated as an
 	 * XOR of the source's hash code and the message key's hash code.
 	 */
 	@Override
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/SynchronousValidator.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/SynchronousValidator.java
index e33cce5..c280db7 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/SynchronousValidator.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/node/SynchronousValidator.java
@@ -1,24 +1,24 @@
 /*******************************************************************************
- * Copyright (c) 2007 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
  * and the Eclipse Distribution License is available at
  * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
+ *
  * Contributors:
  *     Oracle - initial API and implementation
  *
  ******************************************************************************/
 package org.eclipse.persistence.tools.utility.node;
 
-import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 
 /**
- * This implementation of the PluggableValidator.Delegate interface
+ * This implementation of the {@link PluggableValidator.Delegate} interface
  * will validate the node immediately.
- * 
+ * <p>
  * This is useful for debugging in a single thread or generating
  * problem reports.
  */
@@ -33,6 +33,9 @@
 	 */
 	public SynchronousValidator(Node node) {
 		super();
+		if (node == null) {
+			throw new NullPointerException();
+		}
 		this.node = node;
 	}
 
@@ -43,7 +46,6 @@
 
 	@Override
 	public String toString() {
-		return StringTools.buildToStringFor(this, this.node);
+		return ObjectTools.toString(this, this.node);
 	}
-
-}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/prefs/NullPreferences.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/prefs/NullPreferences.java
new file mode 100644
index 0000000..8e01f41
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/prefs/NullPreferences.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.prefs;
+
+import java.util.prefs.AbstractPreferences;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.StringTools;
+
+/**
+ * An implementation of the JDK {@link Preferences} that does nothing,
+ * in a reasonable fashion.
+ */
+public class NullPreferences
+	extends AbstractPreferences
+{
+	// singleton
+	private static final Preferences INSTANCE = new NullPreferences();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static Preferences instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private NullPreferences() {
+		super(null, StringTools.EMPTY_STRING);
+	}
+
+	@Override
+	protected void putSpi(String key, String value) {
+		// NOP
+	}
+
+	@Override
+	protected String getSpi(String key) {
+		return null;
+	}
+
+	@Override
+	protected void removeSpi(String key) {
+		// NOP
+	}
+
+	@Override
+	protected void removeNodeSpi() throws BackingStoreException {
+		// NOP
+	}
+
+	@Override
+	protected String[] keysSpi() throws BackingStoreException {
+		return StringTools.EMPTY_STRING_ARRAY;
+	}
+
+	@Override
+	protected String[] childrenNamesSpi() throws BackingStoreException {
+		return StringTools.EMPTY_STRING_ARRAY;
+	}
+
+	@Override
+	protected AbstractPreferences childSpi(String name) {
+		return this;
+	}
+
+	@Override
+	protected void syncSpi() throws BackingStoreException {
+		// NOP
+	}
+
+	@Override
+	protected void flushSpi() throws BackingStoreException {
+		// NOP
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.singletonToString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/AbstractBooleanReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/AbstractBooleanReference.java
new file mode 100644
index 0000000..4e33682
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/AbstractBooleanReference.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+/**
+ * Convenience abstract class for boolean reference implementations.
+ * Subclasses need only implement<ul>
+ * <li>{@link #getValue()}
+ * </ul>
+ */
+public abstract class AbstractBooleanReference
+	implements BooleanReference
+{
+	protected AbstractBooleanReference() {
+		super();
+	}
+
+	@Override
+	public boolean is(boolean value) {
+		return this.getValue() == value;
+	}
+
+	@Override
+	public boolean isNot(boolean value) {
+		return this.getValue() != value;
+	}
+
+	@Override
+	public boolean isTrue() {
+		return this.getValue();
+	}
+
+	@Override
+	public boolean isFalse() {
+		return ! this.getValue();
+	}
+
+
+	// ********** standard methods **********
+
+	/**
+	 * Object identity is critical to boolean references.
+	 * There is no reason for two different boolean references to be
+	 * <em>equal</em>.
+	 *
+	 * @see #is(boolean)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		return super.equals(obj);
+	}
+
+	/**
+	 * @see #equals(Object)
+	 */
+	@Override
+	public int hashCode() {
+		return super.hashCode();
+	}
+
+	@Override
+	public String toString() {
+		return '[' + String.valueOf(this.getValue()) + ']';
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/AbstractModifiableBooleanReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/AbstractModifiableBooleanReference.java
new file mode 100644
index 0000000..5956a10
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/AbstractModifiableBooleanReference.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+/**
+ * Convenience abstract class for modifiable boolean reference implementations.
+ * Subclasses need only implement<ul>
+ * <li>{@link #getValue()}
+ * <li>{@link #setValue(boolean)}
+ * </ul>
+ */
+public abstract class AbstractModifiableBooleanReference
+	extends AbstractBooleanReference
+	implements ModifiableBooleanReference
+{
+	protected AbstractModifiableBooleanReference() {
+		super();
+	}
+
+	@Override
+	public boolean flip() {
+		return this.setValue( ! this.getValue());
+	}
+
+	@Override
+	public boolean setNot(boolean value) {
+		return this.setValue( ! value);
+	}
+
+	@Override
+	public boolean setTrue() {
+		return this.setValue(true);
+	}
+
+	@Override
+	public boolean setFalse() {
+		return this.setValue(false);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/BooleanReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/BooleanReference.java
new file mode 100644
index 0000000..2c1be49
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/BooleanReference.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+import java.io.Serializable;
+
+/**
+ * Interface for a container for holding a <code>boolean</code> that cannot be
+ * changed by clients.
+ * <p>
+ * 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.
+ *
+ * @see ModifiableBooleanReference
+ */
+@SuppressWarnings("nls")
+public interface BooleanReference {
+
+	/**
+	 * Return the current <code>boolean</code> value.
+	 */
+	boolean getValue();
+
+	/**
+	 * Return whether the current <code>boolean</code> value is equal to the
+	 * specified value.
+	 */
+	boolean is(boolean value);
+
+	/**
+	 * Return whether the current <code>boolean</code> value is not equal to
+	 * the specified value.
+	 */
+	boolean isNot(boolean value);
+
+	/**
+	 * Return whether the current <code>boolean</code> value is
+	 * <code>true</code>.
+	 */
+	boolean isTrue();
+
+	/**
+	 * Return whether the current <code>boolean</code> value is
+	 * <code>false</code>.
+	 */
+	boolean isFalse();
+
+
+	/**
+	 * Convenience method.
+	 */
+	final class Value {
+		public static BooleanReference of(boolean value) {
+			return value ? True.instance() : False.instance();
+		}
+	}
+
+
+	/**
+	 * Singleton implementation of the read-only boolean reference interface
+	 * whose value is always <code>true</code>.
+	 */
+	final class True
+		implements BooleanReference, Serializable
+	{
+		public static final BooleanReference INSTANCE = new True();
+
+		public static BooleanReference instance() {
+			return INSTANCE;
+		}
+
+		// ensure single instance
+		private True() {
+			super();
+		}
+
+		@Override
+		public boolean getValue() {
+			return true;
+		}
+
+		@Override
+		public boolean is(boolean value) {
+			return value;
+		}
+
+		@Override
+		public boolean isNot(boolean value) {
+			return ! value;
+		}
+
+		@Override
+		public boolean isTrue() {
+			return true;
+		}
+
+		@Override
+		public boolean isFalse() {
+			return false;
+		}
+
+		@Override
+		public String toString() {
+			return "[true]";
+		}
+
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+
+
+	/**
+	 * Singleton implementation of the read-only boolean reference interface
+	 * whose value is always <code>false</code>.
+	 */
+	final class False
+		implements BooleanReference, Serializable
+	{
+		public static final BooleanReference INSTANCE = new False();
+
+		public static BooleanReference instance() {
+			return INSTANCE;
+		}
+
+		// ensure single instance
+		private False() {
+			super();
+		}
+
+		@Override
+		public boolean getValue() {
+			return false;
+		}
+
+		@Override
+		public boolean is(boolean value) {
+			return ! value;
+		}
+
+		@Override
+		public boolean isNot(boolean value) {
+			return value;
+		}
+
+		@Override
+		public boolean isTrue() {
+			return false;
+		}
+
+		@Override
+		public boolean isFalse() {
+			return true;
+		}
+
+		@Override
+		public String toString() {
+			return "[false]";
+		}
+
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/FlaggedObjectReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/FlaggedObjectReference.java
new file mode 100644
index 0000000..d1d476a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/FlaggedObjectReference.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+/**
+ * Provide a container for passing an object that can be changed by the
+ * recipient. If the value is set at any time after construction of the
+ * reference, the reference is marked "set". This allows the client to
+ * detect whether the server/recipient ever set the value, even if it remains
+ * unchanged. This is particularly useful when the value can be set to
+ * <code>null</code>.
+ * <p>
+ * The reference can be set multiple times, but it can
+ * never be "unset" once it is "set".
+ */
+public class FlaggedObjectReference<V>
+	extends SimpleObjectReference<V>
+{
+	private volatile boolean set = false;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Create an object reference with the specified initial value.
+	 */
+	public FlaggedObjectReference(V value) {
+		super(value);
+	}
+
+	/**
+	 * Create an object reference with an initial value of
+	 * <code>null</code>.
+	 */
+	public FlaggedObjectReference() {
+		super();
+	}
+
+
+	// ********** set **********
+
+	public boolean isSet() {
+		return this.set;
+	}
+
+
+	// ********** overrides **********
+
+	@Override
+	public V setValue(V value) {
+		this.set = true;
+		return super.setValue(value);
+	}
+
+	@Override
+	public String toString() {
+		String s = super.toString();
+		return (this.set) ? '*' + s : s;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/IntReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/IntReference.java
new file mode 100644
index 0000000..cc40948
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/IntReference.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+/**
+ * Interface for a container for holding an <code>int</code> that cannot be
+ * changed by clients.
+ * <p>
+ * 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.
+ *
+ * @see ModifiableIntReference
+ */
+public interface IntReference
+	extends Comparable<IntReference>
+{
+	/**
+	 * Return the current <code>int</code> value.
+	 */
+	int getValue();
+
+	/**
+	 * Return whether the current <code>int</code> value is equal to the
+	 * specified value.
+	 */
+	boolean equals(int v);
+
+	/**
+	 * Return whether the current <code>int</code> value is not equal to
+	 * the specified value.
+	 */
+	boolean notEqual(int v);
+
+	/**
+	 * Return whether the current <code>int</code> value is zero.
+	 */
+	boolean isZero();
+
+	/**
+	 * Return whether the current <code>int</code> value is not zero.
+	 */
+	boolean isNotZero();
+
+	/**
+	 * Return whether the current <code>int</code> value is greater than
+	 * the specified value.
+	 */
+	boolean isGreaterThan(int v);
+
+	/**
+	 * Return whether the current <code>int</code> value is greater than
+	 * or equal to the specified value.
+	 */
+	boolean isGreaterThanOrEqual(int v);
+
+	/**
+	 * Return whether the current <code>int</code> value is less than
+	 * the specified value.
+	 */
+	boolean isLessThan(int v);
+
+	/**
+	 * Return whether the current <code>int</code> value is less than
+	 * or equal to the specified value.
+	 */
+	boolean isLessThanOrEqual(int v);
+
+	/**
+	 * Return whether the current <code>int</code> value is positive.
+	 */
+	boolean isPositive();
+
+	/**
+	 * Return whether the current <code>int</code> value is not positive
+	 * (i.e. negative or zero).
+	 */
+	boolean isNotPositive();
+
+	/**
+	 * Return whether the current <code>int</code> value is negative.
+	 */
+	boolean isNegative();
+
+	/**
+	 * Return whether the current <code>int</code> value is not negative
+	 * (i.e. zero or positive).
+	 */
+	boolean isNotNegative();
+
+	/**
+	 * Return the absolute value of the current <code>int</code> value.
+	 */
+	int abs();
+
+	/**
+	 * Return the negative value of the current <code>int</code> value.
+	 */
+	int neg();
+
+	/**
+	 * Return the current <code>int</code> value plus the specified value.
+	 */
+	int add(int v);
+
+	/**
+	 * Return current <code>int</code> value minus the specified value.
+	 */
+	int subtract(int v);
+
+	/**
+	 * Return current <code>int</code> value multiplied by the specified value.
+	 */
+	int multiply(int v);
+
+	/**
+	 * Return current <code>int</code> value divided by the specified value.
+	 */
+	int divide(int v);
+
+	/**
+	 * Return the remainder of the current <code>int</code> value divided by
+	 * the specified value.
+	 */
+	int remainder(int v);
+
+	/**
+	 * Return the minimum of the current <code>int</code> value and
+	 * the specified value.
+	 */
+	int min(int v);
+
+	/**
+	 * Return the maximum of the current <code>int</code> value and
+	 * the specified value.
+	 */
+	int max(int v);
+
+	/**
+	 * Return the current <code>int</code> value raised to the power
+	 * of the specified value.
+	 */
+	double pow(int v);
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/LazyObjectReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/LazyObjectReference.java
new file mode 100644
index 0000000..b5bdb3b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/LazyObjectReference.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Provide a thread-safe, reasonably performing container for holding an
+ * object that will be "lazy-initialized" upon its first reference. This is
+ * also useful for preventing direct references (accidental or otherwise) to
+ * lazy-initialized state.
+ * <p>
+ * There are some penalties:<ul>
+ * <li>The reference's use of generics will require casting (and the requisite
+ *     VM testing) with every access
+ * <li>If the value calculated during lazy initialization is <code>null</code>,
+ *     access will be <code>synchronized</code> <em>every</em> time.
+ * </ul>
+ * @see SimpleObjectReference
+ * @see SynchronizedObject
+ */
+public abstract class LazyObjectReference<V>
+	implements ObjectReference<V>, Cloneable, Serializable
+{
+	/** Backing value. */
+	private volatile V value = null;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Create a lazy object reference.
+	 */
+	protected LazyObjectReference() {
+		super();
+	}
+
+
+	// ********** value **********
+
+	/**
+	 * In JDK 5 and later, this "double-checked locking" idiom works as long
+	 * as the instance variable is marked <code>volatile</code>.
+	 */
+	@Override
+	public V getValue() {
+		V result = this.value;
+		if (result == null) {
+			synchronized (this) {
+				result = this.value;
+				if (result == null) {
+					this.value = result = this.buildValue();
+				}
+			}
+		}
+		return result;
+	}
+
+	protected abstract V buildValue();
+
+	@Override
+	public boolean valueEquals(Object object) {
+		return ObjectTools.equals(this.getValue(), object);
+	}
+
+	@Override
+	public boolean valueNotEqual(Object object) {
+		return ObjectTools.notEquals(this.getValue(), object);
+	}
+
+	@Override
+	public boolean isNull() {
+		return this.getValue() == null;
+	}
+
+	@Override
+	public boolean isNotNull() {
+		return this.getValue() != null;
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public LazyObjectReference<V> clone() {
+		try {
+			@SuppressWarnings("unchecked")
+			LazyObjectReference<V> clone = (LazyObjectReference<V>) super.clone();
+			return clone;
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	/**
+	 * This method will <em>not</em> trigger the "lazy-initialization".
+	 */
+	@Override
+	public String toString() {
+		return '[' + String.valueOf(this.value) + ']';
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/ModifiableBooleanReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/ModifiableBooleanReference.java
new file mode 100644
index 0000000..539fa67
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/ModifiableBooleanReference.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+/**
+ * Interface for a container for passing a flag that can be changed by
+ * the recipient.
+ * <p>
+ * 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 ModifiableBooleanReference
+	extends BooleanReference
+{
+	/**
+	 * Set the <code>boolean</code> value.
+	 * Return the previous value.
+	 */
+	boolean setValue(boolean value);
+
+	/**
+	 * Set the <code>boolean</code> value to the NOT of its current value.
+	 * Return the new value.
+	 */
+	boolean flip();
+
+	/**
+	 * Set the <code>boolean</code> value to the NOT of the specified value.
+	 * Return the previous value.
+	 */
+	boolean setNot(boolean v);
+
+	/**
+	 * Set the <code>boolean</code> value to <code>true</code>.
+	 * Return the previous value.
+	 */
+	boolean setTrue();
+
+	/**
+	 * Set the <code>boolean</code> value to <code>false</code>.
+	 * Return the previous value.
+	 */
+	boolean setFalse();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/ModifiableIntReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/ModifiableIntReference.java
new file mode 100644
index 0000000..a069194
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/ModifiableIntReference.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+/**
+ * Interface for a container for passing an integer that can be changed by
+ * the recipient.
+ * <p>
+ * 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 ModifiableIntReference
+	extends IntReference
+{
+	/**
+	 * Set the <code>int</code> value.
+	 * Return the previous value.
+	 */
+	int setValue(int value);
+
+	/**
+	 * Set the <code>int</code> value to zero.
+	 * Return the previous value.
+	 */
+	int setZero();
+
+	/**
+	 * Increment and return the <code>int</code> value.
+	 */
+	int increment();
+
+	/**
+	 * Decrement and return the <code>int</code> value.
+	 */
+	int decrement();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/ModifiableObjectReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/ModifiableObjectReference.java
new file mode 100644
index 0000000..38c90e7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/ModifiableObjectReference.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+/**
+ * Provide a container for passing an object that can be changed by the recipient.
+ * <p>
+ * 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 ModifiableObjectReference<V>
+	extends ObjectReference<V>
+{
+	/**
+	 * Set the value.
+	 * Return the previous value.
+	 */
+	V setValue(V value);
+
+	/**
+	 * Set the value to <code>null</code>.
+	 * Return the previous value.
+	 */
+	V setNull();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/ObjectReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/ObjectReference.java
new file mode 100644
index 0000000..2201ae8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/ObjectReference.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+/**
+ * Provide a container for holding an object that cannot be changed.
+ * <p>
+ * 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.
+ *
+ * @see ModifiableObjectReference
+ */
+public interface ObjectReference<V> {
+	/**
+	 * Return the current value.
+	 */
+	V getValue();
+
+	/**
+	 * Return whether the current value is equal to the specified value.
+	 */
+	boolean valueEquals(Object object);
+
+	/**
+	 * Return whether the current value is not equal to the specified value.
+	 */
+	boolean valueNotEqual(Object object);
+
+	/**
+	 * Return whether the current value is <code>null</code>.
+	 */
+	boolean isNull();
+
+	/**
+	 * Return whether the current value is not <code>null</code>.
+	 */
+	boolean isNotNull();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SimpleBooleanReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SimpleBooleanReference.java
new file mode 100644
index 0000000..f9a1f48
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SimpleBooleanReference.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+import java.io.Serializable;
+
+/**
+ * Provide a container for passing a flag that can be changed by the recipient.
+ *
+ * @see SynchronizedBoolean
+ */
+public class SimpleBooleanReference
+	implements ModifiableBooleanReference, Cloneable, Serializable
+{
+	/** Backing <code>boolean</code>. */
+	protected volatile boolean value;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Create a <code>boolean</code> reference with the specified initial value.
+	 */
+	public SimpleBooleanReference(boolean value) {
+		super();
+		this.value = value;
+	}
+
+	/**
+	 * Create a <code>boolean</code> reference with an initial value of
+	 * <code>false</code>.
+	 */
+	public SimpleBooleanReference() {
+		this(false);
+	}
+
+
+	// ********** accessors **********
+
+	@Override
+	public boolean getValue() {
+		return this.value;
+	}
+
+	@Override
+	public boolean is(boolean v) {
+		return this.value == v;
+	}
+
+	@Override
+	public boolean isNot(boolean v) {
+		return this.value != v;
+	}
+
+	@Override
+	public boolean isTrue() {
+		return this.value;
+	}
+
+	@Override
+	public boolean isFalse() {
+		return ! this.value;
+	}
+
+	@Override
+	public boolean setValue(boolean value) {
+		boolean old = this.value;
+		this.value = value;
+		return old;
+	}
+
+	@Override
+	public boolean flip() {
+		return this.value = ! this.value;
+	}
+
+	@Override
+	public boolean setNot(boolean v) {
+		return this.setValue( ! v);
+	}
+
+	@Override
+	public boolean setTrue() {
+		return this.setValue(true);
+	}
+
+	@Override
+	public boolean setFalse() {
+		return this.setValue(false);
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public SimpleBooleanReference clone() {
+		try {
+			return (SimpleBooleanReference) super.clone();
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	/**
+	 * Object identity is critical to boolean references.
+	 * There is no reason for two different boolean references to be
+	 * <em>equal</em>.
+	 *
+	 * @see #is(boolean)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		return super.equals(obj);
+	}
+
+	/**
+	 * @see #equals(Object)
+	 */
+	@Override
+	public int hashCode() {
+		return super.hashCode();
+	}
+
+	@Override
+	public String toString() {
+		return '[' + String.valueOf(this.value) + ']';
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SimpleIntReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SimpleIntReference.java
new file mode 100644
index 0000000..dc34baf
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SimpleIntReference.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+import java.io.Serializable;
+
+/**
+ * This class can be used wherever a mutable integer object is needed.
+ * It is a cross between an <code>int</code> and an {@link Integer}.
+ * It can be stored in a standard container (e.g. {@link java.util.Collection})
+ * but can be modified. It is also useful passing a value that can be changed
+ * by the recipient.
+ *
+ * @see SynchronizedInt
+ */
+public final class SimpleIntReference
+	implements ModifiableIntReference, Cloneable, Serializable
+{
+	/** Backing <code>int</code>. */
+	private volatile int value = 0;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a <code>int</code> reference with the specified initial value.
+	 */
+	public SimpleIntReference(int count) {
+		super();
+		this.value = count;
+	}
+
+	/**
+	 * Construct a <code>int</code> reference with an initial value of zero.
+	 */
+	public SimpleIntReference() {
+		this(0);
+	}
+
+
+	// ********** methods **********
+
+	@Override
+	public int getValue() {
+		return this.value;
+	}
+
+	@Override
+	public boolean equals(int v) {
+		return this.value == v;
+	}
+
+	@Override
+	public boolean notEqual(int v) {
+		return this.value != v;
+	}
+
+	@Override
+	public boolean isZero() {
+		return this.value == 0;
+	}
+
+	@Override
+	public boolean isNotZero() {
+		return this.value != 0;
+	}
+
+	@Override
+	public boolean isGreaterThan(int v) {
+		return this.value > v;
+	}
+
+	@Override
+	public boolean isGreaterThanOrEqual(int v) {
+		return this.value >= v;
+	}
+
+	@Override
+	public boolean isLessThan(int v) {
+		return this.value < v;
+	}
+
+	@Override
+	public boolean isLessThanOrEqual(int v) {
+		return this.value <= v;
+	}
+
+	@Override
+	public boolean isPositive() {
+		return this.isGreaterThan(0);
+	}
+
+	@Override
+	public boolean isNotPositive() {
+		return this.isLessThanOrEqual(0);
+	}
+
+	@Override
+	public boolean isNegative() {
+		return this.isLessThan(0);
+	}
+
+	@Override
+	public boolean isNotNegative() {
+		return this.isGreaterThanOrEqual(0);
+	}
+
+	@Override
+	public int abs() {
+		return Math.abs(this.value);
+	}
+
+	@Override
+	public int neg() {
+		return -this.value;
+	}
+
+	@Override
+	public int add(int v) {
+		return this.value + v;
+	}
+
+	@Override
+	public int subtract(int v) {
+		return this.value - v;
+	}
+
+	@Override
+	public int multiply(int v) {
+		return this.value * v;
+	}
+
+	@Override
+	public int divide(int v) {
+		return this.value / v;
+	}
+
+	@Override
+	public int remainder(int v) {
+		return this.value % v;
+	}
+
+	@Override
+	public int min(int v) {
+		return Math.min(this.value, v);
+	}
+
+	@Override
+	public int max(int v) {
+		return Math.max(this.value, v);
+	}
+
+	@Override
+	public double pow(int v) {
+		return Math.pow(this.value, v);
+	}
+
+	@Override
+	public int setValue(int value) {
+		int old = this.value;
+		this.value = value;
+		return old;
+	}
+
+	@Override
+	public int setZero() {
+		return this.setValue(0);
+	}
+
+	@Override
+	public int increment() {
+		return ++this.value;
+	}
+
+	@Override
+	public int decrement() {
+		return --this.value;
+	}
+
+
+	// ********** Comparable implementation **********
+
+	@Override
+	public int compareTo(IntReference ref) {
+		int v = ref.getValue();
+		return (this.value < v) ? -1 : ((this.value == v) ? 0 : 1);
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public SimpleIntReference clone() {
+		try {
+			return (SimpleIntReference) super.clone();
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	@Override
+	public String toString() {
+		return '[' + String.valueOf(this.value) + ']';
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SimpleObjectReference.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SimpleObjectReference.java
new file mode 100644
index 0000000..6743c9b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SimpleObjectReference.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Provide a container for passing an object that can be changed by the recipient.
+ *
+ * @see SynchronizedObject
+ */
+public class SimpleObjectReference<V>
+	implements ModifiableObjectReference<V>, Cloneable, Serializable
+{
+	/** Backing value. */
+	private volatile V value;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Create an object reference with the specified initial value.
+	 */
+	public SimpleObjectReference(V value) {
+		super();
+		this.value = value;
+	}
+
+	/**
+	 * Create an object reference with an initial value of
+	 * <code>null</code>.
+	 */
+	public SimpleObjectReference() {
+		this(null);
+	}
+
+
+	// ********** value **********
+
+	@Override
+	public V getValue() {
+		return this.value;
+	}
+
+	@Override
+	public boolean valueEquals(Object object) {
+		return ObjectTools.equals(this.value, object);
+	}
+
+	@Override
+	public boolean valueNotEqual(Object object) {
+		return ObjectTools.notEquals(this.value, object);
+	}
+
+	@Override
+	public boolean isNull() {
+		return this.value == null;
+	}
+
+	@Override
+	public boolean isNotNull() {
+		return this.value != null;
+	}
+
+	@Override
+	public V setValue(V value) {
+		V old = this.value;
+		this.value = value;
+		return old;
+	}
+
+	@Override
+	public V setNull() {
+		return this.setValue(null);
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public SimpleObjectReference<V> clone() {
+		try {
+			@SuppressWarnings("unchecked")
+			SimpleObjectReference<V> clone = (SimpleObjectReference<V>) super.clone();
+			return clone;
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	@Override
+	public String toString() {
+		return '[' + String.valueOf(this.value) + ']';
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SynchronizedBoolean.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SynchronizedBoolean.java
new file mode 100644
index 0000000..9312dcb
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SynchronizedBoolean.java
@@ -0,0 +1,665 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.command.InterruptibleCommand;
+import org.eclipse.persistence.tools.utility.command.InterruptibleCommandExecutor;
+
+/**
+ * This class provides synchronized access to a <code>boolean</code> value.
+ * It also provides protocol for suspending a thread until the
+ * <code>boolean</code> value is set to <code>true</code> or <code>false</code>,
+ * with optional time-outs.
+ *
+ * @see SimpleBooleanReference
+ */
+public class SynchronizedBoolean
+	implements InterruptibleCommandExecutor, ModifiableBooleanReference, Cloneable, Serializable
+{
+	/** Backing <code>boolean</code>. */
+	private boolean value;
+
+	/** Object to synchronize on. */
+	private final Object mutex;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Create a synchronized <code>boolean</code> with the specified
+	 * initial value and mutex.
+	 */
+	public SynchronizedBoolean(boolean value, Object mutex) {
+		super();
+		this.value = value;
+		this.mutex = mutex;
+	}
+
+	/**
+	 * Create a synchronized <code>boolean</code> with the
+	 * specified initial value.
+	 * The synchronized <code>boolean</code> itself will be the mutex.
+	 */
+	public SynchronizedBoolean(boolean value) {
+		super();
+		this.value = value;
+		this.mutex = this;
+	}
+
+	/**
+	 * Create a synchronized <code>boolean</code>
+	 * with an initial value of <code>false</code>
+	 * and specified mutex.
+	 */
+	public SynchronizedBoolean(Object mutex) {
+		this(false, mutex);
+	}
+
+	/**
+	 * Create a synchronized <code>boolean</code>
+	 * with an initial value of <code>false</code>.
+	 * The synchronized <code>boolean</code> itself will be the mutex.
+	 */
+	public SynchronizedBoolean() {
+		this(false);
+	}
+
+
+	// ********** accessors **********
+
+	@Override
+	public boolean getValue() {
+		synchronized (this.mutex) {
+			return this.value;
+		}
+	}
+
+	@Override
+	public boolean is(boolean b) {
+		synchronized (this.mutex) {
+			return this.value == b;
+		}
+	}
+
+	@Override
+	public boolean isNot(boolean b) {
+		synchronized (this.mutex) {
+			return this.value != b;
+		}
+	}
+
+	@Override
+	public boolean isTrue() {
+		synchronized (this.mutex) {
+			return this.value;
+		}
+	}
+
+	@Override
+	public boolean isFalse() {
+		synchronized (this.mutex) {
+			return ! this.value;
+		}
+	}
+
+	/**
+	 * If the value changes, all waiting threads are notified.
+	 * Return the <em>old</em> value.
+	 */
+	@Override
+	public boolean setValue(boolean value) {
+		synchronized (this.mutex) {
+			return (value == this.value) ? value : ! this.setChangedValue_(value);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized; new value is different
+	 * <br>
+	 * Return the <em>new</em> value.
+	 */
+	private boolean setChangedValue_(boolean v) {
+		this.value = v;
+		this.mutex.notifyAll();
+		return v;
+	}
+
+	/**
+	 * If the value changes, all waiting threads are notified.
+	 * Return the new value.
+	 */
+	@Override
+	public boolean flip() {
+		synchronized (this.mutex) {
+			return this.setChangedValue_( ! this.value);
+		}
+	}
+
+	/**
+	 * Set the value to <code>value & b</code> and return the new value.
+	 * If the value changes, all waiting threads are notified.
+	 */
+	public boolean and(boolean b) {
+		synchronized (this.mutex) {
+			return this.setValue_(this.value & b);
+		}
+	}
+
+	/**
+	 * Set the value to <code>value | b</code> and return the new value.
+	 * If the value changes, all waiting threads are notified.
+	 */
+	public boolean or(boolean b) {
+		synchronized (this.mutex) {
+			return this.setValue_(this.value | b);
+		}
+	}
+
+	/**
+	 * Set the value to <code>value ^ b</code> and return the new value.
+	 * If the value changes, all waiting threads are notified.
+	 */
+	public boolean xor(boolean b) {
+		synchronized (this.mutex) {
+			return this.setValue_(this.value ^ b);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 * <br>
+	 * Return the <em>new</em> value.
+	 */
+	private boolean setValue_(boolean v) {
+		return (v == this.value) ? v : this.setChangedValue_(v);
+	}
+
+	/**
+	 * If the value changes, all waiting threads are notified.
+	 */
+	@Override
+	public boolean setNot(boolean b) {
+		return this.setValue( ! b);
+	}
+
+	/**
+	 * If the value changes, all waiting threads are notified.
+	 */
+	@Override
+	public boolean setTrue() {
+		return this.setValue(true);
+	}
+
+	/**
+	 * If the value changes, all waiting threads are notified.
+	 */
+	@Override
+	public boolean setFalse() {
+		return this.setValue(false);
+	}
+
+	/**
+	 * Set the value to the specified new value if it is currently the specified
+	 * expected value. If the value changes, all waiting threads are notified.
+	 * Return whether the commit was successful.
+	 */
+	public boolean commit(boolean expectedValue, boolean newValue) {
+		synchronized (this.mutex) {
+			boolean success = (this.value == expectedValue);
+			if (success) {
+				this.setValue_(newValue);
+			}
+			return success;
+		}
+	}
+
+	/**
+	 * Atomically swap the value of this synchronized boolean with the value of
+	 * the specified synchronized boolean. Make assumptions about the value of
+	 * <em>identity hash code</em> to avoid deadlock when two synchronized
+	 * booleans swap values with each other simultaneously.
+	 * If either value changes, the corresponding waiting threads are notified.
+	 * Return the new value.
+	 */
+	public boolean swap(SynchronizedBoolean other) {
+		if (other == this) {
+			return this.getValue();
+		}
+		boolean thisFirst = System.identityHashCode(this) < System.identityHashCode(other);
+		SynchronizedBoolean first = thisFirst ? this : other;
+		SynchronizedBoolean second = thisFirst ? other : this;
+		synchronized (first.mutex) {
+			synchronized (second.mutex) {
+				boolean thisValue = this.value;
+				boolean otherValue = other.value;
+				if (thisValue == otherValue) {
+					return thisValue;  // nothing changes
+				}
+				other.setChangedValue_(thisValue);
+				return this.setChangedValue_(otherValue);
+			}
+		}
+	}
+
+	/**
+	 * Return the object this object locks on while performing
+	 * its operations.
+	 */
+	public Object getMutex() {
+		return this.mutex;
+	}
+
+
+	// ********** indefinite waits **********
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value changes
+	 * to the specified value. If the <code>boolean</code> value is already the
+	 * specified value, return immediately.
+	 */
+	public void waitUntilValueIs(boolean b) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilValueIs_(b);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void waitUntilValueIs_(boolean b) throws InterruptedException {
+		while (this.value != b) {
+			this.mutex.wait();
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value
+	 * changes to the NOT of the specified value.
+	 * If the <code>boolean</code> value is already the NOT of the specified
+	 * value, return immediately.
+	 */
+	public void waitUntilValueIsNot(boolean b) throws InterruptedException {
+		this.waitUntilValueIs( ! b);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value
+	 * changes to <code>true</code>.
+	 * If the <code>boolean</code> value is already <code>true</code>,
+	 * return immediately.
+	 */
+	public void waitUntilTrue() throws InterruptedException {
+		this.waitUntilValueIs(true);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value
+	 * changes to <code>false</code>.
+	 * If the <code>boolean</code> value is already <code>false</code>,
+	 * return immediately.
+	 */
+	public void waitUntilFalse() throws InterruptedException {
+		this.waitUntilValueIs(false);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value changes to
+	 * the NOT of the specified value, then change it back to the specified
+	 * value and continue executing. If the <code>boolean</code> value is already
+	 * the NOT of the specified value, set the value to the specified value
+	 * immediately.
+	 */
+	public void waitToSetValue(boolean b) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilValueIs_( ! b);
+			this.setChangedValue_(b);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value
+	 * changes to <code>false</code>,
+	 * then change it back to <code>true</code> and continue executing.
+	 * If the <code>boolean</code> value is already <code>false</code>,
+	 * set the value to <code>true</code> immediately.
+	 */
+	public void waitToSetTrue() throws InterruptedException {
+		this.waitToSetValue(true);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value
+	 * changes to <code>true</code>,
+	 * then change it back to <code>false</code> and continue executing.
+	 * If the <code>boolean</code> value is already <code>true</code>,
+	 * set the value to <code>false</code> immediately.
+	 */
+	public void waitToSetFalse() throws InterruptedException {
+		this.waitToSetValue(false);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value
+	 * changes to the specified value,
+	 * then execute the specified command.
+	 * If the <code>boolean</code> value is already equal to the specified
+	 * value, execute the specified command immediately.
+	 */
+	public void whenEqual(boolean b, InterruptibleCommand command) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilValueIs_(b);
+			command.execute();
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value
+	 * changes to the NOT of the specified value,
+	 * then execute the specified command.
+	 * If the <code>boolean</code> value is already the NOT of the specified
+	 * value, execute the specified command immediately.
+	 */
+	public void whenNotEqual(boolean b, InterruptibleCommand command) throws InterruptedException {
+		this.whenEqual( ! b, command);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value
+	 * changes to <code>true</code>,
+	 * then execute the specified command.
+	 * If the <code>boolean</code> value is already <code>true</code>,
+	 * execute the specified command immediately.
+	 */
+	public void whenTrue(InterruptibleCommand command) throws InterruptedException {
+		this.whenEqual(true, command);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value
+	 * changes to <code>false</code>,
+	 * then execute the specified command.
+	 * If the <code>boolean</code> value is already <code>false</code>,
+	 * execute the specified command immediately.
+	 */
+	public void whenFalse(InterruptibleCommand command) throws InterruptedException {
+		this.whenEqual(false, command);
+	}
+
+
+	// ********** timed waits **********
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value changes
+	 * to the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if
+	 * the specified value was achieved;
+	 * return <code>false</code> if a time-out occurred.
+	 * If the <code>boolean</code> value is already the specified value,
+	 * return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilValueIs(boolean b, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilValueIs_(b, timeout);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private boolean waitUntilValueIs_(boolean b, long timeout) throws InterruptedException {
+		if (timeout == 0L) {
+			this.waitUntilValueIs_(b);	// wait indefinitely until notified
+			return true;	// if it ever comes back, the condition was met
+		}
+
+		long stop = System.currentTimeMillis() + timeout;
+		long remaining = timeout;
+		while ((this.value != b) && (remaining > 0L)) {
+			this.mutex.wait(remaining);
+			remaining = stop - System.currentTimeMillis();
+		}
+		return (this.value == b);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value
+	 * changes to the NOT of the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if
+	 * the NOT of the specified value was achieved;
+	 * return <code>false</code> if a time-out occurred.
+	 * If the <code>boolean</code> value is already the NOT of the specified
+	 * value, return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilValueIsNot(boolean b, long timeout) throws InterruptedException {
+		return this.waitUntilValueIs( ! b, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value changes
+	 * to <code>true</code> or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if
+	 * <code>true</code> was achieved;
+	 * return <code>false</code> if a time-out occurred.
+	 * If the <code>boolean</code> value is already <code>true</code>,
+	 * return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilTrue(long timeout) throws InterruptedException {
+		return this.waitUntilValueIs(true, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value changes
+	 * to <code>false</code> or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if
+	 * <code>false</code> was achieved;
+	 * return <code>false</code> if a time-out occurred.
+	 * If the <code>boolean</code> value is already <code>false</code>,
+	 * return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilFalse(long timeout) throws InterruptedException {
+		return this.waitUntilValueIs(false, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value changes
+	 * to the NOT of the specified value, then change it back to the specified
+	 * value and continue executing. If the <code>boolean</code> value does not
+	 * change to <code>false</code> before the time-out, simply continue
+	 * executing without changing the value.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the value was set to the specified value; return <code>false</code>
+	 * if a time-out occurred.
+	 * If the <code>boolean</code> value is already
+	 * the NOT of the specified value, set the value to the specified value
+	 * immediately and return <code>true</code>.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitToSetValue(boolean b, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilValueIs_( ! b, timeout);
+			if (success) {
+				this.setChangedValue_(b);
+			}
+			return success;
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value changes
+	 * to <code>false</code>, then change it back to <code>true</code> and
+	 * continue executing. If the <code>boolean</code> value does not change to
+	 * <code>false</code> before the time-out, simply continue executing without
+	 * changing the value.
+	 * The time-out is specified in milliseconds. Return
+	 * <code>true</code> if the value was set to <code>true</code>;
+	 * return <code>false</code> if a time-out occurred.
+	 * If the <code>boolean</code> value is already <code>false</code>, set the
+	 * value to <code>true</code> immediately and return <code>true</code>.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitToSetTrue(long timeout) throws InterruptedException {
+		return this.waitToSetValue(true, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value changes
+	 * to <code>true</code>, then change it back to <code>false</code> and
+	 * continue executing. If the <code>boolean</code> value does not change to
+	 * <code>true</code> before the time-out, simply continue executing without
+	 * changing the value.
+	 * The time-out is specified in milliseconds. Return
+	 * <code>true</code> if the value was set to <code>false</code>;
+	 * return <code>false</code> if a time-out occurred.
+	 * If the <code>boolean</code> value is already <code>true</code>, set the
+	 * value to <code>false</code> immediately and return <code>true</code>.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitToSetFalse(long timeout) throws InterruptedException {
+		return this.waitToSetValue(false, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value changes
+	 * to the specified value or the specified time-out occurs;
+	 * then, if a time-out did not occur, execute the specified command.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if
+	 * the command was executed;
+	 * return <code>false</code> if a time-out occurred.
+	 * If the <code>boolean</code> value is already the specified value,
+	 * execute the specified command immediately and return <code>true</code>.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean whenEqual(boolean b, InterruptibleCommand command, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilValueIs_(b, timeout);
+			if (success) {
+				command.execute();
+			}
+			return success;
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value changes
+	 * to the NOT of the specified value or the specified time-out occurs;
+	 * then, if a time-out did not occur, execute the specified command.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if
+	 * the command was executed;
+	 * return <code>false</code> if a time-out occurred.
+	 * If the <code>boolean</code> value is already the NOT of the specified value,
+	 * execute the specified command immediately and return <code>true</code>.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean whenNotEqual(boolean b, InterruptibleCommand command, long timeout) throws InterruptedException {
+		return this.whenEqual( ! b, command, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value changes
+	 * to <code>true</code> or the specified time-out occurs;
+	 * then, if a time-out did not occur, execute the specified command.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if
+	 * the command was executed;
+	 * return <code>false</code> if a time-out occurred.
+	 * If the <code>boolean</code> value is already <code>true</code>,
+	 * execute the specified command immediately and return <code>true</code>.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean whenTrue(InterruptibleCommand command, long timeout) throws InterruptedException {
+		return this.whenEqual(true, command, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the <code>boolean</code> value changes
+	 * to <code>false</code> or the specified time-out occurs;
+	 * then, if a time-out did not occur, execute the specified command.
+	 * The time-out is specified in milliseconds. Return <code>true</code> if
+	 * the command was executed;
+	 * return <code>false</code> if a time-out occurred.
+	 * If the <code>boolean</code> value is already <code>false</code>,
+	 * execute the specified command immediately and return <code>true</code>.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean whenFalse(InterruptibleCommand command, long timeout) throws InterruptedException {
+		return this.whenEqual(false, command, timeout);
+	}
+
+
+	// ********** synchronized behavior **********
+
+	/**
+	 * If the current thread is not interrupted, execute the specified command
+	 * with the mutex locked. This is useful for initializing the value from another
+	 * thread.
+	 */
+	@Override
+	public void execute(InterruptibleCommand command) throws InterruptedException {
+		if (Thread.currentThread().isInterrupted()) {
+			throw new InterruptedException();
+		}
+		synchronized (this.mutex) {
+			command.execute();
+		}
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public SynchronizedBoolean clone() {
+		try {
+			synchronized (this.mutex) {
+				return (SynchronizedBoolean) super.clone();
+			}
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	/**
+	 * Object identity is critical to synchronized booleans.
+	 * There is no reason for two different synchronized booleans to be
+	 * <em>equal</em>.
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		return super.equals(obj);
+	}
+
+	/**
+	 * @see #equals(Object)
+	 */
+	@Override
+	public int hashCode() {
+		return super.hashCode();
+	}
+
+	@Override
+	public String toString() {
+		return '[' + String.valueOf(this.getValue()) + ']';
+	}
+
+	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+		synchronized (this.mutex) {
+			s.defaultWriteObject();
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SynchronizedInt.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SynchronizedInt.java
new file mode 100644
index 0000000..cf3a53b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SynchronizedInt.java
@@ -0,0 +1,944 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.command.Command;
+
+/**
+ * This class provides synchronized access to an <code>int</code>.
+ * It also provides protocol for suspending a thread until the
+ * value is set to a specified value, with optional time-outs.
+ *
+ * @see SimpleIntReference
+ */
+public class SynchronizedInt
+	implements ModifiableIntReference, Cloneable, Serializable
+{
+	/** Backing <code>int</code>. */
+	private int value;
+
+	/** Object to synchronize on. */
+	private final Object mutex;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Create a synchronized integer with the specified initial value
+	 * and mutex.
+	 */
+	public SynchronizedInt(int value, Object mutex) {
+		super();
+		this.value = value;
+		this.mutex = mutex;
+	}
+
+	/**
+	 * Create a synchronized integer with the specified initial value.
+	 * The synchronized integer itself will be the mutex.
+	 */
+	public SynchronizedInt(int value) {
+		super();
+		this.value = value;
+		this.mutex = this;
+	}
+
+	/**
+	 * Create a synchronized integer with an initial value of zero
+	 * and the specified mutex.
+	 */
+	public SynchronizedInt(Object mutex) {
+		this(0, mutex);
+	}
+
+	/**
+	 * Create a synchronized object with an initial value of zero.
+	 * The synchronized integer itself will be the mutex.
+	 */
+	public SynchronizedInt() {
+		this(0);
+	}
+
+
+	// ********** methods **********
+
+	@Override
+	public int getValue() {
+		synchronized (this.mutex) {
+			return this.value;
+		}
+	}
+
+	@Override
+	public boolean equals(int v) {
+		synchronized (this.mutex) {
+			return this.value == v;
+		}
+	}
+
+	@Override
+	public boolean notEqual(int v) {
+		synchronized (this.mutex) {
+			return this.value != v;
+		}
+	}
+
+	@Override
+	public boolean isZero() {
+		synchronized (this.mutex) {
+			return this.value == 0;
+		}
+	}
+
+	@Override
+	public boolean isNotZero() {
+		synchronized (this.mutex) {
+			return this.value != 0;
+		}
+	}
+
+	@Override
+	public boolean isGreaterThan(int v) {
+		synchronized (this.mutex) {
+			return this.value > v;
+		}
+	}
+
+	@Override
+	public boolean isGreaterThanOrEqual(int v) {
+		synchronized (this.mutex) {
+			return this.value >= v;
+		}
+	}
+
+	@Override
+	public boolean isLessThan(int v) {
+		synchronized (this.mutex) {
+			return this.value < v;
+		}
+	}
+
+	@Override
+	public boolean isLessThanOrEqual(int v) {
+		synchronized (this.mutex) {
+			return this.value <= v;
+		}
+	}
+
+	@Override
+	public boolean isPositive() {
+		return this.isGreaterThan(0);
+	}
+
+	@Override
+	public boolean isNotPositive() {
+		return this.isLessThanOrEqual(0);
+	}
+
+	@Override
+	public boolean isNegative() {
+		return this.isLessThan(0);
+	}
+
+	@Override
+	public boolean isNotNegative() {
+		return this.isGreaterThanOrEqual(0);
+	}
+
+	@Override
+	public int abs() {
+		synchronized (this.mutex) {
+			return Math.abs(this.value);
+		}
+	}
+
+	@Override
+	public int neg() {
+		synchronized (this.mutex) {
+			return -this.value;
+		}
+	}
+
+	@Override
+	public int add(int v) {
+		synchronized (this.mutex) {
+			return this.value + v;
+		}
+	}
+
+	@Override
+	public int subtract(int v) {
+		synchronized (this.mutex) {
+			return this.value - v;
+		}
+	}
+
+	@Override
+	public int multiply(int v) {
+		synchronized (this.mutex) {
+			return this.value * v;
+		}
+	}
+
+	@Override
+	public int divide(int v) {
+		synchronized (this.mutex) {
+			return this.value / v;
+		}
+	}
+
+	@Override
+	public int remainder(int v) {
+		synchronized (this.mutex) {
+			return this.value % v;
+		}
+	}
+
+	@Override
+	public int min(int v) {
+		synchronized (this.mutex) {
+			return Math.min(this.value, v);
+		}
+	}
+
+	@Override
+	public int max(int v) {
+		synchronized (this.mutex) {
+			return Math.max(this.value, v);
+		}
+	}
+
+	@Override
+	public double pow(int v) {
+		synchronized (this.mutex) {
+			return Math.pow(this.value, v);
+		}
+	}
+
+	/**
+	 * If the value changes, all waiting threads are notified.
+	 */
+	@Override
+	public int setValue(int value) {
+		synchronized (this.mutex) {
+			return this.setValue_(value);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private int setValue_(int v) {
+		int old = this.value;
+		return (old == v) ? old : this.setValue_(v, old);
+	}
+
+	/**
+	 * Pre-condition: synchronized and new value is different
+	 */
+	private int setChangedValue_(int v) {
+		return this.setValue_(v, this.value);
+	}
+
+	/**
+	 * Pre-condition: synchronized and new value is different
+	 */
+	private int setValue_(int v, int old) {
+		this.value = v;
+		this.mutex.notifyAll();
+		return old;
+	}
+
+	/**
+	 * Set the value to zero. If the value changes, all waiting
+	 * threads are notified. Return the previous value.
+	 */
+	@Override
+	public int setZero() {
+		return this.setValue(0);
+	}
+
+	/**
+	 * Increment the value by one.
+	 * Return the new value.
+	 */
+	@Override
+	public int increment() {
+		synchronized (this.mutex) {
+			this.value++;
+			this.mutex.notifyAll();
+			return this.value;
+		}
+	}
+
+	/**
+	 * Decrement the value by one.
+	 * Return the new value.
+	 */
+	@Override
+	public int decrement() {
+		synchronized (this.mutex) {
+			this.value--;
+			this.mutex.notifyAll();
+			return this.value;
+		}
+	}
+
+	/**
+	 * If the current value is the specified expected value, set it to the
+	 * specified new value. Return the previous value.
+	 */
+	public int compareAndSwap(int expectedValue, int newValue) {
+		synchronized (this.mutex) {
+			return this.compareAndSwap_(expectedValue, newValue);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private int compareAndSwap_(int expectedValue, int newValue) {
+		return (this.value == expectedValue) ? this.setValue_(newValue) : this.value;
+	}
+
+	/**
+	 * Return the object the synchronized integer locks on while performing
+	 * its operations.
+	 */
+	public Object getMutex() {
+		return this.mutex;
+	}
+
+
+	// ********** indefinite waits **********
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to the specified value. If the value is already the
+	 * specified value, return immediately.
+	 */
+	public void waitUntilEqual(int v) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilEqual_(v);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void waitUntilEqual_(int v) throws InterruptedException {
+		while (this.value != v) {
+			this.mutex.wait();
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to something other than the specified value. If the
+	 * value is already <em>not</em> the specified value,
+	 * return immediately.
+	 */
+	public void waitUntilNotEqual(int v) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilNotEqual_(v);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void waitUntilNotEqual_(int v) throws InterruptedException {
+		while (this.value == v) {
+			this.mutex.wait();
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to zero.
+	 * If the value is already zero, return immediately.
+	 */
+	public void waitUntilZero() throws InterruptedException {
+		this.waitUntilEqual(0);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to something other than zero.
+	 * If the value is already <em>not</em> zero,
+	 * return immediately.
+	 */
+	public void waitUntilNotZero() throws InterruptedException {
+		this.waitUntilNotEqual(0);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to a value greater than the specified value. If the value is already
+	 * greater than the specified value, return immediately.
+	 */
+	public void waitUntilGreaterThan(int v) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilGreaterThan_(v);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void waitUntilGreaterThan_(int v) throws InterruptedException {
+		while (this.value <= v) {
+			this.mutex.wait();
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to a value greater than or equal to the specified value. If the value is already
+	 * greater than or equal the specified value, return immediately.
+	 */
+	public void waitUntilGreaterThanOrEqual(int v) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilGreaterThanOrEqual_(v);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void waitUntilGreaterThanOrEqual_(int v) throws InterruptedException {
+		while (this.value < v) {
+			this.mutex.wait();
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to a value less than the specified value. If the value is already
+	 * less than the specified value, return immediately.
+	 */
+	public void waitUntilLessThan(int v) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilLessThan_(v);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void waitUntilLessThan_(int v) throws InterruptedException {
+		while (this.value >= v) {
+			this.mutex.wait();
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to a value less than or equal to the specified value. If the value is already
+	 * less than or equal the specified value, return immediately.
+	 */
+	public void waitUntilLessThanOrEqual(int v) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilLessThanOrEqual_(v);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void waitUntilLessThanOrEqual_(int v) throws InterruptedException {
+		while (this.value > v) {
+			this.mutex.wait();
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value is positive.
+	 * If the value is already positive, return immediately.
+	 */
+	public void waitUntilPositive() throws InterruptedException {
+		this.waitUntilGreaterThan(0);
+	}
+
+	/**
+	 * Suspend the current thread until the value is not positive
+	 * (i.e. negative or zero).
+	 * If the value is already <em>not</em> positive,
+	 * return immediately.
+	 */
+	public void waitUntilNotPositive() throws InterruptedException {
+		this.waitUntilLessThanOrEqual(0);
+	}
+
+	/**
+	 * Suspend the current thread until the value is negative.
+	 * If the value is already negative, return immediately.
+	 */
+	public void waitUntilNegative() throws InterruptedException {
+		this.waitUntilLessThan(0);
+	}
+
+	/**
+	 * Suspend the current thread until the value is not negative
+	 * (i.e. zero or positive).
+	 * If the value is already <em>not</em> negative,
+	 * return immediately.
+	 */
+	public void waitUntilNotNegative() throws InterruptedException {
+		this.waitUntilGreaterThanOrEqual(0);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to
+	 * something other than the specified value, then change
+	 * it back to the specified value and continue executing.
+	 * If the value is already <em>not</em> the specified value, set
+	 * the value immediately.
+	 * Return the previous value.
+	 */
+	public int waitToSetValue(int v) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilNotEqual_(v);
+			return this.setChangedValue_(v);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to
+	 * something other than zero, then change it
+	 * back to zero and continue executing.
+	 * If the value is already <em>not</em> zero,
+	 * set the value to zero immediately.
+	 * Return the previous value.
+	 */
+	public int waitToSetZero() throws InterruptedException {
+		return this.waitToSetValue(0);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to
+	 * the specified expected value, then change it
+	 * to the specified new value and continue executing.
+	 * If the value is already the specified expected value,
+	 * set the value to the specified new value immediately.
+	 * Return the previous value.
+	 */
+	public int waitToSwap(int expectedValue, int newValue) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilEqual_(expectedValue);
+			return this.setValue_(newValue);
+		}
+	}
+
+
+	// ********** timed waits **********
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the specified value was achieved; return <code>false</code>
+	 * if a time-out occurred.
+	 * If the value is already the specified value, return true immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilEqual(int v, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilEqual_(v, timeout);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private boolean waitUntilEqual_(int v, long timeout) throws InterruptedException {
+		if (timeout == 0L) {
+			this.waitUntilEqual_(v);  // wait indefinitely until notified
+			return true;  // if it ever comes back, the condition was met
+		}
+
+		long stop = System.currentTimeMillis() + timeout;
+		long remaining = timeout;
+		while ((this.value != v) && (remaining > 0L)) {
+			this.mutex.wait(remaining);
+			remaining = stop - System.currentTimeMillis();
+		}
+		return (this.value == v);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to something
+	 * other than the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the specified value was removed; return <code>false</code> if a
+	 * time-out occurred. If the value is already <em>not</em> the specified
+	 * value, return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilNotEqual(int v, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilNotEqual_(v, timeout);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private boolean waitUntilNotEqual_(int v, long timeout) throws InterruptedException {
+		if (timeout == 0L) {
+			this.waitUntilNotEqual_(v);	// wait indefinitely until notified
+			return true;	// if it ever comes back, the condition was met
+		}
+
+		long stop = System.currentTimeMillis() + timeout;
+		long remaining = timeout;
+		while ((this.value == v) && (remaining > 0L)) {
+			this.mutex.wait(remaining);
+			remaining = stop - System.currentTimeMillis();
+		}
+		return (this.value != v);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to zero or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the value is now zero; return <code>false</code>
+	 * if a time-out occurred. If the value is already zero,
+	 * return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilZero(long timeout) throws InterruptedException {
+		return this.waitUntilEqual(0, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to something other than zero or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the value is now not zero; return <code>false</code>
+	 * if a time-out occurred. If the value is already <em>not</em>
+	 * zero, return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilNotZero(long timeout) throws InterruptedException {
+		return this.waitUntilNotEqual(0, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to a value greater
+	 * than the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the specified value was achieved; return <code>false</code>
+	 * if a time-out occurred.
+	 * If the value is already greater than the specified value, return immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilGreaterThan(int v, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilGreaterThan_(v, timeout);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private boolean waitUntilGreaterThan_(int v, long timeout) throws InterruptedException {
+		if (timeout == 0L) {
+			this.waitUntilGreaterThan_(v);  // wait indefinitely until notified
+			return true;  // if it ever comes back, the condition was met
+		}
+
+		long stop = System.currentTimeMillis() + timeout;
+		long remaining = timeout;
+		while ((this.value <= v) && (remaining > 0L)) {
+			this.mutex.wait(remaining);
+			remaining = stop - System.currentTimeMillis();
+		}
+		return (this.value > v);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to a value greater
+	 * than or equal to the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the specified value was achieved; return <code>false</code>
+	 * if a time-out occurred.
+	 * If the value is already greater than or equal to the specified value,
+	 * return immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilGreaterThanOrEqual(int v, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilGreaterThanOrEqual_(v, timeout);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private boolean waitUntilGreaterThanOrEqual_(int v, long timeout) throws InterruptedException {
+		if (timeout == 0L) {
+			this.waitUntilGreaterThanOrEqual_(v);  // wait indefinitely until notified
+			return true;  // if it ever comes back, the condition was met
+		}
+
+		long stop = System.currentTimeMillis() + timeout;
+		long remaining = timeout;
+		while ((this.value < v) && (remaining > 0L)) {
+			this.mutex.wait(remaining);
+			remaining = stop - System.currentTimeMillis();
+		}
+		return (this.value >= v);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to a value less
+	 * than the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the specified value was achieved; return <code>false</code>
+	 * if a time-out occurred.
+	 * If the value is already less than the specified value, return immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilLessThan(int v, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilLessThan_(v, timeout);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private boolean waitUntilLessThan_(int v, long timeout) throws InterruptedException {
+		if (timeout == 0L) {
+			this.waitUntilLessThan_(v);  // wait indefinitely until notified
+			return true;  // if it ever comes back, the condition was met
+		}
+
+		long stop = System.currentTimeMillis() + timeout;
+		long remaining = timeout;
+		while ((this.value >= v) && (remaining > 0L)) {
+			this.mutex.wait(remaining);
+			remaining = stop - System.currentTimeMillis();
+		}
+		return (this.value < v);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to a value less
+	 * than or equal to the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the specified value was achieved; return <code>false</code>
+	 * if a time-out occurred.
+	 * If the value is already less than or equal to the specified value,
+	 * return immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilLessThanOrEqual(int v, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilLessThanOrEqual_(v, timeout);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private boolean waitUntilLessThanOrEqual_(int v, long timeout) throws InterruptedException {
+		if (timeout == 0L) {
+			this.waitUntilLessThanOrEqual_(v);  // wait indefinitely until notified
+			return true;  // if it ever comes back, the condition was met
+		}
+
+		long stop = System.currentTimeMillis() + timeout;
+		long remaining = timeout;
+		while ((this.value > v) && (remaining > 0L)) {
+			this.mutex.wait(remaining);
+			remaining = stop - System.currentTimeMillis();
+		}
+		return (this.value <= v);
+	}
+
+	/**
+	 * Suspend the current thread until the value is positive
+	 * or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the value is now positive; return <code>false</code>
+	 * if a time-out occurred. If the value is already positive,
+	 * return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilPositive(long timeout) throws InterruptedException {
+		return this.waitUntilGreaterThan(0, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the value is not positive
+	 * or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the value is now not positive; return <code>false</code>
+	 * if a time-out occurred. If the value is already not positive,
+	 * return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilNotPositive(long timeout) throws InterruptedException {
+		return this.waitUntilLessThanOrEqual(0, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the value is negative
+	 * or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the value is now negative; return <code>false</code>
+	 * if a time-out occurred. If the value is already negative,
+	 * return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilNegative(long timeout) throws InterruptedException {
+		return this.waitUntilLessThan(0, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the value is not negative
+	 * or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the value is now not negative; return <code>false</code>
+	 * if a time-out occurred. If the value is already not negative,
+	 * return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilNotNegative(long timeout) throws InterruptedException {
+		return this.waitUntilGreaterThanOrEqual(0, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to
+	 * something other than the specified value, then change
+	 * it back to the specified value and continue executing.
+	 * If the value does not change to something other than the
+	 * specified value before the time-out, simply continue executing
+	 * without changing the value.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the value was set to the specified value; return <code>false</code>
+	 * if a time-out occurred.
+	 * If the value is already something other than the specified value, set
+	 * the value immediately and return <code>true</code>.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitToSetValue(int v, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilNotEqual_(v, timeout);
+			if (success) {
+				this.setChangedValue_(v);
+			}
+			return success;
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to something
+	 * other than zero, then change it back to zero
+	 * and continue executing. If the value does not change to something
+	 * other than zero before the time-out, simply continue
+	 * executing without changing the value.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the value was set to zero; return <code>false</code>
+	 * if a time-out occurred.
+	 * If the value is already something other than zero, set
+	 * the value to zero immediately and return <code>true</code>.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitToSetZero(long timeout) throws InterruptedException {
+		return this.waitToSetValue(0, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to
+	 * the specified expected value, then change it
+	 * to the specified new value and continue executing.
+	 * If the value does not change to the specified expected value
+	 * before the time-out, simply continue executing without changing
+	 * the value.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the value was set to the specified new value; return
+	 * <code>false</code> if a time-out occurred.
+	 * If the value is already the specified expected value,
+	 * set the value to the specified new value immediately.
+	 * Return the previous value.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitToSwap(int expectedValue, int newValue, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilEqual_(expectedValue, timeout);
+			if (success) {
+				this.setValue_(newValue);
+			}
+			return success;
+		}
+	}
+
+
+	// ********** synchronized behavior **********
+
+	/**
+	 * If current thread is not interrupted, execute the specified command
+	 * with the mutex locked. This is useful for initializing the value from another
+	 * thread.
+	 */
+	public void execute(Command command) throws InterruptedException {
+		if (Thread.currentThread().isInterrupted()) {
+			throw new InterruptedException();
+		}
+		synchronized (this.mutex) {
+			command.execute();
+		}
+	}
+
+
+	// ********** Comparable implementation **********
+
+	@Override
+	public int compareTo(IntReference ref) {
+		int thisValue = this.getValue();
+		int otherValue = ref.getValue();
+		return (thisValue < otherValue) ? -1 : ((thisValue == otherValue) ? 0 : 1);
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public SynchronizedInt clone() {
+		try {
+			synchronized (this.mutex) {
+				return (SynchronizedInt) super.clone();
+			}
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	@Override
+	public String toString() {
+		return '[' + String.valueOf(this.getValue()) + ']';
+	}
+
+	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+		synchronized (this.mutex) {
+			s.defaultWriteObject();
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SynchronizedObject.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SynchronizedObject.java
new file mode 100644
index 0000000..6a20039
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/reference/SynchronizedObject.java
@@ -0,0 +1,482 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.reference;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.command.Command;
+
+/**
+ * This class provides synchronized access to an object of type <code>V</code>.
+ * It also provides protocol for suspending a thread until the
+ * value is set to <code>null</code> or a non-<code>null</code> value,
+ * with optional time-outs.
+ *
+ * @parm V the type of the synchronized object's value
+ * @see SimpleObjectReference
+ */
+public class SynchronizedObject<V>
+	implements ModifiableObjectReference<V>, Cloneable, Serializable
+{
+	/** Backing value. */
+	private V value;
+
+	/** Object to synchronize on. */
+	private final Object mutex;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Create a synchronized object with the specified initial value
+	 * and mutex.
+	 */
+	public SynchronizedObject(V value, Object mutex) {
+		super();
+		this.value = value;
+		this.mutex = mutex;
+	}
+
+	/**
+	 * Create a synchronized object with the specified initial value.
+	 * The synchronized object itself will be the mutex.
+	 */
+	public SynchronizedObject(V value) {
+		super();
+		this.value = value;
+		this.mutex = this;
+	}
+
+	/**
+	 * Create a synchronized object with an initial value of <code>null</code>.
+	 * The synchronized object itself will be the mutex.
+	 */
+	public SynchronizedObject() {
+		this(null);
+	}
+
+
+	// ********** accessors **********
+
+	@Override
+	public V getValue() {
+		synchronized (this.mutex) {
+			return this.value;
+		}
+	}
+
+	@Override
+	public boolean valueEquals(Object object) {
+		return ObjectTools.equals(this.getValue(), object);
+	}
+
+	@Override
+	public boolean valueNotEqual(Object object) {
+		return ObjectTools.notEquals(this.getValue(), object);
+	}
+
+	@Override
+	public boolean isNull() {
+		synchronized (this.mutex) {
+			return this.value == null;
+		}
+	}
+
+	@Override
+	public boolean isNotNull() {
+		synchronized (this.mutex) {
+			return this.value != null;
+		}
+	}
+
+	/**
+	 * Set the value. If the value changes, all waiting
+	 * threads are notified. Return the previous value.
+	 */
+	@Override
+	public V setValue(V value) {
+		synchronized (this.mutex) {
+			return this.setValue_(value);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private V setValue_(V v) {
+		V old = this.value;
+		return ObjectTools.equals(old, v) ? old : this.setValue_(v, old);
+	}
+
+	/**
+	 * Pre-condition: synchronized and new value is different
+	 */
+	private V setChangedValue_(V v) {
+		return this.setValue_(v, this.value);
+	}
+
+	/**
+	 * Pre-condition: synchronized and new value is different
+	 */
+	private V setValue_(V v, V old) {
+		this.value = v;
+		this.mutex.notifyAll();
+		return old;
+	}
+
+	/**
+	 * Set the value to <code>null</code>. If the value changes, all waiting
+	 * threads are notified. Return the previous value.
+	 */
+	@Override
+	public V setNull() {
+		return this.setValue(null);
+	}
+
+	/**
+	 * If the current value is the specified expected value, set it to the
+	 * specified new value. Return the previous value.
+	 */
+	public V compareAndSwap(V expectedValue, V newValue) {
+		synchronized (this.mutex) {
+			return this.compareAndSwap_(expectedValue, newValue);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private V compareAndSwap_(V expectedValue, V newValue) {
+		return ObjectTools.equals(this.value, expectedValue) ? this.setValue_(newValue) : this.value;
+	}
+
+	/**
+	 * Return the object the synchronized object locks on while performing
+	 * its operations.
+	 */
+	public Object getMutex() {
+		return this.mutex;
+	}
+
+
+	// ********** indefinite waits **********
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to the specified value. If the value is already the
+	 * specified value, return immediately.
+	 */
+	public void waitUntilValueIs(V v) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilValueIs_(v);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void waitUntilValueIs_(V v) throws InterruptedException {
+		while (ObjectTools.notEquals(this.value, v)) {
+			this.mutex.wait();
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to something other than the specified value. If the
+	 * value is already <em>not</em> the specified value,
+	 * return immediately.
+	 */
+	public void waitUntilValueIsNot(V v) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilValueIsNot_(v);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private void waitUntilValueIsNot_(V v) throws InterruptedException {
+		while (ObjectTools.equals(this.value, v)) {
+			this.mutex.wait();
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to <code>null</code>.
+	 * If the value is already <code>null</code>, return immediately.
+	 */
+	public void waitUntilNull() throws InterruptedException {
+		this.waitUntilValueIs(null);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to something other than <code>null</code>.
+	 * If the value is already <em>not</em> <code>null</code>,
+	 * return immediately.
+	 */
+	public void waitUntilNotNull() throws InterruptedException {
+		this.waitUntilValueIsNot(null);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to
+	 * something other than the specified value, then change
+	 * it back to the specified value and continue executing.
+	 * If the value is already <em>not</em> the specified value, set
+	 * the value immediately.
+	 * Return the previous value.
+	 */
+	public V waitToSetValue(V v) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilValueIsNot_(v);
+			return this.setChangedValue_(v);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to
+	 * something other than <code>null</code>, then change it
+	 * back to <code>null</code> and continue executing.
+	 * If the value is already <em>not</em> <code>null</code>,
+	 * set the value to <code>null</code> immediately.
+	 * Return the previous value.
+	 */
+	public V waitToSetNull() throws InterruptedException {
+		return this.waitToSetValue(null);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to
+	 * the specified expected value, then change it
+	 * to the specified new value and continue executing.
+	 * If the value is already the specified expected value,
+	 * set the value to the specified new value immediately.
+	 * Return the previous value.
+	 */
+	public V waitToSwap(V expectedValue, V newValue) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilValueIs_(expectedValue);
+			return this.setValue_(newValue);
+		}
+	}
+
+
+	// ********** timed waits **********
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the specified value was achieved; return <code>false</code>
+	 * if a time-out occurred.
+	 * If the value is already the specified value, return true immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilValueIs(V v, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilValueIs_(v, timeout);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private boolean waitUntilValueIs_(V v, long timeout) throws InterruptedException {
+		if (timeout == 0L) {
+			this.waitUntilValueIs_(v);  // wait indefinitely until notified
+			return true;  // if it ever comes back, the condition was met
+		}
+
+		long stop = System.currentTimeMillis() + timeout;
+		long remaining = timeout;
+		while (ObjectTools.notEquals(this.value, v) && (remaining > 0L)) {
+			this.mutex.wait(remaining);
+			remaining = stop - System.currentTimeMillis();
+		}
+		return ObjectTools.equals(this.value, v);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to something
+	 * other than the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the specified value was removed; return <code>false</code> if a
+	 * time-out occurred. If the value is already <em>not</em> the specified
+	 * value, return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilValueIsNot(V v, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilValueIsNot_(v, timeout);
+		}
+	}
+
+	/**
+	 * Pre-condition: synchronized
+	 */
+	private boolean waitUntilValueIsNot_(V v, long timeout) throws InterruptedException {
+		if (timeout == 0L) {
+			this.waitUntilValueIsNot_(v);	// wait indefinitely until notified
+			return true;	// if it ever comes back, the condition was met
+		}
+
+		long stop = System.currentTimeMillis() + timeout;
+		long remaining = timeout;
+		while (ObjectTools.equals(this.value, v) && (remaining > 0L)) {
+			this.mutex.wait(remaining);
+			remaining = stop - System.currentTimeMillis();
+		}
+		return ObjectTools.notEquals(this.value, v);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to <code>null</code> or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the specified value was achieved; return <code>false</code>
+	 * if a time-out occurred. If the value is already <code>null</code>,
+	 * return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilNull(long timeout) throws InterruptedException {
+		return this.waitUntilValueIs(null, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to something other than <code>null</code> or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the specified value was achieved; return <code>false</code>
+	 * if a time-out occurred. If the value is already <em>not</em>
+	 * <code>null</code>, return <code>true</code> immediately.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitUntilNotNull(long timeout) throws InterruptedException {
+		return this.waitUntilValueIsNot(null, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to
+	 * something other than the specified value, then change
+	 * it back to the specified value and continue executing.
+	 * If the value does not change to something other than the
+	 * specified value before the time-out, simply continue executing
+	 * without changing the value.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the value was set to the specified value; return <code>false</code>
+	 * if a time-out occurred.
+	 * If the value is already something other than the specified value, set
+	 * the value immediately and return <code>true</code>.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitToSetValue(V v, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilValueIsNot_(v, timeout);
+			if (success) {
+				this.setChangedValue_(v);
+			}
+			return success;
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to something
+	 * other than <code>null</code>, then change it back to <code>null</code>
+	 * and continue executing. If the value does not change to something
+	 * other than <code>null</code> before the time-out, simply continue
+	 * executing without changing the value.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the value was set to <code>null</code>; return <code>false</code>
+	 * if a time-out occurred.
+	 * If the value is already something other than <code>null</code>, set
+	 * the value to <code>null</code> immediately and return <code>true</code>.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitToSetNull(long timeout) throws InterruptedException {
+		return this.waitToSetValue(null, timeout);
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to
+	 * the specified expected value, then change it
+	 * to the specified new value and continue executing.
+	 * If the value does not change to the specified expected value
+	 * before the time-out, simply continue executing without changing
+	 * the value.
+	 * The time-out is specified in milliseconds. Return <code>true</code>
+	 * if the value was set to the specified new value; return
+	 * <code>false</code> if a time-out occurred.
+	 * If the value is already the specified expected value,
+	 * set the value to the specified new value immediately.
+	 * Return the previous value.
+	 * If the time-out is zero, wait indefinitely.
+	 */
+	public boolean waitToSwap(V expectedValue, V newValue, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilValueIs_(expectedValue, timeout);
+			if (success) {
+				this.setValue_(newValue);
+			}
+			return success;
+		}
+	}
+
+
+	// ********** synchronized behavior **********
+
+	/**
+	 * If current thread is not interrupted, execute the specified command
+	 * with the mutex locked. This is useful for initializing the value from another
+	 * thread.
+	 */
+	public void execute(Command command) throws InterruptedException {
+		if (Thread.currentThread().isInterrupted()) {
+			throw new InterruptedException();
+		}
+		synchronized (this.mutex) {
+			command.execute();
+		}
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public SynchronizedObject<V> clone() {
+		try {
+			synchronized (this.mutex) {
+				@SuppressWarnings("unchecked")
+				SynchronizedObject<V> clone = (SynchronizedObject<V>) super.clone();
+				return clone;
+			}
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	@Override
+	public String toString() {
+		return '[' + String.valueOf(this.getValue()) + ']';
+	}
+
+	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+		synchronized (this.mutex) {
+			s.defaultWriteObject();
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/CachingComboBoxModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/CachingComboBoxModel.java
new file mode 100644
index 0000000..03de5cd
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/CachingComboBoxModel.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.swing;
+
+import javax.swing.ComboBoxModel;
+
+/**
+ * This interface allows a client to better control the performance of
+ * a combo box model by allowing the client to specify when it is
+ * acceptable for the model to "cache" and "uncache" its list of elements.
+ * The model may ignore these hints if appropriate.
+ */
+public interface CachingComboBoxModel
+	extends ComboBoxModel
+{
+	/**
+	 * Cache the comboBoxModel List.  If you call this, you
+	 * must make sure to call uncacheList() as well.  Otherwise
+	 * stale data will be in the ComboBox until cacheList() is
+	 * called again or uncacheList() is called.
+	 */
+	void cacheList();
+
+	/**
+	 * Clear the cached list.  Next time the list is needed it will
+	 * be built when it is not cached.
+	 */
+	void uncacheList();
+
+	/**
+	 * Check to see if the list is already cached.  This can be used for
+	 * MouseEvents, since they are not terribly predictable.
+	 */
+	boolean isCached();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/CheckBoxTableCellRenderer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/CheckBoxTableCellRenderer.java
new file mode 100644
index 0000000..9b174aa
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/CheckBoxTableCellRenderer.java
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.swing;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.JCheckBox;
+import javax.swing.JTable;
+import javax.swing.SwingConstants;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import org.eclipse.persistence.tools.utility.swing.TableCellEditorAdapter.ImmediateEditListener;
+
+/**
+ * Make the cell look like a check box.
+ */
+@SuppressWarnings("nls")
+public class CheckBoxTableCellRenderer
+	implements TableCellEditorAdapter.Renderer
+{
+	/** the component used to paint the cell */
+	private final JCheckBox checkBox;
+
+	/** the listener to be notified on an immediate edit */
+	protected TableCellEditorAdapter.ImmediateEditListener immediateEditListener;
+
+	/** "normal" border - assume the default table "focus" border is 1 pixel thick */
+	private static final Border NO_FOCUS_BORDER = BorderFactory.createEmptyBorder(1, 1, 1, 1);
+
+
+	// ********** constructors/initialization **********
+
+	/**
+	 * Construct a cell renderer with no label or icon.
+	 */
+	public CheckBoxTableCellRenderer() {
+		super();
+		this.checkBox = this.buildCheckBox();
+		// by default, check boxes do not paint their borders
+		this.checkBox.setBorderPainted(true);
+		// this setting is recommended for check boxes inside of trees and tables
+		this.checkBox.setBorderPaintedFlat(true);
+	}
+
+	/**
+	 * Construct a cell renderer with the specified text and icon,
+	 * either of which may be null.
+	 */
+	public CheckBoxTableCellRenderer(String text, Icon icon) {
+		this();
+		this.setText(text);
+		this.setIcon(icon);
+	}
+
+	/**
+	 * Construct a cell renderer with the specified text.
+	 */
+	public CheckBoxTableCellRenderer(String text) {
+		this(text, null);
+	}
+
+	/**
+	 * Construct a cell renderer with the specified icon.
+	 */
+	public CheckBoxTableCellRenderer(Icon icon) {
+		this(null, icon);
+	}
+
+	protected JCheckBox buildCheckBox() {
+		JCheckBox cb = new JCheckBox();
+		cb.addActionListener(this.buildActionListener());
+		return cb;
+	}
+
+	private ActionListener buildActionListener() {
+		return new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				if (CheckBoxTableCellRenderer.this.immediateEditListener != null) {
+					CheckBoxTableCellRenderer.this.immediateEditListener.immediateEdit();
+				}
+			}
+		};
+	}
+
+
+	// ********** TableCellRenderer implementation **********
+
+	@Override
+	public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) {
+	    this.checkBox.setHorizontalAlignment(SwingConstants.CENTER);
+		this.checkBox.setComponentOrientation(table.getComponentOrientation());
+		this.checkBox.setFont(table.getFont());
+		this.checkBox.setEnabled(table.isEnabled());
+
+		this.checkBox.setForeground(this.foregroundColor(table, value, selected, hasFocus, row, column));
+		this.checkBox.setBackground(this.backgroundColor(table, value, selected, hasFocus, row, column));
+		// once the colors are set, calculate opaque setting
+		this.checkBox.setOpaque(this.cellIsOpaqueIn(table, value, selected, hasFocus, row, column));
+		this.checkBox.setBorder(this.border(table, value, selected, hasFocus, row, column));
+
+		this.setValue(value);
+		return this.checkBox;
+	}
+
+	/**
+	 * Return the cell's foreground color.
+	 */
+	protected Color foregroundColor(JTable table, @SuppressWarnings("unused") Object value, boolean selected, boolean hasFocus, int row, int column) {
+		if (selected) {
+			if (hasFocus && table.isCellEditable(row, column)) {
+				return UIManager.getColor("Table.focusCellForeground");
+			}
+			return table.getSelectionForeground();
+		}
+		return table.getForeground();
+	}
+
+	/**
+	 * Return the cell's background color.
+	 */
+	protected Color backgroundColor(JTable table, @SuppressWarnings("unused") Object value, boolean selected, boolean hasFocus, int row, int column) {
+		if (selected) {
+			if (hasFocus && table.isCellEditable(row, column)) {
+				return UIManager.getColor("Table.focusCellBackground");
+			}
+			return table.getSelectionBackground();
+		}
+		return table.getBackground();
+	}
+
+	/**
+	 * Return the cell's border.
+	 */
+	protected Border border(@SuppressWarnings("unused") JTable table, @SuppressWarnings("unused") Object value, @SuppressWarnings("unused") boolean selected, boolean hasFocus, @SuppressWarnings("unused") int row, @SuppressWarnings("unused") int column) {
+		return hasFocus ?  UIManager.getBorder("Table.focusCellHighlightBorder") : NO_FOCUS_BORDER;
+	}
+
+	/**
+	 * Return whether the cell should be opaque in the table.
+	 * If the cell's background is the same as the table's background
+	 * and table is opaque, we don't need to paint the background -
+	 * the table will do it.
+	 */
+	protected boolean cellIsOpaqueIn(JTable table, @SuppressWarnings("unused") Object value, @SuppressWarnings("unused") boolean selected, @SuppressWarnings("unused") boolean hasFocus, @SuppressWarnings("unused") int row, @SuppressWarnings("unused") int column) {
+		Color cellBackground = this.checkBox.getBackground();
+		Color tableBackground = table.getBackground();
+		return ! (table.isOpaque() && cellBackground.equals(tableBackground));
+	}
+
+	/**
+	 * Set the check box's value.
+	 */
+	protected void setValue(Object value) {
+		// CR#3999318 - This null check needs to be removed once JDK bug is fixed
+		if (value == null) {
+			value = Boolean.FALSE;
+		}
+		this.checkBox.setSelected(((Boolean) value).booleanValue());
+	}
+
+
+	// ********** TableCellEditorAdapter.Renderer implementation **********
+
+	@Override
+	public Object getValue() {
+		return Boolean.valueOf(this.checkBox.isSelected());
+	}
+
+	@Override
+	public void setImmediateEditListener(ImmediateEditListener listener) {
+		this.immediateEditListener = listener;
+	}
+
+	// ********** public API **********
+
+	/**
+	 * Set the check box's text; which by default is blank.
+	 */
+	public void setText(String text) {
+		this.checkBox.setText(text);
+	}
+
+	/**
+	 * Set the check box's icon; which by default is not present.
+	 */
+	public void setIcon(Icon icon) {
+		this.checkBox.setIcon(icon);
+	}
+
+	/**
+	 * Return the renderer's preferred height. This allows you
+	 * to set the table's row height to something the check box
+	 * will look good in....
+	 */
+	public int preferredHeight() {
+		// add in space for the border top and bottom
+		return (int) this.checkBox.getPreferredSize().getHeight() + 2;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/ComboBoxTableCellRenderer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/ComboBoxTableCellRenderer.java
new file mode 100644
index 0000000..cef9904
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/ComboBoxTableCellRenderer.java
@@ -0,0 +1,342 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.swing;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.BorderFactory;
+import javax.swing.ComboBoxModel;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JTable;
+import javax.swing.ListCellRenderer;
+import javax.swing.SwingConstants;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Make the cell look like a combo-box.
+ */
+@SuppressWarnings("nls")
+public class ComboBoxTableCellRenderer
+	implements TableCellEditorAdapter.Renderer
+{
+	/* caching the combo box because we are caching the comboBoxModel.
+	 * Everytime we rebuilt the comboBox we would set the model on it and not
+	 * remove the model from the old combo box.  This meant that new listeners
+	 * kept being added to the comboBoxModel for every comboBox build.
+	 * Not sure if there is a way to clear out the old combo box, or why
+	 * we were buildig a new combo box every time so I went with caching it.
+	 */
+	private JComboBox comboBox;
+
+	/** the items used to populate the combo box */
+	private CachingComboBoxModel model;
+	private ListCellRenderer renderer;
+	Object value;
+	private static int height = -1;
+	boolean fakeFocusFlag;
+
+	/** the listener to be notified on an immediate edit */
+	protected TableCellEditorAdapter.ImmediateEditListener immediateEditListener;
+
+	/** hold the original colors of the combo-box */
+	private static Color defaultForeground;
+	private static Color defaultBackground;
+
+	/** "normal" border - assume the default table "focus" border is 1 pixel thick */
+	private static final Border NO_FOCUS_BORDER = BorderFactory.createEmptyBorder(1, 1, 1, 1);
+
+
+	// ********** constructors/initialization **********
+
+	/**
+	 * Default constructor.
+	 */
+	private ComboBoxTableCellRenderer() {
+		super();
+		initialize();
+	}
+
+	/**
+	 * Construct a cell renderer that uses the specified combo-box model.
+	 */
+	public ComboBoxTableCellRenderer(ComboBoxModel model) {
+		this(new NonCachingComboBoxModel(model));
+	}
+
+	/**
+	 * Construct a cell renderer that uses the specified caching combo-box model.
+	 */
+	public ComboBoxTableCellRenderer(CachingComboBoxModel model) {
+		this();
+		this.model = model;
+	}
+
+	/**
+	 * Construct a cell renderer that uses the specified
+	 * combo-box model and renderer.
+	 */
+	public ComboBoxTableCellRenderer(ComboBoxModel model, ListCellRenderer renderer) {
+		this(new NonCachingComboBoxModel(model), renderer);
+	}
+
+	/**
+	 * Construct a cell renderer that uses the specified
+	 * caching combo-box model and renderer.
+	 */
+	public ComboBoxTableCellRenderer(CachingComboBoxModel model, ListCellRenderer renderer) {
+		this(model);
+		this.renderer = renderer;
+	}
+
+	protected void initialize() {
+		// save the original colors of the combo-box, so we
+		// can use them to paint non-selected cells
+		if (height == -1) {
+			JComboBox cb = new JComboBox();
+			cb.addItem("m");
+
+			// add in space for the border top and bottom
+			height = cb.getPreferredSize().height + 2;
+
+			defaultForeground = cb.getForeground();
+			defaultBackground = cb.getBackground();
+		}
+	}
+
+    static JLabel prototypeLabel = new JLabel("Prototype", new EmptyIcon(16), SwingConstants.LEADING);
+
+    protected JComboBox buildComboBox() {
+
+		final JComboBox result = new JComboBox() {
+			private boolean fakeFocus;
+			private static final long serialVersionUID = 1L;
+			@Override
+			public boolean hasFocus() {
+				return this.fakeFocus || super.hasFocus();
+			}
+			@Override
+			public void paint(Graphics g) {
+				this.fakeFocus = ComboBoxTableCellRenderer.this.fakeFocusFlag;
+				super.paint(g);
+				this.fakeFocus = false;
+			}
+			//wrap the renderer to deal with the prototypeDisplayValue
+		    @Override
+			public void setRenderer(final ListCellRenderer aRenderer) {
+		        super.setRenderer(new ListCellRenderer(){
+		            @Override
+						public Component getListCellRendererComponent(JList list, Object v, int index, boolean isSelected, boolean cellHasFocus) {
+		                if (v == prototypeLabel) {
+		                    return prototypeLabel;
+		                }
+		                return aRenderer.getListCellRendererComponent(list, v, index, isSelected, cellHasFocus);
+		            }
+		        });
+		    }
+			@Override
+			public int getSelectedIndex() {
+		        boolean listNotCached = !listIsCached();
+		        if (listNotCached) {
+		            cacheList();
+		        }
+
+				int index = super.getSelectedIndex();
+
+		        if (listNotCached) {
+		            uncacheList();
+		        }
+				return index;
+		   }
+
+		};
+		// stole this code from javax.swing.DefaultCellEditor
+		result.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
+		result.addActionListener(this.buildActionListener());
+		result.addPopupMenuListener(this.buildPopupMenuListener());
+
+        //These are used to workaround problems with Swing trying to
+        //determine the size of a comboBox with a large model
+        result.setPrototypeDisplayValue(prototypeLabel);
+        getListBox(result).setPrototypeCellValue(prototypeLabel);
+
+		return result;
+	}
+
+
+    private JList getListBox(JComboBox result) {
+        return (JList) ObjectTools.get(result.getUI(), "listBox");
+    }
+
+
+	private ActionListener buildActionListener() {
+		return new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				JComboBox cb = (JComboBox) e.getSource();
+				Object selectedItem = cb.getSelectedItem();
+
+				// Only update the selected item and invoke immediateEdit() if the
+				// selected item actually changed, during the initialization of the
+				// editing, the model changes and causes this method to be invoked,
+				// it causes CR#3963675 to occur because immediateEdit() stop the
+				// editing, which is done at the wrong time
+				if (ComboBoxTableCellRenderer.this.value != selectedItem) {
+					ComboBoxTableCellRenderer.this.value = cb.getSelectedItem();
+					ComboBoxTableCellRenderer.this.immediateEdit();
+				}
+			}
+		};
+	}
+
+	void immediateEdit() {
+		if (this.immediateEditListener != null) {
+			this.immediateEditListener.immediateEdit();
+		}
+	}
+
+	private PopupMenuListener buildPopupMenuListener() {
+		return new PopupMenuListener() {
+
+			@Override
+			public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+				if (listIsCached()) {
+					uncacheList();
+				}
+				cacheList();
+			}
+
+			@Override
+			public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
+	            if (listIsCached()) {
+	                uncacheList();
+	            }
+
+			}
+
+			@Override
+			public void popupMenuCanceled(PopupMenuEvent e) {
+	            if (listIsCached()) {
+	                uncacheList();
+	            }
+			}
+		};
+	}
+
+
+	void cacheList() {
+		this.model.cacheList();
+	}
+
+	void uncacheList() {
+		this.model.uncacheList();
+	}
+
+	boolean listIsCached() {
+		return this.model.isCached();
+	}
+	// ********** TableCellRenderer implementation **********
+
+	@Override
+	public Component getTableCellRendererComponent(JTable table, Object val, boolean selected, boolean hasFocus, int row, int column) {
+		this.fakeFocusFlag = selected || hasFocus;
+		if (this.comboBox == null) {
+			this.comboBox = this.buildComboBox();
+
+			this.comboBox.setComponentOrientation(table.getComponentOrientation());
+			this.comboBox.setModel(this.model);
+			if (this.renderer != null) {
+				this.comboBox.setRenderer(this.renderer);
+			}
+			this.comboBox.setFont(table.getFont());
+			this.comboBox.setEnabled(table.isEnabled());
+			this.comboBox.setBorder(this.border(table, val, selected, hasFocus, row, column));
+		}
+
+		// We need to go through the model since JComboBox might prevent us from
+		// selecting the value. This can happen when the value is not contained
+		// in the model, see CR#3950044 for an example
+		this.model.setSelectedItem(val);
+
+		return this.comboBox;
+	}
+
+	/**
+	 * Return the cell's foreground color.
+	 */
+	protected Color foregroundColor(JTable table, @SuppressWarnings("unused") Object val, boolean selected, boolean hasFocus, int row, int column) {
+		if (selected) {
+			if (hasFocus && table.isCellEditable(row, column)) {
+				return defaultForeground;
+			}
+			return table.getSelectionForeground();
+		}
+		return defaultForeground;
+	}
+
+	/**
+	 * Return the cell's background color.
+	 */
+	protected Color backgroundColor(JTable table, @SuppressWarnings("unused") Object val, boolean selected, boolean hasFocus, int row, int column) {
+		if (selected) {
+			if (hasFocus && table.isCellEditable(row, column)) {
+				return defaultBackground;
+			}
+			return table.getSelectionBackground();
+		}
+		return defaultBackground;
+	}
+
+	/**
+	 * Return the cell's border.
+	 */
+	protected Border border(@SuppressWarnings("unused") JTable table, @SuppressWarnings("unused") Object val, @SuppressWarnings("unused") boolean selected, boolean hasFocus, @SuppressWarnings("unused") int row, @SuppressWarnings("unused") int column) {
+		return hasFocus ?
+			UIManager.getBorder("Table.focusCellHighlightBorder") //$NON-NLS-1$
+		:
+			NO_FOCUS_BORDER;
+	}
+
+
+	// ********** TableCellEditorAdapter.Renderer implementation **********
+
+	@Override
+	public Object getValue() {
+		return this.value;
+	}
+
+	@Override
+	public void setImmediateEditListener(TableCellEditorAdapter.ImmediateEditListener listener) {
+		this.immediateEditListener = listener;
+	}
+
+
+	// ********** public API **********
+
+	/**
+	 * Return the renderer's preferred height. This allows you
+	 * to set the row height to something the combo-box will look good in....
+	 */
+	public int preferredHeight() {
+		return height;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/EmptyIcon.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/EmptyIcon.java
new file mode 100644
index 0000000..9d3f076
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/EmptyIcon.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.swing;
+
+import java.awt.Component;
+import java.awt.Graphics;
+import javax.swing.Icon;
+
+/**
+ * Implement the {@link Icon} interface with an icon that has a size but
+ * does not paint anything on the graphics context.
+ */
+public class EmptyIcon
+	implements Icon
+{
+	private final int width;
+	private final int height;
+
+	public static final EmptyIcon NULL_INSTANCE = new EmptyIcon(0);
+
+
+	public EmptyIcon(int size) {
+		this(size, size);
+	}
+
+	public EmptyIcon(int width, int height) {
+		super();
+		this.width = width;
+		this.height = height;
+	}
+
+	@Override
+	public void paintIcon(Component c, Graphics g, int x, int y) {
+		// don't paint anything for an empty icon
+	}
+
+	@Override
+	public int getIconWidth() {
+		return this.width;
+	}
+
+	@Override
+	public int getIconHeight() {
+		return this.height;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/FilteringListBrowser.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/FilteringListBrowser.java
new file mode 100644
index 0000000..2721830
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/FilteringListBrowser.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.swing;
+
+import javax.swing.Icon;
+import javax.swing.JComboBox;
+import javax.swing.JOptionPane;
+import javax.swing.ListModel;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * This implementation of ListChooser.ListBrowser uses a
+ * {@link JOptionPane} to prompt the user for the selection. The {@link JOptionPane}
+ * is passed a {@link FilteringListPanel} to assist the user in making
+ * a selection.
+ */
+@SuppressWarnings("nls")
+public class FilteringListBrowser<T>
+	implements ListChooser.ListBrowser
+{
+	private FilteringListPanel<T> panel;
+
+	/**
+	 * Default constructor.
+	 */
+	public FilteringListBrowser() {
+		super();
+		this.panel = this.buildPanel();
+	}
+
+	protected FilteringListPanel<T> buildPanel() {
+		return new LocalFilteringListPanel<T>();
+	}
+
+	/**
+	 * Prompt the user using a JOptionPane with a filtering
+	 * list panel.
+	 */
+	@Override
+	public void browse(ListChooser chooser) {
+		this.initializeCellRenderer(chooser);
+
+		int option =
+			JOptionPane.showOptionDialog(
+				chooser,
+				this.buildMessage(chooser),
+				this.buildTitle(chooser),
+				this.buildOptionType(chooser),
+				this.buildMessageType(chooser),
+				this.buildIcon(chooser),
+				this.buildSelectionValues(chooser),
+				this.buildInitialSelectionValue(chooser)
+		);
+
+		if (option == JOptionPane.OK_OPTION) {
+			chooser.getModel().setSelectedItem(this.panel.getSelection());
+		}
+
+		// clear the text field so the list box is re-filtered
+		this.panel.getTextField().setText("");
+	}
+
+	protected void initializeCellRenderer(JComboBox comboBox) {
+		// default behavior should be to use the cell renderer from the combobox.
+		this.panel.getListBox().setCellRenderer(comboBox.getRenderer());
+	}
+
+	/**
+	 * the message can be anything - here we build a component
+	 */
+	protected Object buildMessage(JComboBox comboBox) {
+		this.panel.setCompleteList(this.convertListModelToArray(comboBox.getModel()));
+		this.panel.setSelection(comboBox.getModel().getSelectedItem());
+		return this.panel;
+	}
+
+	/**
+	 * Convert the list of objects in the specified list model
+	 * into an array.
+	 */
+	@SuppressWarnings("unchecked")
+	protected T[] convertListModelToArray(ListModel model) {
+		int size = model.getSize();
+		T[] result = (T[]) new Object[size];
+		for (int i = 0; i < size; i++) {
+			result[i] = (T) model.getElementAt(i);
+		}
+		return result;
+	}
+
+	protected String buildTitle(@SuppressWarnings("unused") JComboBox comboBox) {
+		return null;
+	}
+
+	protected int buildOptionType(@SuppressWarnings("unused") JComboBox comboBox) {
+		return JOptionPane.OK_CANCEL_OPTION;
+	}
+
+	protected int buildMessageType(@SuppressWarnings("unused") JComboBox comboBox) {
+		return JOptionPane.QUESTION_MESSAGE;
+	}
+
+	protected Icon buildIcon(@SuppressWarnings("unused") JComboBox comboBox) {
+		return null;
+	}
+
+	protected Object[] buildSelectionValues(@SuppressWarnings("unused") JComboBox comboBox) {
+		return null;
+	}
+
+	protected Object buildInitialSelectionValue(@SuppressWarnings("unused") JComboBox comboBox) {
+		return null;
+	}
+
+
+	// ********** custom panel **********
+
+	protected static class LocalFilteringListPanel<S>
+		extends FilteringListPanel<S>
+	{
+		private static final long serialVersionUID = 1L;
+
+		@SuppressWarnings("unchecked")
+		protected LocalFilteringListPanel() {
+			super((S[]) ObjectTools.EMPTY_OBJECT_ARRAY, null);
+		}
+
+		/**
+		 * Disable the performance tweak because JOptionPane
+		 * will try open wide enough to disable the horizontal scroll bar;
+		 * and it looks a bit clumsy.
+		 */
+		@Override
+		protected String getPrototypeCellValue() {
+			return null;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/FilteringListPanel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/FilteringListPanel.java
new file mode 100644
index 0000000..b01566d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/FilteringListPanel.java
@@ -0,0 +1,459 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Font;
+import javax.swing.AbstractListModel;
+import javax.swing.BorderFactory;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+import javax.swing.ListCellRenderer;
+import javax.swing.ListModel;
+import javax.swing.ListSelectionModel;
+import javax.swing.border.Border;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.StringMatcher;
+import org.eclipse.persistence.tools.utility.transformer.StringObjectTransformer;
+import org.eclipse.persistence.tools.utility.transformer.Transformer;
+
+/**
+ * This panel presents an entry field and a list box of choices that
+ * allows the user to filter the entries in the list box by entering
+ * a pattern in the entry field.
+ * <p>
+ * Two wildcards are allowed in the pattern:<ul>
+ * <li>'*' will match any set of zero or more characters
+ * <li>'?' will match any single character
+ * <.ul>
+ * The panel consists of 4 components that can be customized:<ul>
+ * <li>1 text field
+ * <li>1 list box
+ * <li>2 labels, one for each of the above
+ * </ul>
+ * Other aspects of the panel's behavior can be changed:<ul>
+ * <li>the string converter determines how the objects in the
+ *     list are converted to strings and compared to the pattern
+ *     entered in the text field; by default the converter simply
+ *     uses the result of the object's #toString() method
+ *     (if you replace the string converter, you will probably
+ *     want to replace the list box's cell renderer also)
+ * <li>the string matcher can also be changed if you would
+ *     like different pattern matching behavior than that
+ *     described above
+ * <li>you can specify the maximum size of the list - this may
+ *     force the user to enter a pattern restrictive enough
+ *     to result in a list smaller than the maximum size; the
+ *     default is -1, which disables the restriction
+ * </ul>
+ * This panel is not a typical panel, in the sense that it does not share
+ * its model with clients via value models. Instead, this panel's model
+ * is set and queried directly because it is designed to be used in a
+ * dialog that directs the user's behavior (as opposed to a "normal"
+ * window).
+ */
+@SuppressWarnings("nls")
+public class FilteringListPanel<T>
+	extends JPanel
+{
+	/**
+	 * The complete list of available choices
+	 * (as opposed to the partial list held by the list box).
+	 */
+	private T[] completeList;
+
+	/**
+	 * An adapter used to convert the objects in the list
+	 * to strings so they can be run through the matcher
+	 * and displayed in the text field.
+	 */
+	Transformer<T, String> transformer;
+
+	/** The text field. */
+	private JTextField textField;
+	private JLabel textFieldLabel;
+	private DocumentListener textFieldListener;
+
+	/** The list box. */
+	private JList listBox;
+	private JLabel listBoxLabel;
+
+	/** The maximum number of entries displayed in the list box. */
+	private int maxListSize;
+
+	/**
+	 * Performance tweak: We use this buffer instead of
+	 * a temporary variable during filtering so we don't have
+	 * to keep re-allocating it.
+	 */
+	private Object[] buffer;
+
+	private static final Border TEXT_FIELD_LABEL_BORDER = BorderFactory.createEmptyBorder(0, 0, 5, 0);
+	private static final Border LIST_BOX_LABEL_BORDER = BorderFactory.createEmptyBorder(5, 0, 5, 0);
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a FilteringListPanel with the specified list of choices
+	 * and initial selection. Use the default string converter to convert the
+	 * choices and selection to strings (which simply calls #toString() on
+	 * the objects).
+	 */
+	public FilteringListPanel(T[] completeList, T initialSelection) {
+		this(completeList, initialSelection, StringObjectTransformer.<T>instance());
+	}
+
+	/**
+	 * Construct a FilteringListPanel with the specified list of choices
+	 * and initial selection. Use the specified string converter to convert the
+	 * choices and selection to strings.
+	 */
+	public FilteringListPanel(T[] completeList, T initialSelection, Transformer<T, String> stringConverter) {
+		super(new BorderLayout());
+		this.completeList = completeList;
+		this.transformer = stringConverter;
+		this.initialize(initialSelection);
+	}
+
+
+	// ********** initialization **********
+
+	private void initialize(T initialSelection) {
+		this.maxListSize = this.getDefaultMaxListSize();
+		this.buffer = this.buildBuffer();
+
+		this.textFieldListener = this.buildTextFieldListener();
+
+		this.initializeLayout(initialSelection);
+	}
+
+	private Object[] buildBuffer() {
+		return new Object[this.getMax()];
+	}
+
+	/**
+	 * Return the current max number of entries allowed in the list box.
+	 */
+	private int getMax() {
+		return (this.maxListSize == -1) ?
+				this.completeList.length :
+				Math.min(this.maxListSize, this.completeList.length);
+	}
+
+	/**
+	 * Build a listener that will listen to changes in the text field
+	 * and filter the list appropriately.
+	 */
+	private DocumentListener buildTextFieldListener() {
+		return new TextFieldListener();
+	}
+
+	/* CU private */ class TextFieldListener
+		implements DocumentListener
+	{
+		@Override
+		public void insertUpdate(DocumentEvent e) {
+			FilteringListPanel.this.filterList();
+		}
+		@Override
+		public void changedUpdate(DocumentEvent e) {
+			FilteringListPanel.this.filterList();
+		}
+		@Override
+		public void removeUpdate(DocumentEvent e) {
+			FilteringListPanel.this.filterList();
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.toString(this);
+		}
+	}
+
+	private int getDefaultMaxListSize() {
+		return -1;
+	}
+
+	private void initializeLayout(Object initialSelection) {
+		// text field
+		JPanel textFieldPanel = new JPanel(new BorderLayout());
+		this.textFieldLabel = new JLabel();
+		this.textFieldLabel.setBorder(TEXT_FIELD_LABEL_BORDER);
+		textFieldPanel.add(this.textFieldLabel, BorderLayout.NORTH);
+
+		this.textField = new JTextField();
+		this.textField.getDocument().addDocumentListener(this.textFieldListener);
+		this.textFieldLabel.setLabelFor(this.textField);
+		textFieldPanel.add(this.textField, BorderLayout.CENTER);
+
+		this.add(textFieldPanel, BorderLayout.NORTH);
+
+		// list box
+		JPanel listBoxPanel = new JPanel(new BorderLayout());
+		this.listBoxLabel = new JLabel();
+		this.listBoxLabel.setBorder(LIST_BOX_LABEL_BORDER);
+		listBoxPanel.add(this.listBoxLabel, BorderLayout.NORTH);
+
+		this.listBox = new JList();
+		this.listBox.setDoubleBuffered(true);
+		this.listBox.setModel(this.buildPartialArrayListModel(this.completeList, this.getMax()));
+		this.listBox.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+		// performance tweak(?)
+		this.listBox.setPrototypeCellValue(this.getPrototypeCellValue());
+		this.listBox.setPrototypeCellValue(null);
+		this.listBox.setCellRenderer(this.buildDefaultCellRenderer());
+		this.listBoxLabel.setLabelFor(this.listBox);
+		// bug 2777802 - scroll bars shouldn't be on the tab sequence
+		JScrollPane listBoxScrollPane = new JScrollPane(this.listBox);
+		listBoxScrollPane.getHorizontalScrollBar().setFocusable(false);
+		listBoxScrollPane.getVerticalScrollBar().setFocusable(false);
+		listBoxPanel.add(listBoxScrollPane, BorderLayout.CENTER);
+
+		// initialize the widgets
+		this.listBox.setSelectedValue(initialSelection, true);
+		this.textField.select(0, this.textField.getText().length());
+
+		this.add(listBoxPanel, BorderLayout.CENTER);
+	}
+
+
+	// ********** public API **********
+
+	public Object getSelection() {
+		return this.listBox.getSelectedValue();
+	}
+
+	public void setSelection(Object selection) {
+		this.listBox.setSelectedValue(selection, true);
+	}
+
+	public T[] getCompleteList() {
+		return this.completeList;
+	}
+
+	/**
+	 * rebuild the filtering buffer and re-apply the filter
+	 * to the new list
+	 */
+	public void setCompleteList(T[] completeList) {
+		this.completeList = completeList;
+		if (this.buffer.length < this.getMax()) {
+			// the buffer will never shrink - might want to re-consider...  ~bjv
+			this.buffer = this.buildBuffer();
+		}
+		this.filterList();
+	}
+
+	public int getMaxListSize() {
+		return this.maxListSize;
+	}
+
+	public void setMaxListSize(int maxListSize) {
+		this.maxListSize = maxListSize;
+		if (this.buffer.length < this.getMax()) {
+			// the buffer will never shrink - might want to re-consider...  ~bjv
+			this.buffer = this.buildBuffer();
+		}
+		this.filterList();
+	}
+
+	public Transformer<T, String> getTransformer() {
+		return this.transformer;
+	}
+
+	/**
+	 * apply the new filter to the list
+	 */
+	public void setTransformer(Transformer<T, String> transformer) {
+		this.transformer = transformer;
+		this.filterList();
+	}
+
+	/**
+	 * allow client code to access the text field
+	 * (so we can set the focus)
+	 */
+	public JTextField getTextField() {
+		return this.textField;
+	}
+
+	/**
+	 * allow client code to access the text field label
+	 */
+	public JLabel getTextFieldLabel() {
+		return this.textFieldLabel;
+	}
+
+	/**
+	 * convenience method
+	 */
+	public void setTextFieldLabelText(String text) {
+		this.textFieldLabel.setText(text);
+	}
+
+	/**
+	 * allow client code to access the list box
+	 * (so we can add mouse listeners for double-clicking)
+	 */
+	public JList getListBox() {
+		return this.listBox;
+	}
+
+	/**
+	 * convenience method
+	 */
+	public void setListBoxCellRenderer(ListCellRenderer renderer) {
+		this.listBox.setCellRenderer(renderer);
+	}
+
+	/**
+	 * allow client code to access the list box label
+	 */
+	public JLabel getListBoxLabel() {
+		return this.listBoxLabel;
+	}
+
+	/**
+	 * convenience method
+	 */
+	public void setListBoxLabelText(String text) {
+		this.listBoxLabel.setText(text);
+	}
+
+	/**
+	 * convenience method
+	 */
+	public void setComponentsFont(Font font) {
+		this.textFieldLabel.setFont(font);
+		this.textField.setFont(font);
+		this.listBoxLabel.setFont(font);
+		this.listBox.setFont(font);
+	}
+
+
+	// ********** internal methods **********
+
+	/**
+	 * Allow subclasses to disable performance tweak
+	 * by returning null here.
+	 */
+	protected String getPrototypeCellValue() {
+		return "==========> A_STRING_THAT_IS_DEFINITELY_LONGER_THAN_EVERY_STRING_IN_THE_LIST <==========";
+	}
+
+	/**
+	 * By default, use the string converter to build the text
+	 * used by the list box's cell renderer.
+	 */
+	protected ListCellRenderer buildDefaultCellRenderer() {
+		return new DefaultCellRenderer();
+	}
+
+	protected class DefaultCellRenderer
+		extends SimpleListCellRenderer
+	{
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		@SuppressWarnings("unchecked")
+		protected String buildText(Object value) {
+			return FilteringListPanel.this.transformer.transform((T) value);
+		}
+	}
+
+	/**
+	 * Something has changed that requires us to filter the list.
+	 * <p>
+	 * This method is synchronized because a fast typist can
+	 * generate events quicker than we can filter the list. (?  ~bjv)
+	 */
+	synchronized void filterList() {
+		// temporarily stop listening to the list box selection, since we will
+		// be changing the selection during the filtering and don't want
+		// that to affect the text field
+		this.filterList(this.textField.getText());
+	}
+
+	/**
+	 * Filter the contents of the list box to match the
+	 * specified pattern.
+	 */
+	private void filterList(String pattern) {
+		if (pattern.length() == 0) {
+			this.listBox.setModel(this.buildPartialArrayListModel(this.completeList, this.getMax()));
+		} else {
+			StringMatcher stringMatcher = new StringMatcher(pattern + ALL, true, false);
+			int j = 0;
+			int len = this.completeList.length;
+			int max = this.getMax();
+			for (int i = 0; i < len; i++) {
+				if (stringMatcher.match(this.transformer.transform(this.completeList[i]))) {
+					this.buffer[j++] = this.completeList[i];
+				}
+				if (j == max) {
+					break;
+				}
+			}
+			this.listBox.setModel(this.buildPartialArrayListModel(this.buffer, j));
+		}
+
+		// after filtering the list, determine the appropriate selection
+		if (this.listBox.getModel().getSize() == 0) {
+			this.listBox.getSelectionModel().clearSelection();
+		} else {
+			this.listBox.getSelectionModel().setAnchorSelectionIndex(0);
+			this.listBox.getSelectionModel().setLeadSelectionIndex(0);
+			this.listBox.ensureIndexIsVisible(0);
+		}
+	}
+	private static final String ALL = "*";
+
+	/**
+	 * Build a list model that wraps only a portion of the specified array.
+	 * The model will include the array entries from 0 to (size - 1).
+	 */
+	private ListModel buildPartialArrayListModel(Object[] array, int size) {
+		return new PartialArrayListModel<T>(array, size);
+	}
+
+	/* CU private */ static class PartialArrayListModel<T>
+		extends AbstractListModel
+	{
+		private final Object[] array;
+		private final int size;
+		private static final long serialVersionUID = 1L;
+
+		PartialArrayListModel(Object[] array, int size) {
+			super();
+			this.array = array;
+			this.size = size;
+		}
+		@Override
+		public int getSize() {
+			return this.size;
+		}
+		@Override
+		@SuppressWarnings("unchecked")
+		public T getElementAt(int index) {
+			return (T) this.array[index];
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/ListChooser.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/ListChooser.java
new file mode 100644
index 0000000..5335e3c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/ListChooser.java
@@ -0,0 +1,482 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.swing;
+
+import java.awt.AWTEvent;
+import java.awt.AWTException;
+import java.awt.Component;
+import java.awt.EventQueue;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.io.Serializable;
+import javax.swing.ComboBoxModel;
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.ListCellRenderer;
+import javax.swing.SwingConstants;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
+import javax.swing.plaf.basic.BasicComboBoxUI;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * This component provides a way to handle selecting an item from a
+ * list that may grow too large to be handled conveniently by a combo-box.
+ * If the list's size is less than the designated "long" list size,
+ * the choice list will be displayed in a normal combo-box popup;
+ * otherwise, a dialog will be used to prompt the user to choose a selection.
+ *
+ * To change the browse mechanism, subclasses may
+ * 	- override the method #buildBrowser()
+ *  - override the method #browse(), in which case the method
+ * 		#buildBrowser() may be ignored.
+ */
+@SuppressWarnings("nls")
+public class ListChooser
+	extends JComboBox
+{
+	/** the size of a "long" list - anything smaller is a "short" list */
+	int longListSize = DEFAULT_LONG_LIST_SIZE;
+
+	/** the default size of a "long" list, which is 20 (to match JOptionPane's behavior) */
+	public static final int DEFAULT_LONG_LIST_SIZE = 20;
+
+	/** property change associated with long list size */
+	public static final String LONG_LIST_SIZE_PROPERTY = "longListSize";
+
+	static JLabel prototypeLabel = new JLabel("Prototype", new EmptyIcon(17), SwingConstants.LEADING);
+
+	/**
+	 * whether the chooser is choosable.  if a chooser is not choosable,
+	 * it only serves as a display widget.  a user may not change its
+	 * selected value.
+	 */
+	boolean choosable = true;
+
+	/** property change associated with choosable */
+	public static final String CHOOSABLE_PROPERTY = "choosable";
+
+	/** the browser used to make a selection from the long list - typically via a dialog */
+	private ListBrowser browser;
+
+	private NodeSelector nodeSelector;
+
+	/** INTERNAL - The popup is being shown.  Used to prevent infinite loop. */
+	boolean popupAlreadyInProgress;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// **************** Constructors ******************************************
+
+	/**
+	 * Construct a list chooser for the specified model.
+	 */
+	public ListChooser(ComboBoxModel model) {
+		this(model, NodeSelector.Default.instance());
+	}
+
+	public ListChooser(CachingComboBoxModel model) {
+		this(model, NodeSelector.Default.instance());
+	}
+
+	public ListChooser(ComboBoxModel model, NodeSelector nodeSelector) {
+		this(new NonCachingComboBoxModel(model), nodeSelector);
+	}
+
+	public ListChooser(CachingComboBoxModel model, NodeSelector nodeSelector) {
+		super(model);
+		this.initialize();
+		this.nodeSelector = nodeSelector;
+	}
+	// **************** Initialization ****************************************
+
+	protected void initialize() {
+		this.addPopupMenuListener(this.buildPopupMenuListener());
+		this.setRenderer(new DefaultListCellRenderer());
+		this.addKeyListener(this.buildF3KeyListener());
+
+		//These are used to workaround problems with Swing trying to
+		//determine the size of a comboBox with a large model
+		this.setPrototypeDisplayValue(prototypeLabel);
+		this.listBox().setPrototypeCellValue(prototypeLabel);
+	}
+
+
+	private JList listBox() {
+		return (JList) ObjectTools.get(this.ui, "listBox");
+	}
+
+	/**
+	 * When the popup is about to be shown, the event is consumed, and
+	 * PopupHandler determines whether to reshow the popup or to show
+	 * the long list browser.
+	 */
+	private PopupMenuListener buildPopupMenuListener() {
+		return new PopupMenuListener() {
+			@Override
+			public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+				ListChooser.this.aboutToShowPopup();
+			}
+			@Override
+			public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
+				// do nothing
+			}
+			@Override
+			public void popupMenuCanceled(PopupMenuEvent e) {
+				// do nothing
+			}
+			@Override
+			public String toString() {
+				return "pop-up menu listener";
+			}
+		};
+	}
+
+	/**
+	 * If this code is being reached due to the PopupHandler already being in progress,
+	 * then do nothing.  Otherwise, set the flag to true and launch the PopupHandler.
+	 */
+	void aboutToShowPopup() {
+		if (this.popupAlreadyInProgress) {
+			return;
+		}
+
+		this.popupAlreadyInProgress = true;
+		EventQueue.invokeLater(new PopupHandler());
+	}
+
+
+	private KeyListener buildF3KeyListener() {
+		return new KeyAdapter() {
+			@Override
+			public void keyPressed(KeyEvent e) {
+				if (e.getKeyCode() == KeyEvent.VK_F3) {
+					ListChooser.this.goToSelectedItem();
+				}
+			}
+			@Override
+			public String toString() {
+				return "F3 key listener";
+			}
+		};
+	}
+
+	public void goToSelectedItem() {
+		if (this.getSelectedItem() != null) {
+			ListChooser.this.nodeSelector.selectNodeFor(this.getSelectedItem());
+		}
+	}
+
+	// **************** Browsing **********************************************
+
+	/**
+	 * Lazily initialize because subclasses may have further initialization to do
+	 * before browser can be built.
+	 */
+	protected void browse() {
+		if (this.browser == null) {
+			this.browser = this.buildBrowser();
+		}
+
+		this.browser.browse(this);
+	}
+
+	/**
+	 * Return the "browser" used to make a selection from the long list,
+	 * typically via a dialog.
+	 */
+	protected ListChooser.ListBrowser buildBrowser() {
+		return new SimpleListBrowser();
+	}
+
+
+	// **************** Choosable functionality *******************************
+
+	/** override behavior - consume selection if chooser is not choosable */
+	@Override
+	public void setSelectedIndex(int anIndex) {
+		if (this.choosable) {
+			super.setSelectedIndex(anIndex);
+		}
+	}
+
+	private void updateArrowButton() {
+		try {
+			BasicComboBoxUI comboBoxUi = (BasicComboBoxUI) ListChooser.this.getUI();
+			JButton arrowButton = (JButton) ObjectTools.get(comboBoxUi, "arrowButton");
+			arrowButton.setEnabled(this.isEnabled() && this.choosable);
+		}
+		catch (Exception e) {
+			// this is a huge hack to try and make the combo box look right,
+			// so if it doesn't work, just swallow the exception
+		}
+	}
+
+
+	// **************** List Caching *******************************
+
+	void cacheList() {
+		((CachingComboBoxModel) this.getModel()).cacheList();
+	}
+
+	void uncacheList() {
+		((CachingComboBoxModel) this.getModel()).uncacheList();
+	}
+
+	boolean listIsCached() {
+		return ((CachingComboBoxModel) this.getModel()).isCached();
+	}
+
+	// **************** Public ************************************************
+
+	public int longListSize() {
+		return this.longListSize;
+	}
+
+	public void setLongListSize(int newLongListSize) {
+		int oldLongListSize = this.longListSize;
+		this.longListSize = newLongListSize;
+		this.firePropertyChange(LONG_LIST_SIZE_PROPERTY, oldLongListSize, newLongListSize);
+	}
+
+	public boolean isChoosable() {
+		return this.choosable;
+	}
+
+	public void setChoosable(boolean newValue) {
+		boolean oldValue = this.choosable;
+		this.choosable = newValue;
+		this.firePropertyChange(CHOOSABLE_PROPERTY, oldValue, newValue);
+		this.updateArrowButton();
+	}
+
+	// **************** Handle selecting null as a value **********************
+
+	private boolean selectedIndexIsNoneSelectedItem(int index) {
+		return (index == -1) &&
+				 (this.getModel().getSize() > 0) &&
+				 (this.getModel().getElementAt(0) == null);
+	}
+
+	@Override
+	public int getSelectedIndex() {
+		boolean listNotCached = !this.listIsCached();
+		if (listNotCached) {
+			this.cacheList();
+		}
+
+		int index = super.getSelectedIndex();
+
+		// Use index 0 to show the <none selected> item since the actual value is
+		// null and JComboBox does not handle null values
+		if (this.selectedIndexIsNoneSelectedItem(index)) {
+			index = 0;
+		}
+
+		if (listNotCached) {
+			this.uncacheList();
+		}
+		return index;
+   }
+
+	//wrap the renderer to deal with the prototypeDisplayValue
+	@Override
+	public void setRenderer(final ListCellRenderer aRenderer) {
+		super.setRenderer(new ListCellRenderer(){
+			@Override
+			public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+				if (value == prototypeLabel) {
+					return prototypeLabel;
+				}
+				return aRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+			}
+		});
+	}
+
+
+	// **************** Member classes ****************************************
+
+	/**
+	 * Define the API required by this ListChooser when it must
+	 * prompt the user to select an item from the "long" list.
+	 */
+	public interface ListBrowser
+	{
+		/**
+		 * Prompt the user to make a selection from the specified
+		 * combo-box's model.
+		 */
+		void browse(ListChooser parentChooser);
+	}
+
+
+	/**
+	 * Runnable class that consumes popup window and determines whether
+	 * to reshow popup or to launch browser, based on the size of the list.
+	 */
+	private class PopupHandler
+		implements Runnable
+	{
+		/** The mouse event */
+		private MouseEvent lastMouseEvent;
+
+		/** The component from which the last mouse event was thrown */
+		private JComponent eventComponent;
+
+		/** The location of the component at the time the last mouse event was thrown */
+		private Point componentLocation;
+
+		/** The location of the mouse at the time the last mouse event was thrown */
+		private Point mouseLocation;
+
+
+		PopupHandler() {
+			this.initialize();
+		}
+
+		private void initialize() {
+			AWTEvent event = EventQueue.getCurrentEvent();
+
+			if (event instanceof MouseEvent) {
+				this.lastMouseEvent = (MouseEvent) event;
+				this.eventComponent = (JComponent) this.lastMouseEvent.getSource();
+				this.componentLocation = this.eventComponent.getLocationOnScreen();
+				this.mouseLocation = this.lastMouseEvent.getPoint();
+			}
+			else {
+				this.eventComponent = null;
+				this.componentLocation = null;
+				this.mouseLocation = null;
+			}
+		}
+
+		@Override
+		public void run() {
+			ListChooser.this.hidePopup();
+
+			ListChooser.this.cacheList();
+			if (ListChooser.this.choosable == true) {
+				// If the combo box model is of sufficient length, the browser will be shown.
+				// Asking the combo box model for its size should be enough to ensure that
+				//  its size is recalculated.
+				if (ListChooser.this.getModel().getSize() > ListChooser.this.longListSize) {
+					this.checkComboBoxButton();
+					ListChooser.this.browse();
+				}
+				else {
+					ListChooser.this.showPopup();
+					this.checkMousePosition();
+				}
+			}
+			if (ListChooser.this.listIsCached()) {
+				ListChooser.this.uncacheList();
+			}
+
+			ListChooser.this.popupAlreadyInProgress = false;
+		}
+
+		/** If this is not done, the button never becomes un-pressed */
+		private void checkComboBoxButton() {
+			try {
+				BasicComboBoxUI comboBoxUi = (BasicComboBoxUI) ListChooser.this.getUI();
+				JButton arrowButton = (JButton) ObjectTools.get(comboBoxUi, "arrowButton");
+				arrowButton.getModel().setPressed(false);
+			}
+			catch (Exception ex) {
+				// this is a huge hack to try and make the combo box look right,
+				// so if it doesn't work, just swallow the exception
+				this.handleException(ex);
+			}
+		}
+
+		private void handleException(@SuppressWarnings("unused") Exception ex) {
+			// do nothing for now
+		}
+
+		/**
+		 * Moves the mouse back to its original position before any jiggery pokery that we've done.
+		 */
+		private void checkMousePosition() {
+			if (this.eventComponent == null) {
+				return;
+			}
+
+			final Point newComponentLocation = this.eventComponent.getLocationOnScreen();
+			boolean componentMoved =
+				((newComponentLocation.x - this.componentLocation.x) != 0)
+				|| ((newComponentLocation.y - this.componentLocation.y) != 0);
+
+			if (componentMoved) {
+				try {
+					new Robot().mouseMove(
+						newComponentLocation.x + this.mouseLocation.x,
+						newComponentLocation.y + this.mouseLocation.y
+					);
+				}
+				catch (AWTException ex) {
+					// move failed - do nothing
+				}
+			}
+		}
+	}
+
+	/**
+	 * This will be called when the user presses F3 or chooses
+	 * 'Go To' in the context menu
+	 */
+	public interface NodeSelector {
+		/**
+		 * Select the appropriate Node in the tree or the editor panel.
+		 */
+		void selectNodeFor(Object item);
+
+		/**
+		 * This NodeSelector will do nothing when selectNodeFor(Object) is called
+		 */
+		final class Default
+			implements NodeSelector, Serializable
+		{
+			public static final NodeSelector INSTANCE = new Default();
+			public static NodeSelector instance() {
+				return INSTANCE;
+			}
+			// ensure single instance
+			private Default() {
+				super();
+			}
+			@Override
+			public void selectNodeFor(Object item) {
+				//default is to do nothing
+			}
+			@Override
+			public String toString() {
+				return ObjectTools.singletonToString(this);
+			}
+			private static final long serialVersionUID = 1L;
+			private Object readResolve() {
+				// replace this object with the singleton
+				return INSTANCE;
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/NonCachingComboBoxModel.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/NonCachingComboBoxModel.java
new file mode 100644
index 0000000..4b4469e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/NonCachingComboBoxModel.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.swing;
+
+import javax.swing.ComboBoxModel;
+import javax.swing.event.ListDataListener;
+
+/**
+ * This implementation of the CachingComboBoxModel interface can be used
+ * whenever there is no need for caching (i.e. the contents of the selection
+ * list can be generated with little latency). All the normal ComboBoxModel
+ * behavior is delegated to a client-supplied ComboBoxModel.
+ */
+public class NonCachingComboBoxModel
+	implements CachingComboBoxModel
+{
+	private ComboBoxModel wrappedComboBoxModel;
+
+
+	public NonCachingComboBoxModel(ComboBoxModel wrappedComboBoxModel) {
+		this.wrappedComboBoxModel = wrappedComboBoxModel;
+	}
+
+
+	// ********** CachingComboBoxModel implementation **********
+
+	@Override
+	public void cacheList() {
+		//do nothing
+	}
+
+	@Override
+	public void uncacheList() {
+		//do nothing
+	}
+
+	@Override
+	public boolean isCached() {
+		return false;
+	}
+
+
+	// ********** ComboBoxModel implementation **********
+
+	@Override
+	public void setSelectedItem(Object anItem) {
+		this.wrappedComboBoxModel.setSelectedItem(anItem);
+	}
+
+	@Override
+	public Object getSelectedItem() {
+		return this.wrappedComboBoxModel.getSelectedItem();
+	}
+
+
+	// ********** ListModel implementation **********
+
+	@Override
+	public int getSize() {
+		return this.wrappedComboBoxModel.getSize();
+	}
+
+	@Override
+	public Object getElementAt(int index) {
+		return this.wrappedComboBoxModel.getElementAt(index);
+	}
+
+	@Override
+	public void addListDataListener(ListDataListener l) {
+		this.wrappedComboBoxModel.addListDataListener(l);
+	}
+
+	@Override
+	public void removeListDataListener(ListDataListener l) {
+		this.wrappedComboBoxModel.removeListDataListener(l);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/SimpleListBrowser.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/SimpleListBrowser.java
new file mode 100644
index 0000000..f16045f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/SimpleListBrowser.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.swing;
+
+import javax.swing.Icon;
+import javax.swing.JComboBox;
+import javax.swing.JOptionPane;
+import javax.swing.ListModel;
+
+/**
+ * This implementation of ListChooser.Browser uses a
+ * JOptionPane to prompt the user for the selection. Subclasses
+ * can change the dialog's title, message, and/or icon.
+ */
+public class SimpleListBrowser
+	implements ListChooser.ListBrowser
+{
+	/** Default constructor */
+	protected SimpleListBrowser() {
+		super();
+	}
+
+	/**
+	 * Prompt the user using a JOptionPane.
+	 */
+	@Override
+	public void browse(ListChooser chooser) {
+		Object selection =
+			JOptionPane.showInputDialog(
+				chooser,
+				this.message(chooser),
+				this.title(chooser),
+				this.messageType(chooser),
+				this.icon(chooser),
+				this.selectionValues(chooser),
+				this.initialSelectionValue(chooser)
+			);
+
+		if (selection != null) {
+			chooser.getModel().setSelectedItem(selection);
+		}
+	}
+
+	protected Object message(@SuppressWarnings("unused") JComboBox comboBox) {
+		return null;
+	}
+
+	protected String title(@SuppressWarnings("unused") JComboBox comboBox) {
+		return null;
+	}
+
+	protected int messageType(@SuppressWarnings("unused") JComboBox comboBox) {
+		return JOptionPane.QUESTION_MESSAGE;
+	}
+
+	protected Icon icon(@SuppressWarnings("unused") JComboBox comboBox) {
+		return null;
+	}
+
+	protected Object[] selectionValues(JComboBox comboBox) {
+		return this.convertToArray(comboBox.getModel());
+	}
+
+	protected Object initialSelectionValue(JComboBox comboBox) {
+		return comboBox.getModel().getSelectedItem();
+	}
+
+	/**
+	 * Convert the list of objects in the specified list model
+	 * into an array.
+	 */
+	protected Object[] convertToArray(ListModel model) {
+		int size = model.getSize();
+		Object[] result = new Object[size];
+		for (int i = 0; i < size; i++) {
+			result[i] = model.getElementAt(i);
+		}
+		return result;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/SimpleListCellRenderer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/SimpleListCellRenderer.java
new file mode 100644
index 0000000..dfb4ca2
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/SimpleListCellRenderer.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.swing;
+
+import java.awt.Component;
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.Icon;
+import javax.swing.JList;
+import org.eclipse.persistence.tools.utility.StringTools;
+
+/**
+ * This renderer should behave the same as the DefaultListCellRenderer;
+ * but it slightly refactors the calculation of the icon and text of the list
+ * cell so that subclasses can easily override the methods that build
+ * the icon and text.
+ *
+ * In most cases, you need only override:
+ *     #buildIcon(Object value)
+ *     #buildText(Object value)
+ */
+public class SimpleListCellRenderer
+	extends DefaultListCellRenderer
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Construct a simple renderer.
+	 */
+	public SimpleListCellRenderer() {
+		super();
+	}
+
+	@Override
+	public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+		// substitute null for the cell value so nothing is drawn initially...
+		super.getListCellRendererComponent(list, null, index, isSelected, cellHasFocus);
+		this.setOpaque(true);
+
+		// ...then set the icon and text manually
+		this.setIcon(this.buildIcon(list, value, index, isSelected, cellHasFocus));
+		this.setText(this.buildText(list, value, index, isSelected, cellHasFocus));
+
+		this.setToolTipText(this.buildToolTipText(list, value, index, isSelected, cellHasFocus));
+
+		// the context will be initialized only if a reader is running
+		if (this.accessibleContext != null) {
+			this.accessibleContext.setAccessibleName(this.buildAccessibleName(list, value, index, isSelected, cellHasFocus));
+		}
+
+		return this;
+	}
+
+	/**
+	 * Return the icon representation of the specified cell
+	 * value and other settings. (Even more settings are
+	 * accessible via inherited getters: hasFocus, isEnabled, etc.)
+	 */
+	protected Icon buildIcon(@SuppressWarnings("unused") JList list, Object value, @SuppressWarnings("unused") int index, @SuppressWarnings("unused") boolean isSelected, @SuppressWarnings("unused") boolean cellHasFocus) {
+		return this.buildIcon(value);
+	}
+
+	/**
+	 * Return the icon representation of the specified cell
+	 * value. The default is to display no icon at all unless the
+	 * value itself is an icon.
+	 */
+	protected Icon buildIcon(Object value) {
+		// replicate the default behavior
+		return (value instanceof Icon) ? (Icon) value : null;
+	}
+
+	/**
+	 * Return the textual representation of the specified cell
+	 * value and other settings. (Even more settings are
+	 * accessible via inherited getters: hasFocus, isEnabled, etc.)
+	 */
+	protected String buildText(@SuppressWarnings("unused") JList list, Object value, @SuppressWarnings("unused") int index, @SuppressWarnings("unused") boolean isSelected, @SuppressWarnings("unused") boolean cellHasFocus) {
+		return this.buildText(value);
+	}
+
+	/**
+	 * Return the textual representation of the specified cell
+	 * value. The default is to display the object's default string
+	 * representation (as returned by #toString()); unless the
+	 * value itself is an icon, in which case no text is displayed.
+	 */
+	protected String buildText(Object value) {
+		return (value instanceof Icon) ? StringTools.EMPTY_STRING : ((value == null) ? StringTools.EMPTY_STRING : value.toString());
+	}
+
+	/**
+	 * Return the text displayed when the cursor lingers over the specified cell.
+	 * (Even more settings are accessible via inherited getters: hasFocus, isEnabled, etc.)
+	 */
+	protected String buildToolTipText(@SuppressWarnings("unused") JList list, Object value, @SuppressWarnings("unused") int index, @SuppressWarnings("unused") boolean isSelected, @SuppressWarnings("unused") boolean cellHasFocus) {
+		return this.buildToolTipText(value);
+	}
+
+	/**
+	 * Return the text displayed when the cursor lingers over the specified cell.
+	 */
+	protected String buildToolTipText(@SuppressWarnings("unused") Object value) {
+		return null;
+	}
+
+	/**
+	 * Return the accessible name to be given to the component used to render
+	 * the given value and other settings. (Even more settings are accessible via
+	 * inherited getters: hasFocus, isEnabled, etc.)
+	 */
+	protected String buildAccessibleName(@SuppressWarnings("unused") JList list, Object value, @SuppressWarnings("unused") int index, @SuppressWarnings("unused") boolean isSelected, @SuppressWarnings("unused") boolean cellHasFocus) {
+		return this.buildAccessibleName(value);
+	}
+
+	/**
+	 * Return the accessible name to be given to the component used to render
+	 * the given value.
+	 */
+	protected String buildAccessibleName(@SuppressWarnings("unused") Object value) {
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/SpinnerTableCellRenderer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/SpinnerTableCellRenderer.java
new file mode 100644
index 0000000..a59b883
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/SpinnerTableCellRenderer.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.swing;
+
+import java.awt.Color;
+import java.awt.Component;
+import javax.swing.BorderFactory;
+import javax.swing.JComponent;
+import javax.swing.JSpinner;
+import javax.swing.JTable;
+import javax.swing.SpinnerModel;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+/**
+ * Make the cell look like a spinner.
+ */
+@SuppressWarnings("nls")
+public class SpinnerTableCellRenderer
+	implements TableCellEditorAdapter.Renderer
+{
+	/** the component used to paint the cell */
+	protected JSpinner spinner;
+
+	/** the listener to be notified on an immediate edit */
+	protected TableCellEditorAdapter.ImmediateEditListener immediateEditListener;
+
+
+	// ********** constructors/initialization **********
+
+	/**
+	 * Construct a cell renderer that uses the default
+	 * spinner model, which is a "number" model.
+	 */
+	public SpinnerTableCellRenderer() {
+		super();
+		this.initialize();
+	}
+
+	/**
+	 * Construct a cell renderer that uses the specified
+	 * spinner model, which will determine how the values are displayed.
+	 */
+	public SpinnerTableCellRenderer(SpinnerModel model) {
+		this();
+		this.setModel(model);
+	}
+
+	protected void initialize() {
+		this.spinner = this.buildSpinner();
+	}
+
+	protected JSpinner buildSpinner() {
+		JSpinner s = new JSpinner();
+		s.addChangeListener(this.buildChangeListener());
+		return s;
+	}
+
+	private ChangeListener buildChangeListener() {
+		return new ChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				if (SpinnerTableCellRenderer.this.immediateEditListener != null) {
+					SpinnerTableCellRenderer.this.immediateEditListener.immediateEdit();
+				}
+			}
+		};
+	}
+
+
+	// ********** TableCellRenderer implementation **********
+
+	@Override
+	public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) {
+		this.spinner.setComponentOrientation(table.getComponentOrientation());
+		this.spinner.setFont(table.getFont());
+		this.spinner.setEnabled(table.isEnabled());
+
+		JComponent editor = this.editor();
+		editor.setForeground(this.foregroundColor(table, value, selected, hasFocus, row, column));
+		editor.setBackground(this.backgroundColor(table, value, selected, hasFocus, row, column));
+		this.spinner.setBorder(this.border(table, value, selected, hasFocus, row, column));
+
+		this.setValue(value);
+		return this.spinner;
+	}
+
+	/**
+	 * Return the cell's foreground color.
+	 */
+	protected Color foregroundColor(JTable table, @SuppressWarnings("unused") Object value, boolean selected, boolean hasFocus, int row, int column) {
+		if (selected) {
+			if (hasFocus && table.isCellEditable(row, column)) {
+				return UIManager.getColor("Table.focusCellForeground");
+			}
+			return table.getSelectionForeground();
+		}
+		return table.getForeground();
+	}
+
+	/**
+	 * Return the cell's background color.
+	 */
+	protected Color backgroundColor(JTable table, @SuppressWarnings("unused") Object value, boolean selected, boolean hasFocus, int row, int column) {
+		if (selected) {
+			if (hasFocus && table.isCellEditable(row, column)) {
+				return UIManager.getColor("Table.focusCellBackground");
+			}
+			return table.getSelectionBackground();
+		}
+		return table.getBackground();
+	}
+
+	/**
+	 * Return the cell's border.
+	 */
+	protected Border border(JTable table, @SuppressWarnings("unused") Object value, boolean selected, boolean hasFocus, @SuppressWarnings("unused") int row, @SuppressWarnings("unused") int column) {
+		if (hasFocus) {
+			return UIManager.getBorder("Table.focusCellHighlightBorder");
+		}
+		if (selected) {
+			return BorderFactory.createLineBorder(table.getSelectionBackground(), 1);
+		}
+		return BorderFactory.createLineBorder(table.getBackground(), 1);
+	}
+
+	/**
+	 * Return the editor component whose colors should be set
+	 * by the renderer.
+	 */
+	protected JComponent editor() {
+		JComponent editor = this.spinner.getEditor();
+		if (editor instanceof JSpinner.DefaultEditor) {
+			// typically, the editor will be the default or one of its subclasses...
+			editor = ((JSpinner.DefaultEditor) editor).getTextField();
+		}
+		return editor;
+	}
+
+	/**
+	 * Set the spinner's value
+	 */
+	protected void setValue(Object value) {
+		// CR#3999318 - This null check needs to be removed once JDK bug is fixed
+		if (value == null) {
+			value = Integer.valueOf(0);
+		}
+		this.spinner.setValue(value);
+	}
+
+
+	// ********** TableCellEditorAdapter.Renderer implementation **********
+
+	@Override
+	public Object getValue() {
+		return this.spinner.getValue();
+	}
+
+	@Override
+	public void setImmediateEditListener(TableCellEditorAdapter.ImmediateEditListener listener) {
+		this.immediateEditListener = listener;
+	}
+
+
+	// ********** public API **********
+
+	/**
+	 * Set the spinner's model.
+	 */
+	public void setModel(SpinnerModel model) {
+		this.spinner.setModel(model);
+	}
+
+	/**
+	 * Return the renderer's preferred height. This allows you
+	 * to set the row height to something the spinner will look good in....
+	 */
+	public int preferredHeight() {
+		// add in space for the border top and bottom
+		return (int) this.spinner.getPreferredSize().getHeight() + 2;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/TableCellEditorAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/TableCellEditorAdapter.java
new file mode 100644
index 0000000..d691ee8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/swing/TableCellEditorAdapter.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.swing;
+
+import java.awt.Component;
+import javax.swing.AbstractCellEditor;
+import javax.swing.JTable;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
+
+/**
+ * A table cell editor that wraps a table cell renderer.
+ */
+public class TableCellEditorAdapter
+	extends AbstractCellEditor
+	implements TableCellEditor
+{
+	/** delegate to a renderer */
+	private Renderer renderer;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors/initialization **********
+
+	private TableCellEditorAdapter() {
+		super();
+	}
+
+	/**
+	 * Construct a cell editor that behaves like the specified renderer.
+	 */
+	public TableCellEditorAdapter(Renderer renderer) {
+		this();
+		this.initialize(renderer);
+	}
+
+	protected void initialize(Renderer r) {
+		this.renderer = r;
+		r.setImmediateEditListener(this.buildImmediateEditListener());
+	}
+
+	private ImmediateEditListener buildImmediateEditListener() {
+		return new ImmediateEditListener() {
+			@Override
+			public void immediateEdit() {
+				TableCellEditorAdapter.this.stopCellEditing();
+			}
+		};
+	}
+
+
+	// ********** CellEditor implementation **********
+
+	@Override
+	public Object getCellEditorValue() {
+		return this.renderer.getValue();
+	}
+
+
+	// ********** TableCellEditor implementation **********
+
+	@Override
+	public Component getTableCellEditorComponent(JTable table, Object value, boolean selected, int row, int column) {
+		return this.renderer.getTableCellRendererComponent(table, value, selected, true, row, column);
+	}
+
+
+	// ********** Member classes **********************************************
+
+	/**
+	 * This interface defines the methods that must be implemented by a renderer
+	 * that can be wrapped by a TableCellEditorAdapter.
+	 */
+	public interface Renderer
+		extends TableCellRenderer
+	{
+		/**
+		 * Return the current value of the renderer.
+		 */
+		Object getValue();
+
+		/**
+		 * Set the immediate edit listener
+		 */
+		void setImmediateEditListener(ImmediateEditListener listener);
+	}
+
+
+	public interface ImmediateEditListener {
+		/**
+		 * Called when the renderer does an "immediate edit"
+		 */
+		void immediateEdit();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/synchronizers/CallbackSynchronizer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/synchronizers/CallbackSynchronizer.java
deleted file mode 100644
index 49acfe1..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/synchronizers/CallbackSynchronizer.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.synchronizers;
-
-import java.io.Serializable;
-import java.util.EventListener;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * Extend {@link Synchronizer} to notify listeners
- * when a synchronization "cycle" is complete; i.e. the synchronization has,
- * for the moment, quiesced.
- */
-public interface CallbackSynchronizer
-	extends Synchronizer
-{
-	/**
-	 * Add the specified listener to be notified whenever the synchronizer has
-	 * quiesced.
-	 * @see #removeListener(Listener)
-	 */
-	void addListener(Listener listener);
-
-	/**
-	 * Remove the specified listener.
-	 * @see #addListener(Listener)
-	 */
-	void removeListener(Listener listener);
-
-	// ********** listener **********
-
-	/**
-	 * Interface implemented by listeners to be notified whenever the
-	 * synchronizer has quiesced.
-	 */
-	public interface Listener
-		extends EventListener
-	{
-		/**
-		 * The specified synchronizer has quiesced.
-		 */
-		void synchronizationQuiesced(CallbackSynchronizer synchronizer);
-	}
-
-
-	/**
-	 * Singleton implementation of the {@link CallbackSynchronizer} interface that will do
-	 * nothing.
-	 */
-	final class Null
-		implements CallbackSynchronizer, Serializable
-	{
-		public static final CallbackSynchronizer INSTANCE = new Null();
-		public static CallbackSynchronizer instance() {
-			return INSTANCE;
-		}
-		// ensure single instance
-		private Null() {
-			super();
-		}
-		@Override
-		public void start() {
-			// do nothing
-		}
-		@Override
-		public void synchronize() {
-			// do nothing
-		}
-		@Override
-		public void stop() {
-			// do nothing
-		}
-		@Override
-		public void addListener(Listener listener) {
-			// do nothing
-		}
-		@Override
-		public void removeListener(Listener listener) {
-			// do nothing
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-		private static final long serialVersionUID = 1L;
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/synchronizers/CallbackSynchronousSynchronizer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/synchronizers/CallbackSynchronousSynchronizer.java
deleted file mode 100644
index f1e9b59..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/synchronizers/CallbackSynchronousSynchronizer.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.synchronizers;
-
-import org.eclipse.persistence.tools.utility.ListenerList;
-import org.eclipse.persistence.tools.utility.command.Command;
-import org.eclipse.persistence.tools.utility.synchronizers.CallbackSynchronizer;
-
-/**
- * Extend the synchronous synchronizer to notify listeners
- * when a synchronization "cycle" is complete; i.e. the synchronization has,
- * for the moment, handled every "synchronize" request and quiesced.
- * This notification is <em>not</em> guaranteed to occur with <em>every</em>
- * synchronization "cycle";
- * since other, unrelated, synchronizations can be triggered concurrently.
- * <p>
- * <strong>NB:</strong> If another synchronization is initiated while we are
- * notifying the synchronizer's listeners (i.e. the 'again' flag is set), it will not
- * start until all the listeners are notified.
- * Note also, the synchronizer's listeners can, themselves,
- * trigger another synchronization (by directly or indirectly calling
- * {@link org.eclipse.persistence.tools.utility.synchronizers.Synchronizer#synchronize()});
- * but this synchronization will not occur until <em>after</em> all the
- * listeners have been notified.
- */
-public class CallbackSynchronousSynchronizer
-	extends SynchronousSynchronizer
-	implements CallbackSynchronizer
-{
-	private final ListenerList<Listener> listenerList = new ListenerList<Listener>(Listener.class);
-
-	// ********** construction **********
-
-	/**
-	 * Construct a callback synchronous synchronizer that uses the specified
-	 * command to perform the synchronization.
-	 */
-	public CallbackSynchronousSynchronizer(Command command) {
-		super(command);
-	}
-
-
-	// ********** CallbackSynchronizer implementation **********
-
-	@Override
-	public void addListener(Listener listener) {
-		this.listenerList.add(listener);
-	}
-
-	@Override
-	public void removeListener(Listener listener) {
-		this.listenerList.remove(listener);
-	}
-
-	/**
-	 * Notify our listeners.
-	 */
-	private void synchronizationQuiesced() {
-		for (Listener listener : this.listenerList.getListeners()) {
-			listener.synchronizationQuiesced(this);
-		}
-	}
-
-
-	// ********** override **********
-
-	@Override
-	void execute_() {
-		super.execute_();
-		if (this.state.getValue() != State.REPEAT) {
-			// hmmm - we will notify listeners even when we are "stopped";
-			// that seems ok...  ~bjv
-			this.synchronizationQuiesced();
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/synchronizers/Synchronizer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/synchronizers/Synchronizer.java
deleted file mode 100644
index 8b31bba..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/synchronizers/Synchronizer.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.synchronizers;
-
-import java.io.Serializable;
-
-import org.eclipse.persistence.tools.utility.StringTools;
-
-/**
- * This interface defines the protocol for starting, stopping, and executing a
- * long-running, repeatable, and possibly recursive "synchronization" process.
- * The intent is for the synchronizer to synchronize a "secondary" model with
- * a "primary" model. Any change to the "primary" model will trigger the
- * synchronization. The synchronizer implementation will determine whether the
- * "secondary" model remains in sync synchronously or asynchronously.
- * <p>
- * The assumption is that the {@link #start()} and {@link #stop()} methods will be called from
- * a single master thread that would control the synchronizer's lifecycle and
- * the {@link #synchronize()} method will be called multiple times, possibly from
- * multiple threads.
- */
-public interface Synchronizer {
-
-	/**
-	 * Enable the synchronizer to allow future synchronizations as requested
-	 * by calls to {@link #synchronize()}.
-	 */
-	void start();
-
-	/**
-	 * Synchronize the dependent model with the primary model. Do nothing if
-	 * {@link #start()} has not previously been called. Do nothing if {@link #stop}
-	 * has been called (without any intermediate call to {@link #start()}.
-	 */
-	void synchronize();
-
-	/**
-	 * Stop the synchronizer immediately or, if a synchronization is currently
-	 * Returns when the synchronizer is stopped.
-	 * No further synchonizations will performed until {@link #start()} is called.
-	 */
-	void stop();
-
-	/**
-	 * Singleton implementation of the {@link Synchronizer} interface that will do
-	 * nothing.
-	 */
-	final class Null
-		implements Synchronizer, Serializable
-	{
-		public static final Synchronizer INSTANCE = new Null();
-		public static Synchronizer instance() {
-			return INSTANCE;
-		}
-		// ensure single instance
-		private Null() {
-			super();
-		}
-		@Override
-		public void start() {
-			// do nothing
-		}
-		@Override
-		public void synchronize() {
-			// do nothing
-		}
-		@Override
-		public void stop() {
-			// do nothing
-		}
-		@Override
-		public String toString() {
-			return StringTools.buildSingletonToString(this);
-		}
-		private static final long serialVersionUID = 1L;
-		private Object readResolve() {
-			// replace this object with the singleton
-			return INSTANCE;
-		}
-	}
-}
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/synchronizers/SynchronousSynchronizer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/synchronizers/SynchronousSynchronizer.java
deleted file mode 100644
index 5dc232e..0000000
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/synchronizers/SynchronousSynchronizer.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.utility.synchronizers;
-
-import java.util.Vector;
-
-import org.eclipse.persistence.tools.utility.CompositeException;
-import org.eclipse.persistence.tools.utility.StringTools;
-import org.eclipse.persistence.tools.utility.SynchronizedObject;
-import org.eclipse.persistence.tools.utility.command.Command;
-import org.eclipse.persistence.tools.utility.synchronizers.Synchronizer;
-
-/**
- * Returns until the
- * synchronization and any nested (recursive) synchronizations are complete.
- * In some situations this implementation should be used sparingly, and for as
- * short a time as possible, as it increases the probability of deadlocks. A
- * deadlock can occur when {@link Synchronizer#synchronize()} is called from multiple
- * threads and multiple resources are locked by the synchronization in varying
- * orders.
- * <p>
- * As defined in the {@link Synchronizer} interface, {@link Synchronizer#start()}
- * and {@link Synchronizer#stop()}
- * should be called in the same thread, but it is not required.
- * {@link Synchronizer#synchronize()} should
- * always be called in the same thread (i.e. only recursively, beyond the
- * initial call); although, this too is not required.
- * This thread need not be the same thread that executes
- * {@link Synchronizer#start()} and {@link Synchronizer#stop()}.
- */
-@SuppressWarnings("nls")
-public class SynchronousSynchronizer
-	implements Synchronizer
-{
-	/**
-	 * The client-supplied command that performs the synchronization. It may
-	 * trigger further calls to {@link #synchronize()} (i.e. the
-	 * synchronization may recurse).
-	 */
-	private final Command command;
-
-	/**
-	 * The synchronizer's current state.
-	 */
-	final SynchronizedObject<State> state;
-
-	/**
-	 * The synchronizer's initial state is {@link #STOPPED}.
-	 */
-	enum State {
-		STOPPED,
-		READY,
-		EXECUTING,
-		REPEAT,
-		STOPPING
-	}
-
-	/**
-	 * A list of the uncaught exceptions thrown by the command.
-	 */
-	final Vector<Throwable> exceptions = new Vector<Throwable>();
-
-	// ********** construction **********
-
-	/**
-	 * Construct a synchronous synchronizer that uses the specified command to
-	 * perform the synchronization.
-	 */
-	public SynchronousSynchronizer(Command command) {
-		super();
-		if (command == null) {
-			throw new NullPointerException();
-		}
-		this.command = command;
-		// use the synchronizer as the mutex so it is freed up by the wait in #stop()
-		this.state = new SynchronizedObject<State>(State.STOPPED, this);
-	}
-
-
-	// ********** Synchronizer implementation **********
-
-	/**
-	 * Set the synchronizer's {@link #state} to {@link State#READY READY}
-	 * and execute the first synchronization. Throw an exception if the
-	 * synchronizer is not {@link State#STOPPED STOPPED}.
-	 */
-	@Override
-	public synchronized void start() {
-		switch (this.state.getValue()) {
-			case STOPPED:
-				this.state.setValue(State.READY);
-				this.synchronize();
-				break;
-			case READY:
-			case EXECUTING:
-			case REPEAT:
-			case STOPPING:
-				throw this.buildISE();
-		}
-	}
-
-	/**
-	 * It's possible to come back here if the synchronization command recurses
-	 * and triggers another synchronization.
-	 */
-	@Override
-	public void synchronize() {
-		if (this.beginSynchronization()) {
-			this.synchronize_();
-		}
-	}
-
-	/**
-	 * A client has requested a synchronization.
-	 * Returns whether we can begin a new synchronization.
-	 * Returns <code>false</code>;
-	 * but set the {@link #state} to {@link State#REPEAT REPEAT}
-	 * so another synchronization will occur once the current
-	 * synchronization is complete.
-	 */
-	private synchronized boolean beginSynchronization() {
-		switch (this.state.getValue()) {
-			case STOPPED:
-				// synchronization is not allowed
-				return false;
-			case READY:
-				// begin a new synchronization
-				this.state.setValue(State.EXECUTING);
-				return true;
-			case EXECUTING:
-				// set flag so a new synchronization will occur once the current one is finished
-				this.state.setValue(State.REPEAT);
-				return false;
-			case REPEAT:
-				// the "repeat" flag is already set
-				return false;
-			case STOPPING:
-				// no further synchronizations are allowed
-				return false;
-		}
-		throw this.buildISE();
-	}
-
-	/**
-	 * This method should be called only once per set of "recursing"
-	 * synchronizations. Any recursive call to {@link #synchronize()} will
-	 * simply set the {@link #state} to {@link State#REPEAT REPEAT},
-	 * causing the command to execute again.
-	 */
-	private void synchronize_() {
-		do {
-			this.execute();
-		} while (this.repeatSynchronization());
-	}
-
-	/**
-	 * Execute the client-supplied command. Do not allow any unhandled
-	 * exceptions to kill the thread. Store them up for later pain.
-	 */
-	private void execute() {
-		try {
-			this.execute_();
-		} catch (Throwable ex) {
-			this.exceptions.add(ex);
-		}
-	}
-
-	/**
-	 * By default, just execute the command.
-	 */
-	void execute_() {
-		this.command.execute();
-	}
-
-	/**
-	 * The current synchronization has finished.
-	 * Returns whether we should begin another synchronization.
-	 */
-	private synchronized boolean repeatSynchronization() {
-		switch (this.state.getValue()) {
-			case STOPPED:
-			case READY:
-				throw this.buildISE();
-			case EXECUTING:
-				// * Returns to "ready"
-				this.state.setValue(State.READY);
-				return false;
-			case REPEAT:
-				// the "repeat" flag was set; clear it and start another synchronization
-				this.state.setValue(State.EXECUTING);
-				return true;
-			case STOPPING:
-				// a client has initiated a "stop"; mark the "stop" complete and perform no more synchronizations
-				this.state.setValue(State.STOPPED);
-				return false;
-		}
-		throw this.buildISE();
-	}
-
-	/**
-	 * Set the flags so that no further synchronizations occur. If any uncaught
-	 * exceptions were thrown while the synchronization was executing,
-	 * wrap them in a composite exception and throw the composite exception.
-	 */
-	@Override
-	public synchronized void stop() {
-		switch (this.state.getValue()) {
-			case STOPPED:
-				throw this.buildISE();
-			case READY:
-				// * Returns to "stopped" state
-				this.state.setValue(State.STOPPED);
-				break;
-			case EXECUTING:
-			case REPEAT:
-				// set the "stopping" flag and wait until the synchronization has finished
-				this.state.setValue(State.STOPPING);
-				this.waitUntilStopped();
-				break;
-			case STOPPING:
-				throw this.buildISE();
-		}
-
-		if (this.exceptions.size() > 0) {
-			Throwable[] temp = this.exceptions.toArray(new Throwable[this.exceptions.size()]);
-			this.exceptions.clear();
-			throw new CompositeException(temp);
-		}
-	}
-
-	/**
-	 * This wait will free up the synchronizer's synchronized methods
-	 * (since the synchronizer is the state's mutex).
-	 */
-	private void waitUntilStopped() {
-		try {
-			this.state.waitUntilValueIs(State.STOPPED);
-		} catch (InterruptedException ex) {
-			// the thread that called #stop() was interrupted while waiting
-			// for the synchronization to finish - ignore;
-			// 'state' is still set to 'STOPPING', so the #synchronize_() loop
-			// will still stop - we just won't wait around for it...
-		}
-	}
-
-	private IllegalStateException buildISE() {
-		return new IllegalStateException("state: " + this.state);
-	}
-
-	@Override
-	public String toString() {
-		return StringTools.buildToStringFor(this, this.state);
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/AbstractTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/AbstractTransformer.java
new file mode 100644
index 0000000..5423278
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/AbstractTransformer.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+/**
+ * Convenience transformer that returns <code>null</code> if the original
+ * object is <code>null</code>; otherwise it calls {@link #transform_(Object)},
+ * which is to be implemented by subclasses.
+ *
+ * @param <T1> the type of the object passed to the transformer
+ * @param <T2> the type of the object returned by the transformer
+ *
+ * @see TransformerAdapter
+ */
+public abstract class AbstractTransformer<T1, T2>
+	extends TransformerAdapter<T1, T2>
+{
+	@Override
+	public final T2 transform(T1 o) {
+		return (o == null) ? null : this.transform_(o);
+	}
+
+	/**
+	 * Transform the specified object; its value is guaranteed to be not
+	 * <code>null</code>.
+	 */
+	protected abstract T2 transform_(T1 o);
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/BooleanStringTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/BooleanStringTransformer.java
new file mode 100644
index 0000000..0c10a4d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/BooleanStringTransformer.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+import java.io.Serializable;
+
+/**
+ * Transform a {@link String} into a {@link Boolean} (i.e. transform
+ * a string equal to <code>"true"</code> (ignoring case) into
+ * {@link Boolean#TRUE}; transform all other non-<code>null</code>
+ * strings into {@link Boolean#FALSE}).
+ * Transform a <code>null</code> string into a <code>null</code> {@link Boolean}.
+ */
+public final class BooleanStringTransformer
+	extends AbstractTransformer<String, Boolean>
+	implements Serializable
+{
+	public static final Transformer<String, Boolean> INSTANCE = new BooleanStringTransformer();
+
+	public static Transformer<String, Boolean> instance() {
+		return INSTANCE;
+	}
+
+	// ensure single instance
+	private BooleanStringTransformer() {
+		super();
+	}
+
+	/**
+	 * @see Boolean#valueOf(String)
+	 */
+	@Override
+	protected Boolean transform_(String string) {
+		return Boolean.valueOf(string);
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the singleton
+		return INSTANCE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/IntegerStringTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/IntegerStringTransformer.java
new file mode 100644
index 0000000..c46f26f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/IntegerStringTransformer.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+import java.io.Serializable;
+
+/**
+ * Transform a {@link String} into an {@link Integer} if possible.
+ * Transform a <code>null</code> string into a <code>null</code> {@link Integer}.
+ */
+public final class IntegerStringTransformer
+	extends AbstractTransformer<String, Integer>
+	implements Serializable
+{
+	public static final Transformer<String, Integer> INSTANCE = new IntegerStringTransformer();
+
+	public static Transformer<String, Integer> instance() {
+		return INSTANCE;
+	}
+
+	// ensure single instance
+	private IntegerStringTransformer() {
+		super();
+	}
+
+	/**
+	 * @see Integer#valueOf(String)
+	 */
+	@Override
+	protected Integer transform_(String string) {
+		return Integer.valueOf(string);
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the singleton
+		return INSTANCE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NonNullBooleanTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NonNullBooleanTransformer.java
new file mode 100644
index 0000000..3d2b7e1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NonNullBooleanTransformer.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * A <code>NonNullBooleanTransformer</code> will transform a possibly-null
+ * {@link Boolean} to a non-null {@link Boolean}:<ul>
+ * <li>When the original {@link Boolean} is <em>not</em> <code>null</code>,
+ * the transformer will return it unchanged.
+ * <li>When the original {@link Boolean} is <code>null</code>,
+ * the transformer will return its client-specified "null value"
+ * ({@link Boolean#TRUE} or {@link Boolean#FALSE}).
+ * </ul>
+ */
+public final class NonNullBooleanTransformer
+	implements Transformer<Boolean, Boolean>, Serializable
+{
+	// not null
+	private final Boolean nullValue;
+
+	/**
+	 * A {@link Transformer} that will return the original {@link Boolean} when
+	 * it is non-<code>null</code>; otherwise the {@link Transformer} will return
+	 * {@link Boolean#TRUE}.
+	 */
+	public static final Transformer<Boolean, Boolean> TRUE = new NonNullBooleanTransformer(Boolean.TRUE);
+
+	/**
+	 * A {@link Transformer} that will return the original {@link Boolean} when
+	 * it is non-<code>null</code>; otherwise the {@link Transformer} will return
+	 * {@link Boolean#FALSE}.
+	 */
+	public static final Transformer<Boolean, Boolean> FALSE = new NonNullBooleanTransformer(Boolean.FALSE);
+
+	/**
+	 * Return a transformer that will return the specified value if the original
+	 * value is <code>null</code>. Throw a {@link NullPointerException} if the
+	 * specified value is <code>null</code>.
+	 */
+	public static Transformer<Boolean, Boolean> valueOf(Boolean b) {
+		return valueOf(b.booleanValue());
+	}
+
+	/**
+	 * Return a transformer that will return the {@link Boolean} corresponding
+	 * to the specified value if the original value is <code>null</code>.
+	 */
+	public static Transformer<Boolean, Boolean> valueOf(boolean b) {
+		return b ? TRUE : FALSE;
+	}
+
+	/**
+	 * Ensure only 2 constant versions.
+	 */
+	private NonNullBooleanTransformer(Boolean nullValue) {
+		super();
+		if (nullValue == null) {
+			throw new NullPointerException();
+		}
+		this.nullValue = nullValue;
+	}
+
+	@Override
+	public Boolean transform(Boolean b) {
+		return (b != null) ? b : this.nullValue;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.nullValue);
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the appropriate constant
+		return valueOf(this.nullValue);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NonNullStaticTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NonNullStaticTransformer.java
new file mode 100644
index 0000000..e8f4493
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NonNullStaticTransformer.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Transform any object into a single client-specified
+ * non-<code>null</code> object.
+ *
+ * @param <T1> the type of the object passed to the transformer
+ * @param <T2> the type of the object returned by the transformer
+ */
+public class NonNullStaticTransformer<T1, T2>
+	implements Transformer<T1, T2>
+{
+	private final T2 object;
+
+	public NonNullStaticTransformer(T2 object) {
+		super();
+		if (object == null) {
+			throw new NullPointerException();
+		}
+		this.object = object;
+	}
+
+	@Override
+	public T2 transform(T1 o) {
+		return this.object;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.object);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NonNullStringObjectTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NonNullStringObjectTransformer.java
new file mode 100644
index 0000000..286f630
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NonNullStringObjectTransformer.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Transform an object into the string returned by its {@link Object#toString()}
+ * method. A <code>null</code> object is transformed into a client-configured
+ * non-<code>null</code> string (<code>"null"</code> by default).
+ *
+ * @param <T> the type of the object passed to the transformer
+ */
+public class NonNullStringObjectTransformer<T>
+	implements Transformer<T, String>, Serializable
+{
+	// not null
+	private String nullString;
+
+	private static final long serialVersionUID = 1L;
+
+	public NonNullStringObjectTransformer() {
+		this(String.valueOf((Object) null));
+	}
+
+	public NonNullStringObjectTransformer(String nullString) {
+		super();
+		if (nullString == null) {
+			throw new NullPointerException();
+		}
+		this.nullString = nullString;
+	}
+
+	@Override
+	public String transform(T o) {
+		return (o == null) ? this.nullString : o.toString();
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.nullString);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NotBooleanTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NotBooleanTransformer.java
new file mode 100644
index 0000000..06545cd
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NotBooleanTransformer.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.BooleanTools;
+
+/**
+ * A <code>NotBooleanTransformer</code> will transform a
+ * {@link Boolean} to its NOT value:<ul>
+ * <li>If the original {@link Boolean} is {@link Boolean#TRUE},
+ * the transformer will return {@link Boolean#FALSE}.
+ * <li>If the original {@link Boolean} is {@link Boolean#FALSE},
+ * the transformer will return {@link Boolean#TRUE}.
+ * <li>If the original {@link Boolean} is <code>null</code>,
+ * the transformer will return <code>null</code>.
+ * </ul>
+ * Use a {@link NonNullBooleanTransformer} to specify a value for when a
+ * {@link Boolean} is <code>null</code>
+ */
+public class NotBooleanTransformer
+	implements Transformer<Boolean, Boolean>, Serializable
+{
+	public static final Transformer<Boolean, Boolean> INSTANCE = new NotBooleanTransformer();
+
+	public static Transformer<Boolean, Boolean> instance() {
+		return INSTANCE;
+	}
+
+	// ensure single instance
+	private NotBooleanTransformer() {
+		super();
+	}
+
+	@Override
+	public Boolean transform(Boolean b) {
+		return (b == null) ? null : BooleanTools.not(b);
+	}
+
+	@Override
+	public String toString() {
+		return this.getClass().getSimpleName();
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the singleton
+		return INSTANCE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NotNullObjectTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NotNullObjectTransformer.java
new file mode 100644
index 0000000..1c99176
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NotNullObjectTransformer.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+import java.io.Serializable;
+
+/**
+ * A {@link NotNullObjectTransformer} will transform an object to a
+ * {@link Boolean}:<ul>
+ * <li>If the object is <code>null</code>,
+ * the transformer will return {@link Boolean#FALSE}.
+ * <li>If the object is <em>not</em> <code>null</code>,
+ * the transformer will return {@link Boolean#TRUE}.
+ * </ul>
+ *
+ * @param <T> the type of the object passed to the transformer
+ */
+public class NotNullObjectTransformer<T>
+	implements Transformer<T, Boolean>, Serializable
+{
+	@SuppressWarnings("rawtypes")
+	public static final Transformer INSTANCE = new NotNullObjectTransformer();
+
+	@SuppressWarnings("unchecked")
+	public static <S> Transformer<S, Boolean> instance() {
+		return INSTANCE;
+	}
+
+	// ensure single instance
+	private NotNullObjectTransformer() {
+		super();
+	}
+
+	@Override
+	public Boolean transform(T o) {
+		return Boolean.valueOf(o != null);
+	}
+
+	@Override
+	public String toString() {
+		return this.getClass().getSimpleName();
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the singleton
+		return INSTANCE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NullObjectTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NullObjectTransformer.java
new file mode 100644
index 0000000..bb7f134
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/NullObjectTransformer.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+import java.io.Serializable;
+
+/**
+ * A {@link NullObjectTransformer} will transform an object to a
+ * {@link Boolean}:<ul>
+ * <li>If the object is <code>null</code>,
+ * the transformer will return {@link Boolean#TRUE}.
+ * <li>If the object is <em>not</em> <code>null</code>,
+ * the transformer will return {@link Boolean#FALSE}.
+ * </ul>
+ *
+ * @param <T> the type of the object passed to the transformer
+ */
+public class NullObjectTransformer<T>
+	implements Transformer<T, Boolean>, Serializable
+{
+	@SuppressWarnings("rawtypes")
+	public static final Transformer INSTANCE = new NullObjectTransformer();
+
+	@SuppressWarnings("unchecked")
+	public static <S> Transformer<S, Boolean> instance() {
+		return INSTANCE;
+	}
+
+	// ensure single instance
+	private NullObjectTransformer() {
+		super();
+	}
+
+	@Override
+	public Boolean transform(T o) {
+		return Boolean.valueOf(o == null);
+	}
+
+	@Override
+	public String toString() {
+		return this.getClass().getSimpleName();
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the singleton
+		return INSTANCE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/StaticTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/StaticTransformer.java
new file mode 100644
index 0000000..6c5ab54
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/StaticTransformer.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+/**
+ * Transform any object, except <code>null</code>, into a single
+ * client-specified object. Any <code>null</code> object will be
+ * transformed into <code>null</code>.
+ *
+ * @param <T1> the type of the object passed to the transformer
+ * @param <T2> the type of the object returned by the transformer
+ */
+public class StaticTransformer<T1, T2>
+	extends AbstractTransformer<T1, T2>
+{
+	private final T2 object;
+
+	public StaticTransformer() {
+		this(null);
+	}
+
+	public StaticTransformer(T2 object) {
+		super();
+		this.object = object;
+	}
+
+	@Override
+	protected T2 transform_(T1 o) {
+		return this.object;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/StringObjectTransformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/StringObjectTransformer.java
new file mode 100644
index 0000000..205940f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/StringObjectTransformer.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+import java.io.Serializable;
+
+/**
+ * Transform an object into the string returned by its {@link Object#toString()}
+ * method. A <code>null</code> object is transformed into <code>null</code>.
+ *
+ * @param <T> the type of the object passed to the transformer
+ */
+public final class StringObjectTransformer<T>
+	extends AbstractTransformer<T, String>
+	implements Serializable
+{
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	public static final Transformer<?, String> INSTANCE = new StringObjectTransformer();
+
+	@SuppressWarnings("unchecked")
+	public static <R> Transformer<R, String> instance() {
+		return (Transformer<R, String>) INSTANCE;
+	}
+
+	// ensure single instance
+	private StringObjectTransformer() {
+		super();
+	}
+
+	@Override
+	protected String transform_(T o) {
+		return o.toString();
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the singleton
+		return INSTANCE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/Transformer.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/Transformer.java
new file mode 100644
index 0000000..36c4591
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/Transformer.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+import java.io.Serializable;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Used by various "pluggable" classes to transform objects.
+ * Transform an object of type <code>T1</code> to an object of type
+ * <code>T2</code>.
+ * <p>
+ * 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.
+ *
+ * @param <T1> the type of the object passed to the transformer
+ * @param <T2> the type of the object returned by the transformer
+ */
+public interface Transformer<T1, T2> {
+
+	/**
+	 * Return the transformed object.
+	 * The semantics of "transform" is determined by the
+	 * contract between the client and the server.
+	 */
+	T2 transform(T1 o);
+
+
+	/**
+	 * A "non" transformer will perform no transformation at all;
+	 * it will simply return the object "untransformed".
+	 */
+	final class Non<S>
+		implements Transformer<S, S>, Serializable
+	{
+		@SuppressWarnings("rawtypes")
+		public static final Transformer INSTANCE = new Non();
+		@SuppressWarnings("unchecked")
+		public static <R> Transformer<R, R> instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Non() {
+			super();
+		}
+		// simply return the object, unchanged
+		@Override
+		public S transform(S o) {
+			return o;
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+
+	/**
+	 * A "null" transformer will always return <code>null</code>.
+	 */
+	final class Null<S1, S2>
+		implements Transformer<S1, S2>, Serializable
+	{
+		@SuppressWarnings("rawtypes")
+		public static final Transformer INSTANCE = new Null();
+		@SuppressWarnings("unchecked")
+		public static <R1, R2> Transformer<R1, R2> instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Null() {
+			super();
+		}
+		// simply return null
+		@Override
+		public S2 transform(S1 o) {
+			return null;
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+
+	/**
+	 * A "disabled" transformer will throw an exception if
+	 * {@link #transform(Object)} is called. This is useful in situations
+	 * where a transformer is optional and the default transformer should
+	 * not be used.
+	 */
+	final class Disabled<S1, S2>
+		implements Transformer<S1, S2>, Serializable
+	{
+		@SuppressWarnings("rawtypes")
+		public static final Transformer INSTANCE = new Disabled();
+		@SuppressWarnings("unchecked")
+		public static <R1, R2> Transformer<R1, R2> instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Disabled() {
+			super();
+		}
+		// throw an exception
+		@Override
+		public S2 transform(S1 o) {
+			throw new UnsupportedOperationException();
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.singletonToString(this);
+		}
+		private static final long serialVersionUID = 1L;
+		private Object readResolve() {
+			// replace this object with the singleton
+			return INSTANCE;
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/TransformerAdapter.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/TransformerAdapter.java
new file mode 100644
index 0000000..0f6baa7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/TransformerAdapter.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Convenience transformer that returns <code>null</code> for every
+ * transformation.
+ *
+ * @param <T1> the type of the object passed to the transformer
+ * @param <T2> the type of the object returned by the transformer
+ *
+ * @see AbstractTransformer
+ */
+public class TransformerAdapter<T1, T2>
+	implements Transformer<T1, T2>
+{
+	@Override
+	public T2 transform(T1 o) {
+		return null;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/TransformerWrapper.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/TransformerWrapper.java
new file mode 100644
index 0000000..8678088
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/TransformerWrapper.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+import org.eclipse.persistence.tools.utility.ObjectTools;
+
+/**
+ * Tranformer wrapper that can have its wrapped transformer changed,
+ * allowing a client to change a previously-supplied transformer's
+ * behavior mid-stream.
+ *
+ * @param <T1> the type of the object passed to the transformer
+ * @param <T2> the type of the object returned by the transformer
+ * @see #setTransformer(Transformer)
+ */
+public class TransformerWrapper<T1, T2>
+	implements Transformer<T1, T2>
+{
+	protected volatile Transformer<T1, T2> transformer;
+
+	public TransformerWrapper(Transformer<T1, T2> transformer) {
+		super();
+		if (transformer == null) {
+			throw new NullPointerException();
+		}
+		this.transformer = transformer;
+	}
+
+	@Override
+	public T2 transform(T1 o) {
+		return this.transformer.transform(o);
+	}
+
+	public void setTransformer(Transformer<T1, T2> transformer) {
+		if (transformer == null) {
+			throw new NullPointerException();
+		}
+		this.transformer = transformer;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.transformer);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/XMLStringDecoder.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/XMLStringDecoder.java
new file mode 100644
index 0000000..0892340
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/XMLStringDecoder.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Serializable;
+import java.io.StringReader;
+
+/**
+ * This transformer will convert a string with any XML <em>character references</em>
+ * by replacing the <em>character references</em> with the characters
+ * themselves: <code>"&amp;#x2f;" => '/'</code>
+ * @see XMLStringEncoder
+ */
+@SuppressWarnings("nls")
+public final class XMLStringDecoder
+	extends AbstractTransformer<String, String>
+	implements Serializable
+{
+	public static final Transformer<String, String> INSTANCE = new XMLStringDecoder();
+
+	public static Transformer<String, String> instance() {
+		return INSTANCE;
+	}
+	/**
+	 * Construct a decoder that converts XML character references
+	 * into the corresponding characters.
+	 */
+	private XMLStringDecoder() {
+		super();
+	}
+
+	/**
+	 * Return the specified string with any XML character references
+	 * replaced by the characters themselves.
+	 */
+	@Override
+	protected String transform_(String s) {
+		StringBuilder sb = new StringBuilder(s.length());
+		StringBuilder temp = new StringBuilder();	// performance tweak
+		this.decode(sb, new StringReader(s), temp);
+		return sb.toString();
+	}
+
+	private void decode(StringBuilder sb, Reader reader, StringBuilder temp) {
+		try {
+			this.decode_(sb, reader, temp);
+		} catch (IOException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+	private void decode_(StringBuilder sb, Reader reader, StringBuilder temp) throws IOException {
+		int c = reader.read();
+		while (c != -1) {
+			if (c == '&') {
+				this.decodeCharacterReference(sb, reader, temp);
+			} else {
+				sb.append((char) c);
+			}
+			c = reader.read();
+		}
+		reader.close();
+	}
+
+	private void decodeCharacterReference(StringBuilder sb, Reader reader, StringBuilder temp) throws IOException {
+		int c = reader.read();
+		this.checkChar(c, '#');
+		c = reader.read();
+		this.checkChar(c, 'x');
+
+		temp.setLength(0);  // re-use temp
+		c = reader.read();
+		while (c != ';') {
+			this.checkEndOfStream(c);
+			temp.append((char) c);
+			c = reader.read();
+		}
+		String charValue = temp.toString();
+		if (charValue.length() == 0) {
+			throw new IllegalStateException("missing numeric string");
+		}
+		sb.append((char) Integer.parseInt(charValue, 16));
+	}
+
+	private void checkChar(int c, int expected) {
+		this.checkEndOfStream(c);
+		if (c != expected) {
+			throw new IllegalStateException("expected '" + (char) expected + "', but encountered '" + (char) c + "'"); //$NON-NLS-3$
+		}
+	}
+
+	private void checkEndOfStream(int c) {
+		if (c == -1) {
+			throw new IllegalStateException("unexpected end of string");
+		}
+	}
+
+	private static final long serialVersionUID = 1L;
+	private Object readResolve() {
+		// replace this object with the singleton
+		return INSTANCE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/XMLStringEncoder.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/XMLStringEncoder.java
new file mode 100644
index 0000000..91efc7c
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/transformer/XMLStringEncoder.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.utility.transformer;
+
+import org.eclipse.persistence.tools.utility.ArrayTools;
+
+/**
+ * This transformer will replace any of a specified set of characters with an XML
+ * <em>character reference</em>: <code>'/' => "&amp;#x2f;"</code>
+ * @see XMLStringDecoder
+ */
+@SuppressWarnings("nls")
+public final class XMLStringEncoder
+	extends AbstractTransformer<String, String>
+{
+	/** The set of characters to be converted into XML character references. */
+	private final char[] chars;
+
+	/** Cache the value of the highest character in the set above. */
+	private final char maxChar;
+
+
+	/**
+	 * Construct an encoder that converts the specified set of characters
+	 * into XML character references.
+	 */
+	public XMLStringEncoder(char[] chars) {
+		super();
+		if (chars == null) {
+			throw new NullPointerException();
+		}
+		// the ampersand must be included since it is the escape character
+		if (ArrayTools.contains(chars, '&')) {
+			this.chars = chars;
+		} else {
+			this.chars = ArrayTools.add(chars, '&');
+		}
+		this.maxChar = this.calculateMaxInvalidFileNameChar();
+	}
+
+	/**
+	 * Calculate the maximum value of the set of characters to be converted
+	 * into XML character references. This will be used to short-circuit the
+	 * search for a character in the set.
+	 * @see #charIsToBeEncoded(char)
+	 */
+	private char calculateMaxInvalidFileNameChar() {
+		char[] localChars = this.chars;
+		char max = 0;
+		for (int i = localChars.length; i-- > 0; ) {
+			char c = localChars[i];
+			if (max < c) {
+				max = c;
+			}
+		}
+		return max;
+	}
+
+	/**
+	 * Return the specified string with any characters in the set
+	 * replaced with XML character references.
+	 */
+	@Override
+	protected String transform_(String s) {
+		int len = s.length();
+		// allow for a few encoded characters
+		StringBuilder sb = new StringBuilder(len + 20);
+		for (int i = 0; i < len; i++) {
+			this.append(sb, s.charAt(i));
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Append the specified character to the string buffer,
+	 * converting it to an XML character reference if necessary.
+	 */
+	private void append(StringBuilder sb, char c) {
+		if (this.charIsToBeEncoded(c)) {
+			this.appendCharacterReference(sb, c);
+		} else {
+			sb.append(c);
+		}
+	}
+
+	/**
+	 * Return whether the specified character is one of the characters
+	 * to be converted to XML character references.
+	 */
+	private boolean charIsToBeEncoded(char c) {
+		return (c <= this.maxChar) && ArrayTools.contains(this.chars, c);
+	}
+
+	/**
+	 * Append the specified character's XML character reference to the
+	 * specified string buffer (e.g. '/' => "&#x2f;").
+	 */
+	private void appendCharacterReference(StringBuilder sb, char c) {
+		sb.append("&#x");
+		sb.append(Integer.toString(c, 16));
+		sb.append(';');
+	}
+}
\ No newline at end of file