add some Comparator tests
diff --git a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/InternalJptResourceType.java b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/InternalJptResourceType.java
index 5f80f2c..6ba5d51 100644
--- a/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/InternalJptResourceType.java
+++ b/common/plugins/org.eclipse.jpt.common.core/src/org/eclipse/jpt/common/core/internal/InternalJptResourceType.java
@@ -13,7 +13,7 @@
 import org.eclipse.core.runtime.content.IContentType;
 import org.eclipse.jpt.common.core.JptResourceType;
 import org.eclipse.jpt.common.core.JptResourceTypeManager;
-import org.eclipse.jpt.common.utility.internal.comparator.VersionComparator;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
 import org.eclipse.jpt.common.utility.internal.iterable.SuperIterableWrapper;
 import com.ibm.icu.text.Collator;
 
@@ -112,7 +112,7 @@
 		if (v.equals(UNDETERMINED_VERSION)) {
 			return 1;
 		}
-		return VersionComparator.INTEGER_VERSION_COMPARATOR.compare(this.version, v);
+		return ComparatorTools.integerVersionComparator().compare(this.version, v);
 	}
 
 	@Override
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/SystemTools.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/SystemTools.java
index 96ab402..4a5d2e9 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/SystemTools.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/SystemTools.java
@@ -11,7 +11,7 @@
 
 import java.io.PrintStream;
 import java.util.Map;
-import org.eclipse.jpt.common.utility.internal.comparator.VersionComparator;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
 
 /**
  * Various system utility methods.
@@ -75,7 +75,7 @@
 	 * developers. :-)
 	 */
 	public static boolean javaSpecificationVersionIsGreaterThan(String version) {
-		return VersionComparator.INTEGER_VERSION_COMPARATOR.compare(javaSpecificationVersion(), version) > 0;
+		return ComparatorTools.integerVersionComparator().compare(javaSpecificationVersion(), version) > 0;
 	}
 
 	/**
@@ -91,7 +91,7 @@
 	 * 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 ComparatorTools.integerVersionComparator().compare(javaSpecificationVersion(), version) < 0;
 	}
 
 	/**
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/collection/CollectionTools.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/collection/CollectionTools.java
index 4f5e27e..6f3439f 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/collection/CollectionTools.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/collection/CollectionTools.java
@@ -255,6 +255,9 @@
 	 * partitions, all the partitions will be one of two sizes; the first
 	 * partions will be of size <code>collection.size()/count+1</code>,
 	 * while the last partions will be of size <code>collection.size()/count</code>.
+	 * The partitions will maintain the order of elements returned by the
+	 * collection's iterator (i.e. the first elements returned by the iterator
+	 * will be in the first partition, first element first).
 	 */
 	public static <E> ArrayList<ArrayList<E>> partition(Collection<? extends E> collection, int count) {
 		if (count <= 0) {
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparableComparator.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparableComparator.java
index be2671c..da14504 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparableComparator.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparableComparator.java
@@ -15,16 +15,17 @@
 /**
  * This comparator compares elements that implement the
  * {@link Comparable} interface.
+ * 
  * @param <E> the type of elements to be compared
  */
-public class ComparableComparator<E extends Comparable<E>>
+public final class ComparableComparator<E extends Comparable<E>>
 	implements Comparator<E>, Serializable
 {
 	@SuppressWarnings("rawtypes")
 	public static final Comparator INSTANCE = new ComparableComparator();
 
 	@SuppressWarnings("unchecked")
-	public static <E> Comparator<E> instance() {
+	public static <E extends Comparable<E>> Comparator<E> instance() {
 		return INSTANCE;
 	}
 
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparatorAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparatorAdapter.java
index 8ef71ad..137dfc6 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparatorAdapter.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparatorAdapter.java
@@ -15,12 +15,12 @@
 /**
  * Convenience comparator that always returns 0;
  * 
- * @param <T> the type of objects to be compared
+ * @param <E> the type of objects to be compared
  */
-public class ComparatorAdapter<T>
-	implements Comparator<T>
+public class ComparatorAdapter<E>
+	implements Comparator<E>
 {
-	public int compare(T o1, T o2) {
+	public int compare(E o1, E o2) {
 		return 0;
 	}
 
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparatorChain.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparatorChain.java
new file mode 100644
index 0000000..c168aa2
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparatorChain.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.common.utility.internal.comparator;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
+
+/**
+ * This comparator will use a list of comparators to compare two objects.
+ * If the first comparator returns a non-zero value, that will be the
+ * comparator's value; otherwise the next comparator will be called; and so on.
+ * 
+ * @param <E> the type of elements to be compared
+ */
+public class ComparatorChain<E>
+	implements Comparator<E>
+{
+	private final Iterable<Comparator<? super E>> comparators;
+
+	public ComparatorChain(Iterable<Comparator<? super E>> comparators) {
+		super();
+		if (IterableTools.isOrContainsNull(comparators)) {
+			throw new NullPointerException();
+		}
+		if (IterableTools.isEmpty(comparators)) {
+			throw new IllegalArgumentException("comparators must not empty"); //$NON-NLS-1$
+		}
+		this.comparators = comparators;
+	}
+
+	public int compare(E o1, E o2) {
+		int result = 0;
+		for (Iterator<Comparator<? super E>> stream = this.comparators.iterator(); stream.hasNext() && (result == 0); ) {
+			result = stream.next().compare(o1, o2);
+		}
+		return result;
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.comparators);
+	}
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparatorTools.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparatorTools.java
index 12881f2..ed7142f 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparatorTools.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ComparatorTools.java
@@ -9,8 +9,11 @@
  ******************************************************************************/
 package org.eclipse.jpt.common.utility.internal.comparator;
 
+import java.text.Collator;
 import java.util.Comparator;
-import org.eclipse.jpt.common.utility.internal.transformer.TransformationComparator;
+import java.util.Locale;
+import org.eclipse.jpt.common.utility.internal.ArrayTools;
+import org.eclipse.jpt.common.utility.internal.comparator.VersionComparator.SegmentParser;
 import org.eclipse.jpt.common.utility.transformer.Transformer;
 
 /**
@@ -18,21 +21,208 @@
  */
 public final class ComparatorTools {
 
+	/**
+	 * Of the two specified objects, return the one that is ordered first.
+	 * @param <E> the type of elements to be compared
+	 * @see Comparable#compareTo(Object)
+	 */
+	public static <E extends Comparable<E>> E min(E o1, E o2) {
+		return (o1.compareTo(o2) < 0) ? o1 : o2;
+	}
+
+	/**
+	 * Of the two specified objects, return the one that is ordered first,
+	 * as determined by the specified comparator.
+	 * @param <E> the type of elements to be compared
+	 * @see Comparable#compareTo(Object)
+	 */
+	public static <E> E min(E o1, E o2, Comparator<? super E> comparator) {
+		return (comparator.compare(o1, o2) < 0) ? o1 : o2;
+	}
+
+	/**
+	 * Of the two specified objects, return the one that is ordered last.
+	 * @param <E> the type of elements to be compared
+	 * @see Comparable#compareTo(Object)
+	 */
+	public static <E extends Comparable<E>> E max(E o1, E o2) {
+		return (o1.compareTo(o2) > 0) ? o1 : o2;
+	}
+
+	/**
+	 * Of the two specified objects, return the one that is ordered last,
+	 * as determined by the specified comparator.
+	 * @param <E> the type of elements to be compared
+	 * @see Comparable#compareTo(Object)
+	 */
+	public static <E> E max(E o1, E o2, Comparator<? super E> comparator) {
+		return (comparator.compare(o1, o2) > 0) ? o1 : o2;
+	}
+
+
+	// ********** boolean **********
+
+	/**
+	 * Return a comparator will compare {@link Boolean}s, depending the
+	 * specified "true first" flag.
+	 */
+	public static Comparator<Boolean> booleanComparator(boolean trueFirst) {
+		return trueFirst ? truesFirstBooleanComparator() : falsesFirstBooleanComparator();
+	}
+
+	/**
+	 * Return a comparator will compare {@link Boolean}s, sorting
+	 * <code>false</code>s first.
+	 */
+	public static Comparator<Boolean> falsesFirstBooleanComparator() {
+		return FalsesFirstBooleanComparator.instance();
+	}
+
+	/**
+	 * Return a comparator will compare {@link Boolean}s, sorting
+	 * <code>true</code>s first.
+	 */
+	public static Comparator<Boolean> truesFirstBooleanComparator() {
+		return TruesFirstBooleanComparator.instance();
+	}
+
+
+	// ********** chain **********
+
+	/**
+	 * @see #chain(Iterable)
+	 */
+	public static <E> Comparator<E> chain(Comparator<? super E>... comparators) {
+		return chain(ArrayTools.iterable(comparators));
+	}
+
+	/**
+	 * Return a comparator that will use the specified list of comparators to
+	 * compare two objects.
+	 * If the first comparator returns a non-zero value, that will be the
+	 * comparator's value; otherwise the next comparator will be called;
+	 * and so on.
+	 * @param <E> the type of elements to be compared
+	 */
+	public static <E> Comparator<E> chain(Iterable<Comparator<? super E>> comparators) {
+		return new ComparatorChain<E>(comparators);
+	}
+
+
+	// ********** comparable/natural **********
+
+	/**
+	 * Return a comparator will compare {@link Comparable}s.
+	 * @param <E> the type of elements to be compared
+	 */
+	public static <E extends Comparable<E>> Comparator<E> comparableComparator() {
+		return ComparableComparator.instance();
+	}
+
+	/**
+	 * Return a comparator will compare {@link Comparable}s.
+	 * @param <E> the type of elements to be compared
+	 */
+	public static <E extends Comparable<E>> Comparator<E> naturalComparator() {
+		return comparableComparator();
+	}
+
+
+	// ********** nulls **********
+
+	/**
+	 * Return a comparator that will sort <code>null</code>s <em>before</em> any
+	 * non-<code>null</code> elements. Non-<code>null</code> elements will be
+	 * compared by the specified comparator.
+	 * @param <E> the type of elements to be compared
+	 */
+	public static <E> Comparator<E> nullsFirst(Comparator<? super E> comparator) {
+		return new NullsFirstComparator<E>(comparator);
+	}
+
+	/**
+	 * Return a comparator that will sort <code>null</code>s <em>after</em> any
+	 * non-<code>null</code> elements. Non-<code>null</code> elements will be
+	 * compared by the specified comparator.
+	 * @param <E> the type of elements to be compared
+	 */
+	public static <E> Comparator<E> nullsLast(Comparator<? super E> comparator) {
+		return new NullsLastComparator<E>(comparator);
+	}
+
+
+	// ********** reverse **********
+
+	/**
+	 * Return a comparator that will reverse the order of
+	 * {@link Comparable}s.
+	 * @param <E> the type of elements to be compared
+	 */
+	@SuppressWarnings("unchecked")
+	public static <E extends Comparable<E>> Comparator<E> reverseComparator() {
+		return reverse((Comparator<E>) comparableComparator());
+	}
+
+	/**
+	 * Return a comparator that will reverse the order of the specified
+	 * comparator.
+	 * @param <E> the type of elements to be compared
+	 */
+	public static <E> Comparator<E> reverse(Comparator<? super E> comparator) {
+		return new ReverseComparator<E>(comparator);
+	}
+
+
+	// ********** string **********
+
+	/**
+	 * Return a collator that wraps the default Java text collator and
+	 * implements a {@link String} {@link Comparator} (instead of an
+	 * {@link Object} {@link Comparator}, which is what {@link Collator} does,
+	 * possibly for backward-compatibility reasons(?)).
+	 * @see Collator#getInstance()
+	 */
+	public static Comparator<String> stringCollator() {
+		return stringCollator(Collator.getInstance());
+	}
+
+	/**
+	 * Return a collator that wraps the Java text collator for the specified
+	 * locale and implements a
+	 * {@link String} {@link Comparator} (instead of an {@link Object}
+	 * {@link Comparator}, which is what {@link Collator} does, possibly for
+	 * backward-compatibility reasons(?)).
+	 * @see Collator#getInstance(Locale)
+	 */
+	public static Comparator<String> stringCollator(Locale locale) {
+		return stringCollator(Collator.getInstance(locale));
+	}
+
+	/**
+	 * Return a collator that wraps the specified Java text collator and
+	 * implements a {@link String} {@link Comparator} (instead of an
+	 * {@link Object} {@link Comparator}, which is what {@link Collator}
+	 * does, possibly for backward-compatibility reasons(?)).
+	 * @see Collator
+	 */
+	public static Comparator<String> stringCollator(Collator collator) {
+		return new StringCollator(collator);
+	}
+
+
 	// ********** transformation **********
 
 	/**
 	 * Return a comparator will transform the elements to be compared and
 	 * compare the resulting outputs (i.e. assume the outputs
 	 * implement the {@link Comparable} interface).
-	 * 
 	 * @param <E> the type of elements to be compared
 	 * @param <O> the type of the result of transforming the elements and the type
 	 *   of the elements to be compared by the wrapped comaparator, if present
-	 *   
-	 * @see TransformationComparator
 	 */
+	@SuppressWarnings("unchecked")
 	public static <E, O> Comparator<E> transformationComparator(Transformer<? super E, ? extends O> transformer) {
-		return transformationComparator(transformer, null);
+		return transformationComparator(transformer, (Comparator<O>) comparableComparator());
 	}
 
 	/**
@@ -41,18 +231,69 @@
 	 * If the specified comparator is <code>null</code>,
 	 * the natural ordering of the outputs will be used (i.e. assume the outputs
 	 * implement the {@link Comparable} interface).
-	 * 
 	 * @param <E> the type of elements to be compared
 	 * @param <O> the type of the result of transforming the elements and the type
 	 *     of the elements to be compared by the wrapped comaparator, if present
-	 * 
-	 * @see TransformationComparator
 	 */
 	public static <E, O> Comparator<E> transformationComparator(Transformer<? super E, ? extends O> transformer, Comparator<O> comparator) {
 		return new TransformationComparator<E, O>(transformer, comparator);
 	}
 
 
+	// ********** version **********
+
+	/**
+	 * Return a version comparator that converts
+	 * each version into a series of integers and compares them.
+	 * <p>
+	 * <strong>NB:</strong> With this comparator
+	 * <code>"2.<strong>14</strong>" > "2.<strong>2</strong>"</code>
+	 * is <code>true</code>.
+	 */
+	public static <T extends Comparable<T>> Comparator<String> integerVersionComparator() {
+		return INTEGER_VERSION_COMPARATOR;
+	}
+
+	/**
+	 * @see #integerVersionComparator()
+	 */
+	public static final Comparator<String> INTEGER_VERSION_COMPARATOR = versionComparator(VersionComparator.SegmentParser.IntegerSegmentParser.instance());
+
+	/**
+	 * The default delimiter is <code>'.'</code>.
+	 * @see #versionComparator(String, SegmentParser)
+	 */
+	public static <T extends Comparable<T>> Comparator<String> versionComparator(SegmentParser<T> segmentParser) {
+		return versionComparator(".", segmentParser); //$NON-NLS-1$
+	}
+
+	/**
+	 * @see #versionComparator(String, SegmentParser)
+	 */
+	public static <T extends Comparable<T>> Comparator<String> versionComparator(char delimiter, SegmentParser<T> segmentParser) {
+		return versionComparator(new char[] {delimiter}, segmentParser);
+	}
+
+	/**
+	 * @see #versionComparator(String, SegmentParser)
+	 */
+	public static <T extends Comparable<T>> Comparator<String> versionComparator(char[] delimiters, SegmentParser<T> segmentParser) {
+		return versionComparator(new String(delimiters), segmentParser);
+	}
+
+	/**
+	 * Return a comparator tha 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>.
+	 * @param <T> the type of comparable returned by the comparator's segment parser
+	 */
+	public static <T extends Comparable<T>> Comparator<String> versionComparator(String delimiters, SegmentParser<T> segmentParser) {
+		return new VersionComparator<T>(delimiters, segmentParser);
+	}
+
+
 	// ********** constructor **********
 
 	/**
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/FalsesFirstBooleanComparator.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/FalsesFirstBooleanComparator.java
new file mode 100644
index 0000000..cbb07d7
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/FalsesFirstBooleanComparator.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.common.utility.internal.comparator;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * This comparator will compare {@link Boolean}s and can be configured to sort
+ * either boolean first.
+ */
+public final class FalsesFirstBooleanComparator
+	implements Comparator<Boolean>, Serializable
+{
+	public static final Comparator<Boolean> INSTANCE = new FalsesFirstBooleanComparator();
+
+	public static Comparator<Boolean> instance() {
+		return INSTANCE;
+	}
+
+	// ensure single instance
+	private FalsesFirstBooleanComparator() {
+		super();
+	}
+
+	public int compare(Boolean b1, Boolean b2) {
+		return b1.booleanValue() ? 
+				(b2.booleanValue() ?  0 : 1) :
+				(b2.booleanValue() ? -1 : 0);
+	}
+
+	@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/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/NullsFirstComparator.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/NullsFirstComparator.java
new file mode 100644
index 0000000..0ab6ec0
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/NullsFirstComparator.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.common.utility.internal.comparator;
+
+import java.util.Comparator;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * This comparator sort <code>null</code>s <em>before</em> any
+ * non-<code>null</code> elements. Non-<code>null</code> elements will be
+ * compared by the configured comparator.
+ * 
+ * @param <E> the type of elements to be compared
+ */
+public class NullsFirstComparator<E>
+	implements Comparator<E>
+{
+	private final Comparator<? super E> comparator;
+
+	public NullsFirstComparator(Comparator<? super E> comparator) {
+		super();
+		if (comparator == null) {
+			throw new NullPointerException();
+		}
+		this.comparator = comparator;
+	}
+
+	public int compare(E e1, E e2) {
+		return (e1 == null) ?
+				((e2 == null) ? 0 : -1) :
+				((e2 == null) ? 1 : this.comparator.compare(e1, e2));
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.comparator);
+	}
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/NullsLastComparator.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/NullsLastComparator.java
new file mode 100644
index 0000000..c9b4e74
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/NullsLastComparator.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.common.utility.internal.comparator;
+
+import java.util.Comparator;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+
+/**
+ * This comparator sort <code>null</code>s <em>after</em> any
+ * non-<code>null</code> elements. Non-<code>null</code> elements will be
+ * compared by the configured comparator.
+ * 
+ * @param <E> the type of elements to be compared
+ */
+public class NullsLastComparator<E>
+	implements Comparator<E>
+{
+	private final Comparator<? super E> comparator;
+
+	public NullsLastComparator(Comparator<? super E> comparator) {
+		super();
+		if (comparator == null) {
+			throw new NullPointerException();
+		}
+		this.comparator = comparator;
+	}
+
+	public int compare(E e1, E e2) {
+		return (e1 == null) ?
+				((e2 == null) ? 0 : 1) :
+				((e2 == null) ? -1 : this.comparator.compare(e1, e2));
+	}
+
+	@Override
+	public String toString() {
+		return ObjectTools.toString(this, this.comparator);
+	}
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ReverseComparator.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ReverseComparator.java
index deabac8..db2673a 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ReverseComparator.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/ReverseComparator.java
@@ -9,43 +9,29 @@
  ******************************************************************************/
 package org.eclipse.jpt.common.utility.internal.comparator;
 
-import java.io.Serializable;
 import java.util.Comparator;
 import org.eclipse.jpt.common.utility.internal.ObjectTools;
 
 /**
- * This comparator will reverse the order of the specified comparator.
- * 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.
+ * This comparator will reverse the order of the configured comparator.
+ * 
  * @param <E> the type of elements to be compared
  */
 public class ReverseComparator<E>
-	implements Comparator<E>, Serializable
+	implements Comparator<E>
 {
-	private final Comparator<E> comparator;
-	private static final long serialVersionUID = 1L;
+	private final Comparator<? super E> comparator;
 
-	/**
-	 * 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) {
+	public ReverseComparator(Comparator<? super E> comparator) {
 		super();
+		if (comparator == null) {
+			throw new NullPointerException();
+		}
 		this.comparator = comparator;
 	}
 
-	@SuppressWarnings("unchecked")
 	public int compare(E e1, E e2) {
-		return (this.comparator != null) ? this.comparator.compare(e2, e1) : ((Comparable<E>) e2).compareTo(e1);
+		return this.comparator.compare(e2, e1);
 	}
 
 	@Override
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/StringCollator.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/StringCollator.java
index d2d071a..c8295a1 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/StringCollator.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/StringCollator.java
@@ -11,7 +11,6 @@
 
 import java.text.Collator;
 import java.util.Comparator;
-import java.util.Locale;
 import org.eclipse.jpt.common.utility.internal.ObjectTools;
 
 /**
@@ -27,23 +26,6 @@
 {
 	private final Collator collator;
 
-
-	/**
-	 * Wrap the default collator.
-	 * @see Collator#getInstance()
-	 */
-	public StringCollator() {
-		this(Collator.getInstance());
-	}
-
-	/**
-	 * Wrap the collator for the specified locale.
-	 * @see Collator#getInstance(Locale)
-	 */
-	public StringCollator(Locale locale) {
-		this(Collator.getInstance(locale));
-	}
-
 	/**
 	 * Wrap the specified collator.
 	 */
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/transformer/TransformationComparator.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/TransformationComparator.java
similarity index 66%
rename from common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/transformer/TransformationComparator.java
rename to common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/TransformationComparator.java
index 80c856b..d3feaec 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/transformer/TransformationComparator.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/TransformationComparator.java
@@ -7,7 +7,7 @@
  * Contributors:
  *     Oracle - initial API and implementation
  ******************************************************************************/
-package org.eclipse.jpt.common.utility.internal.transformer;
+package org.eclipse.jpt.common.utility.internal.comparator;
 
 import java.util.Comparator;
 import org.eclipse.jpt.common.utility.internal.ObjectTools;
@@ -16,9 +16,6 @@
 /**
  * This comparator will transform the elements to be compared and pass the
  * resulting outputs to a wrapped transformer.
- * If the wrapped comparator is <code>null</code>,
- * the natural ordering of the outputs will be used (i.e. assume the outputs
- * implement the {@link Comparable} interface).
  * @param <E> the type of elements to be compared
  * @param <O> the type of the result of transforming the elements and the type
  *   of the elements to be compared by the wrapped comaparator, if present
@@ -30,27 +27,17 @@
 	private final Comparator<O> comparator;
 
 
-	/**
-	 * Construct a comparator that will use the specified transformer to
-	 * transform the elements to be compared. The resulting outputs will be
-	 * passed to the specified comparator and the result returned by the
-	 * transformation comparator as the result of comparing the original
-	 * elements.
-	 */
 	public TransformationComparator(Transformer<? super E, ? extends O> transformer, Comparator<O> comparator) {
 		super();
-		if (transformer == null) {
+		if ((transformer == null) || (comparator == null)) {
 			throw new NullPointerException();
 		}
 		this.transformer = transformer;
 		this.comparator = comparator;
 	}
 
-	@SuppressWarnings("unchecked")
 	public int compare(E e1, E e2) {
-		O o1 = this.transformer.transform(e1);
-		O o2 = this.transformer.transform(e2);
-		return (this.comparator != null) ? this.comparator.compare(o1, o2) : ((Comparable<O>) o1).compareTo(o2);
+		return this.comparator.compare(this.transformer.transform(e1), this.transformer.transform(e2));
 	}
 
 	@Override
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/TruesFirstBooleanComparator.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/TruesFirstBooleanComparator.java
new file mode 100644
index 0000000..d0e060f
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/TruesFirstBooleanComparator.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.common.utility.internal.comparator;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * This comparator will compare {@link Boolean}s and can be configured to sort
+ * either boolean first.
+ */
+public final class TruesFirstBooleanComparator
+	implements Comparator<Boolean>, Serializable
+{
+	public static final Comparator<Boolean> INSTANCE = new TruesFirstBooleanComparator();
+
+	public static Comparator<Boolean> instance() {
+		return INSTANCE;
+	}
+
+	// ensure single instance
+	private TruesFirstBooleanComparator() {
+		super();
+	}
+
+	public int compare(Boolean b1, Boolean b2) {
+		return b1.booleanValue() ? 
+				(b2.booleanValue() ? 0 : -1) :
+				(b2.booleanValue() ? 1 :  0);
+	}
+
+	@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/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/VersionComparator.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/VersionComparator.java
index ff54f51..a74e479 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/VersionComparator.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/comparator/VersionComparator.java
@@ -22,7 +22,7 @@
  * <em>segments</em> as well as a parser to be used for parsing each
  * <em>segment</em>.
  * 
- * @see #INTEGER_VERSION_COMPARATOR
+ * @param <T> the type of comparable returned by the comparator's segment parser
  */
 public class VersionComparator<T extends Comparable<T>>
 	implements Comparator<String>
@@ -31,42 +31,6 @@
 	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.<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());
-
-
-	/**
-	 * Use the specified segment parser.
-	 * The default delimiter is <code>'.'</code>.
-	 */
-	public VersionComparator(SegmentParser<T> segmentParser) {
-		this(".", segmentParser); //$NON-NLS-1$
-	}
-
-	/**
-	 * 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)) {
@@ -76,11 +40,10 @@
 		this.segmentParser = segmentParser;
 	}
 
-
 	/**
 	 * <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
+	 * integer segment parser {@link ComparatorTools#INTEGER_VERSION_COMPARATOR} can throw a
 	 * {@link NumberFormatException} if any segement string contains non-numeric
 	 * characters.
 	 */
@@ -194,40 +157,5 @@
 				return INSTANCE;
 			}
 		}
-
-		/**
-		 * Singleton implementation of the segment parser interface that throws
-		 * an exception if called.
-		 */
-		final class Disabled<S extends Comparable<S>>
-			implements SegmentParser<S>, Serializable
-		{
-			@SuppressWarnings("rawtypes")
-			public static final SegmentParser INSTANCE = new Disabled();
-			@SuppressWarnings("unchecked")
-			public static <R extends Comparable<R>> SegmentParser<R> instance() {
-				return INSTANCE;
-			}
-			// ensure single instance
-			private Disabled() {
-				super();
-			}
-			// throw an exception
-			public S parse(int segmentIndex, String segment) {
-				throw new UnsupportedOperationException();
-			}
-			public S getZero() {
-				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;
-			}
-		}
 	}
 }
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/ArrayToolsTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/ArrayToolsTests.java
index e142de2..c411ca7 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/ArrayToolsTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/ArrayToolsTests.java
@@ -24,7 +24,7 @@
 import org.eclipse.jpt.common.utility.internal.StringTools;
 import org.eclipse.jpt.common.utility.internal.closure.ClosureAdapter;
 import org.eclipse.jpt.common.utility.internal.closure.InterruptibleClosureAdapter;
-import org.eclipse.jpt.common.utility.internal.comparator.ReverseComparator;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
 import org.eclipse.jpt.common.utility.internal.iterator.EmptyIterator;
 import org.eclipse.jpt.common.utility.internal.predicate.PredicateAdapter;
 import org.eclipse.jpt.common.utility.internal.predicate.PredicateTools;
@@ -1682,7 +1682,7 @@
 	}
 
 	public void testInsertionIndexOfObjectArrayObjectComparator() {
-		Comparator<String> c = new ReverseComparator<String>();
+		Comparator<String> c = ComparatorTools.reverseComparator();
 		String[] a = new String[] { "D", "C", "A" };
 		assertEquals(2, ArrayTools.insertionIndexOf(a, "B", c));
 
@@ -1726,7 +1726,7 @@
 	}
 
 	public void testLastInsertionIndexOfObjectArrayObjectComparator() {
-		Comparator<String> c = new ReverseComparator<String>();
+		Comparator<String> c = ComparatorTools.reverseComparator();
 		String[] a = new String[] { "D", "C", "A" };
 		assertEquals(2, ArrayTools.lastInsertionIndexOf(a, "B", c));
 
@@ -3712,7 +3712,7 @@
 		a1[0] = "y";
 		a1[1] = "b";
 		a1[2] = "m";
-		String[] a2 = ArrayTools.sort(a1, new ReverseComparator<String>());
+		String[] a2 = ArrayTools.sort(a1, ComparatorTools.<String>reverseComparator());
 		String last = "z";
 		for (String x : a1) {
 			assertTrue(last.compareTo(x) > 0);
@@ -3752,7 +3752,7 @@
 		a2[5] = "m";
 		int from = 3;
 		int to = 6;
-		String[] a3 = ArrayTools.sort(a2, from, to, new ReverseComparator<String>());
+		String[] a3 = ArrayTools.sort(a2, from, to, ComparatorTools.<String>reverseComparator());
 		String last = "z";
 		for (int i = 0; i < a1.length; i++) {
 			String x = a1[i];
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/JptCommonUtilityTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/JptCommonUtilityTests.java
index 7412be4..34edf48 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/JptCommonUtilityTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/JptCommonUtilityTests.java
@@ -61,7 +61,7 @@
 		suite.addTestSuite(ClassNameToolsTests.class);
 		suite.addTestSuite(ClasspathTests.class);
 		suite.addTestSuite(ListenerListTests.class);
-		suite.addTestSuite(MapKeyAssociationTests.class);
+		suite.addTestSuite(MapEntryAssociationTests.class);
 		suite.addTestSuite(NameToolsTests.class);
 		suite.addTestSuite(ObjectToolsTests.class);
 		suite.addTestSuite(RangeTests.class);
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/MapKeyAssociationTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/MapEntryAssociationTests.java
similarity index 97%
rename from common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/MapKeyAssociationTests.java
rename to common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/MapEntryAssociationTests.java
index f90c4d5..ca4a897 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/MapKeyAssociationTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/MapEntryAssociationTests.java
@@ -16,12 +16,12 @@
 import org.eclipse.jpt.common.utility.internal.MapEntryAssociation;
 
 @SuppressWarnings("nls")
-public class MapKeyAssociationTests
+public class MapEntryAssociationTests
 	extends TestCase
 {
 	private MapEntryAssociation<String, String> assoc;
 
-	public MapKeyAssociationTests(String name) {
+	public MapEntryAssociationTests(String name) {
 		super(name);
 	}
 
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/collection/CollectionToolsTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/collection/CollectionToolsTests.java
index ca3682b..d198057 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/collection/CollectionToolsTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/collection/CollectionToolsTests.java
@@ -25,7 +25,7 @@
 import org.eclipse.jpt.common.utility.internal.ClassTools;
 import org.eclipse.jpt.common.utility.internal.collection.CollectionTools;
 import org.eclipse.jpt.common.utility.internal.collection.EmptyBag;
-import org.eclipse.jpt.common.utility.internal.comparator.ReverseComparator;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
 import org.eclipse.jpt.common.utility.internal.iterable.EmptyIterable;
 import org.eclipse.jpt.common.utility.internal.iterator.EmptyIterator;
 import org.eclipse.jpt.common.utility.internal.iterator.IteratorTools;
@@ -884,11 +884,11 @@
 		list.add("3");
 		list.add("1");
 
-		SortedSet<String> ss1 = new TreeSet<String>(new ReverseComparator<String>());
+		SortedSet<String> ss1 = new TreeSet<String>(ComparatorTools.<String>reverseComparator());
 		ss1.addAll(list);
 
 		Iterable<String> iterable = list;
-		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(iterable, new ReverseComparator<String>());
+		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(iterable, ComparatorTools.<String>reverseComparator());
 		assertEquals(ss1, ss2);
 	}
 
@@ -899,11 +899,11 @@
 		list.add("3");
 		list.add("1");
 
-		SortedSet<String> ss1 = new TreeSet<String>(new ReverseComparator<String>());
+		SortedSet<String> ss1 = new TreeSet<String>(ComparatorTools.<String>reverseComparator());
 		ss1.addAll(list);
 
 		Iterable<String> iterable = list;
-		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(iterable, new ReverseComparator<String>(), 5);
+		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(iterable, ComparatorTools.<String>reverseComparator(), 5);
 		assertEquals(ss1, ss2);
 	}
 
@@ -937,11 +937,11 @@
 		list.add("3");
 		list.add("1");
 
-		SortedSet<String> ss1 = new TreeSet<String>(new ReverseComparator<String>());
+		SortedSet<String> ss1 = new TreeSet<String>(ComparatorTools.<String>reverseComparator());
 		ss1.addAll(list);
 
 		String[] array = list.toArray(new String[list.size()]);
-		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(array, new ReverseComparator<String>());
+		SortedSet<String> ss2 = CollectionTools.<String>sortedSet(array, ComparatorTools.<String>reverseComparator());
 		assertEquals(ss1, ss2);
 	}
 
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/collection/ListToolsTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/collection/ListToolsTests.java
index 59db529..6c24296 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/collection/ListToolsTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/collection/ListToolsTests.java
@@ -27,7 +27,7 @@
 import org.eclipse.jpt.common.utility.internal.Range;
 import org.eclipse.jpt.common.utility.internal.collection.CollectionTools;
 import org.eclipse.jpt.common.utility.internal.collection.ListTools;
-import org.eclipse.jpt.common.utility.internal.comparator.ReverseComparator;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
 import org.eclipse.jpt.common.utility.internal.iterable.EmptyIterable;
 import org.eclipse.jpt.common.utility.internal.iterator.EmptyIterator;
 import org.eclipse.jpt.common.utility.internal.predicate.PredicateTools;
@@ -346,7 +346,7 @@
 	}
 
 	public void testInsertionIndexOfListObjectComparatorRandomAccess() {
-		Comparator<String> c = new ReverseComparator<String>();
+		Comparator<String> c = ComparatorTools.reverseComparator();
 		List<String> list = Arrays.asList(new String[] { "D", "C", "A" });
 		assertEquals(2, ListTools.insertionIndexOf(list, "B", c));
 
@@ -367,7 +367,7 @@
 	}
 
 	public void testInsertionIndexOfListObjectComparatorNonRandomAccess() {
-		Comparator<String> c = new ReverseComparator<String>();
+		Comparator<String> c = ComparatorTools.reverseComparator();
 		List<String> list = new LinkedList<String>(Arrays.asList(new String[] { "D", "C", "A" }));
 		assertEquals(2, ListTools.insertionIndexOf(list, "B", c));
 
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/BooleanComparatorTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/BooleanComparatorTests.java
new file mode 100644
index 0000000..25c8085
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/BooleanComparatorTests.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.common.utility.tests.internal.comparator;
+
+import java.util.Comparator;
+import junit.framework.TestCase;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
+
+public class BooleanComparatorTests
+	extends TestCase
+{
+	public BooleanComparatorTests(String name) {
+		super(name);
+	}
+
+	public void testTrueFirstEqual() {
+		Comparator<Boolean> comparator = ComparatorTools.booleanComparator(true);
+		assertEquals(0, comparator.compare(Boolean.TRUE, Boolean.TRUE));
+	}
+
+	public void testTrueFirstLess() {
+		Comparator<Boolean> comparator = ComparatorTools.booleanComparator(true);
+		assertTrue(comparator.compare(Boolean.TRUE, Boolean.FALSE) < 0);
+	}
+
+	public void testTrueFirstGreater() {
+		Comparator<Boolean> comparator = ComparatorTools.booleanComparator(true);
+		assertTrue(comparator.compare(Boolean.FALSE, Boolean.TRUE) > 0);
+	}
+
+	public void testFalseFirstEqual() {
+		Comparator<Boolean> comparator = ComparatorTools.booleanComparator(false);
+		assertEquals(0, comparator.compare(Boolean.FALSE, Boolean.FALSE));
+	}
+
+	public void testFalseFirstLess() {
+		Comparator<Boolean> comparator = ComparatorTools.booleanComparator(false);
+		assertTrue(comparator.compare(Boolean.FALSE, Boolean.TRUE) < 0);
+	}
+
+	public void testFalseFirstGreater() {
+		Comparator<Boolean> comparator = ComparatorTools.booleanComparator(false);
+		assertTrue(comparator.compare(Boolean.TRUE, Boolean.FALSE) > 0);
+	}
+}
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/ComparatorToolsTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/ComparatorToolsTests.java
new file mode 100644
index 0000000..1b99f55
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/ComparatorToolsTests.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.common.utility.tests.internal.comparator;
+
+import java.text.Collator;
+import java.text.DateFormat;
+import java.util.Comparator;
+import java.util.Date;
+import junit.framework.TestCase;
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorAdapter;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
+
+@SuppressWarnings("nls")
+public class ComparatorToolsTests
+	extends TestCase
+{
+	public ComparatorToolsTests(String name) {
+		super(name);
+	}
+
+	public void testMinObjectObject() {
+		String foo = "foo";
+		String bar = "bar";
+		assertEquals(bar, ComparatorTools.min(foo, bar));
+		assertEquals(bar, ComparatorTools.min(bar, foo));
+	}
+
+	public void testMinObjectObjectComparator() {
+		String foo = "foo";
+		String bar = "bar";
+		assertEquals(foo, ComparatorTools.min(foo, bar, ComparatorTools.<String>reverseComparator()));
+		assertEquals(foo, ComparatorTools.min(bar, foo, ComparatorTools.<String>reverseComparator()));
+	}
+
+	public void testMaxObjectObject() {
+		String foo = "foo";
+		String bar = "bar";
+		assertEquals(foo, ComparatorTools.max(foo, bar));
+		assertEquals(foo, ComparatorTools.max(bar, foo));
+	}
+
+	public void testMaxObjectObjectComparator() {
+		String foo = "foo";
+		String bar = "bar";
+		assertEquals(bar, ComparatorTools.max(foo, bar, ComparatorTools.<String>reverseComparator()));
+		assertEquals(bar, ComparatorTools.max(bar, foo, ComparatorTools.<String>reverseComparator()));
+	}
+
+	public void testComparableComparator() {
+		assertTrue(ComparatorTools.<String>comparableComparator().compare("foo", "foo") == 0);
+		assertTrue(ComparatorTools.<String>comparableComparator().compare("foo", "bar") > 0);
+		assertTrue(ComparatorTools.<String>comparableComparator().compare("bar", "foo") < 0);
+	}
+
+	public void testNaturalComparator() {
+		assertTrue(ComparatorTools.<String>naturalComparator().compare("foo", "foo") == 0);
+		assertTrue(ComparatorTools.<String>naturalComparator().compare("foo", "bar") > 0);
+		assertTrue(ComparatorTools.<String>naturalComparator().compare("bar", "foo") < 0);
+	}
+
+	public void testComparatorChain() throws Exception {
+		@SuppressWarnings("unchecked")
+		Comparator<Person> comparator = ComparatorTools.chain(Person.LAST_NAME_COMPARATOR, Person.FIRST_NAME_COMPARATOR, Person.BIRTH_DATE_COMPARATOR);
+		Person john = new Person("John", "Smith", DateFormat.getDateInstance(DateFormat.SHORT).parse("10/11/55"));
+		Person jane = new Person("Jane", "Smith", DateFormat.getDateInstance(DateFormat.SHORT).parse("10/11/55"));
+		assertTrue(comparator.compare(john, john) == 0);
+		assertTrue(comparator.compare(jane, john) < 0);
+		assertTrue(comparator.compare(john, jane) > 0);
+		Person oldJohn = new Person("John", "Smith", DateFormat.getDateInstance(DateFormat.SHORT).parse("10/11/33"));
+		assertTrue(comparator.compare(oldJohn, oldJohn) == 0);
+		assertTrue(comparator.compare(oldJohn, john) < 0);
+		assertTrue(comparator.compare(john, oldJohn) > 0);
+	}
+
+	public void testNullsFirstComparator() {
+		assertTrue(ComparatorTools.nullsFirst(ComparatorTools.stringCollator()).compare("foo", "foo") == 0);
+		assertTrue(ComparatorTools.nullsFirst(ComparatorTools.stringCollator()).compare("foo", "bar") > 0);
+		assertTrue(ComparatorTools.nullsFirst(ComparatorTools.stringCollator()).compare("bar", "foo") < 0);
+
+		assertTrue(ComparatorTools.nullsFirst(ComparatorTools.stringCollator()).compare(null, null) == 0);
+		assertTrue(ComparatorTools.nullsFirst(ComparatorTools.stringCollator()).compare("foo", null) > 0);
+		assertTrue(ComparatorTools.nullsFirst(ComparatorTools.stringCollator()).compare(null, "foo") < 0);
+	}
+
+	public void testNullsLastComparator() {
+		assertTrue(ComparatorTools.nullsLast(ComparatorTools.stringCollator()).compare("foo", "foo") == 0);
+		assertTrue(ComparatorTools.nullsLast(ComparatorTools.stringCollator()).compare("foo", "bar") > 0);
+		assertTrue(ComparatorTools.nullsLast(ComparatorTools.stringCollator()).compare("bar", "foo") < 0);
+
+		assertTrue(ComparatorTools.nullsLast(ComparatorTools.stringCollator()).compare(null, null) == 0);
+		assertTrue(ComparatorTools.nullsLast(ComparatorTools.stringCollator()).compare("foo", null) < 0);
+		assertTrue(ComparatorTools.nullsLast(ComparatorTools.stringCollator()).compare(null, "foo") > 0);
+	}
+
+	public void testTransformationComparator() {
+		assertTrue(ComparatorTools.nullsLast(ComparatorTools.stringCollator()).compare("foo", "foo") == 0);
+		assertTrue(ComparatorTools.nullsLast(ComparatorTools.stringCollator()).compare("foo", "bar") > 0);
+		assertTrue(ComparatorTools.nullsLast(ComparatorTools.stringCollator()).compare("bar", "foo") < 0);
+
+		assertTrue(ComparatorTools.nullsLast(ComparatorTools.stringCollator()).compare(null, null) == 0);
+		assertTrue(ComparatorTools.nullsLast(ComparatorTools.stringCollator()).compare("foo", null) < 0);
+		assertTrue(ComparatorTools.nullsLast(ComparatorTools.stringCollator()).compare(null, "foo") > 0);
+	}
+
+	public static class Person {
+		public final String firstName;
+		public final String lastName;
+		public final Date birthDate;
+		public Person(String firstName, String lastName, Date birthDate) {
+			super();
+			this.firstName = firstName;
+			this.lastName = lastName;
+			this.birthDate = birthDate;
+		}
+		@Override
+		public String toString() {
+			return ObjectTools.toString(this, this.firstName + ' ' + this.lastName);
+		}
+
+		public static final Comparator<Person> FIRST_NAME_COMPARATOR = new FirstNameComparator();
+		public static class FirstNameComparator
+			extends ComparatorAdapter<Person>
+		{
+			@Override
+			public int compare(Person p1, Person p2) {
+				return Collator.getInstance().compare(p1.firstName, p2.firstName);
+			}
+		}
+
+		public static final Comparator<Person> LAST_NAME_COMPARATOR = new LastNameComparator();
+		public static class LastNameComparator
+			extends ComparatorAdapter<Person>
+		{
+			@Override
+			public int compare(Person p1, Person p2) {
+				return Collator.getInstance().compare(p1.lastName, p2.lastName);
+			}
+		}
+
+		public static final Comparator<Person> BIRTH_DATE_COMPARATOR = new BirthDateComparator();
+		public static class BirthDateComparator
+			extends ComparatorAdapter<Person>
+		{
+			@Override
+			public int compare(Person p1, Person p2) {
+				return p1.birthDate.compareTo(p2.birthDate);
+			}
+		}
+	}
+}
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/JptCommonUtilityComparatorTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/JptCommonUtilityComparatorTests.java
index 24fb62c..ec13492 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/JptCommonUtilityComparatorTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/JptCommonUtilityComparatorTests.java
@@ -17,6 +17,8 @@
 	public static Test suite() {
 		TestSuite suite = new TestSuite(JptCommonUtilityComparatorTests.class.getPackage().getName());
 
+		suite.addTestSuite(BooleanComparatorTests.class);
+		suite.addTestSuite(ComparatorToolsTests.class);
 		suite.addTestSuite(ReverseComparatorTests.class);
 		suite.addTestSuite(VersionComparatorTests.class);
 
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/ReverseComparatorTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/ReverseComparatorTests.java
index 44c60a0..57e28e9 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/ReverseComparatorTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/ReverseComparatorTests.java
@@ -15,6 +15,7 @@
 import java.util.List;
 import junit.framework.TestCase;
 import org.eclipse.jpt.common.utility.internal.ObjectTools;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
 import org.eclipse.jpt.common.utility.internal.comparator.ReverseComparator;
 import org.eclipse.jpt.common.utility.tests.internal.TestTools;
 
@@ -33,7 +34,7 @@
 	@Override
 	protected void setUp() throws Exception {
 		super.setUp();
-		this.naturalReverseComparator = new ReverseComparator<String>();
+		this.naturalReverseComparator = ComparatorTools.reverseComparator();
 		this.customComparator = this.buildCustomComparator();
 		this.customReverseComparator = new ReverseComparator<String>(this.customComparator);
 	}
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/VersionComparatorTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/VersionComparatorTests.java
index ff595f0..a58ede2 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/VersionComparatorTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/comparator/VersionComparatorTests.java
@@ -13,8 +13,8 @@
 import java.math.BigDecimal;
 import java.util.Comparator;
 import junit.framework.TestCase;
-
 import org.eclipse.jpt.common.utility.internal.ObjectTools;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
 import org.eclipse.jpt.common.utility.internal.comparator.VersionComparator;
 import org.eclipse.jpt.common.utility.internal.comparator.VersionComparator.SegmentParser;
 
@@ -27,28 +27,28 @@
 	}
 
 	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);
+		assertTrue(ComparatorTools.integerVersionComparator().compare("2.0.0", "2.0.0") == 0);
+		assertTrue(ComparatorTools.integerVersionComparator().compare("2.0.0", "2.0.0.0") == 0);
+		assertTrue(ComparatorTools.integerVersionComparator().compare("2.0.0.0.0.0.0000", "2.0") == 0);
+		assertTrue(ComparatorTools.integerVersionComparator().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);
+		assertTrue(ComparatorTools.integerVersionComparator().compare("2.0.0", "2.0.1") < 0);
+		assertTrue(ComparatorTools.integerVersionComparator().compare("2.5.0", "2.14") < 0);
+		assertTrue(ComparatorTools.integerVersionComparator().compare("2.5.0", "2.5.0.0.1.0") < 0);
+		assertTrue(ComparatorTools.integerVersionComparator().compare("2.5.0.0.0.-1", "2.5") < 0);
+		assertTrue(ComparatorTools.integerVersionComparator().compare("2.0.-1", "2.0.0") < 0);
+		assertTrue(ComparatorTools.integerVersionComparator().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);
+		assertTrue(ComparatorTools.integerVersionComparator().compare("2.0.2", "2.0.1") > 0);
+		assertTrue(ComparatorTools.integerVersionComparator().compare("2.0.2", "2.0.1") > 0);
+		assertTrue(ComparatorTools.integerVersionComparator().compare("2.5.0.0.1.0", "2.5.0") > 0);
+		assertTrue(ComparatorTools.integerVersionComparator().compare("2.5", "2.5.0.0.0.-1") > 0);
+		assertTrue(ComparatorTools.integerVersionComparator().compare("2.0.0", "2.0.-1") > 0);
+		assertTrue(ComparatorTools.integerVersionComparator().compare("2", "2.0.-1") > 0);
 	}
 
 	public void testVersionIsEqual_integer_comma() {
@@ -68,7 +68,7 @@
 	}
 
 	public void testVersionIsGreater_integer_comma() {
-		Comparator<String> versionComparator = new VersionComparator<BigDecimal>(',', DecimalSegmentParser.instance());
+		Comparator<String> versionComparator = ComparatorTools.versionComparator(',', 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);
@@ -76,7 +76,7 @@
 	}
 
 	public void testVersionIsEqual_subclass() {
-		Comparator<String> versionComparator = VersionComparator.INTEGER_VERSION_COMPARATOR;
+		Comparator<String> versionComparator = ComparatorTools.integerVersionComparator();
 		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);
@@ -84,7 +84,7 @@
 	}
 
 	public void testVersionIsLess_subclass() {
-		Comparator<String> versionComparator = VersionComparator.INTEGER_VERSION_COMPARATOR;
+		Comparator<String> versionComparator = ComparatorTools.integerVersionComparator();
 		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);
@@ -93,7 +93,7 @@
 	}
 
 	public void testVersionIsGreater_subclass() {
-		Comparator<String> versionComparator = VersionComparator.INTEGER_VERSION_COMPARATOR;
+		Comparator<String> versionComparator = ComparatorTools.integerVersionComparator();
 		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);
@@ -105,7 +105,7 @@
 		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);
+			assertTrue(ComparatorTools.integerVersionComparator().compare("2.0.0", "2.O.O") == 0);
 		} catch (NumberFormatException ex) {
 			exCaught = true;
 		}
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/enumeration/EnumerationToolsTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/enumeration/EnumerationToolsTests.java
index 7bb5946..3cf6960 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/enumeration/EnumerationToolsTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/enumeration/EnumerationToolsTests.java
@@ -20,7 +20,7 @@
 import org.eclipse.jpt.common.utility.internal.ArrayTools;
 import org.eclipse.jpt.common.utility.internal.ClassTools;
 import org.eclipse.jpt.common.utility.internal.StringTools;
-import org.eclipse.jpt.common.utility.internal.comparator.ReverseComparator;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
 import org.eclipse.jpt.common.utility.internal.enumeration.EnumerationTools;
 import org.eclipse.jpt.common.utility.internal.iterator.IteratorTools;
 
@@ -410,11 +410,11 @@
 		list.add("3");
 		list.add("1");
 
-		SortedSet<String> ss = new TreeSet<String>(new ReverseComparator<String>());
+		SortedSet<String> ss = new TreeSet<String>(ComparatorTools.<String>reverseComparator());
 		ss.addAll(list);
 
 		Enumeration<String> enumeration1 = list.elements();
-		Enumeration<String> enumeration2 = EnumerationTools.<String>sort(enumeration1, new ReverseComparator<String>());
+		Enumeration<String> enumeration2 = EnumerationTools.<String>sort(enumeration1, ComparatorTools.<String>reverseComparator());
 		assertTrue(EnumerationTools.elementsAreEqual(EnumerationTools.enumeration(ss), enumeration2));
 	}
 
@@ -425,11 +425,11 @@
 		list.add("3");
 		list.add("1");
 
-		SortedSet<String> ss = new TreeSet<String>(new ReverseComparator<String>());
+		SortedSet<String> ss = new TreeSet<String>(ComparatorTools.<String>reverseComparator());
 		ss.addAll(list);
 
 		Enumeration<String> enumeration1 = list.elements();
-		Enumeration<String> enumeration2 = EnumerationTools.<String>sort(enumeration1, new ReverseComparator<String>(), 77);
+		Enumeration<String> enumeration2 = EnumerationTools.<String>sort(enumeration1, ComparatorTools.<String>reverseComparator(), 77);
 		assertTrue(EnumerationTools.elementsAreEqual(EnumerationTools.enumeration(ss), enumeration2));
 	}
 
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/iterable/IterableToolsTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/iterable/IterableToolsTests.java
index 9b2d52d..4afe1fe 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/iterable/IterableToolsTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/iterable/IterableToolsTests.java
@@ -20,7 +20,7 @@
 import junit.framework.TestCase;
 import org.eclipse.jpt.common.utility.internal.ClassTools;
 import org.eclipse.jpt.common.utility.internal.collection.HashBag;
-import org.eclipse.jpt.common.utility.internal.comparator.ReverseComparator;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
 import org.eclipse.jpt.common.utility.internal.iterable.EmptyIterable;
 import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
 import org.eclipse.jpt.common.utility.tests.internal.ArrayToolsTests;
@@ -337,11 +337,11 @@
 		list.add("3");
 		list.add("1");
 
-		SortedSet<String> ss = new TreeSet<String>(new ReverseComparator<String>());
+		SortedSet<String> ss = new TreeSet<String>(ComparatorTools.<String>reverseComparator());
 		ss.addAll(list);
 
 		Iterable<String> iterable1 = list;
-		Iterable<String> iterable2 = IterableTools.<String>sort(iterable1, new ReverseComparator<String>());
+		Iterable<String> iterable2 = IterableTools.<String>sort(iterable1, ComparatorTools.<String>reverseComparator());
 		assertTrue(IterableTools.elementsAreEqual(ss, iterable2));
 	}
 
@@ -352,11 +352,11 @@
 		list.add("3");
 		list.add("1");
 
-		SortedSet<String> ss = new TreeSet<String>(new ReverseComparator<String>());
+		SortedSet<String> ss = new TreeSet<String>(ComparatorTools.<String>reverseComparator());
 		ss.addAll(list);
 
 		Iterable<String> iterable1 = list;
-		Iterable<String> iterable2 = IterableTools.<String>sort(iterable1, new ReverseComparator<String>(), 77);
+		Iterable<String> iterable2 = IterableTools.<String>sort(iterable1, ComparatorTools.<String>reverseComparator(), 77);
 		assertTrue(IterableTools.elementsAreEqual(ss, iterable2));
 	}
 
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/iterator/IteratorToolsTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/iterator/IteratorToolsTests.java
index 8cc0b3a..35f30ce 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/iterator/IteratorToolsTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/iterator/IteratorToolsTests.java
@@ -22,7 +22,7 @@
 import junit.framework.TestCase;
 import org.eclipse.jpt.common.utility.internal.ClassTools;
 import org.eclipse.jpt.common.utility.internal.collection.HashBag;
-import org.eclipse.jpt.common.utility.internal.comparator.ReverseComparator;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
 import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
 import org.eclipse.jpt.common.utility.internal.iterator.EmptyIterator;
 import org.eclipse.jpt.common.utility.internal.iterator.IteratorTools;
@@ -588,11 +588,11 @@
 		list.add("3");
 		list.add("1");
 
-		SortedSet<String> ss = new TreeSet<String>(new ReverseComparator<String>());
+		SortedSet<String> ss = new TreeSet<String>(ComparatorTools.<String>reverseComparator());
 		ss.addAll(list);
 
 		Iterator<String> iterator1 = list.iterator();
-		Iterator<String> iterator2 = IteratorTools.<String>sort(iterator1, new ReverseComparator<String>());
+		Iterator<String> iterator2 = IteratorTools.<String>sort(iterator1, ComparatorTools.<String>reverseComparator());
 		assertTrue(IteratorTools.elementsAreEqual(ss.iterator(), iterator2));
 	}
 
@@ -603,11 +603,11 @@
 		list.add("3");
 		list.add("1");
 
-		SortedSet<String> ss = new TreeSet<String>(new ReverseComparator<String>());
+		SortedSet<String> ss = new TreeSet<String>(ComparatorTools.<String>reverseComparator());
 		ss.addAll(list);
 
 		Iterator<String> iterator1 = list.iterator();
-		Iterator<String> iterator2 = IteratorTools.<String>sort(iterator1, new ReverseComparator<String>(), 77);
+		Iterator<String> iterator2 = IteratorTools.<String>sort(iterator1, ComparatorTools.<String>reverseComparator(), 77);
 		assertTrue(IteratorTools.elementsAreEqual(ss.iterator(), iterator2));
 	}
 
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/model/value/SortedListValueModelAdapterTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/model/value/SortedListValueModelAdapterTests.java
index e11c6e3..83752b4 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/model/value/SortedListValueModelAdapterTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/model/value/SortedListValueModelAdapterTests.java
@@ -15,14 +15,12 @@
 import java.util.Comparator;
 import java.util.List;
 import java.util.TreeSet;
-
 import junit.framework.TestCase;
-
 import org.eclipse.jpt.common.utility.collection.Bag;
 import org.eclipse.jpt.common.utility.internal.collection.CollectionTools;
 import org.eclipse.jpt.common.utility.internal.collection.HashBag;
 import org.eclipse.jpt.common.utility.internal.collection.ListTools;
-import org.eclipse.jpt.common.utility.internal.comparator.ReverseComparator;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
 import org.eclipse.jpt.common.utility.internal.model.AbstractModel;
 import org.eclipse.jpt.common.utility.internal.model.value.SimpleCollectionValueModel;
 import org.eclipse.jpt.common.utility.internal.model.value.SortedListValueModelAdapter;
@@ -166,8 +164,8 @@
 		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>());
+		this.adapter.setComparator(ComparatorTools.<String>reverseComparator());
+		this.verifyList(this.wrappedCollection, this.adapter, ComparatorTools.<String>reverseComparator());
 		assertEquals(this.wrappedCollection, CollectionTools.collection(synchList.iterator()));
 		assertEquals(this.wrappedCollection, synchCollection);
 	}
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/model/value/SortedListValueModelWrapperTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/model/value/SortedListValueModelWrapperTests.java
index faff4b4..e2a384a 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/model/value/SortedListValueModelWrapperTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/model/value/SortedListValueModelWrapperTests.java
@@ -15,11 +15,9 @@
 import java.util.Comparator;
 import java.util.List;
 import java.util.TreeSet;
-
 import junit.framework.TestCase;
-
 import org.eclipse.jpt.common.utility.internal.collection.ListTools;
-import org.eclipse.jpt.common.utility.internal.comparator.ReverseComparator;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
 import org.eclipse.jpt.common.utility.internal.model.AbstractModel;
 import org.eclipse.jpt.common.utility.internal.model.value.SimpleListValueModel;
 import org.eclipse.jpt.common.utility.internal.model.value.SortedListValueModelWrapper;
@@ -183,8 +181,8 @@
 		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>());
+		this.sortedListModel.setComparator(ComparatorTools.<String>reverseComparator());
+		this.verifyList(this.list, this.sortedListModel, ComparatorTools.<String>reverseComparator());
 		assertEquals(this.list, synchList);
 	}
 
diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatformFactory.java
index 4133d91..3860905 100644
--- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatformFactory.java
+++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatformFactory.java
@@ -10,7 +10,7 @@
 package org.eclipse.jpt.jpa.core.internal;
 
 import org.eclipse.jpt.common.core.JptResourceType;
-import org.eclipse.jpt.common.utility.internal.comparator.VersionComparator;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
 import org.eclipse.jpt.jpa.core.JpaPlatform;
 import org.eclipse.jpt.jpa.core.JpaPlatformFactory;
 import org.eclipse.jpt.jpa.core.JpaPlatformVariation;
@@ -100,7 +100,7 @@
 		 * For now, generic platforms are backward-compatible.
 		 */
 		public boolean isCompatibleWithJpaVersion(String version) {
-			return VersionComparator.INTEGER_VERSION_COMPARATOR.compare(this.jpaVersion, version) >= 0;
+			return ComparatorTools.integerVersionComparator().compare(this.jpaVersion, version) >= 0;
 		}
 
 		@Override
diff --git a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLinkJpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLinkJpaPlatformFactory.java
index 4c65a12..b54d5b3 100644
--- a/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLinkJpaPlatformFactory.java
+++ b/jpa/plugins/org.eclipse.jpt.jpa.eclipselink.core/src/org/eclipse/jpt/jpa/eclipselink/core/internal/EclipseLinkJpaPlatformFactory.java
@@ -11,7 +11,7 @@
 
 import org.eclipse.jpt.common.core.AnnotationProvider;
 import org.eclipse.jpt.common.core.JptResourceType;
-import org.eclipse.jpt.common.utility.internal.comparator.VersionComparator;
+import org.eclipse.jpt.common.utility.internal.comparator.ComparatorTools;
 import org.eclipse.jpt.jpa.core.JpaPlatform;
 import org.eclipse.jpt.jpa.core.JpaPlatformFactory;
 import org.eclipse.jpt.jpa.core.JpaPlatformVariation;
@@ -119,7 +119,7 @@
 		 * @see EclipseLinkJpaPlatformFactory2_5#VERSION
 		 */
 		public boolean isCompatibleWithEclipseLinkVersion(String version) {
-			return VersionComparator.INTEGER_VERSION_COMPARATOR.compare(this.eclipseLinkVersion, version) >= 0;
+			return ComparatorTools.integerVersionComparator().compare(this.eclipseLinkVersion, version) >= 0;
 		}
 
 		@Override