You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2014/01/01 00:50:04 UTC

svn commit: r1554592 [1/2] - in /sis/branches/JDK6: ./ core/sis-referencing/src/main/java/org/apache/sis/geometry/ core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/ core/sis-referencing/src/main/java/org/apache/sis/io/wkt/ co...

Author: desruisseaux
Date: Tue Dec 31 23:50:03 2013
New Revision: 1554592

URL: http://svn.apache.org/r1554592
Log:
Merge from the JDK7 branch.

Added:
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CS_AffineCS.java
      - copied unchanged from r1554591, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CS_AffineCS.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CS_AxisDirection.java
      - copied unchanged from r1554591, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CS_AxisDirection.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CS_CartesianCS.java
      - copied unchanged from r1554591, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CS_CartesianCS.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CS_CoordinateSystemAxis.java
      - copied unchanged from r1554591, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CS_CoordinateSystemAxis.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CS_EllipsoidalCS.java
      - copied unchanged from r1554591, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CS_EllipsoidalCS.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CS_TimeCS.java
      - copied unchanged from r1554591, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CS_TimeCS.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CS_VerticalCS.java
      - copied unchanged from r1554591, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CS_VerticalCS.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Legacy.java
      - copied unchanged from r1554591, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Legacy.java
    sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/datum/Mean Sea Level.xml
      - copied unchanged from r1554591, sis/branches/JDK7/core/sis-referencing/src/test/resources/org/apache/sis/referencing/datum/Mean Sea Level.xml
Modified:
    sis/branches/JDK6/   (props changed)
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition1D.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_GeodeticDatum.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_ImageDatum.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_TemporalDatum.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_VerticalDatum.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/FormattableObject.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/TimeDependentBWP.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticObjectVerifier.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/NamedIdentifierTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/datum/WGS 84.xml
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/math/DecimalFunctions.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
    sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/math/DecimalFunctionsTest.java
    sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java

Propchange: sis/branches/JDK6/
------------------------------------------------------------------------------
  Merged /sis/branches/JDK7:r1553961-1554591

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -33,6 +33,7 @@ import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.Utilities;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.internal.util.Numerics;
 
 import static java.lang.Double.doubleToLongBits;
 import static org.apache.sis.util.StringBuilders.trimFractionalPart;
@@ -362,8 +363,7 @@ parse:  while (i < length) {
         final int dimension = getDimension();
         int code = 1;
         for (int i=0; i<dimension; i++) {
-            final long bits = doubleToLongBits(getOrdinate(i));
-            code = 31 * code + (((int) bits) ^ (int) (bits >>> 32));
+            code = code*31 + Numerics.hashCode(doubleToLongBits(getOrdinate(i)));
         }
         return code + Objects.hashCode(getCoordinateReferenceSystem());
     }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -33,6 +33,7 @@ import org.opengis.referencing.crs.Coord
 import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.RangeMeaning;
+import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.Emptiable;
 import org.apache.sis.util.Utilities;
 import org.apache.sis.util.ComparisonMode;
@@ -1019,19 +1020,14 @@ public abstract class AbstractEnvelope i
     @Override
     public int hashCode() {
         final int dimension = getDimension();
-        int code = 1;
+        long code = 1;
         boolean p = true;
         do {
             for (int i=0; i<dimension; i++) {
-                final long bits = doubleToLongBits(p ? getLower(i) : getUpper(i));
-                code = 31 * code + (((int) bits) ^ (int) (bits >>> 32));
+                code = code*31 + doubleToLongBits(p ? getLower(i) : getUpper(i));
             }
         } while ((p = !p) == false);
-        final CoordinateReferenceSystem crs = getCoordinateReferenceSystem();
-        if (crs != null) {
-            code += crs.hashCode();
-        }
-        return code;
+        return Numerics.hashCode(code) + Objects.hashCode(getCoordinateReferenceSystem());
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition1D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition1D.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition1D.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition1D.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -25,10 +25,14 @@ import java.io.Serializable;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.geometry.MismatchedDimensionException;
+import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.resources.Errors;
 
 import static org.apache.sis.util.ArgumentChecks.ensureDimensionMatches;
 
+// Related to JDK7
+import org.apache.sis.internal.jdk7.Objects;
+
 
 /**
  * Holds the coordinates for a one-dimensional position within some coordinate reference system.
@@ -224,6 +228,8 @@ public class DirectPosition1D extends Ab
 
     /**
      * Returns a copy of this position.
+     *
+     * @return A copy of this position.
      */
     @Override
     public DirectPosition1D clone() {
@@ -240,11 +246,7 @@ public class DirectPosition1D extends Ab
      */
     @Override
     public int hashCode() {
-        final long value = Double.doubleToLongBits(ordinate);
-        int code = 31 + (((int) value) ^ (int) (value >>> 32));
-        if (crs != null) {
-            code += crs.hashCode();
-        }
+        final int code = 31 + Numerics.hashCode(Double.doubleToLongBits(ordinate)) + Objects.hashCode(crs);
         assert code == super.hashCode();
         return code;
     }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -21,6 +21,7 @@ import org.opengis.geometry.DirectPositi
 import org.opengis.geometry.MismatchedDimensionException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.cs.AxisDirection;
+import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.resources.Errors;
 
 import static java.lang.Double.doubleToLongBits;
@@ -302,14 +303,9 @@ public class DirectPosition2D extends Po
      */
     @Override
     public int hashCode() {
-        int code;
-        long bits;
-        bits = doubleToLongBits(x); code = 31      + (((int) bits) ^ (int) (bits >>> 32));
-        bits = doubleToLongBits(y); code = 31*code + (((int) bits) ^ (int) (bits >>> 32));
-        if (crs != null) {
-            code += crs.hashCode();
-        }
-        return code;
+        int code =  31 + Numerics.hashCode(doubleToLongBits(x));
+        code = code*31 + Numerics.hashCode(doubleToLongBits(y));
+        return code + Objects.hashCode(crs);
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_GeodeticDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_GeodeticDatum.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_GeodeticDatum.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_GeodeticDatum.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -60,7 +60,7 @@ public final class CD_GeodeticDatum exte
 
     /**
      * Invoked by {@link PropertyType} at marshalling time for wrapping the given value
-     * in a {@code <gml:geodeticDatum>} XML element.
+     * in a {@code <gml:GeodeticDatum>} XML element.
      *
      * @param  value The element to marshall.
      * @return A {@code PropertyType} wrapping the given the element.
@@ -72,7 +72,7 @@ public final class CD_GeodeticDatum exte
 
     /**
      * Invoked by JAXB at marshalling time for getting the actual element to write
-     * inside the {@code <gml:geodeticDatum>} XML element.
+     * inside the {@code <gml:GeodeticDatum>} XML element.
      * This is the value or a copy of the value given in argument to the {@code wrap} method.
      *
      * @return The element to be marshalled.

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_ImageDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_ImageDatum.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_ImageDatum.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_ImageDatum.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -60,7 +60,7 @@ public final class CD_ImageDatum extends
 
     /**
      * Invoked by {@link PropertyType} at marshalling time for wrapping the given value
-     * in a {@code <gml:imageDatum>} XML element.
+     * in a {@code <gml:ImageDatum>} XML element.
      *
      * @param  value The element to marshall.
      * @return A {@code PropertyType} wrapping the given the element.
@@ -72,7 +72,7 @@ public final class CD_ImageDatum extends
 
     /**
      * Invoked by JAXB at marshalling time for getting the actual element to write
-     * inside the {@code <gml:imageDatum>} XML element.
+     * inside the {@code <gml:ImageDatum>} XML element.
      * This is the value or a copy of the value given in argument to the {@code wrap} method.
      *
      * @return The element to be marshalled.

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_TemporalDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_TemporalDatum.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_TemporalDatum.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_TemporalDatum.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -60,7 +60,7 @@ public final class CD_TemporalDatum exte
 
     /**
      * Invoked by {@link PropertyType} at marshalling time for wrapping the given value
-     * in a {@code <gml:temporalDatum>} XML element.
+     * in a {@code <gml:TemporalDatum>} XML element.
      *
      * @param  value The element to marshall.
      * @return A {@code PropertyType} wrapping the given the element.
@@ -72,7 +72,7 @@ public final class CD_TemporalDatum exte
 
     /**
      * Invoked by JAXB at marshalling time for getting the actual element to write
-     * inside the {@code <gml:temporalDatum>} XML element.
+     * inside the {@code <gml:TemporalDatum>} XML element.
      * This is the value or a copy of the value given in argument to the {@code wrap} method.
      *
      * @return The element to be marshalled.

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_VerticalDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_VerticalDatum.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_VerticalDatum.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/CD_VerticalDatum.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -60,7 +60,7 @@ public final class CD_VerticalDatum exte
 
     /**
      * Invoked by {@link PropertyType} at marshalling time for wrapping the given value
-     * in a {@code <gml:verticalDatum>} XML element.
+     * in a {@code <gml:VerticalDatum>} XML element.
      *
      * @param  value The element to marshall.
      * @return A {@code PropertyType} wrapping the given the element.
@@ -72,7 +72,7 @@ public final class CD_VerticalDatum exte
 
     /**
      * Invoked by JAXB at marshalling time for getting the actual element to write
-     * inside the {@code <gml:verticalDatum>} XML element.
+     * inside the {@code <gml:VerticalDatum>} XML element.
      * This is the value or a copy of the value given in argument to the {@code wrap} method.
      *
      * @return The element to be marshalled.

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -16,25 +16,20 @@
  */
 package org.apache.sis.io.wkt;
 
-import javax.measure.unit.SI;
 import javax.measure.unit.Unit;
 import javax.measure.quantity.Angle;
 import javax.measure.quantity.Quantity;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.CoordinateSystem;
-import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.crs.GeocentricCRS;
 import org.opengis.referencing.operation.OperationMethod;
 import org.opengis.referencing.operation.CoordinateOperation;
 import org.apache.sis.util.Debug;
 import org.apache.sis.metadata.iso.citation.Citations;
-import org.apache.sis.referencing.cs.DefaultCartesianCS;
 import org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis;
 
-import static java.util.Collections.singletonMap;
 import static javax.measure.unit.NonSI.DEGREE_ANGLE;
-import static org.opengis.referencing.cs.CoordinateSystemAxis.NAME_KEY;
 
 
 /**
@@ -101,7 +96,7 @@ public enum Convention {
         @Override
         public CoordinateSystem toConformCS(CoordinateSystem cs) {
             if (cs instanceof CartesianCS) {
-                cs = replace((CartesianCS) cs, false);
+                cs = Legacy.replace((CartesianCS) cs, false);
             }
             return cs;
         }
@@ -205,18 +200,6 @@ public enum Convention {
     };
 
     /**
-     * A three-dimensional Cartesian CS with the legacy set of geocentric axes.
-     * Those axes were defined in the OGC 01-009 specification as <var>Other</var>,
-     * <var>{@linkplain DefaultCoordinateSystemAxis#EASTING Easting}</var>,
-     * <var>{@linkplain DefaultCoordinateSystemAxis#NORTHING Northing}</var>
-     * in metres, where the "Other" axis is toward prime meridian.
-     */
-    private static final DefaultCartesianCS LEGACY = new DefaultCartesianCS(singletonMap(NAME_KEY, "Legacy geocentric"),
-            new DefaultCoordinateSystemAxis(singletonMap(NAME_KEY, "Geocentric X"), "X", AxisDirection.OTHER, SI.METRE),
-            new DefaultCoordinateSystemAxis(singletonMap(NAME_KEY, "Geocentric Y"), "Y", AxisDirection.EAST,  SI.METRE),
-            new DefaultCoordinateSystemAxis(singletonMap(NAME_KEY, "Geocentric Z"), "Z", AxisDirection.NORTH, SI.METRE));
-
-    /**
      * If non-null, forces {@code PRIMEM} and {@code PARAMETER} angular units to this field
      * value instead than inferring it from the context. The standard value is {@code null},
      * which means that the angular units are inferred from the context as required by the
@@ -344,32 +327,8 @@ public enum Convention {
      */
     public CoordinateSystem toConformCS(CoordinateSystem cs) {
         if (cs instanceof CartesianCS) {
-            cs = replace((CartesianCS) cs, true);
+            cs = Legacy.replace((CartesianCS) cs, true);
         }
         return cs;
     }
-
-    /**
-     * Returns the axes to use instead of the ones in the given coordinate system.
-     * If the coordinate system axes should be used as-is, returns {@code cs}.
-     *
-     * @param  cs The coordinate system for which to compare the axis directions.
-     * @param  legacy {@code true} for replacing ISO directions by the legacy ones,
-     *         or {@code false} for the other way around.
-     * @return The axes to use instead of the ones in the given CS,
-     *         or {@code cs} if the CS axes should be used as-is.
-     */
-    static CartesianCS replace(final CartesianCS cs, final boolean legacy) {
-        final CartesianCS check = legacy ? DefaultCartesianCS.GEOCENTRIC : LEGACY;
-        final int dimension = check.getDimension();
-        if (cs.getDimension() != dimension) {
-            return cs;
-        }
-        for (int i=0; i<dimension; i++) {
-            if (!cs.getAxis(i).getDirection().equals(check.getAxis(i).getDirection())) {
-                return cs;
-            }
-        }
-        return legacy ? LEGACY : DefaultCartesianCS.GEOCENTRIC;
-    }
 }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/FormattableObject.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/FormattableObject.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/FormattableObject.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/FormattableObject.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -18,10 +18,10 @@ package org.apache.sis.io.wkt;
 
 import java.io.Console;
 import java.io.PrintWriter;
+import java.util.concurrent.atomic.AtomicReference;
 import javax.xml.bind.annotation.XmlTransient;
 import org.opengis.parameter.GeneralParameterValue;
 import org.apache.sis.util.Debug;
-import org.apache.sis.util.Classes;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.internal.util.X364;
 
@@ -58,12 +58,20 @@ import org.apache.sis.internal.util.X364
 @XmlTransient
 public class FormattableObject {
     /**
-     * The formatter for the {@link #toWKT()} and {@link #toString()} methods.
-     * Formatters are not thread-safe, consequently we need a different instance for each thread.
-     * We do not use synchronization because the formatter will call back user's code, which
-     * introduce a risk of thread lock if the user performs his own synchronization.
+     * The formatter for the {@link #toWKT()} and {@link #toString()} methods. Formatters are not
+     * thread-safe, consequently we must make sure that only one thread uses a given instance.
+     *
+     * {@note We do not use synchronization because the formatter will call back user's code, which
+     *        introduce a risk of thread lock if the user performs his own synchronization.}
+     *
+     * {@note We do not use <code>ThreadLocal</code> because <code>Formatter</code> is not reentrant
+     *        neither, so it may produce very confusing behavior when debugging a code that perform
+     *        WKT formatting (some debuggers seem to invoke <code>toString()</code> for their own
+     *        purpose in the same thread). Since <code>toString()</code> is typically invoked for
+     *        debugging purpose, a single formatter for any thread is presumed sufficient.}
+     *
      */
-    private static final ThreadLocal<Formatter> FORMATTER = new ThreadLocal<Formatter>();
+    private static final AtomicReference<Formatter> FORMATTER = new AtomicReference<Formatter>();
 
     /**
      * Default constructor.
@@ -82,7 +90,7 @@ public class FormattableObject {
      * @see org.opengis.referencing.IdentifiedObject#toWKT()
      */
     public String toWKT() throws UnformattableObjectException {
-        return formatWKT(Convention.OGC, false, true);
+        return formatWKT(Convention.OGC, WKTFormat.DEFAULT_INDENTATION, false, true);
     }
 
     /**
@@ -94,7 +102,7 @@ public class FormattableObject {
      */
     @Override
     public String toString() {
-        return formatWKT(Convention.OGC, false, false);
+        return formatWKT(Convention.OGC, WKTFormat.DEFAULT_INDENTATION, false, false);
     }
 
     /**
@@ -108,7 +116,7 @@ public class FormattableObject {
      */
     public String toString(final Convention convention) {
         ArgumentChecks.ensureNonNull("convention", convention);
-        return formatWKT(convention, false, false);
+        return formatWKT(convention, WKTFormat.DEFAULT_INDENTATION, false, false);
     }
 
     /**
@@ -123,7 +131,8 @@ public class FormattableObject {
     public void print() {
         final Console console = System.console();
         final PrintWriter out = (console != null) ? console.writer() : null;
-        final String wkt = formatWKT(Convention.OGC, (out != null) && X364.isAnsiSupported(), false);
+        final String wkt = formatWKT(Convention.OGC, WKTFormat.DEFAULT_INDENTATION,
+                (out != null) && X364.isAnsiSupported(), false);
         if (out != null) {
             out.println(wkt);
         } else {
@@ -135,23 +144,25 @@ public class FormattableObject {
      * Returns a WKT for this object using the specified convention.
      * If {@code strict} is true, then an exception is thrown if the WKT is not standard-compliant.
      *
-     * @param  convention The convention for choosing WKT entities names.
-     * @param  colorize   {@code true} for applying syntax coloring, or {@code false} otherwise.
-     * @param  strict     {@code true} if an exception shall be thrown for unformattable objects,
-     *                    or {@code false} for providing a non-standard formatting instead.
+     * @param  convention  The convention for choosing WKT entities names.
+     * @param  indentation The indentation to apply, or {@link WKTFormat#SINGLE_LINE}.
+     * @param  colorize    {@code true} for applying syntax coloring, or {@code false} otherwise.
+     * @param  strict      {@code true} if an exception shall be thrown for unformattable objects,
+     *                     or {@code false} for providing a non-standard formatting instead.
      * @return The Well Known Text (WKT) or a pseudo-WKT representation of this object.
      * @throws UnformattableObjectException If {@code strict} is {@code true} and this object can not be formatted.
      */
-    private String formatWKT(final Convention convention, final boolean colorize, final boolean strict)
+    final String formatWKT(final Convention convention, final byte indentation, final boolean colorize, final boolean strict)
              throws UnformattableObjectException
     {
-        Formatter formatter = FORMATTER.get();
+        Formatter formatter = FORMATTER.getAndSet(null);
         if (formatter == null) {
             formatter = new Formatter();
-            FORMATTER.set(formatter);
         }
+        formatter.indentation = indentation;
         formatter.colors = colorize ? Colors.DEFAULT : null;
         formatter.setConvention(convention, null);
+        final String wkt;
         try {
             /*
              * Special processing for parameter values, which is formatted
@@ -164,22 +175,26 @@ public class FormattableObject {
                 formatter.append(this);
             }
             if (strict) {
-                formatter.ensureValidWKT();
+                final String message = formatter.getErrorMessage();
+                if (message != null) {
+                    throw new UnformattableObjectException(message, formatter.errorCause);
+                }
             }
-            return formatter.toString();
+            wkt = formatter.toString();
         } finally {
             formatter.clear();
         }
+        FORMATTER.set(formatter);
+        return wkt;
     }
 
     /**
      * Formats the inner part of this <cite>Well Known Text</cite> (WKT) element into the given formatter.
      * This method is automatically invoked by {@link WKTFormat} when a formattable element is found.
      *
-     * <p>Element keyword and {@linkplain org.apache.sis.referencing.IdentifiedObjects#getIdentifierCode
-     * authority code} shall not be formatted here. For example if this formattable element is for a
-     * {@code GEOGCS} element, then this method shall write the content starting at the insertion point
-     * shows below:</p>
+     * <p>Element keyword and authority code shall not be formatted here.
+     * For example if this formattable element is for a {@code GEOGCS} element,
+     * then this method shall write the content starting at the insertion point shows below:</p>
      *
      * {@preformat text
      *     GEOGCS["WGS 84", AUTHORITY["EPSG","4326"]]
@@ -198,16 +213,11 @@ public class FormattableObject {
      * @see #toString()
      */
     protected String formatTo(final Formatter formatter) {
-        Class<?> type = getClass();
-        for (final Class<?> candidate : type.getInterfaces()) {
-            final String name = candidate.getName();
-            if (name.startsWith("org.opengis.") && !name.startsWith("org.opengis.util.")) {
-                type = candidate;
-                break;
-            }
+        formatter.setInvalidWKT(getClass());
+        String name = formatter.invalidElement;
+        if (name == null) { // May happen if the user override Formatter.setInvalidWKT(Class).
+            name = "UNKNOWN";
         }
-        final String name = Classes.getShortName(type);
-        formatter.setInvalidWKT(name);
         return name;
     }
 }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -41,6 +41,7 @@ import org.opengis.util.CodeList;
 
 import org.apache.sis.measure.Units;
 import org.apache.sis.math.DecimalFunctions;
+import org.apache.sis.util.Classes;
 import org.apache.sis.util.Numbers;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ArgumentChecks;
@@ -172,7 +173,7 @@ public class Formatter {
      * The amount of spaces to use in indentation, or {@value org.apache.sis.io.wkt.WKTFormat#SINGLE_LINE}
      * if indentation is disabled.
      */
-    int indentation;
+    byte indentation;
 
     /**
      * The amount of space to write on the left side of each line. This amount is increased
@@ -188,25 +189,28 @@ public class Formatter {
     private boolean requestNewLine;
 
     /**
-     * {@code true} if the last formatted element was invalid WKT. This field is for internal use only.
-     * It is reset to {@code false} after the invalid part has been processed by {@link #append(FormattableObject)}.
+     * {@code true} if the last formatted element was invalid WKT and shall be highlighted with syntatic coloration.
+     * This field has no effect if {@link #colors} is null. This field is reset to {@code false} after the invalid
+     * part has been processed by {@link #append(FormattableObject)}, in order to highlight only the first erroneous
+     * element without clearing the {@link #invalidElement} value.
      */
-    private boolean wasInvalidWKT;
+    private boolean highlightError;
 
     /**
      * Non-null if the WKT is invalid. If non-null, then this field contains a keyword that identify the
      * problematic part.
      *
      * @see #isInvalidWKT()
+     * @see #getErrorMessage()
      */
-    private String unformattable;
+    String invalidElement;
 
     /**
-     * Warning that may be produced during WKT formatting, or {@code null} if none.
+     * Error that occurred during WKT formatting, or {@code null} if none.
      *
-     * @see #isInvalidWKT()
+     * @see #getErrorMessage()
      */
-    private Exception warning;
+    Exception errorCause;
 
     /**
      * Creates a new formatter instance with the default symbols, no syntax coloring and the default indentation.
@@ -225,15 +229,12 @@ public class Formatter {
      *        or {@link WKTFormat#SINGLE_LINE} for formatting the whole WKT on a single line.
      */
     public Formatter(final Convention convention, final Symbols symbols, final Colors colors, final int indentation) {
-        ArgumentChecks.ensureNonNull("convention", convention);
-        ArgumentChecks.ensureNonNull("symbols", symbols);
-        if (indentation < WKTFormat.SINGLE_LINE) {
-            throw new IllegalArgumentException(Errors.format(
-                    Errors.Keys.IllegalArgumentValue_2, "indentation", indentation));
-        }
+        ArgumentChecks.ensureNonNull("convention",  convention);
+        ArgumentChecks.ensureNonNull("symbols",     symbols);
+        ArgumentChecks.ensureBetween("indentation", WKTFormat.SINGLE_LINE, Byte.MAX_VALUE, indentation);
         this.convention   = convention;
         this.symbols      = symbols.immutable();
-        this.indentation  = indentation;
+        this.indentation  = (byte) indentation;
         this.numberFormat = symbols.createNumberFormat();
         this.unitFormat   = UnitFormat.getInstance(symbols.getLocale());
         this.buffer       = new StringBuffer();
@@ -444,8 +445,8 @@ public class Formatter {
         indent(+1);
         requestNewLine = false;
         String keyword = object.formatTo(this);
-        if (colors != null && wasInvalidWKT) {
-            wasInvalidWKT = false;
+        if (colors != null && highlightError) {
+            highlightError = false;
             final String color = colors.getAnsiSequence(ElementKind.ERROR);
             if (color != null) {
                 buffer.insert(base, color + BACKGROUND_DEFAULT);
@@ -575,7 +576,8 @@ public class Formatter {
                             buffer.insert(stop, BACKGROUND_DEFAULT).insert(start, c);
                         }
                     }
-                    warning = exception;
+                    setInvalidWKT(descriptor);
+                    errorCause = exception;
                     value = Double.NaN;
                 }
                 format(value);
@@ -693,13 +695,13 @@ public class Formatter {
     private void format(double number) {
         setColor(ElementKind.NUMBER);
         /*
-         * The -2 above is for using two less fraction digits than the expected number accuracy.
+         * The 2 below is for using two less fraction digits than the expected number accuracy.
          * The intend is to give to DecimalFormat a chance to hide rounding errors, keeping in
          * mind that the number value is not necessarily the original one (we may have applied
          * a unit conversion). In the case of WGS84 semi-major axis in metres, we still have a
          * maximum of 8 fraction digits, which is more than enough.
          */
-        numberFormat.setMaximumFractionDigits(DecimalFunctions.fractionDigitsForValue(number) - 2);
+        numberFormat.setMaximumFractionDigits(DecimalFunctions.fractionDigitsForValue(number, 2));
         numberFormat.setMinimumFractionDigits(1); // Must be after setMaximumFractionDigits(…).
         numberFormat.format(number, buffer, dummy);
         resetColor();
@@ -782,7 +784,7 @@ public class Formatter {
      * @return {@code true} if the WKT is invalid.
      */
     public boolean isInvalidWKT() {
-        return unformattable != null || (buffer != null && buffer.length() == 0);
+        return (invalidElement != null) || (buffer != null && buffer.length() == 0);
         /*
          * Note: we really use a "and" condition (not an other "or") for the buffer test because
          *       the buffer is reset to 'null' by WKTFormat after a successfull formatting.
@@ -790,28 +792,51 @@ public class Formatter {
     }
 
     /**
-     * Sets a flag marking the current WKT as not strictly compliant to the
-     * <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html">WKT
-     * specification</a>. This method is invoked by {@link FormattableObject#formatTo(Formatter)}
-     * methods when the object to format is more complex than what the WKT specification allows.
+     * Marks the current WKT representation of the given object as not strictly compliant to the WKT specification.
+     * This method can be invoked by implementations of {@link FormattableObject#formatTo(Formatter)} when the object
+     * to format is more complex than what the WKT specification allows.
      * Applications can test {@link #isInvalidWKT()} later for checking WKT validity.
      *
-     * @param unformattable A keyword that identify the component that can not be formatted,
+     * @param unformattable The object that can not be formatted,
      */
-    public void setInvalidWKT(final String unformattable) {
+    public void setInvalidWKT(final IdentifiedObject unformattable) {
         ArgumentChecks.ensureNonNull("unformattable", unformattable);
-        this.unformattable = unformattable;
-        wasInvalidWKT = true;
+        String name = getName(unformattable);
+        if (name != null) {
+            invalidElement = name;
+            highlightError = true;
+        } else {
+            setInvalidWKT(unformattable.getClass());
+        }
     }
 
     /**
-     * Throws an exception if {@link #isInvalidWKT()} is set.
+     * Marks the current WKT representation of the given class as not strictly compliant to the WKT specification.
+     * This method can be used as an alternative to {@link #setInvalidWKT(IdentifiedObject)} when the problematic
+     * object is not an instance of {@code IdentifiedObject}.
+     *
+     * @param unformattable The class of the object that can not be formatted,
      */
-    final void ensureValidWKT() throws UnformattableObjectException {
-        if (isInvalidWKT()) {
-            throw new UnformattableObjectException(Errors.format(
-                    Errors.Keys.CanNotRepresentInFormat_2, "WKT", unformattable), warning);
+    public void setInvalidWKT(Class<?> unformattable) {
+        ArgumentChecks.ensureNonNull("unformattable", unformattable);
+        if (!unformattable.isInterface()) {
+            for (final Class<?> candidate : unformattable.getInterfaces()) {
+                if (candidate.getName().startsWith("org.opengis.")) {
+                    unformattable = candidate;
+                    break;
+                }
+            }
         }
+        invalidElement = Classes.getShortName(unformattable);
+        highlightError = true;
+    }
+
+    /**
+     * Returns the error message {@link #isInvalidWKT()} is set, or {@code null} otherwise.
+     * If non-null, a cause may be available in the {@link #errorCause} field.
+     */
+    final String getErrorMessage() {
+        return isInvalidWKT() ? Errors.format(Errors.Keys.CanNotRepresentInFormat_2, "WKT", invalidElement) : null;
     }
 
     /**
@@ -825,19 +850,23 @@ public class Formatter {
     }
 
     /**
-     * Clears this formatter. All properties (including {@linkplain #getLinearUnit() unit}
-     * and {@linkplain #isInvalidWKT() WKT validity flag} are reset to their default value.
-     * After this method call, this {@code Formatter} object is ready for formatting a new object.
+     * Clears this formatter before formatting a new object. This method clears the
+     * {@linkplain #getLinearUnit() linear unit} and {@linkplain #isInvalidWKT() WKT validity flag}.
      */
     public void clear() {
+        /*
+         * Configuration options (indentation, colors, conventions) are left unchanged.
+         * We do not mention that fact in the Javadoc because those options do not appear
+         * in the Formatter public API (they are in the WKTFormat API instead).
+         */
         if (buffer != null) {
             buffer.setLength(0);
         }
         linearUnit     = null;
         angularUnit    = null;
-        unformattable  = null;
-        warning        = null;
-        wasInvalidWKT  = false;
+        invalidElement = null;
+        errorCause     = null;
+        highlightError = false;
         requestNewLine = false;
         margin         = 0;
     }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -27,5 +27,5 @@ public class WKTFormat {
     /**
      * The default indentation value.
      */
-    static final int DEFAULT_INDENTATION = 2;
+    static final byte DEFAULT_INDENTATION = 2;
 }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -40,6 +40,7 @@ import org.opengis.referencing.Identifie
 import org.opengis.referencing.ReferenceIdentifier;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.jaxb.referencing.Code;
+import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.xml.Namespaces;
 import org.apache.sis.util.Deprecable;
@@ -625,7 +626,7 @@ public class AbstractIdentifiedObject ex
      *         relevant to coordinate transformations.
      * @return {@code true} if both objects are equal.
      *
-     * @see #hashCode(ComparisonMode)
+     * @see #computeHashCode()
      * @see org.apache.sis.util.Utilities#deepEquals(Object, Object, ComparisonMode)
      */
     @Override
@@ -633,40 +634,35 @@ public class AbstractIdentifiedObject ex
         if (object == null) {
             return false;
         }
-        if (getClass() == object.getClass()) {
-            /*
-             * If the classes are the same, then the hash codes should be computed in the same
-             * way. Since those codes are cached, this is an efficient way to quickly check if
-             * the two objects are different. Note that using the hash codes for comparisons
-             * that ignore metadata is okay only if the implementation note described in the
-             * 'computeHashCode()' javadoc hold (metadata not used in hash code computation).
-             */
-            if (mode.ordinal() < ComparisonMode.APPROXIMATIVE.ordinal()) {
-                final int tc = hashCode;
-                if (tc != 0) {
-                    final int oc = ((AbstractIdentifiedObject) object).hashCode;
-                    if (oc != 0 && tc != oc) {
-                        return false;
-                    }
-                }
-            }
-        } else {
-            if (mode == ComparisonMode.STRICT) { // Same class was required for this mode.
-                return false;
-            }
-            if (!(object instanceof IdentifiedObject)) {
-                return false;
-            }
-        }
         switch (mode) {
             case STRICT: {
+                if (getClass() != object.getClass()) {
+                    return false;
+                }
                 final AbstractIdentifiedObject that = (AbstractIdentifiedObject) object;
+                /*
+                 * If the hash codes were cached for both objects, opportunistically compare them.
+                 * This is an efficient way to quickly check if the two objects are different
+                 * before the more extensive check below.
+                 */
+                if (mode == ComparisonMode.STRICT) {
+                    final int tc = hashCode;
+                    if (tc != 0) {
+                        final int oc = that.hashCode;
+                        if (oc != 0 && tc != oc) {
+                            return false;
+                        }
+                    }
+                }
                 return Objects.equals(name, that.name) &&
                        nonNull(alias).equals(nonNull(that.alias)) &&
                        nonNull(identifiers).equals(nonNull(that.identifiers)) &&
                        Objects.equals(remarks, that.remarks);
             }
             case BY_CONTRACT: {
+                if (!(object instanceof IdentifiedObject)) {
+                    return false;
+                }
                 final IdentifiedObject that = (IdentifiedObject) object;
                 return deepEquals(getName(),        that.getName(),        mode) &&
                        deepEquals(getAlias(),       that.getAlias(),       mode) &&
@@ -676,7 +672,7 @@ public class AbstractIdentifiedObject ex
             case IGNORE_METADATA:
             case APPROXIMATIVE:
             case DEBUG: {
-                return true;
+                return (object instanceof IdentifiedObject);
             }
             default: {
                 throw new IllegalArgumentException(Errors.format(Errors.Keys.UnknownEnumValue_1, mode));
@@ -685,51 +681,6 @@ public class AbstractIdentifiedObject ex
     }
 
     /**
-     * Computes a hash value consistent with the given comparison mode.
-     * This method accepts only the following enumeration values:
-     *
-     * <ul>
-     *   <li>{@link ComparisonMode#STRICT STRICT}: this method may use any property,
-     *       including implementation-specific ones if any, at implementation choice.</li>
-     *   <li>{@link ComparisonMode#BY_CONTRACT BY_CONTRACT}: this method can use any property defined
-     *       in the implemented interface (typically a GeoAPI interface).</li>
-     *   <li>{@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA}: this method ignores the metadata that do not
-     *       affect coordinate operations. By default, the ignored properties are the {@linkplain #getName() name},
-     *       {@linkplain #getIdentifiers() identifiers} and {@linkplain #getRemarks() remarks}.
-     *       However subclasses may ignore a different list of properties.</li>
-     * </ul>
-     *
-     * In the later case, two identified objects will return the same hash value if they are equal in the sense of
-     * <code>{@linkplain #equals(Object, ComparisonMode) equals}(object, IGNORE_METADATA)</code>.
-     * This feature allows users to implement metadata-insensitive {@link java.util.HashMap}.
-     *
-     * @param  mode Specifies the properties that can be used for hash code computation.
-     * @return The hash code value. This value may change between different execution of the Apache SIS library.
-     * @throws IllegalArgumentException If the given {@code mode} is not one of {@code STRICT}, {@code BY_CONTRACT}
-     *         or {@code IGNORE_METADATA} enumeration values.
-     */
-    public int hashCode(final ComparisonMode mode) throws IllegalArgumentException {
-        int code = (int) serialVersionUID;
-        switch (mode) {
-            case STRICT: {
-                code ^= Objects.hash(name, nonNull(alias), nonNull(identifiers), remarks);
-                break;
-            }
-            case BY_CONTRACT: {
-                code ^= Objects.hash(getName(), getAlias(), getIdentifiers(), getRemarks());
-                break;
-            }
-            case IGNORE_METADATA: {
-                break;
-            }
-            default: {
-                throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2, "mode", mode));
-            }
-        }
-        return code;
-    }
-
-    /**
      * Compares the specified object with this object for equality.
      * This method is implemented as below (omitting assertions):
      *
@@ -751,30 +702,53 @@ public class AbstractIdentifiedObject ex
     }
 
     /**
-     * Returns a hash value for this identified object.
-     * This method derives a value from <code>{@linkplain #hashCode(ComparisonMode) hashCode}(STRICT)</code>.
-     * Notes:
+     * Returns a hash value for this identified object. Two {@code AbstractIdentifiedObject} instances
+     * for which {@link #equals(Object)} returns {@code true} shall have the same hash code value, if
+     * the hash codes are computed on the same JVM instance for both objects. The hash code value is
+     * <em>not</em> guaranteed to be stable between different versions of the Apache SIS library, or
+     * between libraries running on different JVM.
+     *
+     * {@section Implementation note}
+     * This method invokes {@link #computeHashCode()} when first needed, then caches the result.
+     * Subclasses shall override {@link #computeHashCode()} instead than this method.
      *
-     * <ul>
-     *   <li>The derived value may be different than {@code hashCode(STRICT)}.</li>
-     *   <li>This method may cache the hash code value.</li>
-     * </ul>
-     *
-     * Subclasses shall override {@link #hashCode(ComparisonMode)} instead than this method.
-     *
-     * @return The hash code value. This value may change between different execution of the Apache SIS library.
+     * @return The hash code value. This value may change in any future Apache SIS version.
      */
     @Override
     public final int hashCode() { // No need to synchronize; ok if invoked twice.
         int hash = hashCode;
         if (hash == 0) {
-            hash = hashCode(ComparisonMode.STRICT);
+            hash = Numerics.hashCode(computeHashCode());
             if (hash == 0) {
                 hash = -1;
             }
             hashCode = hash;
         }
-        assert hash == -1 || hash == hashCode(ComparisonMode.STRICT) : this;
+        assert hash == -1 || hash == Numerics.hashCode(computeHashCode()) : hash;
         return hash;
     }
+
+    /**
+     * Invoked by {@link #hashCode()} for computing the hash code when first needed.
+     * This method is invoked at most once in normal execution, or an arbitrary amount of times if Java
+     * assertions are enabled. The hash code value shall never change during the whole lifetime of this
+     * object.
+     *
+     * {@section Overriding}
+     * Subclasses can override this method for using more properties in hash code calculation.
+     * All {@code computeHashCode()} methods shall invoke {@code super.computeHashCode()},
+     * <strong>not</strong> {@code hashCode()}. Example:
+     *
+     * {@preformat java
+     *     &#64;Override
+     *     protected long computeHashCode() {
+     *         return super.computeHashCode() + 31 * Objects.hash(myProperties);
+     *     }
+     * }
+     *
+     * @return The hash code value. This value may change in any future Apache SIS version.
+     */
+    protected long computeHashCode() {
+        return Objects.hash(name, nonNull(alias), nonNull(identifiers), remarks) ^ serialVersionUID;
+    }
 }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -223,31 +223,18 @@ public class AbstractReferenceSystem ext
     }
 
     /**
-     * Computes a hash value consistent with the given comparison mode.
-     * If the given argument is {@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA}, then the
-     * {@linkplain #getDomainOfValidity() domain of validity} and the {@linkplain #getScope() scope}
-     * properties are ignored, in addition to other ignored properties documented in the
-     * {@linkplain AbstractIdentifiedObject#hashCode(ComparisonMode) super-class}.
+     * Invoked by {@link #hashCode()} for computing the hash code when first needed.
+     * See {@link org.apache.sis.referencing.AbstractIdentifiedObject#computeHashCode()}
+     * for more information.
      *
-     * @return The hash code value for the given comparison mode.
+     * @return The hash code value. This value may change in any future Apache SIS version.
      */
     @Override
-    public int hashCode(final ComparisonMode mode) throws IllegalArgumentException {
+    protected long computeHashCode() {
         /*
-         * The "^ (int) serialVersionUID" is an arbitrary change applied to the hash code value in order to
+         * The "serialVersionUID ^ …" is an arbitrary change applied to the hash code value in order to
          * differentiate this ReferenceSystem implementation from implementations of other GeoAPI interfaces.
          */
-        int code = super.hashCode(mode) ^ (int) serialVersionUID;
-        switch (mode) {
-            case STRICT: {
-                code ^= Objects.hash(domainOfValidity, scope);
-                break;
-            }
-            case BY_CONTRACT: {
-                code ^= Objects.hash(getDomainOfValidity(), getScope());
-                break;
-            }
-        }
-        return code;
+        return serialVersionUID ^ (super.computeHashCode() + Objects.hash(domainOfValidity, scope));
     }
 }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -32,7 +32,7 @@ import org.opengis.referencing.Reference
 import org.apache.sis.util.Static;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.iso.DefaultNameSpace;
-import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.metadata.iso.citation.Citations; // For javadoc.
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 import static org.apache.sis.util.Characters.Filter.LETTERS_AND_DIGITS;
@@ -74,9 +74,26 @@ public final class IdentifiedObjects ext
     }
 
     /**
+     * Returns every object names and aliases according the given authority. This method performs
+     * the same work than {@link #getName(IdentifiedObject, Citation)}, except that it does not
+     * stop at the first match. This method is useful in the rare cases where the same authority
+     * declares more than one name, and all those names are of interest.
+     *
+     * @param  object The object to get the names and aliases from, or {@code null}.
+     * @param  authority The authority for the names to return, or {@code null} for any authority.
+     * @return The object's names and aliases, or an empty set if no name or alias matching the
+     *         specified authority has been found.
+     */
+    public static Set<String> getNames(final IdentifiedObject object, final Citation authority) {
+        final Set<String> names = new LinkedHashSet<String>(8);
+        name(object, authority, names);
+        return names;
+    }
+
+    /**
      * Returns an object name according the given authority.
-     * This method checks first the {@linkplain IdentifiedObject#getName() primary name},
-     * then all {@linkplain IdentifiedObject#getAlias() alias} in their iteration order.
+     * This method checks first the {@linkplain AbstractIdentifiedObject#getName() primary name},
+     * then all {@linkplain AbstractIdentifiedObject#getAlias() aliases} in their iteration order.
      *
      * <ul>
      *   <li><p>If the name or alias implements the {@link ReferenceIdentifier} interface,
@@ -110,23 +127,6 @@ public final class IdentifiedObjects ext
     }
 
     /**
-     * Returns every object names and aliases according the given authority. This method performs
-     * the same work than {@link #getName(IdentifiedObject, Citation)}, except that it does not
-     * stop at the first match. This method is useful in the rare cases where the same authority
-     * declares more than one name, and all those names are of interest.
-     *
-     * @param  object The object to get the names and aliases from, or {@code null}.
-     * @param  authority The authority for the names to return, or {@code null} for any authority.
-     * @return The object's names and aliases, or an empty set if no name or alias matching the
-     *         specified authority has been found.
-     */
-    public static Set<String> getNames(final IdentifiedObject object, final Citation authority) {
-        final Set<String> names = new LinkedHashSet<String>(8);
-        name(object, authority, names);
-        return names;
-    }
-
-    /**
      * Returns an object name according the given authority. This method is {@code null}-safe:
      * every properties are checked for null values, even the properties that are supposed to
      * be mandatory (not all implementation defines all mandatory values).
@@ -218,8 +218,8 @@ public final class IdentifiedObjects ext
 
     /**
      * Returns an identifier for the given object according the given authority.
-     * This method checks all {@linkplain IdentifiedObject#getIdentifiers() identifiers} in their iteration order
-     * and returns the first identifier with an {@linkplain ReferenceIdentifier#getAuthority() authority} citation
+     * This method checks all {@linkplain AbstractIdentifiedObject#getIdentifiers() identifiers} in their iteration
+     * order and returns the first identifier with an {@linkplain NamedIdentifier#getAuthority() authority} citation
      * {@linkplain Citations#identifierMatches(Citation, Citation) matching} the specified authority.
      *
      * @param  object The object to get the identifier from, or {@code null}.
@@ -246,15 +246,11 @@ public final class IdentifiedObjects ext
     }
 
     /**
-     * Returns the declared identifier, or {@code null} if none. This method searches for the first
-     * identifier (which is usually the main one) explicitly declared in the {@link IdentifiedObject}.
-     * At the contrary of {@link #searchIdentifierCode(IdentifiedObject, boolean)},
-     * <em>this method does not verify the identifier validity</em>.
-     *
-     * <p>More specifically, this method uses the first non-null element found in
-     * <code>object.{@linkplain IdentifiedObject#getIdentifiers() getIdentifiers()}</code>.
-     * If there is none, then it uses <code>object.{@linkplain IdentifiedObject#getName() getName()}</code>,
-     * which is not guaranteed to be a valid identifier.</p>
+     * Returns the string representation of the first identifier, or the object name if there is no identifier.
+     * This method searches for the first non-null element in
+     * <code>object.{@linkplain AbstractIdentifiedObject#getIdentifiers() getIdentifiers()}</code>. If there is none,
+     * then this method fallback on <code>object.{@linkplain AbstractIdentifiedObject#getName() getName()}</code>.
+     * The first element found is formatted by {@link #toString(Identifier)}.
      *
      * {@section Recommanded alternatives}
      * <ul>
@@ -265,12 +261,12 @@ public final class IdentifiedObjects ext
      * </ul>
      *
      * @param  object The identified object, or {@code null}.
-     * @return Identifier represented as a string for communication between systems, or {@code null}.
+     * @return A string representation of the first identifier or name, or {@code null} if none.
      *
      * @see #getIdentifier(IdentifiedObject, Citation)
      * @see #searchIdentifierCode(IdentifiedObject, boolean)
      */
-    public static String getIdentifierCode(final IdentifiedObject object) {
+    public static String getIdentifierOrName(final IdentifiedObject object) {
         if (object != null) {
             final Iterator<ReferenceIdentifier> it = iterator(object.getIdentifiers());
             if (it != null) while (it.hasNext()) {
@@ -288,6 +284,53 @@ public final class IdentifiedObjects ext
     }
 
     /**
+     * Returns the first name, alias or identifier which is a
+     * {@linkplain CharSequences#isUnicodeIdentifier(CharSequence) valid Unicode identifier}.
+     * This method performs the search in the following order:
+     *
+     * <ul>
+     *   <li><code>object.{@linkplain AbstractIdentifiedObject#getName() getName()}</code></li>
+     *   <li><code>object.{@linkplain AbstractIdentifiedObject#getAlias() getAlias()}</code> in iteration order</li>
+     *   <li><code>object.{@linkplain AbstractIdentifiedObject#getIdentifiers() getIdentifiers()}</code> in iteration order</li>
+     * </ul>
+     *
+     * @param  object The identified object, or {@code null}.
+     * @return The first name, alias or identifier which is a valid Unicode identifier, or {@code null} if none.
+     */
+    public static String getUnicodeIdentifier(final IdentifiedObject object) {
+        if (object != null) {
+            ReferenceIdentifier identifier = object.getName();
+            if (identifier != null) { // Paranoiac check.
+                final String code = identifier.getCode();
+                if (CharSequences.isUnicodeIdentifier(code)) {
+                    return code;
+                }
+            }
+            final Iterator<GenericName> it = iterator(object.getAlias());
+            if (it != null) while (it.hasNext()) {
+                GenericName alias = it.next();
+                if (alias != null && (alias = alias.tip()) != null) {
+                    final String code = alias.toString();
+                    if (CharSequences.isUnicodeIdentifier(code)) {
+                        return code;
+                    }
+                }
+            }
+            final Iterator<ReferenceIdentifier> id = iterator(object.getIdentifiers());
+            if (id != null) while (id.hasNext()) {
+                identifier = id.next();
+                if (identifier != null) { // Paranoiac check.
+                    final String code = identifier.getCode();
+                    if (CharSequences.isUnicodeIdentifier(code)) {
+                        return code;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
      * Returns {@code true} if either the {@linkplain AbstractIdentifiedObject#getName() primary name} or at least
      * one {@linkplain AbstractIdentifiedObject#getAlias() alias} matches the given string according heuristic rules.
      * If the given object is an instance of {@link AbstractIdentifiedObject}, then this method delegates to its
@@ -409,13 +452,15 @@ public final class IdentifiedObjects ext
             return identifier.toString();
         }
         final String code = identifier.getCode();
+        final String cs;
         if (identifier instanceof ReferenceIdentifier) {
-            final String cs = ((ReferenceIdentifier) identifier).getCodeSpace();
-            if (cs != null) {
-                return cs + DefaultNameSpace.DEFAULT_SEPARATOR + code;
-            }
+            cs = ((ReferenceIdentifier) identifier).getCodeSpace();
+        } else {
+            cs = org.apache.sis.internal.util.Citations.getIdentifier(identifier.getAuthority());
+        }
+        if (cs != null && !cs.isEmpty()) {
+            return cs + DefaultNameSpace.DEFAULT_SEPARATOR + code;
         }
-        final String authority = org.apache.sis.internal.util.Citations.getIdentifier(identifier.getAuthority());
-        return (authority != null) ? (authority + DefaultNameSpace.DEFAULT_SEPARATOR + code) : code;
+        return code;
     }
 }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -19,6 +19,9 @@ package org.apache.sis.referencing;
 import java.util.Map;
 import java.util.List;
 import java.util.Locale;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import org.opengis.util.NameSpace;
 import org.opengis.util.LocalName;
 import org.opengis.util.ScopedName;
@@ -81,7 +84,7 @@ public class NamedIdentifier extends Imm
     /**
      * Serial number for inter-operability with different versions.
      */
-    private static final long serialVersionUID = 8474731565582774497L;
+    private static final long serialVersionUID = 8474731565582874497L;
 
     /**
      * A pool of {@link NameSpace} values for given {@link InternationalString}.
@@ -91,10 +94,15 @@ public class NamedIdentifier extends Imm
 
     /**
      * The name of this identifier as a generic name. If {@code null}, will be constructed
-     * only when first needed. This field is serialized (instead of being recreated after
-     * deserialization) because it may be a user-supplied value.
+     * only when first needed.
      */
-    private GenericName name;
+    private transient GenericName name;
+
+    /**
+     * {@code true} if {@link #name} has been given explicitly by the user.
+     * Consider this field as final - it is not only for constructors convenience.
+     */
+    private boolean isNameSupplied;
 
     /**
      * Creates a new identifier from the specified one. This is a copy constructor
@@ -111,6 +119,7 @@ public class NamedIdentifier extends Imm
         super(identifier);
         if (identifier instanceof GenericName) {
             name = (GenericName) identifier;
+            isNameSupplied = true;
         }
     }
 
@@ -141,6 +150,7 @@ public class NamedIdentifier extends Imm
     public NamedIdentifier(final Citation authority, final InternationalString code) {
         this(authority, code.toString(Locale.ROOT));
         name = createName(authority, code);
+        isNameSupplied = true; // Because 'code' is an international string.
     }
 
     /**
@@ -360,12 +370,46 @@ public class NamedIdentifier extends Imm
             return true;
         }
         if (super.equals(object)) {
+            if (!isNameSupplied) {
+                return true; // No need to compare names if they are computed from the same values.
+            }
             final NamedIdentifier that = (NamedIdentifier) object;
             return Objects.equals(this.getName(), that.getName());
         }
         return false;
     }
 
-    // We do not override hashCode because the name is usually inferred from existing properties.
-    // The above 'equals' method nevertheless compare the name in case it was explicitely specified.
+    /**
+     * Returns a hash code value for this object.
+     */
+    @Override
+    public int hashCode() {
+        /*
+         * We do not use the name because it is usually inferred from existing properties.
+         * We only revert the bits for differentiating this NamedIdentifier class from its parent class.
+         */
+        return ~super.hashCode();
+    }
+
+    /**
+     * Invoked on serialization for writing the {@linkplain #name} if it was supplied by the user.
+     * Otherwise, we will let {@link #getName()} recompute the name only when needed.
+     */
+    private void writeObject(final ObjectOutputStream out) throws IOException {
+        out.defaultWriteObject();
+        if (isNameSupplied) {
+            out.writeObject(name);
+        }
+    }
+
+    /**
+     * Invoked on deserialization for reading the name written by {@link #writeObject(ObjectOutputStream)},
+     * if any.
+     */
+    private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+        if (isNameSupplied) {
+            name = (GenericName) in.readObject();
+        }
+    }
 }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -77,12 +77,27 @@ public class AbstractCS extends Abstract
     static final int VALID = 0, INVALID_DIRECTION = 1, INVALID_UNIT = 2;
 
     /**
+     * An empty array of axes, used only for JAXB.
+     */
+    private static final CoordinateSystemAxis[] EMPTY = new CoordinateSystemAxis[0];
+
+    /**
      * The sequence of axes for this coordinate system.
      */
     @XmlElement(name = "axis")
     private final CoordinateSystemAxis[] axes;
 
     /**
+     * Constructs a new object in which every attributes are set to a null value.
+     * <strong>This is not a valid object.</strong> This constructor is strictly
+     * reserved to JAXB, which will assign values to the fields using reflexion.
+     */
+    AbstractCS() {
+        super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
+        axes = EMPTY;
+    }
+
+    /**
      * Constructs a coordinate system from a set of properties and a sequence of axes.
      * The properties map is given unchanged to the
      * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
@@ -268,13 +283,19 @@ public class AbstractCS extends Abstract
     }
 
     /**
-     * Computes a hash value consistent with the given comparison mode.
+     * Invoked by {@link #hashCode()} for computing the hash code when first needed.
+     * See {@link org.apache.sis.referencing.AbstractIdentifiedObject#computeHashCode()}
+     * for more information.
      *
-     * @return The hash code value for the given comparison mode.
+     * @return The hash code value. This value may change in any future Apache SIS version.
      */
     @Override
-    public int hashCode(final ComparisonMode mode) throws IllegalArgumentException {
-        return Arrays.hashCode(axes) + 31*super.hashCode(mode);
+    protected long computeHashCode() {
+        /*
+         * The "serialVersionUID ^ …" is an arbitrary change applied to the hash code value in order to
+         * differentiate this CoordinateSystem implementation from implementations of other GeoAPI interfaces.
+         */
+        return serialVersionUID ^ (super.computeHashCode() + Arrays.hashCode(axes));
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -63,9 +63,6 @@ public class DefaultCartesianCS extends 
      */
     private static final long serialVersionUID = -6182037957705712945L;
 
-    @Deprecated
-    public static final DefaultCartesianCS GEOCENTRIC = null; // TODO: Not supported yet.
-
     /**
      * Constructs a one-dimensional coordinate system from a set of properties.
      * The properties map is given unchanged to the

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -39,7 +39,6 @@ import org.apache.sis.measure.Latitude;
 import org.apache.sis.measure.Units;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.resources.Errors;
-import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.io.wkt.Formatter;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
@@ -154,6 +153,21 @@ public class DefaultCoordinateSystemAxis
     private final RangeMeaning rangeMeaning;
 
     /**
+     * Constructs a new object in which every attributes are set to a null value.
+     * <strong>This is not a valid object.</strong> This constructor is strictly
+     * reserved to JAXB, which will assign values to the fields using reflexion.
+     */
+    private DefaultCoordinateSystemAxis() {
+        super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
+        abbreviation = null;
+        direction    = null;
+        unit         = null;
+        rangeMeaning = null;
+        minimum      = Double.NEGATIVE_INFINITY;
+        maximum      = Double.POSITIVE_INFINITY;
+    }
+
+    /**
      * Constructs an axis from a set of properties and a given range.
      * The properties map is given unchanged to the
      * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
@@ -538,20 +552,20 @@ public class DefaultCoordinateSystemAxis
     }
 
     /**
-     * Computes a hash value consistent with the given comparison mode.
+     * Invoked by {@link #hashCode()} for computing the hash code when first needed.
+     * See {@link org.apache.sis.referencing.AbstractIdentifiedObject#computeHashCode()}
+     * for more information.
      *
-     * @return The hash code value for the given comparison mode.
+     * @return The hash code value. This value may change in any future Apache SIS version.
      */
     @Override
-    public int hashCode(final ComparisonMode mode) throws IllegalArgumentException {
-        int code = super.hashCode(mode);
-        if (unit      != null) code = 31*code + unit     .hashCode();
-        if (direction != null) code = 31*code + direction.hashCode();
-        if (mode == ComparisonMode.STRICT) {
-            code = Numerics.hash(minimum, code);
-            code = Numerics.hash(maximum, code);
-        }
-        return code;
+    protected long computeHashCode() {
+        /*
+         * The "serialVersionUID ^ …" is an arbitrary change applied to the hash code value in order to
+         * differentiate this CoordinateSystemAxis implementation from implementations of other GeoAPI interfaces.
+         */
+        return serialVersionUID ^ (super.computeHashCode() + Objects.hashCode(unit) + Objects.hashCode(direction)
+                + Double.doubleToLongBits(minimum) + 31*Double.doubleToLongBits(maximum));
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -235,7 +235,7 @@ final class DirectionAlongMeridian imple
         if (object instanceof DirectionAlongMeridian) {
             final DirectionAlongMeridian that = (DirectionAlongMeridian) object;
             return baseDirection.equals(that.baseDirection) &&
-                   Double.doubleToLongBits(meridian) == Double.doubleToLongBits(that.meridian);
+                   Numerics.equals(meridian, that.meridian);
         }
         return false;
     }
@@ -245,7 +245,7 @@ final class DirectionAlongMeridian imple
      */
     @Override
     public int hashCode() {
-        return Numerics.hash(meridian, baseDirection.hashCode()) ^ (int) serialVersionUID;
+        return Numerics.hashCode(serialVersionUID ^ (Double.doubleToLongBits(meridian) + baseDirection.hashCode()));
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java?rev=1554592&r1=1554591&r2=1554592&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java [UTF-8] Tue Dec 31 23:50:03 2013
@@ -67,9 +67,10 @@ import org.apache.sis.internal.jdk7.Obje
  * @see org.apache.sis.referencing.crs.AbstractCRS
  */
 @XmlType(name="AbstractDatumType")
-@XmlSeeAlso(
-    DefaultGeodeticDatum.class
-)
+@XmlSeeAlso({
+    DefaultGeodeticDatum.class,
+    DefaultVerticalDatum.class
+})
 public class AbstractDatum extends AbstractIdentifiedObject implements Datum {
     /**
      * Serial number for inter-operability with different versions.
@@ -400,37 +401,20 @@ public class AbstractDatum extends Abstr
     }
 
     /**
-     * Computes a hash value consistent with the given comparison mode.
-     * If the given argument is {@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA}, then the
-     * {@linkplain #getAnchorPoint() anchor point}, {@linkplain #getRealizationEpoch() realization epoch},
-     * {@linkplain #getDomainOfValidity() domain of validity} and the {@linkplain #getScope() scope}
-     * properties are ignored.
+     * Invoked by {@link #hashCode()} for computing the hash code when first needed.
+     * See {@link org.apache.sis.referencing.AbstractIdentifiedObject#computeHashCode()}
+     * for more information.
      *
-     * @return The hash code value for the given comparison mode.
+     * @return The hash code value. This value may change in any future Apache SIS version.
      */
     @Override
-    public int hashCode(final ComparisonMode mode) throws IllegalArgumentException {
+    protected long computeHashCode() {
         /*
-         * The "^ (int) serialVersionUID" is an arbitrary change applied to the hash code value in order to
+         * The "serialVersionUID ^ …" is an arbitrary change applied to the hash code value in order to
          * differentiate this Datum implementation from implementations of other GeoAPI interfaces.
          */
-        int code = super.hashCode(mode) ^ (int) serialVersionUID;
-        switch (mode) {
-            case STRICT: {
-                code += Objects.hash(anchorPoint, realizationEpoch, domainOfValidity, scope);
-                break;
-            }
-            case BY_CONTRACT: {
-                code += Objects.hash(getAnchorPoint(), getRealizationEpoch(), getDomainOfValidity(), getScope());
-                break;
-            }
-            /*
-             * The name is significant for all modes, but we nevertheless ignore it because
-             * of the way the name is compared in the equals(Object, ComparisonMode) method
-             * which make hash code computation impractical in the IGNORE_METADATA case.
-             */
-        }
-        return code;
+        return serialVersionUID ^ (super.computeHashCode() +
+                Objects.hash(anchorPoint, realizationEpoch, domainOfValidity, scope));
     }
 
     /**