Index: /applications/editors/josm/plugins/proj4j/build.xml
===================================================================
--- /applications/editors/josm/plugins/proj4j/build.xml	(revision 26408)
+++ /applications/editors/josm/plugins/proj4j/build.xml	(revision 26409)
@@ -37,5 +37,4 @@
     <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
     <property name="plugin.main.version" value="3872"/>
-    <property name="libproj4j" value="lib/proj4j-0.1.0.jar"/>
     <!--
       ************************************************
@@ -68,5 +67,4 @@
             <classpath>
                 <pathelement location="${josm}"/>
-                <pathelement location="${libproj4j}"/>
             </classpath>
             <compilerarg value="-Xlint:deprecation"/>
@@ -98,5 +96,4 @@
         <jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
             <!-- All jar files necessary to run plugin (no tests) -->
-            <zipfileset src="${libproj4j}"/>
             <!--
         ************************************************
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/BasicCoordinateTransform.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/BasicCoordinateTransform.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/BasicCoordinateTransform.java	(revision 26409)
@@ -0,0 +1,191 @@
+package org.osgeo.proj4j;
+
+import org.osgeo.proj4j.datum.*;
+
+/**
+ * Represents the operation of transforming 
+ * a {@link ProjCoordinate} from one {@link CoordinateReferenceSystem} 
+ * into a different one, using reprojection and datum conversion
+ * as required.
+ * <p>
+ * Computing the transform involves the following steps:
+ * <ul>
+ * <li>If the source coordinate is in a projected coordinate system,
+ * it is inverse-projected into a geographic coordinate system
+ * based on the source datum
+ * <li>If the source and target {@link Datum}s are different,
+ * the source geographic coordinate is converted 
+ * from the source to the target datum
+ * as accurately as possible
+ * <li>If the target coordinate system is a projected coordinate system, 
+ * the converted geographic coordinate is projected into a projected coordinate.
+ * </ul>
+ * Symbolically this can be presented as:
+ * <pre>
+ * [ SrcProjCRS {InverseProjection} ] SrcGeoCRS [ {Datum Conversion} ] TgtGeoCRS [ {Projection} TgtProjCRS ]
+ * </pre>
+ * <tt>BasicCoordinateTransform</tt> objects are stateful, 
+ * and thus are not thread-safe.
+ * However, they may be reused any number of times within a single thread.
+ * <p>
+ * Information about the transformation procedure is pre-computed
+ * and cached in this object for efficient computation.
+ * 
+ * @author Martin Davis
+ * @see CoordinateTransformFactory
+ *
+ */
+public class BasicCoordinateTransform 
+implements CoordinateTransform
+{
+	private CoordinateReferenceSystem srcCRS;
+	private CoordinateReferenceSystem tgtCRS;
+	
+  // temporary variable for intermediate results
+  private ProjCoordinate geoCoord = new ProjCoordinate(0,0);
+	
+  // precomputed information
+	private boolean doInverseProjection = true;
+	private boolean doForwardProjection = true;
+  private boolean doDatumTransform = false;
+  private boolean transformViaGeocentric = false;
+  private GeocentricConverter srcGeoConv; 
+  private GeocentricConverter tgtGeoConv; 
+	
+  /**
+   * Creates a transformation from a source {@link CoordinateReferenceSystem} 
+   * to a target one.
+   * 
+   * @param srcCRS the source CRS to transform from
+   * @param tgtCRS the target CRS to transform to
+   */
+	public BasicCoordinateTransform(CoordinateReferenceSystem srcCRS, 
+      CoordinateReferenceSystem tgtCRS)
+	{
+		this.srcCRS = srcCRS;
+		this.tgtCRS = tgtCRS;
+		
+		// compute strategy for transformation at initialization time, to make transformation more efficient
+		// this may include precomputing sets of parameters
+		
+		doInverseProjection = (srcCRS != null && srcCRS != CoordinateReferenceSystem.CS_GEO);
+		doForwardProjection = (tgtCRS != null && tgtCRS != CoordinateReferenceSystem.CS_GEO);
+    doDatumTransform = doInverseProjection && doForwardProjection
+      && srcCRS.getDatum() != tgtCRS.getDatum();
+    
+    if (doDatumTransform) {
+      
+      boolean isEllipsoidEqual = srcCRS.getDatum().getEllipsoid().isEqual(tgtCRS.getDatum().getEllipsoid());
+      if (! isEllipsoidEqual) 
+          transformViaGeocentric = true;
+      if (srcCRS.getDatum().hasTransformToWGS84() 
+          || tgtCRS.getDatum().hasTransformToWGS84())
+          transformViaGeocentric = true;
+      
+      if (transformViaGeocentric) {
+        srcGeoConv = new GeocentricConverter(srcCRS.getDatum().getEllipsoid());
+        tgtGeoConv = new GeocentricConverter(tgtCRS.getDatum().getEllipsoid());
+      }
+    }
+	}
+	
+  public CoordinateReferenceSystem getSourceCRS()
+  {
+    return srcCRS;
+  }
+  
+  public CoordinateReferenceSystem getTargetCRS()
+  {
+    return tgtCRS;
+  }
+  
+  
+	/**
+   * Tranforms a coordinate from the source {@link CoordinateReferenceSystem} 
+   * to the target one.
+   * 
+   * @param src the input coordinate to be transformed
+   * @param tgt the transformed coordinate
+   * @return the target coordinate which was passed in
+   * 
+   * @throws Proj4jException if a computation error is encountered
+	 */
+	public ProjCoordinate transform( ProjCoordinate src, ProjCoordinate tgt )
+  throws Proj4jException
+	{
+		// NOTE: this method may be called many times, so needs to be as efficient as possible
+    
+		if (doInverseProjection) {
+      // inverse project to geographic
+      srcCRS.getProjection().inverseProjectRadians(src, geoCoord);
+		}
+		else {
+      geoCoord.setValue(src);
+		}
+
+    //TODO: adjust src Prime Meridian if specified
+    
+    if (doDatumTransform) {
+      datumTransform(geoCoord);
+    }
+		
+    //TODO: adjust target Prime Meridian if specified
+
+		if (doForwardProjection) {
+      // project from geographic to planar
+      tgtCRS.getProjection().projectRadians(geoCoord, tgt);
+    }
+    else {
+			tgt.setValue(geoCoord);
+		}
+
+		return tgt;
+	}
+  
+  /**
+   * 
+   * Input:  long/lat/z coordinates in radians in the source datum
+   * Output: long/lat/z coordinates in radians in the target datum
+   * 
+   * @param pt the point containing the input and output values
+   */
+  private void datumTransform(ProjCoordinate pt)
+  {
+    /* -------------------------------------------------------------------- */
+    /*      Short cut if the datums are identical.                          */
+    /* -------------------------------------------------------------------- */
+    if (srcCRS.getDatum().isEqual(tgtCRS.getDatum()))
+      return;
+    
+    // TODO: grid shift if required
+    
+    /* ==================================================================== */
+    /*      Do we need to go through geocentric coordinates?                */
+    /* ==================================================================== */
+    if (transformViaGeocentric) {
+      /* -------------------------------------------------------------------- */
+      /*      Convert to geocentric coordinates.                              */
+      /* -------------------------------------------------------------------- */
+      srcGeoConv.convertGeodeticToGeocentric( pt );
+      
+      /* -------------------------------------------------------------------- */
+      /*      Convert between datums.                                         */
+      /* -------------------------------------------------------------------- */
+      if( srcCRS.getDatum().hasTransformToWGS84() ) {
+        srcCRS.getDatum().transformFromGeocentricToWgs84( pt );
+      }
+      if( tgtCRS.getDatum().hasTransformToWGS84() ) {
+        tgtCRS.getDatum().transformToGeocentricFromWgs84( pt );
+      }
+
+      /* -------------------------------------------------------------------- */
+      /*      Convert back to geodetic coordinates.                           */
+      /* -------------------------------------------------------------------- */
+      tgtGeoConv.convertGeocentricToGeodetic( pt );
+    }
+    
+    // TODO: grid shift if required
+
+  }
+  
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/CRSFactory.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/CRSFactory.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/CRSFactory.java	(revision 26409)
@@ -0,0 +1,119 @@
+package org.osgeo.proj4j;
+
+import org.osgeo.proj4j.io.Proj4FileReader;
+import org.osgeo.proj4j.parser.Proj4Parser;
+
+/**
+ * A factory which can create {@link CoordinateReferenceSystem}s
+ * from a variety of ways
+ * of specifying them.
+ * <p>
+ * <tt>CoordinateReferenceSystem</tt>s can be used to
+ * define {@link CoordinateTransform}s to perform transformations
+ * on {@link ProjCoordinate}s. 
+ * 
+ * @author Martin Davis
+ *
+ */
+public class CRSFactory 
+{
+  private static Proj4FileReader csReader = new Proj4FileReader();
+  
+  private static Registry registry = new Registry();
+
+	// TODO: add method to allow reading from arbitrary PROJ4 CS file
+	
+  /**
+   * Creates a new factory.
+   */
+	public CRSFactory()
+	{
+		
+	}
+	
+  /**
+   * Gets the {@link Registry} used by this factory.
+   * @return the Registry
+   */
+  public Registry getRegistry()
+  {
+    return registry;
+  }
+  
+  /**
+   * Creates a {@link CoordinateReferenceSystem} from a well-known name.
+   * Names are of the form: <tt>"authority:code"</tt>.
+   * <ul>
+   * <li><b><tt>authority</tt></b> is a code for a namespace supported by
+   * PROJ.4.  
+   * Currently supported values are 
+   * <tt>EPSG</tt>, <tt>ESRI</tt>, <tt>WORLD</tt>, <tt>NA83</tt>, <tt>NAD27</tt>.
+   * If no authority is provided, <tt>EPSG</tt> is assumed.
+   * <li><b><tt>code</tt></b> is the id of a coordinate system in the authority namespace.
+   * For example, in the <tt>EPSG</tt> namespace a code is an integer value
+   * which identifies a CRS definition in the EPSG database.
+   * </ul>
+   * An example of a valid name is <tt>EPSG:3005</tt>.
+   * 
+   * @param name the name of a coordinate system, with optional authority prefix
+   * @return a {@link CoordinateReferenceSystem}
+   * @throws UnsupportedParameterException if a PROJ.4 parameter is not supported
+   * @throws InvalidValueException if a parameter value is invalid
+   * @throws UnknownAuthorityCodeException if the authority code cannot be found
+   */
+  public CoordinateReferenceSystem createFromName(String name)
+  throws UnsupportedParameterException, InvalidValueException, UnknownAuthorityCodeException
+  {
+    String[] params = csReader.getParameters(name);
+    if (params == null)
+      throw new UnknownAuthorityCodeException(name);
+    return createFromParameters(name, params);
+  }
+  
+  /**
+   * Creates a {@link CoordinateReferenceSystem} 
+   * defined by a PROJ.4 parameter string.
+   * <p>
+   * An example of a valid PROJ.4 parameter string is:
+   * <pre>
+   * +proj=aea +lat_1=50 +lat_2=58.5 +lat_0=45 +lon_0=-126 +x_0=1000000 +y_0=0 +ellps=GRS80 +units=m
+   * </pre>
+   * @param name a name for this coordinate system (may be <tt>null</tt>)
+   * @param paramStr a PROJ.4 parameter string
+   * @return a {@link CoordinateReferenceSystem}
+   * @throws UnsupportedParameterException if a PROJ.4 parameter is not supported
+   * @throws InvalidValueException if a parameter value is invalid
+   */
+  public CoordinateReferenceSystem createFromParameters(String name, String paramStr)
+  throws UnsupportedParameterException, InvalidValueException
+  {
+    return createFromParameters(name, splitParameters(paramStr));
+  }
+  
+  /**
+   * Creates a {@link CoordinateReferenceSystem} 
+   * defined by an array of PROJ.4 parameters.
+   * 
+   * @param name a name for this coordinate system (may be null)
+   * @param args an array of PROJ.4 parameters
+   * @return a {@link CoordinateReferenceSystem}
+   * @throws UnsupportedParameterException if a PROJ.4 parameter is not supported
+   * @throws InvalidValueException if a parameter value is invalid
+  */
+  public CoordinateReferenceSystem createFromParameters(String name, String[] args)
+  throws UnsupportedParameterException, InvalidValueException
+  {
+    if (args == null)
+      return null;
+    
+    Proj4Parser parser = new Proj4Parser(registry);
+    return parser.parse(name, args);
+  }
+
+  private static String[] splitParameters(String paramStr)
+  {
+    String[] params = paramStr.split("\\s+");
+    return params;
+  }
+  
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/ConvergenceFailureException.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/ConvergenceFailureException.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/ConvergenceFailureException.java	(revision 26409)
@@ -0,0 +1,21 @@
+
+package org.osgeo.proj4j;
+
+/**
+ * Signals that an interative mathematical algorithm has failed to converge.
+ * This is usually due to values exceeding the
+ * allowable bounds for the computation in which they are being used.
+ * 
+ * @author mbdavis
+ *
+ */
+public class ConvergenceFailureException extends Proj4jException 
+{
+	public ConvergenceFailureException() {
+		super();
+	}
+
+	public ConvergenceFailureException(String message) {
+		super(message);
+	}
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/CoordinateReferenceSystem.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/CoordinateReferenceSystem.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/CoordinateReferenceSystem.java	(revision 26409)
@@ -0,0 +1,109 @@
+package org.osgeo.proj4j;
+
+import org.osgeo.proj4j.datum.Datum;
+import org.osgeo.proj4j.datum.Ellipsoid;
+import org.osgeo.proj4j.proj.LongLatProjection;
+import org.osgeo.proj4j.proj.Projection;
+import org.osgeo.proj4j.units.Unit;
+import org.osgeo.proj4j.units.Units;
+
+/**
+ * Represents a projected or geodetic geospatial coordinate system,
+ * to which coordinates may be referenced.
+ * A coordinate system is defined by the following things:
+ * <ul>
+ * <li>an {@link Ellipsoid} specifies how the shape of the Earth is approximated
+ * <li>a {@link Datum} provides the mapping from the ellipsoid to 
+ * actual locations on the earth
+ * <li>a {@link Projection} method maps the ellpsoidal surface to a planar space.
+ * (The projection method may be null in the case of geodetic coordinate systems).
+ * <li>a {@link Unit} indicates how the ordinate values 
+ * of coordinates are interpreted
+ * </ul>
+ * 
+ * @author Martin Davis
+ * 
+ * @see CRSFactory
+ *
+ */
+public class CoordinateReferenceSystem 
+{
+  // allows specifying transformations which convert to/from Geographic coordinates on the same datum
+  public static final CoordinateReferenceSystem CS_GEO = new CoordinateReferenceSystem("CS_GEO", null, null, null);
+
+	//TODO: add metadata like authority, id, name, parameter string, datum, ellipsoid, datum shift parameters
+	
+	private String name;
+  private String[] params;
+  private Datum datum;
+	private Projection proj;
+	
+	public CoordinateReferenceSystem(String name, String[] params, Datum datum, Projection proj)
+	{
+		this.name = name;
+    this.params = params;
+    this.datum = datum;
+		this.proj = proj;
+    
+    if (name == null) {
+      String projName = "null-proj"; 
+      if (proj != null)
+        projName = proj.getName();
+      this.name = projName + "-CS";
+    }
+	}
+	
+  public String getName()
+  {
+    return name;
+  }
+  
+  public String[] getParameters()
+  {
+    return params;
+  }
+  
+  public Datum getDatum()
+  {
+    return datum;
+  }
+  
+  public Projection getProjection()
+  {
+    return proj;
+  }
+  
+  public String getParameterString()
+  {
+    if (params == null) return "";
+    
+    StringBuffer buf = new StringBuffer();
+    for (int i = 0; i < params.length; i++) {
+      buf.append(params[i]);
+      buf.append(" ");
+    }
+    return buf.toString();
+  }
+  
+  /**
+   * Creates a geographic (unprojected) {@link CoordinateReferenceSystem} 
+   * based on the {@link Datum} of this CRS.
+   * This is useful for defining {@link CoordinateTransform}s
+   * to and from geographic coordinate systems,
+   * where no datum transformation is required.
+   * The {@link Units} of the geographic CRS are set to {@link Units#DEGREES}. 
+   * 
+   * @return a geographic CoordinateReferenceSystem based on the datum of this CRS
+   */
+  public CoordinateReferenceSystem createGeographic()
+  {
+    Datum datum = getDatum();
+    Projection geoProj = new LongLatProjection();
+    geoProj.setEllipsoid(getProjection().getEllipsoid());
+    geoProj.setUnits(Units.DEGREES);
+    geoProj.initialize();
+    return new CoordinateReferenceSystem("GEO-" + datum.getCode(), null, datum, geoProj);
+  }
+
+	public String toString() { return name; }
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/CoordinateTransform.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/CoordinateTransform.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/CoordinateTransform.java	(revision 26409)
@@ -0,0 +1,36 @@
+package org.osgeo.proj4j;
+
+import org.osgeo.proj4j.datum.*;
+
+/**
+ * An interface for the operation of transforming 
+ * a {@link ProjCoordinate} from one {@link CoordinateReferenceSystem} 
+ * into a different one.
+ * 
+ * @author Martin Davis
+ * 
+ * @see CoordinateTransformFactory
+ */
+public interface CoordinateTransform 
+{
+
+  public CoordinateReferenceSystem getSourceCRS();
+  
+  public CoordinateReferenceSystem getTargetCRS();
+  
+  
+	/**
+   * Tranforms a coordinate from the source {@link CoordinateReferenceSystem} 
+   * to the target one.
+   * 
+   * @param src the input coordinate to transform
+   * @param tgt the transformed coordinate
+   * @return the target coordinate which was passed in
+   * 
+   * @throws Proj4jException if a computation error is encountered
+	 */
+	public ProjCoordinate transform( ProjCoordinate src, ProjCoordinate tgt )
+  throws Proj4jException;
+  
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/CoordinateTransformFactory.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/CoordinateTransformFactory.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/CoordinateTransformFactory.java	(revision 26409)
@@ -0,0 +1,38 @@
+package org.osgeo.proj4j;
+
+import org.osgeo.proj4j.datum.Datum;
+
+/**
+ * Creates {@link CoordinateTransform}s
+ * from source and target {@link CoordinateReferenceSystem}s.
+ * 
+ * @author mbdavis
+ *
+ */
+public class CoordinateTransformFactory 
+{
+	/**
+	 * Creates a new factory.
+	 *
+	 */
+	public CoordinateTransformFactory()
+	{
+		
+	}
+	
+	/**
+	 * Creates a transformation from a source CRS to a target CRS,
+	 * following the logic in PROJ.4.
+	 * The transformation may include any or all of inverse projection, datum transformation,
+	 * and reprojection, depending on the nature of the coordinate reference systems 
+	 * provided.
+	 *  
+	 * @param sourceCRS the source CoordinateReferenceSystem
+	 * @param targetCRS the target CoordinateReferenceSystem
+	 * @return a tranformation from the source CRS to the target CRS
+	 */
+	public CoordinateTransform createTransform(CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS)
+	{
+		return new BasicCoordinateTransform(sourceCRS, targetCRS);
+	}
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/InvalidValueException.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/InvalidValueException.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/InvalidValueException.java	(revision 26409)
@@ -0,0 +1,19 @@
+package org.osgeo.proj4j;
+
+/**
+ * Signals that a parameter or computed internal variable
+ * has a value which lies outside the 
+ * allowable bounds for the computation in which it is being used.
+ * 
+ * @author mbdavis
+ *
+ */
+public class InvalidValueException extends Proj4jException {
+	public InvalidValueException() {
+		super();
+	}
+
+	public InvalidValueException(String message) {
+		super(message);
+	}
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/Proj4jException.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/Proj4jException.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/Proj4jException.java	(revision 26409)
@@ -0,0 +1,23 @@
+package org.osgeo.proj4j;
+
+/**
+ * Signals that a situation or data state has been encountered
+ * which prevents computation from proceeding,
+ * or which would lead to erroneous results.
+ * <p>
+ * This is the base class for all exceptions 
+ * thrown in the Proj4J API.
+ * 
+ * @author mbdavis
+ *
+ */
+public class Proj4jException extends RuntimeException 
+{
+	public Proj4jException() {
+		super();
+	}
+
+	public Proj4jException(String message) {
+		super(message);
+	}
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/ProjCoordinate.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/ProjCoordinate.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/ProjCoordinate.java	(revision 26409)
@@ -0,0 +1,376 @@
+package org.osgeo.proj4j;
+
+/**
+ * Stores a the coordinates for a position  
+ * defined relative to some {@link CoordinateReferenceSystem}.
+ * The coordinate is defined via X, Y, and optional Z ordinates. 
+ * Provides utility methods for comparing the ordinates of two positions and
+ * for creating positions from Strings/storing positions as strings.
+ * <p>
+ * The primary use of this class is to represent coordinate
+ * values which are to be transformed
+ * by a {@link CoordinateTransform}.
+ */
+public class ProjCoordinate 
+{
+	/**
+	 * The X ordinate for this point. 
+	 * <p>
+	 * Note: This member variable
+	 * can be accessed directly. In the future this direct access should
+	 * be replaced with getter and setter methods. This will require 
+	 * refactoring of the Proj4J code base.
+	 */
+	public double x;
+	
+	/**
+	 * The Y ordinate for this point. 
+	 * <p>
+	 * Note: This member variable
+	 * can be accessed directly. In the future this direct access should
+	 * be replaced with getter and setter methods. This will require 
+	 * refactoring of the Proj4J code base.
+	 */
+	public double y;
+	
+	/**
+	 * The Z ordinate for this point. 
+	 * If this variable has the value <tt>Double.NaN</tt>
+	 * then this coordinate does not have a Z value.
+	 * <p>
+	 * Note: This member variable
+	 * can be accessed directly. In the future this direct access should
+	 * be replaced with getter and setter methods. This will require 
+	 * refactoring of the Proj4J code base.
+	 */
+	public double z;
+	
+	/**
+	 * Creates a ProjCoordinate with default ordinate values.
+	 *
+	 */
+  public ProjCoordinate()
+  {
+    this(0.0, 0.0);
+  }
+
+	/**
+	 * Creates a ProjCoordinate using the provided double parameters.
+	 * The first double parameter is the x ordinate (or easting), 
+	 * the second double parameter is the y ordinate (or northing), 
+	 * and the third double parameter is the z ordinate (elevation or height).
+	 * 
+	 * Valid values should be passed for all three (3) double parameters. If
+	 * you want to create a horizontal-only point without a valid Z value, use
+	 * the constructor defined in this class that only accepts two (2) double
+	 * parameters.
+	 * 
+	 * @see #ProjCoordinate(double argX, double argY)
+	 */
+	public ProjCoordinate(double argX, double argY, double argZ)
+	{
+		this.x = argX;
+		this.y = argY;
+		this.z = argZ;
+	}
+	
+	/**
+	 * Creates a ProjCoordinate using the provided double parameters.
+	 * The first double parameter is the x ordinate (or easting), 
+	 * the second double parameter is the y ordinate (or northing). 
+	 * This constructor is used to create a "2D" point, so the Z ordinate
+	 * is automatically set to Double.NaN. 
+	 */
+	public ProjCoordinate(double argX, double argY)
+	{
+		this.x = argX;
+		this.y = argY;
+		this.z = Double.NaN;
+	}
+	
+	/** 
+	 * Create a ProjCoordinate by parsing a String in the same format as returned
+	 * by the toString method defined by this class.
+	 * 
+	 * @param argToParse the string to parse
+	 */
+	public ProjCoordinate(String argToParse)
+	{
+		// Make sure the String starts with "ProjCoordinate: ".
+		boolean startsWith = argToParse.startsWith("ProjCoordinate: ");
+		
+		if(startsWith == false)
+		{
+			IllegalArgumentException toThrow = new IllegalArgumentException
+			("The input string was not in the proper format.");
+			
+			throw toThrow;
+		}
+		
+		// 15 characters should cut out "ProjCoordinate: ".
+		String chomped = argToParse.substring(16);
+		
+		// Get rid of the starting and ending square brackets.
+		
+		String withoutFrontBracket = chomped.substring(1);
+		
+		// Calc the position of the last bracket.
+		int length = withoutFrontBracket.length();
+		int positionOfCharBeforeLast = length - 2;
+		String withoutBackBracket = withoutFrontBracket.substring(0, 
+				positionOfCharBeforeLast);
+		
+		// We should be left with just the ordinate values as strings, 
+		// separated by spaces. Split them into an array of Strings.
+		String[] parts = withoutBackBracket.split(" ");
+		
+		// Get number of elements in Array. There should be two (2) elements
+		// or three (3) elements.
+		// If we don't have an array with two (2) or three (3) elements,
+		// then we need to throw an exception.
+		if(parts.length != 2)
+		{
+			if(parts.length != 3)
+			{
+				IllegalArgumentException toThrow = new IllegalArgumentException
+				("The input string was not in the proper format.");
+				
+				throw toThrow;
+			}
+		}
+		
+		// Convert strings to doubles.
+		this.x = Double.parseDouble(parts[0]);
+		this.y = Double.parseDouble(parts[0]);
+		
+		// You might not always have a Z ordinate. If you do, set it.
+		if(parts.length == 3)
+		{
+			this.z = Double.parseDouble(parts[0]);
+		}
+	}
+	
+  /**
+   * Sets the value of this coordinate to 
+   * be equal to the given coordinate's ordinates.
+   * 
+   * @param p the coordinate to copy
+   */
+  public void setValue(ProjCoordinate p)
+  {
+    this.x = p.x;
+    this.y = p.y;
+    this.z = p.z;
+  }
+  
+	/**
+	 * Returns a boolean indicating if the X ordinate value of the 
+	 * ProjCoordinate provided as an ordinate is equal to the X ordinate
+	 * value of this ProjCoordinate. Because we are working with floating
+	 * point numbers the ordinates are considered equal if the difference
+	 * between them is less than the specified tolerance.
+	 */	
+	public boolean areXOrdinatesEqual(ProjCoordinate argToCompare, 
+			double argTolerance)
+	{
+		// Subtract the x ordinate values and then see if the difference
+		// between them is less than the specified tolerance. If the difference
+		// is less, return true.
+		double difference = argToCompare.x - this.x;
+		
+		if(difference > argTolerance)
+		{
+			return false;
+		}
+		
+		else
+		{
+			return true;
+		}
+	}
+	
+	/**
+	 * Returns a boolean indicating if the Y ordinate value of the 
+	 * ProjCoordinate provided as an ordinate is equal to the Y ordinate
+	 * value of this ProjCoordinate. Because we are working with floating
+	 * point numbers the ordinates are considered equal if the difference
+	 * between them is less than the specified tolerance.
+	 */
+	public boolean areYOrdinatesEqual(ProjCoordinate argToCompare,
+			double argTolerance)
+	{
+		// Subtract the y ordinate values and then see if the difference
+		// between them is less than the specified tolerance. If the difference
+		// is less, return true.
+		double difference = argToCompare.y - this.y;
+		
+		if(difference > argTolerance)
+		{
+			return false;
+		}
+		
+		else
+		{
+			return true;
+		}
+	}
+	
+	/**
+	 * Returns a boolean indicating if the Z ordinate value of the 
+	 * ProjCoordinate provided as an ordinate is equal to the Z ordinate
+	 * value of this ProjCoordinate. Because we are working with floating
+	 * point numbers the ordinates are considered equal if the difference
+	 * between them is less than the specified tolerance.
+	 * 
+	 * If both Z ordinate values are Double.NaN this method will return
+	 * true. If one Z ordinate value is a valid double value and one is
+	 * Double.Nan, this method will return false.
+	 */
+	public boolean areZOrdinatesEqual(ProjCoordinate argToCompare,
+			double argTolerance)
+	{
+		// We have to handle Double.NaN values here, because not every
+		// ProjCoordinate will have a valid Z Value.
+		if(Double.isNaN(z))
+		{
+			if(Double.isNaN(argToCompare.z))
+			{
+				// Both the z ordinate values are Double.Nan. Return true.
+				return true;
+			}
+			
+			else
+			{
+				// We've got one z ordinate with a valid value and one with
+				// a Double.NaN value. Return false.
+				return false;
+			}
+		}
+		
+		// We have a valid z ordinate value in this ProjCoordinate object.
+		else
+		{
+			if(Double.isNaN(argToCompare.z))
+			{
+				// We've got one z ordinate with a valid value and one with
+				// a Double.NaN value. Return false.
+				return false;
+			}
+
+			// If we get to this point in the method execution, we have to
+			// z ordinates with valid values, and we need to do a regular 
+			// comparison. This is done in the remainder of the method.
+		}
+		
+		// Subtract the z ordinate values and then see if the difference
+		// between them is less than the specified tolerance. If the difference
+		// is less, return true.
+		double difference = argToCompare.z - this.z;
+		
+		if(difference > argTolerance)
+		{
+			return false;
+		}
+		
+		else
+		{
+			return true;
+		}
+	}
+	
+	/**
+	 * Returns a string representing the ProjPoint in the format:
+	 * <tt>ProjCoordinate[X Y Z]</tt>.
+	 * <p>
+	 * Example: 
+	 * <pre>
+	 *    ProjCoordinate[6241.11 5218.25 12.3]
+	 * </pre>
+	 */
+	public String toString()
+	{
+		StringBuilder builder = new StringBuilder();
+		builder.append("ProjCoordinate[");
+		builder.append(this.x);
+		builder.append(" ");
+		builder.append(this.y);
+		builder.append(" ");
+		builder.append(this.z);
+		builder.append("]");
+		
+		return builder.toString();
+	}
+
+	/**
+	 * Returns a string representing the ProjPoint in the format:
+	 * <tt>[X Y]</tt> 
+	 * or <tt>[X, Y, Z]</tt>.
+	 * Z is not displayed if it is NaN.
+	 * <p>
+	 * Example: 
+	 * <pre>
+	 * 		[6241.11, 5218.25, 12.3]
+	 * </pre>
+	 */
+	public String toShortString()
+	{
+		StringBuilder builder = new StringBuilder();
+		builder.append("[");
+		builder.append(this.x);
+		builder.append(", ");
+		builder.append(this.y);
+		if (! Double.isNaN(z)) {
+			builder.append(", ");
+			builder.append(this.z);
+		}
+		builder.append("]");
+		
+		return builder.toString();
+	}
+	
+	public boolean hasValidZOrdinate()
+	{
+		if(Double.isNaN(this.z))
+		{
+			return false;
+		}
+		
+		else
+		{
+			return true;
+		}
+	}
+	
+	/**
+	 * Indicates if this ProjCoordinate has valid X ordinate and Y ordinate
+	 * values. Values are considered invalid if they are Double.NaN or 
+	 * positive/negative infinity.
+	 */
+	public boolean hasValidXandYOrdinates()
+	{
+		if(Double.isNaN(x))
+		{
+			return false;
+		}
+		
+		else if(Double.isInfinite(this.x) == true)
+		{
+			return false;
+		}
+		
+		if(Double.isNaN(y))
+		{
+			return false;
+		}
+		
+		else if(Double.isInfinite(this.y) == true)
+		{
+			return false;
+		}
+		
+		else
+		{
+			return true;
+		}
+	}
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/ProjectionException.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/ProjectionException.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/ProjectionException.java	(revision 26409)
@@ -0,0 +1,43 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j;
+
+import org.osgeo.proj4j.proj.Projection;
+
+/**
+ * Signals that an erroneous situation has
+ * occured during the computation of
+ * a projected coordinate system value. 
+ * 
+ * @author mbdavis
+ *
+ */
+public class ProjectionException extends Proj4jException 
+{
+  public static String ERR_17 = "non-convergent inverse meridinal dist";
+  
+	public ProjectionException() {
+		super();
+	}
+
+  public ProjectionException(String message) {
+    super(message);
+  }
+  public ProjectionException(Projection proj, String message) {
+    this(proj.toString() + ": " + message);
+  }
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/Registry.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/Registry.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/Registry.java	(revision 26409)
@@ -0,0 +1,260 @@
+package org.osgeo.proj4j;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgeo.proj4j.datum.Datum;
+import org.osgeo.proj4j.datum.Ellipsoid;
+import org.osgeo.proj4j.proj.*;
+
+/**
+ * Records predefined values for various library classes
+ * such as {@link Ellipsoid}, {@link Datum}, and {@link Projection}. 
+ * 
+ * @author Martin Davis
+ *
+ */
+public class Registry {
+
+  public Registry() {
+    super();
+  }
+
+  public final static Datum[] datums = 
+  {
+    Datum.WGS84,
+    Datum.GGRS87,
+    Datum.NAD27,
+    Datum.NAD83,
+    Datum.POTSDAM,
+    Datum.CARTHAGE,
+    Datum.HERMANNSKOGEL,
+    Datum.IRE65,
+    Datum.NZGD49,
+    Datum.OSEB36
+  };
+
+  public Datum getDatum(String code)
+  {
+    for ( int i = 0; i < datums.length; i++ ) {
+      if ( datums[i].getCode().equals( code ) ) {
+        return datums[i];
+      }
+    }
+    return null;
+  }
+
+  public final static Ellipsoid[] ellipsoids = 
+  {
+    Ellipsoid.SPHERE,
+    new Ellipsoid("MERIT", 6378137.0, 0.0, 298.257, "MERIT 1983"),
+    new Ellipsoid("SGS85", 6378136.0, 0.0, 298.257, "Soviet Geodetic System 85"),
+    Ellipsoid.GRS80,
+    new Ellipsoid("IAU76", 6378140.0, 0.0, 298.257, "IAU 1976"),
+    Ellipsoid.AIRY,
+    Ellipsoid.MOD_AIRY,
+    new Ellipsoid("APL4.9", 6378137.0, 0.0, 298.25, "Appl. Physics. 1965"),
+    new Ellipsoid("NWL9D", 6378145.0, 298.25, 0.0, "Naval Weapons Lab., 1965"),
+    new Ellipsoid("andrae", 6377104.43, 300.0, 0.0, "Andrae 1876 (Den., Iclnd.)"),
+    new Ellipsoid("aust_SA", 6378160.0, 0.0, 298.25, "Australian Natl & S. Amer. 1969"),
+    new Ellipsoid("GRS67", 6378160.0, 0.0, 298.2471674270, "GRS 67 (IUGG 1967)"),
+    Ellipsoid.BESSEL,
+    new Ellipsoid("bess_nam", 6377483.865, 0.0, 299.1528128, "Bessel 1841 (Namibia)"),
+    Ellipsoid.CLARKE_1866,
+    Ellipsoid.CLARKE_1880,
+    new Ellipsoid("CPM", 6375738.7, 0.0, 334.29, "Comm. des Poids et Mesures 1799"),
+    new Ellipsoid("delmbr", 6376428.0, 0.0, 311.5, "Delambre 1810 (Belgium)"),
+    new Ellipsoid("engelis", 6378136.05, 0.0, 298.2566, "Engelis 1985"),
+    Ellipsoid.EVEREST,
+    new Ellipsoid("evrst48", 6377304.063, 0.0, 300.8017, "Everest 1948"),
+    new Ellipsoid("evrst56", 6377301.243, 0.0, 300.8017, "Everest 1956"),
+    new Ellipsoid("evrst69", 6377295.664, 0.0, 300.8017, "Everest 1969"),
+    new Ellipsoid("evrstSS", 6377298.556, 0.0, 300.8017, "Everest (Sabah & Sarawak)"),
+    new Ellipsoid("fschr60", 6378166.0, 0.0, 298.3, "Fischer (Mercury Datum) 1960"),
+    new Ellipsoid("fschr60m", 6378155.0, 0.0, 298.3, "Modified Fischer 1960"),
+    new Ellipsoid("fschr68", 6378150.0, 0.0, 298.3, "Fischer 1968"),
+    new Ellipsoid("helmert", 6378200.0, 0.0, 298.3, "Helmert 1906"),
+    new Ellipsoid("hough", 6378270.0, 0.0, 297.0, "Hough"),
+    Ellipsoid.INTERNATIONAL,
+    Ellipsoid.INTERNATIONAL_1967,
+    Ellipsoid.KRASSOVSKY,
+    new Ellipsoid("kaula", 6378163.0, 0.0, 298.24, "Kaula 1961"),
+    new Ellipsoid("lerch", 6378139.0, 0.0, 298.257, "Lerch 1979"),
+    new Ellipsoid("mprts", 6397300.0, 0.0, 191.0, "Maupertius 1738"),
+    new Ellipsoid("plessis", 6376523.0, 6355863.0, 0.0, "Plessis 1817 France)"),
+    new Ellipsoid("SEasia", 6378155.0, 6356773.3205, 0.0, "Southeast Asia"),
+    new Ellipsoid("walbeck", 6376896.0, 6355834.8467, 0.0, "Walbeck"),
+    Ellipsoid.WGS60,
+    Ellipsoid.WGS66,
+    Ellipsoid.WGS72,
+    Ellipsoid.WGS84,
+        new Ellipsoid("NAD27", 6378249.145, 0.0, 293.4663, "NAD27: Clarke 1880 mod."),
+        new Ellipsoid("NAD83", 6378137.0, 0.0, 298.257222101, "NAD83: GRS 1980 (IUGG, 1980)"),
+  };
+
+
+  public Ellipsoid getEllipsoid(String name)
+  {
+    for ( int i = 0; i < ellipsoids.length; i++ ) {
+      if ( ellipsoids[i].shortName.equals( name ) ) {
+        return ellipsoids[i];
+      }
+    }
+    return null;
+  }
+
+  private Map<String, Class> projRegistry;
+
+  private void register( String name, Class cls, String description ) {
+    projRegistry.put( name, cls );
+  }
+
+  public Projection getProjection( String name ) {
+    if ( projRegistry == null )
+      initialize();
+    Class cls = (Class)projRegistry.get( name );
+    if ( cls != null ) {
+      try {
+        Projection projection = (Projection)cls.newInstance();
+        if ( projection != null )
+          projection.setName( name );
+        return projection;
+      }
+      catch ( IllegalAccessException e ) {
+        e.printStackTrace();
+      }
+      catch ( InstantiationException e ) {
+        e.printStackTrace();
+      }
+    }
+    return null;
+  }
+  
+  private void initialize() {
+    projRegistry = new HashMap();
+    register( "aea", AlbersProjection.class, "Albers Equal Area" );
+    register( "aeqd", EquidistantAzimuthalProjection.class, "Azimuthal Equidistant" );
+    register( "airy", AiryProjection.class, "Airy" );
+    register( "aitoff", AitoffProjection.class, "Aitoff" );
+    register( "alsk", Projection.class, "Mod. Stereographics of Alaska" );
+    register( "apian", Projection.class, "Apian Globular I" );
+    register( "august", AugustProjection.class, "August Epicycloidal" );
+    register( "bacon", Projection.class, "Bacon Globular" );
+    register( "bipc", BipolarProjection.class, "Bipolar conic of western hemisphere" );
+    register( "boggs", BoggsProjection.class, "Boggs Eumorphic" );
+    register( "bonne", BonneProjection.class, "Bonne (Werner lat_1=90)" );
+    register( "cass", CassiniProjection.class, "Cassini" );
+    register( "cc", CentralCylindricalProjection.class, "Central Cylindrical" );
+    register( "cea", Projection.class, "Equal Area Cylindrical" );
+//    register( "chamb", Projection.class, "Chamberlin Trimetric" );
+    register( "collg", CollignonProjection.class, "Collignon" );
+    register( "crast", CrasterProjection.class, "Craster Parabolic (Putnins P4)" );
+    register( "denoy", DenoyerProjection.class, "Denoyer Semi-Elliptical" );
+    register( "eck1", Eckert1Projection.class, "Eckert I" );
+    register( "eck2", Eckert2Projection.class, "Eckert II" );
+//    register( "eck3", Eckert3Projection.class, "Eckert III" );
+    register( "eck4", Eckert4Projection.class, "Eckert IV" );
+    register( "eck5", Eckert5Projection.class, "Eckert V" );
+    register( "eck6", Eckert6Projection.class, "Eckert VI" );
+    register( "eqc", PlateCarreeProjection.class, "Equidistant Cylindrical (Plate Caree)" );
+    register( "eqdc", EquidistantConicProjection.class, "Equidistant Conic" );
+    register( "euler", EulerProjection.class, "Euler" );
+    register( "fahey", FaheyProjection.class, "Fahey" );
+    register( "fouc", FoucautProjection.class, "Foucaut" );
+    register( "fouc_s", FoucautSinusoidalProjection.class, "Foucaut Sinusoidal" );
+    register( "gall", GallProjection.class, "Gall (Gall Stereographic)" );
+//    register( "gins8", Projection.class, "Ginsburg VIII (TsNIIGAiK)" );
+//    register( "gn_sinu", Projection.class, "General Sinusoidal Series" );
+    register( "gnom", GnomonicAzimuthalProjection.class, "Gnomonic" );
+    register( "goode", GoodeProjection.class, "Goode Homolosine" );
+//    register( "gs48", Projection.class, "Mod. Stererographics of 48 U.S." );
+//    register( "gs50", Projection.class, "Mod. Stererographics of 50 U.S." );
+    register( "hammer", HammerProjection.class, "Hammer & Eckert-Greifendorff" );
+    register( "hatano", HatanoProjection.class, "Hatano Asymmetrical Equal Area" );
+//    register( "imw_p", Projection.class, "Internation Map of the World Polyconic" );
+    register( "kav5", KavraiskyVProjection.class, "Kavraisky V" );
+//    register( "kav7", Projection.class, "Kavraisky VII" );
+//    register( "labrd", Projection.class, "Laborde" );
+//    register( "laea", Projection.class, "Lambert Azimuthal Equal Area" );
+    register( "lagrng", LagrangeProjection.class, "Lagrange" );
+    register( "larr", LarriveeProjection.class, "Larrivee" );
+    register( "lask", LaskowskiProjection.class, "Laskowski" );
+    register( "latlong", LongLatProjection.class, "Lat/Long" );
+    register( "longlat", LongLatProjection.class, "Lat/Long" );
+    register( "lcc", LambertConformalConicProjection.class, "Lambert Conformal Conic" );
+    register( "leac", LambertEqualAreaConicProjection.class, "Lambert Equal Area Conic" );
+//    register( "lee_os", Projection.class, "Lee Oblated Stereographic" );
+    register( "loxim", LoximuthalProjection.class, "Loximuthal" );
+    register( "lsat", LandsatProjection.class, "Space oblique for LANDSAT" );
+//    register( "mbt_s", Projection.class, "McBryde-Thomas Flat-Polar Sine" );
+    register( "mbt_fps", McBrydeThomasFlatPolarSine2Projection.class, "McBryde-Thomas Flat-Pole Sine (No. 2)" );
+    register( "mbtfpp", McBrydeThomasFlatPolarParabolicProjection.class, "McBride-Thomas Flat-Polar Parabolic" );
+    register( "mbtfpq", McBrydeThomasFlatPolarQuarticProjection.class, "McBryde-Thomas Flat-Polar Quartic" );
+//    register( "mbtfps", Projection.class, "McBryde-Thomas Flat-Polar Sinusoidal" );
+    register( "merc", MercatorProjection.class, "Mercator" );
+//    register( "mil_os", Projection.class, "Miller Oblated Stereographic" );
+    register( "mill", MillerProjection.class, "Miller Cylindrical" );
+//    register( "mpoly", Projection.class, "Modified Polyconic" );
+    register( "moll", MolleweideProjection.class, "Mollweide" );
+    register( "murd1", Murdoch1Projection.class, "Murdoch I" );
+    register( "murd2", Murdoch2Projection.class, "Murdoch II" );
+    register( "murd3", Murdoch3Projection.class, "Murdoch III" );
+    register( "nell", NellProjection.class, "Nell" );
+//    register( "nell_h", Projection.class, "Nell-Hammer" );
+    register( "nicol", NicolosiProjection.class, "Nicolosi Globular" );
+    register( "nsper", PerspectiveProjection.class, "Near-sided perspective" );
+//    register( "nzmg", Projection.class, "New Zealand Map Grid" );
+//    register( "ob_tran", Projection.class, "General Oblique Transformation" );
+//    register( "ocea", Projection.class, "Oblique Cylindrical Equal Area" );
+//    register( "oea", Projection.class, "Oblated Equal Area" );
+    register( "omerc", ObliqueMercatorProjection.class, "Oblique Mercator" );
+//    register( "ortel", Projection.class, "Ortelius Oval" );
+    register( "ortho", OrthographicAzimuthalProjection.class, "Orthographic" );
+    register( "pconic", PerspectiveConicProjection.class, "Perspective Conic" );
+    register( "poly", PolyconicProjection.class, "Polyconic (American)" );
+//    register( "putp1", Projection.class, "Putnins P1" );
+    register( "putp2", PutninsP2Projection.class, "Putnins P2" );
+//    register( "putp3", Projection.class, "Putnins P3" );
+//    register( "putp3p", Projection.class, "Putnins P3'" );
+    register( "putp4p", PutninsP4Projection.class, "Putnins P4'" );
+    register( "putp5", PutninsP5Projection.class, "Putnins P5" );
+    register( "putp5p", PutninsP5PProjection.class, "Putnins P5'" );
+//    register( "putp6", Projection.class, "Putnins P6" );
+//    register( "putp6p", Projection.class, "Putnins P6'" );
+    register( "qua_aut", QuarticAuthalicProjection.class, "Quartic Authalic" );
+    register( "robin", RobinsonProjection.class, "Robinson" );
+    register( "rpoly", RectangularPolyconicProjection.class, "Rectangular Polyconic" );
+    register( "sinu", SinusoidalProjection.class, "Sinusoidal (Sanson-Flamsteed)" );
+//    register( "somerc", Projection.class, "Swiss. Obl. Mercator" );
+    register( "stere", StereographicAzimuthalProjection.class, "Stereographic" );
+    register( "sterea", ObliqueStereographicAlternativeProjection.class, "Oblique Stereographic Alternative" );
+    register( "tcc", TranverseCentralCylindricalProjection.class, "Transverse Central Cylindrical" );
+    register( "tcea", TransverseCylindricalEqualArea.class, "Transverse Cylindrical Equal Area" );
+//    register( "tissot", TissotProjection.class, "Tissot Conic" );
+    register( "tmerc", TransverseMercatorProjection.class, "Transverse Mercator" );
+//    register( "tpeqd", Projection.class, "Two Point Equidistant" );
+//    register( "tpers", Projection.class, "Tilted perspective" );
+//    register( "ups", Projection.class, "Universal Polar Stereographic" );
+//    register( "urm5", Projection.class, "Urmaev V" );
+    register( "urmfps", UrmaevFlatPolarSinusoidalProjection.class, "Urmaev Flat-Polar Sinusoidal" );
+    register( "utm", TransverseMercatorProjection.class, "Universal Transverse Mercator (UTM)" );
+    register( "vandg", VanDerGrintenProjection.class, "van der Grinten (I)" );
+//    register( "vandg2", Projection.class, "van der Grinten II" );
+//    register( "vandg3", Projection.class, "van der Grinten III" );
+//    register( "vandg4", Projection.class, "van der Grinten IV" );
+    register( "vitk1", VitkovskyProjection.class, "Vitkovsky I" );
+    register( "wag1", Wagner1Projection.class, "Wagner I (Kavraisky VI)" );
+    register( "wag2", Wagner2Projection.class, "Wagner II" );
+    register( "wag3", Wagner3Projection.class, "Wagner III" );
+    register( "wag4", Wagner4Projection.class, "Wagner IV" );
+    register( "wag5", Wagner5Projection.class, "Wagner V" );
+//    register( "wag6", Projection.class, "Wagner VI" );
+    register( "wag7", Wagner7Projection.class, "Wagner VII" );
+    register( "weren", WerenskioldProjection.class, "Werenskiold I" );
+//    register( "wink1", Projection.class, "Winkel I" );
+//    register( "wink2", Projection.class, "Winkel II" );
+    register( "wintri", WinkelTripelProjection.class, "Winkel Tripel" );
+  }
+
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/UnknownAuthorityCodeException.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/UnknownAuthorityCodeException.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/UnknownAuthorityCodeException.java	(revision 26409)
@@ -0,0 +1,20 @@
+
+package org.osgeo.proj4j;
+
+/**
+ * Signals that an authority code is unknown 
+ * and cannot be mapped to a CRS definition.
+ * 
+ * @author mbdavis
+ *
+ */
+public class UnknownAuthorityCodeException extends Proj4jException 
+{
+	public UnknownAuthorityCodeException() {
+		super();
+	}
+
+	public UnknownAuthorityCodeException(String message) {
+		super(message);
+	}
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/UnsupportedParameterException.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/UnsupportedParameterException.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/UnsupportedParameterException.java	(revision 26409)
@@ -0,0 +1,20 @@
+
+package org.osgeo.proj4j;
+
+/**
+ * Signals that a parameter in a CRS specification
+ * is not currently supported, or unknown.
+ * 
+ * @author mbdavis
+ *
+ */
+public class UnsupportedParameterException extends Proj4jException 
+{
+	public UnsupportedParameterException() {
+		super();
+	}
+
+	public UnsupportedParameterException(String message) {
+		super(message);
+	}
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/cmd/MetaCRSTestCmd.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/cmd/MetaCRSTestCmd.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/cmd/MetaCRSTestCmd.java	(revision 26409)
@@ -0,0 +1,144 @@
+package org.osgeo.proj4j.cmd;
+
+
+import java.io.*;
+import java.util.*;
+
+import org.osgeo.proj4j.*;
+import org.osgeo.proj4j.io.*;
+import org.osgeo.proj4j.util.*;
+
+/**
+ * A command-line application which runs test files 
+ * in MetaCRS Transformation Test format.
+ * <p>
+ * Usage:
+ * <pre>
+ *   MetaCRSTestCmd <test-file-name>
+ * </pre>
+ * 
+ * @author Martin Davis
+ *
+ */
+public class MetaCRSTestCmd 
+{
+  // TODO: display line numbers of tests in verbose mode
+  public static void main(String args[]) 
+  {
+    MetaCRSTestCmd cmd = new MetaCRSTestCmd();
+    cmd.parseArgs(args);
+    try {
+      cmd.execute();
+    }
+    catch (Exception ex) {
+      ex.printStackTrace();
+    }
+  }
+
+  private static String usage()
+  {
+    return "Usage: MetaCRSTestCmd [-verbose] { <test-file-name> }";
+  }
+  private static final int TESTS_PER_LINE = 50;
+  
+  private static CRSFactory csFactory = new CRSFactory();
+
+  private List<String> filenames = new ArrayList<String>();
+  private boolean verbose = false;
+  
+  int count = 0;
+  int failCount = 0;
+  int errCount = 0;
+
+  private CRSCache crsCache = new CRSCache();
+  
+  public MetaCRSTestCmd() 
+  {
+  }
+  
+  private void parseArgs(String[] args)
+  {
+    //TODO: error handling
+    if (args.length <= 0) {
+      System.err.println(usage());
+      System.exit(1);
+    }
+    parseFlags(args);
+    
+    parseFiles(args);
+  }
+
+  private void parseFlags(String[] args)
+  {
+    for (String arg : args) {
+      if (arg.startsWith("-")) {
+        if (arg.equalsIgnoreCase("-verbose")) {
+          verbose = true;
+        }
+      }
+    }
+  }
+  private void parseFiles(String[] args)
+  {
+    for (String arg : args) {
+      if (! arg.startsWith("-")) {
+        filenames.add(arg);
+      }
+    }
+  }
+  private void execute()
+  throws IOException
+  {
+    long timeInMillis = System.currentTimeMillis();
+    for (String filename : filenames) {
+      execute(filename);
+    }
+    
+    System.out.println();
+    System.out.println("Tests run: " + count
+        + ",  Failures: " + failCount
+        + ",  Errors: " + errCount);
+
+    long timeMS = System.currentTimeMillis() - timeInMillis;
+    System.out.println("Time: " + (timeMS / 1000.0) + " s");
+  }
+  
+  private void execute(String filename)
+  throws IOException
+  {
+    System.out.println("File: " + filename);
+    
+    File file = new File(filename);
+    MetaCRSTestFileReader reader = new MetaCRSTestFileReader(file);
+    List<MetaCRSTestCase> tests = reader.readTests();
+    
+    for (MetaCRSTestCase test : tests) 
+    {
+      test.setCache(crsCache);
+      count++;
+      System.out.print(".");
+      boolean isOk;
+      try {
+        isOk = test.execute(csFactory);
+      }
+      catch (Proj4jException ex) {
+        System.out.println(ex);
+        errCount++;
+        continue;
+      }
+      if (! isOk) {
+        failCount++;
+        System.out.print("F");
+      }
+      if (verbose || ! isOk) {
+        System.out.println();
+        test.print(System.out);
+      }
+
+      if (count % TESTS_PER_LINE == 0)
+        System.out.println();
+    }
+    System.out.println();   
+  }
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/datum/Datum.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/datum/Datum.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/datum/Datum.java	(revision 26409)
@@ -0,0 +1,246 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.datum;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+
+/**
+ * A class representing a geodetic datum.
+ * <p>
+ * A geodetic datum consists of a set of reference points on or in the Earth,
+ * and a reference {@link Ellipsoid} giving an approximation 
+ * to the true shape of the geoid.
+ * <p>
+ * In order to transform between two geodetic points specified 
+ * on different datums, it is necessary to transform between the 
+ * two datums.  There are various ways in which this
+ * datum conversion may be specified:
+ * <ul>
+ * <li>A 3-parameter conversion
+ * <li>A 7-parameter conversion
+ * <li>A grid-shift conversion
+ * </ul>
+ * 
+ * <p>
+ * Notable datums in common use include {@link #NAD83} and {@link #WGS84}.
+ * 
+ */
+public class Datum 
+{
+  public static final int TYPE_UNKNOWN = 0;
+  public static final int TYPE_WGS84 = 1;
+  public static final int TYPE_3PARAM = 2;
+  public static final int TYPE_7PARAM = 3;
+  public static final int TYPE_GRIDSHIFT = 4;
+  
+  private static final double[] DEFAULT_TRANSFORM = new double[] { 0.0, 0.0, 0.0 };
+
+  public static final Datum WGS84 = new Datum("WGS84", 0,0,0, Ellipsoid.WGS84, "WGS84"); 
+  public static final Datum GGRS87 = new Datum("GGRS87", -199.87,74.79,246.62, Ellipsoid.GRS80, "Greek_Geodetic_Reference_System_1987");
+  public static final Datum NAD83 = new Datum("NAD83", 0,0,0, Ellipsoid.GRS80,"North_American_Datum_1983");
+  public static final Datum NAD27 = new Datum("NAD27", "@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat", Ellipsoid.CLARKE_1866,"North_American_Datum_1927");
+  public static final Datum POTSDAM = new Datum("potsdam", 606.0,23.0,413.0, Ellipsoid.BESSEL, "Potsdam Rauenberg 1950 DHDN");
+  public static final Datum CARTHAGE = new Datum("carthage",-263.0,6.0,431.0, Ellipsoid.CLARKE_1880, "Carthage 1934 Tunisia");
+  public static final Datum HERMANNSKOGEL = new Datum("hermannskogel", 653.0,-212.0,449.0, Ellipsoid.BESSEL, "Hermannskogel");
+  public static final Datum IRE65 = new Datum("ire65", 482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15, Ellipsoid.MOD_AIRY, "Ireland 1965");
+  public static final Datum NZGD49 = new Datum("nzgd49", 59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993, Ellipsoid.INTERNATIONAL, "New Zealand Geodetic Datum 1949");
+  public static final Datum OSEB36 = new Datum("OSGB36", 446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894, Ellipsoid.AIRY, "Airy 1830");
+
+  private String code;
+	private String name;
+	private Ellipsoid ellipsoid;
+	private double[] transform = DEFAULT_TRANSFORM;
+	
+  public Datum(String code, 
+      String transformSpec, 
+      Ellipsoid ellipsoid,
+      String name) {
+    // TODO: implement handling of transform specification
+    this(code, (double[]) null, ellipsoid, name);
+  }
+  
+  public Datum(String code, 
+      double deltaX, double deltaY, double deltaZ, 
+      Ellipsoid ellipsoid,
+      String name) {
+    this(code, new double[] { deltaX, deltaY, deltaZ },ellipsoid, name);
+  }
+  
+  public Datum(String code, 
+      double deltaX, double deltaY, double deltaZ,
+      double rx, double ry, double rz, double mbf,
+      Ellipsoid ellipsoid,
+      String name) {
+    this(code, new double[] { deltaX, deltaY, deltaZ, rx, ry, rx, mbf },ellipsoid, name);
+  }
+  
+  public Datum(String code, 
+      double[] transform, 
+      Ellipsoid ellipsoid,
+      String name) {
+    this.code = code;
+    this.name = name;
+    this.ellipsoid = ellipsoid;
+    if (transform != null)
+      this.transform = transform;
+  }
+  
+  public String getCode() { return code; }
+  
+  public String getName() { return name; }
+  
+  public String toString() { return "[Datum-" + name + "]"; }
+  
+  public Ellipsoid getEllipsoid()
+  {
+    return ellipsoid;
+  }
+  
+  public double[] getTransformToWGS84()
+  {
+    return transform;
+  }
+  
+  public int getTransformType()
+  {
+    if (transform  == null) return TYPE_WGS84;
+    
+    if (isZero(transform)) return TYPE_WGS84;
+    
+    if (transform.length  == 3) return TYPE_3PARAM;
+    if (transform.length  == 7) return TYPE_7PARAM;
+    return TYPE_WGS84;
+  }
+  
+  private static boolean isZero(double[] transform)
+  {
+    for (int i = 0; i < transform.length; i++) {
+      if (transform[i] != 0.0) return false;
+    }
+    return true;
+  }
+  
+  public boolean hasTransformToWGS84()
+  {
+    return getTransformType() == TYPE_3PARAM || getTransformType() == TYPE_7PARAM;
+  }
+  
+  public static final double ELLIPSOID_E2_TOLERANCE = 0.000000000050;
+  
+  /**
+   * Tests if this is equal to another {@link Datum}.
+   * <p>
+   * Datums are considered to be equal iff:
+   * <ul>
+   * <li>their transforms are equal
+   * <li>OR their ellipsoids are (approximately) equal
+   * </ul>
+   * 
+   * @param datum
+   * @return
+   */
+  public boolean isEqual(Datum datum)
+  {
+  	// false if tranforms are not equal
+    if( getTransformType() != datum.getTransformType()) {
+      return false; 
+    }
+    // false if ellipsoids are not (approximately) equal
+    if( ellipsoid.getEquatorRadius() != ellipsoid.getEquatorRadius()) {
+      if (Math.abs(ellipsoid.getEccentricitySquared() 
+           - datum.ellipsoid.getEccentricitySquared() )  > ELLIPSOID_E2_TOLERANCE)
+      return false;
+    } 
+    
+    // false if transform parameters are not identical
+    if( getTransformType() == TYPE_3PARAM || getTransformType() == TYPE_7PARAM) {
+      for (int i = 0; i < transform.length; i++) {
+        if (transform[i] != datum.transform[i])
+          return false;
+      }
+      return true;
+    } 
+    /* 
+     //TODO: complete
+    else if( this.datum_type == Proj4js.common.PJD_GRIDSHIFT ) {
+      return strcmp( pj_param(this.params,"snadgrids").s,
+                     pj_param(dest.params,"snadgrids").s ) == 0;
+    }
+    */ 
+    return true; // datums are equal
+
+  }
+
+  
+  public void transformFromGeocentricToWgs84(ProjCoordinate p) 
+  {
+    if( transform.length == 3 )
+    {
+      p.x += transform[0];
+      p.y += transform[1];
+      p.z += transform[2];
+
+    }
+    else if (transform.length == 7)
+    {
+      double Dx_BF = transform[0];
+      double Dy_BF = transform[1];
+      double Dz_BF = transform[2];
+      double Rx_BF = transform[3];
+      double Ry_BF = transform[4];
+      double Rz_BF = transform[5];
+      double M_BF  = transform[6];
+      
+      double x_out = M_BF*(       p.x - Rz_BF*p.y + Ry_BF*p.z) + Dx_BF;
+      double y_out = M_BF*( Rz_BF*p.x +       p.y - Rx_BF*p.z) + Dy_BF;
+      double z_out = M_BF*(-Ry_BF*p.x + Rx_BF*p.y +       p.z) + Dz_BF;
+
+      p.x = x_out;
+      p.y = y_out;
+      p.z = z_out;
+    }
+  }
+  public void transformToGeocentricFromWgs84(ProjCoordinate p) 
+  {
+    if( transform.length == 3 )
+    {
+      p.x -= transform[0];
+      p.y -= transform[1];
+      p.z -= transform[2];
+
+    }
+    else if (transform.length == 7)
+    {
+      double Dx_BF = transform[0];
+      double Dy_BF = transform[1];
+      double Dz_BF = transform[2];
+      double Rx_BF = transform[3];
+      double Ry_BF = transform[4];
+      double Rz_BF = transform[5];
+      double M_BF  = transform[6];
+      
+      double x_tmp = (p.x - Dx_BF) / M_BF;
+      double y_tmp = (p.y - Dy_BF) / M_BF;
+      double z_tmp = (p.z - Dz_BF) / M_BF;
+
+      p.x =        x_tmp + Rz_BF*y_tmp - Ry_BF*z_tmp;
+      p.y = -Rz_BF*x_tmp +       y_tmp + Rx_BF*z_tmp;
+      p.z =  Ry_BF*x_tmp - Rx_BF*y_tmp +       z_tmp;
+    }
+  }
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/datum/Ellipsoid.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/datum/Ellipsoid.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/datum/Ellipsoid.java	(revision 26409)
@@ -0,0 +1,380 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.osgeo.proj4j.datum;
+
+/**
+ * A class representing a geographic reference ellipsoid 
+ * (or more correctly an oblate spheroid), 
+ * used to model the shape of the surface of the earth.
+ * <p>
+ * An oblate spheroid is a geometric surface formed
+ * by the rotation of an ellipse about its minor axis.
+ * In geodesy this is used as a convenient approximation to the
+ * geoid, the true shape of the earth's surface.
+ * <p>
+ * An ellipsoid is defined by the following parameters:
+ * <ul>
+ * <li><i>a</i>, the equatorial radius or semi-major axis
+ * (see {@link #getA()})
+ * </ul>
+ * and one of:
+ * <ul>
+ * <li><i>b</i>, the polar radius or semi-minor axis 
+ * (see {@link #getB()})
+ * <li><i>f</i>, the reciprocal flattening
+ * (<i>f = (a - b) / a</i>)
+ * </ul>
+ * In order to be used as a model of the geoid,
+ * the exact positioning of an ellipsoid
+ * relative to the geoid surface needs to be specified.
+ * This is provided by means of a geodetic {@link Datum}.
+ * <p>
+ * Notable ellipsoids in common use include 
+ * {@link #CLARKE_1866}, {@link #GRS80}, and {@link #WGS84}.
+ *   
+ * @see Datum
+ */
+public class Ellipsoid implements Cloneable
+{
+
+  public String name;
+
+  public String shortName;
+
+  public double equatorRadius = 1.0;
+
+  public double poleRadius = 1.0;
+
+  public double eccentricity = 1.0;
+
+  public double eccentricity2 = 1.0;
+
+  // From: USGS PROJ package.
+  public final static Ellipsoid INTERNATIONAL = new Ellipsoid("intl",
+      6378388.0, 0.0, 297.0, "International 1909 (Hayford)");
+
+  public final static Ellipsoid BESSEL = new Ellipsoid("bessel", 6377397.155,
+      0.0, 299.1528128, "Bessel 1841");
+
+  public final static Ellipsoid CLARKE_1866 = new Ellipsoid("clrk66",
+      6378206.4, 6356583.8, 0.0, "Clarke 1866");
+
+  public final static Ellipsoid CLARKE_1880 = new Ellipsoid("clrk80",
+      6378249.145, 0.0, 293.4663, "Clarke 1880 mod.");
+
+  public final static Ellipsoid AIRY = new Ellipsoid("airy", 6377563.396,
+      6356256.910, 0.0, "Airy 1830");
+
+  public final static Ellipsoid WGS60 = new Ellipsoid("WGS60", 6378165.0, 0.0,
+      298.3, "WGS 60");
+
+  public final static Ellipsoid WGS66 = new Ellipsoid("WGS66", 6378145.0, 0.0,
+      298.25, "WGS 66");
+
+  public final static Ellipsoid WGS72 = new Ellipsoid("WGS72", 6378135.0, 0.0,
+      298.26, "WGS 72");
+
+  public final static Ellipsoid WGS84 = new Ellipsoid("WGS84", 6378137.0, 0.0,
+      298.257223563, "WGS 84");
+
+  public final static Ellipsoid KRASSOVSKY = new Ellipsoid("krass", 6378245.0,
+      0.0, 298.3, "Krassovsky, 1942");
+
+  public final static Ellipsoid EVEREST = new Ellipsoid("evrst30", 6377276.345,
+      0.0, 300.8017, "Everest 1830");
+
+  public final static Ellipsoid INTERNATIONAL_1967 = new Ellipsoid("new_intl",
+      6378157.5, 6356772.2, 0.0, "New International 1967");
+
+  public final static Ellipsoid GRS80 = new Ellipsoid("GRS80", 6378137.0, 0.0,
+      298.257222101, "GRS 1980 (IUGG, 1980)");
+
+  public final static Ellipsoid AUSTRALIAN = new Ellipsoid("australian",
+      6378160.0, 6356774.7, 298.25, "Australian");
+
+  public final static Ellipsoid MERIT = new Ellipsoid("MERIT", 6378137.0, 0.0,
+      298.257, "MERIT 1983");
+
+  public final static Ellipsoid SGS85 = new Ellipsoid("SGS85", 6378136.0, 0.0,
+      298.257, "Soviet Geodetic System 85");
+
+  public final static Ellipsoid IAU76 = new Ellipsoid("IAU76", 6378140.0, 0.0,
+      298.257, "IAU 1976");
+
+  public final static Ellipsoid APL4_9 = new Ellipsoid("APL4.9", 6378137.0,
+      0.0, 298.25, "Appl. Physics. 1965");
+
+  public final static Ellipsoid NWL9D = new Ellipsoid("NWL9D", 6378145.0, 0.0,
+      298.25, "Naval Weapons Lab., 1965");
+
+  public final static Ellipsoid MOD_AIRY = new Ellipsoid("mod_airy",
+      6377340.189, 6356034.446, 0.0, "Modified Airy");
+
+  public final static Ellipsoid ANDRAE = new Ellipsoid("andrae", 6377104.43,
+      0.0, 300.0, "Andrae 1876 (Den., Iclnd.)");
+
+  public final static Ellipsoid AUST_SA = new Ellipsoid("aust_SA", 6378160.0,
+      0.0, 298.25, "Australian Natl & S. Amer. 1969");
+
+  public final static Ellipsoid GRS67 = new Ellipsoid("GRS67", 6378160.0, 0.0,
+      298.2471674270, "GRS 67 (IUGG 1967)");
+
+  public final static Ellipsoid BESS_NAM = new Ellipsoid("bess_nam",
+      6377483.865, 0.0, 299.1528128, "Bessel 1841 (Namibia)");
+
+  public final static Ellipsoid CPM = new Ellipsoid("CPM", 6375738.7, 0.0,
+      334.29, "Comm. des Poids et Mesures 1799");
+
+  public final static Ellipsoid DELMBR = new Ellipsoid("delmbr", 6376428.0,
+      0.0, 311.5, "Delambre 1810 (Belgium)");
+
+  public final static Ellipsoid ENGELIS = new Ellipsoid("engelis", 6378136.05,
+      0.0, 298.2566, "Engelis 1985");
+
+  public final static Ellipsoid EVRST48 = new Ellipsoid("evrst48", 6377304.063,
+      0.0, 300.8017, "Everest 1948");
+
+  public final static Ellipsoid EVRST56 = new Ellipsoid("evrst56", 6377301.243,
+      0.0, 300.8017, "Everest 1956");
+
+  public final static Ellipsoid EVRTS69 = new Ellipsoid("evrst69", 6377295.664,
+      0.0, 300.8017, "Everest 1969");
+
+  public final static Ellipsoid EVRTSTSS = new Ellipsoid("evrstSS",
+      6377298.556, 0.0, 300.8017, "Everest (Sabah & Sarawak)");
+
+  public final static Ellipsoid FRSCH60 = new Ellipsoid("fschr60", 6378166.0,
+      0.0, 298.3, "Fischer (Mercury Datum) 1960");
+
+  public final static Ellipsoid FSRCH60M = new Ellipsoid("fschr60m", 6378155.0,
+      0.0, 298.3, "Modified Fischer 1960");
+
+  public final static Ellipsoid FSCHR68 = new Ellipsoid("fschr68", 6378150.0,
+      0.0, 298.3, "Fischer 1968");
+
+  public final static Ellipsoid HELMERT = new Ellipsoid("helmert", 6378200.0,
+      0.0, 298.3, "Helmert 1906");
+
+  public final static Ellipsoid HOUGH = new Ellipsoid("hough", 6378270.0, 0.0,
+      297.0, "Hough");
+
+  public final static Ellipsoid INTL = new Ellipsoid("intl", 6378388.0, 0.0,
+      297.0, "International 1909 (Hayford)");
+
+  public final static Ellipsoid KAULA = new Ellipsoid("kaula", 6378163.0, 0.0,
+      298.24, "Kaula 1961");
+
+  public final static Ellipsoid LERCH = new Ellipsoid("lerch", 6378139.0, 0.0,
+      298.257, "Lerch 1979");
+
+  public final static Ellipsoid MPRTS = new Ellipsoid("mprts", 6397300.0, 0.0,
+      191.0, "Maupertius 1738");
+
+  public final static Ellipsoid PLESSIS = new Ellipsoid("plessis", 6376523.0,
+      6355863.0, 0.0, "Plessis 1817 France)");
+
+  public final static Ellipsoid SEASIA = new Ellipsoid("SEasia", 6378155.0,
+      6356773.3205, 0.0, "Southeast Asia");
+
+  public final static Ellipsoid WALBECK = new Ellipsoid("walbeck", 6376896.0,
+      6355834.8467, 0.0, "Walbeck");
+
+  public final static Ellipsoid NAD27 = new Ellipsoid("NAD27", 6378249.145,
+      0.0, 293.4663, "NAD27: Clarke 1880 mod.");
+
+  public final static Ellipsoid NAD83 = new Ellipsoid("NAD83", 6378137.0, 0.0,
+      298.257222101, "NAD83: GRS 1980 (IUGG, 1980)");
+
+  public final static Ellipsoid SPHERE = new Ellipsoid("sphere", 6371008.7714,
+      6371008.7714, 0.0, "Sphere");
+
+  public final static Ellipsoid[] ellipsoids = { 
+    BESSEL, 
+    CLARKE_1866,
+    CLARKE_1880, 
+    AIRY, 
+    WGS60, 
+    WGS66, 
+    WGS72, 
+    WGS84, 
+    KRASSOVSKY, 
+    EVEREST,
+    INTERNATIONAL_1967, 
+    GRS80, 
+    AUSTRALIAN, 
+    MERIT, 
+    SGS85, 
+    IAU76, 
+    APL4_9,
+    NWL9D, 
+    MOD_AIRY, 
+    ANDRAE, 
+    AUST_SA, 
+    GRS67, 
+    BESS_NAM, 
+    CPM, 
+    DELMBR, 
+    ENGELIS,
+    EVRST48, 
+    EVRST56, 
+    EVRTS69, 
+    EVRTSTSS, 
+    FRSCH60, 
+    FSRCH60M, 
+    FSCHR68, 
+    HELMERT,
+    HOUGH, 
+    INTL, 
+    KAULA, 
+    LERCH, 
+    MPRTS, 
+    PLESSIS, 
+    SEASIA, 
+    WALBECK, 
+    NAD27, 
+    NAD83,
+    SPHERE };
+
+  public Ellipsoid()
+  {
+  }
+
+  /**
+   * Creates a new Ellipsoid. 
+   * One of of poleRadius or reciprocalFlattening must
+   * be specified, the other must be zero
+   */
+  public Ellipsoid(String shortName, double equatorRadius, double poleRadius,
+      double reciprocalFlattening, String name)
+  {
+    this.shortName = shortName;
+    this.name = name;
+    this.equatorRadius = equatorRadius;
+    this.poleRadius = poleRadius;
+
+    if (poleRadius == 0.0 && reciprocalFlattening == 0.0)
+      throw new IllegalArgumentException(
+          "One of poleRadius or reciprocalFlattening must be specified");
+    // don't check for only one of poleRadius or reciprocalFlattening to be
+    // specified,
+    // since some defs actually supply two
+
+    // reciprocalFlattening takes precedence over poleRadius
+    if (reciprocalFlattening != 0) {
+      double flattening = 1.0 / reciprocalFlattening;
+      double f = flattening;
+      eccentricity2 = 2 * f - f * f;
+      this.poleRadius = equatorRadius * Math.sqrt(1.0 - eccentricity2);
+    }
+    else {
+      eccentricity2 = 1.0 - (poleRadius * poleRadius)
+          / (equatorRadius * equatorRadius);
+    }
+    eccentricity = Math.sqrt(eccentricity2);
+  }
+
+  public Ellipsoid(String shortName, double equatorRadius,
+      double eccentricity2, String name)
+  {
+    this.shortName = shortName;
+    this.name = name;
+    this.equatorRadius = equatorRadius;
+    setEccentricitySquared(eccentricity2);
+  }
+
+  public Object clone()
+  {
+    try {
+      Ellipsoid e = (Ellipsoid) super.clone();
+      return e;
+    }
+    catch (CloneNotSupportedException e) {
+      throw new InternalError();
+    }
+  }
+
+  public void setName(String name)
+  {
+    this.name = name;
+  }
+
+  public String getName()
+  {
+    return name;
+  }
+
+  public void setShortName(String shortName)
+  {
+    this.shortName = shortName;
+  }
+
+  public String getShortName()
+  {
+    return shortName;
+  }
+
+  public void setEquatorRadius(double equatorRadius)
+  {
+    this.equatorRadius = equatorRadius;
+  }
+
+  public double getEquatorRadius()
+  {
+    return equatorRadius;
+  }
+
+  public double getA()
+  {
+    return equatorRadius;
+  }
+
+  public double getB()
+  {
+    return poleRadius;
+  }
+
+  public void setEccentricitySquared(double eccentricity2)
+  {
+    this.eccentricity2 = eccentricity2;
+    poleRadius = equatorRadius * Math.sqrt(1.0 - eccentricity2);
+    eccentricity = Math.sqrt(eccentricity2);
+  }
+
+  public double getEccentricitySquared()
+  {
+    return eccentricity2;
+  }
+
+  public boolean isEqual(Ellipsoid e)
+  {
+    return equatorRadius == e.equatorRadius && eccentricity2 == e.eccentricity2;
+  }
+
+  public boolean isEqual(Ellipsoid e, double e2Tolerance)
+  {
+    if (equatorRadius != e.equatorRadius) return false; 
+    if (Math.abs(eccentricity2 
+        - e.eccentricity2 ) > e2Tolerance) return false;
+    return true;
+  }
+
+  public String toString()
+  {
+    return name;
+  }
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/datum/GeocentricConverter.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/datum/GeocentricConverter.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/datum/GeocentricConverter.java	(revision 26409)
@@ -0,0 +1,221 @@
+package org.osgeo.proj4j.datum;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+/**
+ *  Provides conversions between Geodetic coordinates 
+ *  (latitude, longitude in radians and height in meters) 
+ *  and Geocentric coordinates
+ *  (X, Y, Z) in meters.
+ *  <p>
+ *  Provenance: Ported from GEOCENTRIC by the U.S. Army Topographic Engineering Center via PROJ.4
+ *    
+ * @author Martin Davis
+ *
+ */
+public class GeocentricConverter 
+{
+  /*
+   * 
+   * REFERENCES
+   *    
+   *    An Improved Algorithm for Geocentric to Geodetic Coordinate Conversion,
+   *    Ralph Toms, February 1996  UCRL-JC-123138.
+   *    
+   *    Further information on GEOCENTRIC can be found in the Reuse Manual.
+   *
+   *    GEOCENTRIC originated from : U.S. Army Topographic Engineering Center
+   *                                 Geospatial Information Division
+   *                                 7701 Telegraph Road
+   *                                 Alexandria, VA  22310-3864
+   *
+   * LICENSES
+   *
+   *    None apply to this component.
+   *
+   * RESTRICTIONS
+   *
+   *    GEOCENTRIC has no restrictions.
+   */
+
+  double a;
+  double b;
+  double a2;
+  double b2;
+  double e2;
+  double ep2;
+  
+  public GeocentricConverter(Ellipsoid ellipsoid) {
+    this(ellipsoid.getA(), ellipsoid.getB());
+  }
+  public GeocentricConverter(double a, double b) {
+    this.a = a;
+    this.b = b;
+    a2 = a * a;
+    b2 = b * b;
+    e2 = (a2 - b2) / a2;
+    ep2 = (a2 - b2) / b2;
+  }
+
+  /**
+   * Converts geodetic coordinates
+   * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z),
+   * according to the current ellipsoid parameters.
+   *
+   *    Latitude  : Geodetic latitude in radians                     (input)
+   *    Longitude : Geodetic longitude in radians                    (input)
+   *    Height    : Geodetic height, in meters                       (input)
+   *    
+   *    X         : Calculated Geocentric X coordinate, in meters    (output)
+   *    Y         : Calculated Geocentric Y coordinate, in meters    (output)
+   *    Z         : Calculated Geocentric Z coordinate, in meters    (output)
+   *
+   */
+  public void convertGeodeticToGeocentric(ProjCoordinate p)
+  {
+    double Longitude = p.x;
+    double Latitude = p.y;
+    double Height = p.hasValidZOrdinate() ? p.z : 0;   //Z value not always supplied
+    double X;  // output
+    double Y;
+    double Z;
+
+    double Rn;            /*  Earth radius at location  */
+    double Sin_Lat;       /*  Math.sin(Latitude)  */
+    double Sin2_Lat;      /*  Square of Math.sin(Latitude)  */
+    double Cos_Lat;       /*  Math.cos(Latitude)  */
+
+    /*
+    ** Don't blow up if Latitude is just a little out of the value
+    ** range as it may just be a rounding issue.  Also removed longitude
+    ** test, it should be wrapped by Math.cos() and Math.sin().  NFW for PROJ.4, Sep/2001.
+    */
+    if( Latitude < -ProjectionMath.HALFPI && Latitude > -1.001 * ProjectionMath.HALFPI ) {
+        Latitude = -ProjectionMath.HALFPI;
+    } else if( Latitude > ProjectionMath.HALFPI && Latitude < 1.001 * ProjectionMath.HALFPI ) {
+        Latitude = ProjectionMath.HALFPI;
+    } else if ((Latitude < -ProjectionMath.HALFPI) || (Latitude > ProjectionMath.HALFPI)) {
+      /* Latitude out of range */
+      throw new IllegalStateException("Latitude is out of range: " + Latitude);
+    }
+
+    if (Longitude > ProjectionMath.PI) Longitude -= (2*ProjectionMath.PI);
+    Sin_Lat = Math.sin(Latitude);
+    Cos_Lat = Math.cos(Latitude);
+    Sin2_Lat = Sin_Lat * Sin_Lat;
+    Rn = a / (Math.sqrt(1.0e0 - e2 * Sin2_Lat));
+    X = (Rn + Height) * Cos_Lat * Math.cos(Longitude);
+    Y = (Rn + Height) * Cos_Lat * Math.sin(Longitude);
+    Z = ((Rn * (1 - e2)) + Height) * Sin_Lat;
+
+    p.x = X;
+    p.y = Y;
+    p.z = Z;
+  }
+  
+  public void convertGeocentricToGeodetic(ProjCoordinate p)
+  {
+    convertGeocentricToGeodeticIter(p);
+  }
+    
+  public void convertGeocentricToGeodeticIter(ProjCoordinate p)
+  {
+  	/* local defintions and variables */
+  	/* end-criterium of loop, accuracy of sin(Latitude) */
+  	double genau = 1.E-12;
+  	double genau2 = (genau*genau);
+  	int maxiter = 30;
+
+  	double P;        /* distance between semi-minor axis and location */
+  	double RR;       /* distance between center and location */
+  	double CT;       /* sin of geocentric latitude */
+  	double ST;       /* cos of geocentric latitude */
+  	double RX;
+  	double RK;
+  	double RN;       /* Earth radius at location */
+  	double CPHI0;    /* cos of start or old geodetic latitude in iterations */
+  	double SPHI0;    /* sin of start or old geodetic latitude in iterations */
+  	double CPHI;     /* cos of searched geodetic latitude */
+  	double SPHI;     /* sin of searched geodetic latitude */
+  	double SDPHI;    /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */
+  	boolean At_Pole;     /* indicates location is in polar region */
+  	int iter;        /* # of continous iteration, max. 30 is always enough (s.a.) */
+
+  	double X = p.x;
+  	double Y = p.y;
+  	double Z = p.hasValidZOrdinate() ? p.z : 0;   //Z value not always supplied
+  	double Longitude;
+  	double Latitude;
+  	double Height;
+
+  	At_Pole = false;
+  	P = Math.sqrt(X*X+Y*Y);
+  	RR = Math.sqrt(X*X+Y*Y+Z*Z);
+
+  	/*      special cases for latitude and longitude */
+  	if (P/this.a < genau) {
+
+  		/*  special case, if P=0. (X=0., Y=0.) */
+  		At_Pole = true;
+  		Longitude = 0.0;
+
+  		/*  if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis
+  		 *  of ellipsoid (=center of mass), Latitude becomes PI/2 */
+  		if (RR/this.a < genau) {
+  			Latitude = ProjectionMath.HALFPI;
+  			Height   = -this.b;
+  			return;
+  		}
+  	} else {
+  		/*  ellipsoidal (geodetic) longitude
+  		 *  interval: -PI < Longitude <= +PI */
+  		Longitude=Math.atan2(Y,X);
+  	}
+
+  	/* --------------------------------------------------------------
+  	 * Following iterative algorithm was developped by
+  	 * "Institut für Erdmessung", University of Hannover, July 1988.
+  	 * Internet: www.ife.uni-hannover.de
+  	 * Iterative computation of CPHI,SPHI and Height.
+  	 * Iteration of CPHI and SPHI to 10**-12 radian resp.
+  	 * 2*10**-7 arcsec.
+  	 * --------------------------------------------------------------
+  	 */
+  	CT = Z/RR;
+  	ST = P/RR;
+  	RX = 1.0/Math.sqrt(1.0-this.e2*(2.0-this.e2)*ST*ST);
+  	CPHI0 = ST*(1.0-this.e2)*RX;
+  	SPHI0 = CT*RX;
+  	iter = 0;
+
+  	/* loop to find sin(Latitude) resp. Latitude
+  	 * until |sin(Latitude(iter)-Latitude(iter-1))| < genau */
+  	do
+  	{
+  		iter++;
+  		RN = this.a/Math.sqrt(1.0-this.e2*SPHI0*SPHI0);
+
+  		/*  ellipsoidal (geodetic) height */
+  		Height = P*CPHI0+Z*SPHI0-RN*(1.0-this.e2*SPHI0*SPHI0);
+
+  		RK = this.e2*RN/(RN+Height);
+  		RX = 1.0/Math.sqrt(1.0-RK*(2.0-RK)*ST*ST);
+  		CPHI = ST*(1.0-RK)*RX;
+  		SPHI = CT*RX;
+  		SDPHI = SPHI*CPHI0-CPHI*SPHI0;
+  		CPHI0 = CPHI;
+  		SPHI0 = SPHI;
+  	}
+  	while (SDPHI*SDPHI > genau2 && iter < maxiter);
+
+  	/*      ellipsoidal (geodetic) latitude */
+  	Latitude=Math.atan(SPHI/Math.abs(CPHI));
+
+  	p.x = Longitude;
+  	p.y = Latitude;
+  	p.z = Height;
+  }
+  
+  //TODO: port non-iterative algorithm????
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/io/CSVRecordParser.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/io/CSVRecordParser.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/io/CSVRecordParser.java	(revision 26409)
@@ -0,0 +1,210 @@
+package org.osgeo.proj4j.io;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Parses a single record in a CSV file into an array of {@link String}s.
+ * 
+ * 
+ * @author Martin Davis
+ *
+ */
+public class CSVRecordParser 
+{
+  private static final int CH_QUOTE = 1;
+  private static final int CH_WHITESPACE = 2;
+  private static final int CH_DATA = 3;
+  private static final int CH_SEPARATOR = 4;
+  private static final int CH_EOL = 5;
+
+  private static final int STATE_DATA = 1;
+  private static final int STATE_BEFORE = 2;
+  private static final int STATE_QUOTED_DATA = 3;
+  private static final int STATE_SEEN_QUOTE = 4;
+  private static final int STATE_AFTER = 5;
+  
+  private static final String[] strArrayType = new String[0];
+  
+  private char quote = '"';
+  private char separator = ',';
+  
+  private int loc = 0;
+  
+  /**
+   * Controls whether the parsing strictly follows the CSV specification.
+   * If not in strict mode:
+   * <ul>
+   * <li>quotes which occur in the middle of fields are simply scanned as data
+   * </ul>
+   */
+  private boolean isStrictMode = false;
+  
+  /**
+   * Creates a new parser.
+   *
+   */
+  public CSVRecordParser() {
+  }
+
+  /**
+   * Parses a single record of a CSV file.
+   * 
+   * @param record
+   * @return an array of the fields in the record
+   * @throws IllegalArgumentException if the parsing of a field fails
+   */
+  public String[] parse(String record)
+  {
+    loc = 0;
+    List vals = new ArrayList();
+    int lineLen = record.length();
+    while (loc < lineLen) {
+      vals.add(parseField(record));
+    }
+    return (String[]) vals.toArray(strArrayType);
+  }
+  
+  private String parseField(String line)
+  {
+    StringBuffer data = new StringBuffer();
+    
+    int state = STATE_BEFORE;
+    while (true) {
+      int category = CH_EOL;
+      if (loc < line.length())
+        category = categorize(line.charAt(loc));
+      
+      switch (state) {
+      case STATE_BEFORE:
+        switch (category) {
+        case CH_WHITESPACE:
+          loc++;  
+          break;
+        case CH_QUOTE:
+          loc++;
+          state = STATE_QUOTED_DATA;
+          break;
+        case CH_SEPARATOR:
+          loc++;
+          return "";
+        case CH_DATA:
+          data.append(line.charAt(loc));
+          state = STATE_DATA;
+          loc++;
+          break;
+        case CH_EOL:
+          return null;
+        }
+        break;
+      case STATE_DATA:
+        switch (category) {
+        case CH_SEPARATOR:
+        case CH_EOL:
+          loc++;
+          return data.toString();
+        case CH_QUOTE:
+          if (isStrictMode) {
+            throw new IllegalArgumentException("Malformed field - quote not at beginning of field");
+          }
+          else {
+            data.append(line.charAt(loc));
+            loc++;
+          }
+          break;
+        case CH_WHITESPACE:
+        case CH_DATA:
+          data.append(line.charAt(loc));
+          loc++;
+          break;
+        }
+        break;
+      case STATE_QUOTED_DATA:
+        switch (category) {
+        case CH_QUOTE:
+          loc++;
+          state = STATE_SEEN_QUOTE;
+          break;
+        case CH_SEPARATOR:
+        case CH_WHITESPACE:
+        case CH_DATA:
+          data.append(line.charAt(loc));
+          loc++;
+          break;
+        case CH_EOL:
+          return data.toString();
+        }
+        break;
+      case STATE_SEEN_QUOTE:
+        switch (category) {
+        case CH_QUOTE:
+          // double quote - add to value
+          loc++;
+          data.append('"');
+          state = STATE_QUOTED_DATA;
+          break;
+        case CH_SEPARATOR:
+        case CH_EOL:
+          // at end of field
+          loc++;
+          return data.toString();
+        case CH_WHITESPACE:
+          loc++;
+          state = STATE_AFTER;
+          break;
+        case CH_DATA:
+          throw new IllegalArgumentException("Malformed field - quote not at end of field");
+        }
+        break;
+      case STATE_AFTER:
+        switch (category) {
+        case CH_QUOTE:
+          throw new IllegalArgumentException("Malformed field - unexpected quote");
+        case CH_EOL:
+        case CH_SEPARATOR:
+          // at end of field
+          loc++;
+          return data.toString();
+        case CH_WHITESPACE:
+          // skip trailing whitespace
+          loc++;
+          break;
+        case CH_DATA:
+          throw new IllegalArgumentException("Malformed field - unexpected data after quote");
+        }
+      
+      }
+    }
+  }
+  
+  /**
+   * Categorizes a character into a lexical category.
+   * 
+   * @param c the character to categorize
+   * @return the lexical category
+   */
+  private int categorize(char c) {
+    switch (c) {
+    case ' ':
+    case '\r':
+    case 0xff:
+    case '\n':
+      return CH_WHITESPACE;
+    default:
+      if (c == quote) {
+        return CH_QUOTE;
+      } else if (c == separator) {
+        return CH_SEPARATOR;
+      }
+      else if ('!' <= c && c <= '~') {
+        return CH_DATA;
+      } else if (0x00 <= c && c <= 0x20) {
+        return CH_WHITESPACE;
+      } else if (Character.isWhitespace(c)) {
+        return CH_WHITESPACE;
+      } else {
+        return CH_DATA;
+      }
+    }
+  }
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/io/MetaCRSTestCase.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/io/MetaCRSTestCase.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/io/MetaCRSTestCase.java	(revision 26409)
@@ -0,0 +1,187 @@
+package org.osgeo.proj4j.io;
+
+import java.io.*;
+import org.osgeo.proj4j.*;
+import org.osgeo.proj4j.util.*;
+
+public class MetaCRSTestCase 
+{
+	private static final CoordinateTransformFactory ctFactory = new CoordinateTransformFactory();
+	
+  private boolean verbose = true;
+  
+  String testName;
+  String testMethod;
+  
+  String srcCrsAuth;
+  String srcCrs;
+  
+  String tgtCrsAuth;
+  String tgtCrs;
+  
+  double srcOrd1;
+  double srcOrd2;
+  double srcOrd3;
+  
+  double tgtOrd1;
+  double tgtOrd2;
+  double tgtOrd3;
+  
+  double tolOrd1;
+  double tolOrd2;
+  double tolOrd3;
+  
+  String using;
+  String dataSource;
+  String dataCmnts;
+  String maintenanceCmnts;
+
+  CoordinateReferenceSystem srcCS;
+  CoordinateReferenceSystem tgtCS;
+
+  ProjCoordinate srcPt = new ProjCoordinate();
+  ProjCoordinate resultPt = new ProjCoordinate();
+
+  private boolean isInTol;
+  private CRSCache crsCache = null;
+  
+  public MetaCRSTestCase(
+      String testName,
+      String testMethod,
+      String srcCrsAuth,
+      String srcCrs,
+      String tgtCrsAuth,
+      String tgtCrs,
+      double srcOrd1,
+      double srcOrd2,
+      double srcOrd3,
+      double tgtOrd1,
+      double tgtOrd2,
+      double tgtOrd3,
+      double tolOrd1,
+      double tolOrd2,
+      double tolOrd3,
+      String using,
+      String dataSource,
+      String dataCmnts,
+      String maintenanceCmnts
+  )
+  {
+    this.testName = testName;
+    this.testMethod = testMethod;
+    this.srcCrsAuth = srcCrsAuth;
+    this.srcCrs = srcCrs;
+    this.tgtCrsAuth = tgtCrsAuth;
+    this.tgtCrs = tgtCrs;
+    this.srcOrd1 = srcOrd1;
+    this.srcOrd2 = srcOrd2;
+    this.srcOrd3 = srcOrd3;
+    this.tgtOrd1 = tgtOrd1;
+    this.tgtOrd2 = tgtOrd2;
+    this.tgtOrd3 = tgtOrd3;
+    this.tolOrd1 = tolOrd1;
+    this.tolOrd2 = tolOrd2;
+    this.tolOrd3 = tolOrd3;
+    this.using = using;
+    this.dataSource = dataSource;
+    this.dataCmnts = dataCmnts;
+    this.maintenanceCmnts = maintenanceCmnts;
+  }
+
+  public String getName() { return testName; }
+  
+  public String getSourceCrsName() { return csName(srcCrsAuth, srcCrs); }
+  
+  public String getTargetCrsName() { return csName(tgtCrsAuth, tgtCrs); }
+  
+  public CoordinateReferenceSystem getSourceCS() { return srcCS; }
+  
+  public CoordinateReferenceSystem getTargetCS() { return tgtCS; }
+  
+  public ProjCoordinate getSourceCoordinate()
+  {
+    return new ProjCoordinate(srcOrd1, srcOrd2, srcOrd3);
+  }
+  
+  public ProjCoordinate getTargetCoordinate()
+  {
+    return new ProjCoordinate(tgtOrd1, tgtOrd2, tgtOrd3);
+  }
+  
+  public ProjCoordinate getResultCoordinate()
+  {
+    return new ProjCoordinate(resultPt.x, resultPt.y);
+  }
+  
+  public void setCache(CRSCache crsCache)
+  {
+    this.crsCache = crsCache;
+  }
+  
+  public boolean execute(CRSFactory csFactory)
+  {
+    boolean isOK = false;
+    srcCS = createCS(csFactory, srcCrsAuth, srcCrs);
+    tgtCS = createCS(csFactory, tgtCrsAuth, tgtCrs);
+    isOK = executeTransform(srcCS, tgtCS);
+    return isOK;
+  }
+  
+  public static String csName(String auth, String code)
+  {
+    return auth + ":" + code;
+  }
+  
+  public CoordinateReferenceSystem createCS(CRSFactory csFactory, String auth, String code)
+  {
+    String name = csName(auth, code);
+    
+    if (crsCache != null) {
+      return crsCache.createFromName(name);
+    }
+    CoordinateReferenceSystem cs = csFactory.createFromName(name);
+    return cs;
+  }
+  
+  private boolean executeTransform(
+      CoordinateReferenceSystem srcCS,
+      CoordinateReferenceSystem tgtCS)
+  {
+    srcPt.x = srcOrd1;
+    srcPt.y = srcOrd2;
+    // Testing: flip axis order to test SS sample file
+    //srcPt.x = srcOrd2;
+    //srcPt.y = srcOrd1;
+    
+    CoordinateTransform trans = ctFactory.createTransform(srcCS, tgtCS);
+
+    trans.transform(srcPt, resultPt);
+    
+    double dx = Math.abs(resultPt.x - tgtOrd1);
+    double dy = Math.abs(resultPt.y - tgtOrd2);
+    
+    isInTol =  dx <= tolOrd1 && dy <= tolOrd2;
+
+    return isInTol;
+  }
+
+  public void print(PrintStream os)
+  {
+      System.out.println(testName);
+      System.out.println(ProjectionUtil.toString(srcPt) 
+          + " -> " + ProjectionUtil.toString(resultPt)
+          + " ( expected: " + tgtOrd1 + ", " + tgtOrd2 + " )"
+          );
+
+    
+    if (! isInTol) {
+      System.out.println("FAIL");
+      System.out.println("Src CRS: (" 
+          + srcCrsAuth + ":" + srcCrs + ") " 
+          + srcCS.getParameterString());
+      System.out.println("Tgt CRS: ("
+          + tgtCrsAuth + ":" + tgtCrs + ") " 
+          + tgtCS.getParameterString());
+    }
+  }
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/io/MetaCRSTestFileReader.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/io/MetaCRSTestFileReader.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/io/MetaCRSTestFileReader.java	(revision 26409)
@@ -0,0 +1,114 @@
+package org.osgeo.proj4j.io;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Reads a file in MetaCRS Test format
+ * into a list of {@link MetaCRSTestCase}.
+ * This format is a CSV file with a standard set of columns.
+ * Each record defines a transformation from one coordinate system
+ * to another.
+ * For full details on the file format, see http://trac.osgeo.org/metacrs/
+ * 
+ * @author Martin Davis
+ *
+ */
+public class MetaCRSTestFileReader 
+{
+  public static final int COL_COUNT = 19;
+  
+  private File file;
+  private CSVRecordParser lineParser = new CSVRecordParser();
+  
+  public MetaCRSTestFileReader(File file) 
+  {
+    this.file = file;
+  }
+
+  public List<MetaCRSTestCase> readTests()
+  throws IOException
+  {
+    LineNumberReader lineReader = new LineNumberReader(new FileReader(file));
+    List<MetaCRSTestCase> tests = null;
+    try {
+       tests = parseFile(lineReader);
+    } 
+    finally {
+      lineReader.close();
+    }
+    return tests;
+  }
+  
+  private List<MetaCRSTestCase> parseFile(LineNumberReader lineReader)
+  throws IOException
+  {
+    List<MetaCRSTestCase> tests = new ArrayList<MetaCRSTestCase>();
+    boolean isHeaderRead = false;
+    while (true) {
+      String line = lineReader.readLine();
+      if (line == null)
+        break;
+      // skip comments
+      if (line.startsWith("#"))
+        continue;
+      // skip header
+      if (! isHeaderRead) {
+        // TODO: validate header line to have correct set of columns
+        isHeaderRead = true;
+        continue;
+      }
+      tests.add(parseTest(line));
+    }
+    return tests;
+  }
+  
+  private MetaCRSTestCase parseTest(String line)
+  {
+    String[] cols = lineParser.parse(line);
+    if (cols.length != COL_COUNT)
+      throw new IllegalStateException("Expected " + COL_COUNT+ " columns in file, but found " + cols.length);
+    String testName    = cols[0];
+    String testMethod  = cols[1];
+    String srcCrsAuth  = cols[2];
+    String srcCrs      = cols[3];
+    String tgtCrsAuth  = cols[4];
+    String tgtCrs      = cols[5];
+    double srcOrd1     = parseNumber(cols[6]);
+    double srcOrd2     = parseNumber(cols[7]);
+    double srcOrd3     = parseNumber(cols[8]);
+    double tgtOrd1     = parseNumber(cols[9]);
+    double tgtOrd2     = parseNumber(cols[10]);
+    double tgtOrd3     = parseNumber(cols[11]);
+    double tolOrd1     = parseNumber(cols[12]);
+    double tolOrd2     = parseNumber(cols[13]);
+    double tolOrd3     = parseNumber(cols[14]);
+    String using       = cols[15];
+    String dataSource  = cols[16];
+    String dataCmnts   = cols[17];
+    String maintenanceCmnts = cols[18];
+    
+    return new MetaCRSTestCase(testName,testMethod,srcCrsAuth,srcCrs,tgtCrsAuth,tgtCrs,srcOrd1,srcOrd2,srcOrd3,tgtOrd1,tgtOrd2,tgtOrd3,tolOrd1,tolOrd2,tolOrd3,using,dataSource,dataCmnts,maintenanceCmnts);
+  }
+  
+  /**
+   * Parses a number from a String.
+   * If the string is empty returns {@link Double.Nan}.
+   * 
+   * @param numStr
+   * @return the number as a double
+   * @return Double.NaN if the string is null or empty
+   * @throws NumberFormatException if the number is ill-formed
+   */
+  private static double parseNumber(String numStr)
+  {
+    if (numStr == null || numStr.length() == 0) {
+      return Double.NaN;
+    }
+    return Double.parseDouble(numStr);
+  }
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/io/Proj4FileReader.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/io/Proj4FileReader.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/io/Proj4FileReader.java	(revision 26409)
@@ -0,0 +1,143 @@
+package org.osgeo.proj4j.io;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StreamTokenizer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Proj4FileReader 
+{
+
+  public Proj4FileReader() {
+    super();
+  }
+
+  public String[] readFile( String file, String name ) 
+  throws IOException 
+  {
+    // TODO: read comment preceding CS string as CS description
+    // TODO: use simpler parser than StreamTokenizer for speed and flexibility
+    // TODO: parse CSes line-at-a-time (this allows preserving CS param string for later access)
+    
+  	String filename = "/nad/" + file.toLowerCase();
+  	InputStream inStr = Proj4FileReader.class.getResourceAsStream( filename );
+  	if (inStr == null) {
+  		throw new IllegalStateException("Unable to access resource " + filename);
+  	}
+    BufferedReader reader = new BufferedReader( 
+          new InputStreamReader(inStr) );
+    String[] args;
+    try {
+      args = readFile(reader, name);
+    }
+    finally {
+      if (reader != null)
+        reader.close();
+    }
+    return args;
+  }
+  
+  private String[] readFile( BufferedReader reader, String name) 
+  throws IOException 
+  {
+    StreamTokenizer t = new StreamTokenizer( reader );
+    t.commentChar( '#' );
+    t.ordinaryChars( '0', '9' );
+    t.ordinaryChars( '.', '.' );
+    t.ordinaryChars( '-', '-' );
+    t.ordinaryChars( '+', '+' );
+    t.wordChars( '0', '9' );
+    t.wordChars( '\'', '\'' );
+    t.wordChars( '"', '"' );
+    t.wordChars( '_', '_' );
+    t.wordChars( '.', '.' );
+    t.wordChars( '-', '-' );
+    t.wordChars( '+', '+' );
+    t.wordChars( ',', ',' );
+    t.wordChars( '@', '@' );
+    t.nextToken();
+    while ( t.ttype == '<' ) {
+      t.nextToken();
+      if ( t.ttype != StreamTokenizer.TT_WORD ) 
+        throw new IOException( t.lineno()+": Word expected after '<'" );
+      String cname = t.sval;
+      t.nextToken();
+      if ( t.ttype != '>' )
+        throw new IOException( t.lineno()+": '>' expected" );
+      t.nextToken();
+      List v = new ArrayList();
+
+      while ( t.ttype != '<' ) {
+        if ( t.ttype == '+' )
+          t.nextToken();
+        if ( t.ttype != StreamTokenizer.TT_WORD ) 
+          throw new IOException( t.lineno()+": Word expected after '+'" );
+        String key = t.sval;
+        t.nextToken();
+        
+
+        // parse =arg, if any
+        if ( t.ttype == '=' ) {
+          t.nextToken();
+          //Removed check to allow for proj4 hack +nadgrids=@null 
+          //if ( t.ttype != StreamTokenizer.TT_WORD ) 
+          //  throw new IOException( t.lineno()+": Value expected after '='" );
+          String value = t.sval;
+          t.nextToken();
+          addParam(v, key, value);
+        }
+        else {
+          // add param with no value
+          addParam(v, key, null);
+        }
+      }
+      t.nextToken();
+      if ( t.ttype != '>' )
+        throw new IOException( t.lineno()+": '<>' expected" );
+      t.nextToken();
+      if ( cname.equals( name ) ) {
+        String[] args = (String[]) v.toArray( new String[0] );
+        return args;
+      }
+    }
+    return null;
+  }
+  
+  private static void addParam(List v, String key, String value)
+  {
+    String plusKey = key;
+    if ( ! key.startsWith("+") )
+      plusKey = "+" + key;
+    
+    if (value != null)
+      v.add( plusKey+"="+value );
+    else 
+      v.add(plusKey);
+
+
+  }
+  public String[] getParameters(String name) {
+    try {
+      int p = name.indexOf(':');
+      if (p >= 0)
+        return readFile(name.substring(0, p), name.substring(p + 1));
+      
+      /*
+       // not sure this is needed or a good idea
+        String[] files = { "world", "nad83", "nad27", "esri", "epsg", };
+      for (int i = 0; i < files.length; i++) {
+        Projection projection = readProjectionFile(files[i], name);
+        if (projection != null)
+          return projection;
+      }
+      */
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+    return null;
+  }
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/DatumParameters.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/DatumParameters.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/DatumParameters.java	(revision 26409)
@@ -0,0 +1,131 @@
+package org.osgeo.proj4j.parser;
+
+import org.osgeo.proj4j.CoordinateReferenceSystem;
+import org.osgeo.proj4j.datum.Datum;
+import org.osgeo.proj4j.datum.Ellipsoid;
+
+/**
+ * Contains the parsed/computed parameter values 
+ * which are used to create 
+ * the datum and ellipsoid for a {@link CoordinateReferenceSystem}.
+ * This class also implements the policies for 
+ * which parameters take precedence
+ * when multiple inconsisent ones are present.
+ * 
+ * @author Martin Davis
+ *
+ */
+public class DatumParameters 
+{
+  // TODO: check for inconsistent datum and ellipsoid (some PROJ4 cs specify both - not sure why)
+
+  private final static double SIXTH = .1666666666666666667; /* 1/6 */
+  private final static double RA4 = .04722222222222222222; /* 17/360 */
+  private final static double RA6 = .02215608465608465608; /* 67/3024 */
+  private final static double RV4 = .06944444444444444444; /* 5/72 */
+  private final static double RV6 = .04243827160493827160; /* 55/1296 */
+
+  private Datum datum = null;
+  private double[] datumTransform = null;
+  
+  private Ellipsoid ellipsoid;
+  private double a = Double.NaN;
+  private double es = Double.NaN;
+
+  public DatumParameters() {
+    // Default datum is WGS84
+//    setDatum(Datum.WGS84);
+  }
+
+  public Datum getDatum()
+  {
+    if (datum != null)
+      return datum;
+    // if no ellipsoid was specified, return WGS84 as the default
+    if (ellipsoid == null && ! isDefinedExplicitly()) {
+      return Datum.WGS84;
+    }
+    // if ellipsoid was WGS84, return that datum
+    if (ellipsoid == Ellipsoid.WGS84)
+      return Datum.WGS84;
+    
+    // otherwise, return a custom datum with the specified ellipsoid
+    return new Datum("User", datumTransform, getEllipsoid(), "User-defined");
+  }
+  
+  private boolean isDefinedExplicitly()
+  {
+    return ! (Double.isNaN(a) || Double.isNaN(es));
+  }
+  
+  public Ellipsoid getEllipsoid()
+  {
+    if (ellipsoid != null)
+        return ellipsoid;
+    return new Ellipsoid("user", a, es, "User-defined");
+  }
+  
+  public void setDatumTransform(double[] datumTransform)
+  {
+    this.datumTransform = datumTransform;
+    // force new Datum to be created
+    datum = null;
+  }
+  
+  public void setDatum(Datum datum)
+  {
+    this.datum = datum;
+  }
+  
+  public void setEllipsoid(Ellipsoid ellipsoid)
+  {
+    this.ellipsoid = ellipsoid;
+    es = ellipsoid.eccentricity2;
+    a = ellipsoid.equatorRadius;
+  }
+  
+  public void setA(double a)
+  {
+    ellipsoid = null;  // force user-defined ellipsoid
+    this.a = a;
+  }
+  
+  public void setB(double b)
+  {
+    ellipsoid = null;  // force user-defined ellipsoid
+    es = 1. - (b * b) / (a * a);
+  }
+  
+  public void setES(double es)
+  {
+    ellipsoid = null;  // force user-defined ellipsoid
+    this.es = es;
+  }
+  
+  public void setRF(double rf)
+  {
+    ellipsoid = null;  // force user-defined ellipsoid
+    es = rf * (2. - rf);
+  }
+  
+  public void setR_A()
+  {
+    ellipsoid = null;  // force user-defined ellipsoid
+    a *= 1. - es * (SIXTH + es * (RA4 + es * RA6));
+  }
+  
+  public void setF(double f)
+  {
+    ellipsoid = null;  // force user-defined ellipsoid
+    double rf = 1.0 / f;
+    es = rf * (2. - rf);
+  }
+  
+  public double getA() {
+    return a;
+  }
+  
+  public double getES() {
+    return es;
+  }
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/ParameterUtil.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/ParameterUtil.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/ParameterUtil.java	(revision 26409)
@@ -0,0 +1,12 @@
+package org.osgeo.proj4j.parser;
+
+import org.osgeo.proj4j.units.AngleFormat;
+
+public class ParameterUtil {
+
+  public static final AngleFormat format = new AngleFormat( AngleFormat.ddmmssPattern, true );
+
+  public static double parseAngle( String s ) {
+    return format.parse( s, null ).doubleValue();
+  }
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/Proj4Keyword.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/Proj4Keyword.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/Proj4Keyword.java	(revision 26409)
@@ -0,0 +1,118 @@
+package org.osgeo.proj4j.parser;
+
+import java.util.*;
+import org.osgeo.proj4j.*;
+
+public class Proj4Keyword 
+{
+
+  public static final String a = "a";
+  public static final String b = "b";
+  public static final String f = "f";
+  public static final String alpha = "alpha";
+  public static final String datum = "datum";
+  public static final String ellps = "ellps";
+  public static final String es = "es";
+
+  public static final String azi = "azi";
+  public static final String k = "k";
+  public static final String k_0 = "k_0";
+  public static final String lat_ts = "lat_ts";
+  public static final String lat_0 = "lat_0";
+  public static final String lat_1 = "lat_1";
+  public static final String lat_2 = "lat_2";
+  public static final String lon_0 = "lon_0";
+  public static final String lonc = "lonc";
+  public static final String pm = "pm";
+  
+  public static final String proj = "proj";
+  
+  public static final String R = "R";
+  public static final String R_A = "R_A";
+  public static final String R_a = "R_a";
+  public static final String R_V = "R_V";
+  public static final String R_g = "R_g";
+  public static final String R_h = "R_h";
+  public static final String R_lat_a = "R_lat_a";
+  public static final String R_lat_g = "R_lat_g";
+  public static final String rf = "rf";
+  
+  public static final String south = "south";
+  public static final String to_meter = "to_meter";
+  public static final String towgs84 = "towgs84";
+  public static final String units = "units";
+  public static final String x_0 = "x_0";
+  public static final String y_0 = "y_0";
+  public static final String zone = "zone";
+  
+  public static final String title = "title";
+  public static final String nadgrids = "nadgrids";
+  public static final String no_defs = "no_defs";
+  public static final String wktext = "wktext";
+
+
+  private static Set<String> supportedParams = null;
+  
+  public static Set supportedParameters()
+  {
+    if (supportedParams == null) {
+      supportedParams = new TreeSet<String>();
+      
+      supportedParams.add(a);
+      supportedParams.add(rf);
+      supportedParams.add(f);
+      supportedParams.add(alpha);
+      supportedParams.add(es);
+      supportedParams.add(b);
+      supportedParams.add(datum);
+      supportedParams.add(ellps);
+      
+      supportedParams.add(R_A);
+   
+      supportedParams.add(k);
+      supportedParams.add(k_0);
+      supportedParams.add(lat_ts);
+      supportedParams.add(lat_0);
+      supportedParams.add(lat_1);
+      supportedParams.add(lat_2);
+      supportedParams.add(lon_0);
+      supportedParams.add(lonc);
+      
+      supportedParams.add(x_0);
+      supportedParams.add(y_0);
+
+      supportedParams.add(proj);
+      supportedParams.add(south);
+      supportedParams.add(towgs84);
+      supportedParams.add(to_meter);
+      supportedParams.add(units);
+      supportedParams.add(zone);
+      
+      supportedParams.add(title);       // no-op
+      supportedParams.add(no_defs);     // no-op
+      supportedParams.add(wktext);      // no-op
+      supportedParams.add(nadgrids);    // no-op for now
+
+    }
+    return supportedParams;
+  }
+  
+  public static boolean isSupported(String paramKey)
+  {
+    return supportedParameters().contains(paramKey);
+  }
+  
+  public static void checkUnsupported(String paramKey)
+  {
+    if (! isSupported(paramKey)) {
+      throw new UnsupportedParameterException(paramKey + " parameter is not supported");
+    }
+  }
+  
+  public static void checkUnsupported(Collection params)
+  {
+    for (Object s : params) {
+      checkUnsupported((String) s);
+    }
+  }
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/Proj4Parser.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/Proj4Parser.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/Proj4Parser.java	(revision 26409)
@@ -0,0 +1,324 @@
+package org.osgeo.proj4j.parser;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgeo.proj4j.*;
+import org.osgeo.proj4j.Registry;
+import org.osgeo.proj4j.datum.Datum;
+import org.osgeo.proj4j.datum.Ellipsoid;
+import org.osgeo.proj4j.proj.Projection;
+import org.osgeo.proj4j.proj.TransverseMercatorProjection;
+import org.osgeo.proj4j.units.AngleFormat;
+import org.osgeo.proj4j.units.Unit;
+import org.osgeo.proj4j.units.Units;
+
+public class Proj4Parser 
+{
+  private Registry registry;
+  
+  public Proj4Parser(Registry registry) {
+    this.registry = registry;
+  }
+  
+  public CoordinateReferenceSystem parse(String name, String[] args)
+  {
+    if (args == null)
+      return null;
+    
+    Map params = createParameterMap(args);
+    Proj4Keyword.checkUnsupported(params.keySet());
+    DatumParameters datumParam = new DatumParameters();
+    parseDatum(params, datumParam);
+    parseEllipsoid(params, datumParam);
+    Datum datum = datumParam.getDatum();
+    Ellipsoid ellipsoid = datum.getEllipsoid(); 
+    // TODO: this makes a difference - why?
+    // which is better?
+//    Ellipsoid ellipsoid = datumParam.getEllipsoid(); 
+    Projection proj = parseProjection(params, ellipsoid);
+    return new CoordinateReferenceSystem(name, args, datum, proj);
+  }
+
+  /*
+  
+  // not currently used
+ private final static double SIXTH = .1666666666666666667; // 1/6 
+ private final static double RA4 = .04722222222222222222; // 17/360 
+ private final static double RA6 = .02215608465608465608; // 67/3024 
+ private final static double RV4 = .06944444444444444444; // 5/72 
+ private final static double RV6 = .04243827160493827160; // 55/1296 
+ */
+
+ private static AngleFormat format = new AngleFormat( AngleFormat.ddmmssPattern, true );
+
+ /**
+  * Creates a {@link Projection}
+  * initialized from a PROJ.4 argument list.
+  */
+ private Projection parseProjection( Map params, Ellipsoid ellipsoid ) {
+   Projection projection = null;
+
+   String s;
+   s = (String)params.get( Proj4Keyword.proj );
+   if ( s != null ) {
+     projection = registry.getProjection( s );
+     if ( projection == null )
+       throw new InvalidValueException( "Unknown projection: "+s );
+   }
+
+   projection.setEllipsoid(ellipsoid);
+
+   // not sure what CSes use this??
+   /*
+   s = (String)params.get( "init" );
+   if ( s != null ) {
+     projection = createFromName( s ).getProjection();
+     if ( projection == null )
+       throw new ProjectionException( "Unknown projection: "+s );
+           a = projection.getEquatorRadius();
+           es = projection.getEllipsoid().getEccentricitySquared();
+   }
+   */
+   
+   
+   //TODO: better error handling for things like bad number syntax.  
+   // Should be able to report the original param string in the error message
+   // Also should the exception be lib specific?  (Say ParseException)
+   
+   // Other parameters
+//   projection.setProjectionLatitudeDegrees( 0 );
+//   projection.setProjectionLatitude1Degrees( 0 );
+//   projection.setProjectionLatitude2Degrees( 0 );
+   s = (String)params.get( Proj4Keyword.alpha );
+   if ( s != null ) 
+     projection.setAlphaDegrees( Double.parseDouble( s ) );
+   
+   s = (String)params.get( Proj4Keyword.lonc );
+   if ( s != null ) 
+     projection.setLonCDegrees( Double.parseDouble( s ) );
+   
+   s = (String)params.get( Proj4Keyword.lat_0 );
+   if ( s != null ) 
+     projection.setProjectionLatitudeDegrees( parseAngle( s ) );
+   
+   s = (String)params.get( Proj4Keyword.lon_0 );
+   if ( s != null ) 
+     projection.setProjectionLongitudeDegrees( parseAngle( s ) );
+   
+   s = (String)params.get( Proj4Keyword.lat_1 );
+   if ( s != null ) 
+     projection.setProjectionLatitude1Degrees( parseAngle( s ) );
+   
+   s = (String)params.get( Proj4Keyword.lat_2 );
+   if ( s != null ) 
+     projection.setProjectionLatitude2Degrees( parseAngle( s ) );
+   
+   s = (String)params.get( Proj4Keyword.lat_ts );
+   if ( s != null ) 
+     projection.setTrueScaleLatitudeDegrees( parseAngle( s ) );
+   
+   s = (String)params.get( Proj4Keyword.x_0 );
+   if ( s != null ) 
+     projection.setFalseEasting( Double.parseDouble( s ) );
+   
+   s = (String)params.get( Proj4Keyword.y_0 );
+   if ( s != null ) 
+     projection.setFalseNorthing( Double.parseDouble( s ) );
+
+   s = (String)params.get( Proj4Keyword.k_0 );
+   if ( s == null ) 
+     s = (String)params.get( Proj4Keyword.k );
+   if ( s != null ) 
+     projection.setScaleFactor( Double.parseDouble( s ) );
+
+   s = (String)params.get( Proj4Keyword.units );
+   if ( s != null ) {
+     Unit unit = Units.findUnits( s );
+     // TODO: report unknown units name as error
+     if ( unit != null ) {
+       projection.setFromMetres( 1.0 / unit.value );
+       projection.setUnits( unit );
+     }
+   }
+   
+   s = (String)params.get( Proj4Keyword.to_meter );
+   if ( s != null ) 
+     projection.setFromMetres( 1.0/Double.parseDouble( s ) );
+
+   if ( params.containsKey( Proj4Keyword.south ) ) 
+     projection.setSouthernHemisphere(true);
+
+   //TODO: implement some of these parameters ?
+     
+   // this must be done last, since behaviour depends on other params being set (eg +south)
+   if (projection instanceof TransverseMercatorProjection) {
+     s = (String) params.get("zone");
+     if (s != null)
+       ((TransverseMercatorProjection) projection).setUTMZone(Integer
+           .parseInt(s));
+   }
+
+   projection.initialize();
+
+   return projection;
+ }
+
+ private void parseDatum(Map params, DatumParameters datumParam) 
+ {
+   String towgs84 = (String) params.get(Proj4Keyword.towgs84);
+   if (towgs84 != null) {
+     double[] datumConvParams = parseDatumTransform(towgs84); 
+     datumParam.setDatumTransform(datumConvParams);
+   }
+
+   String code = (String) params.get(Proj4Keyword.datum);
+   if (code != null) {
+     Datum datum = registry.getDatum(code);
+     if (datum == null)
+       throw new InvalidValueException("Unknown datum: " + code);
+     datumParam.setDatum(datum);
+   }
+   
+ }
+ 
+ private double[] parseDatumTransform(String paramList)
+ {
+   String[] numStr = paramList.split(",");
+   
+   if (! (numStr.length == 3 || numStr.length == 7)) {
+     throw new InvalidValueException("Invalid number of values (must be 3 or 7) in +towgs84: " + paramList);
+   }
+   double[] param = new double[numStr.length];
+   for (int i = 0; i < numStr.length; i++) {
+     // TODO: better error reporting
+     param[i] = Double.parseDouble(numStr[i]);
+   }
+   return param;
+ }
+ 
+ private void parseEllipsoid(Map params, DatumParameters datumParam) 
+ {
+   double b = 0;
+   String s;
+
+   /*
+    * // not supported by PROJ4 s = (String) params.get(Proj4Param.R); if (s !=
+    * null) a = Double.parseDouble(s);
+    */
+
+   String code = (String) params.get(Proj4Keyword.ellps);
+   if (code != null) {
+     Ellipsoid ellipsoid = registry.getEllipsoid(code);
+     if (ellipsoid == null)
+       throw new InvalidValueException("Unknown ellipsoid: " + code);
+     datumParam.setEllipsoid(ellipsoid);
+   }
+
+   /*
+    * Explicit parameters override ellps and datum settings
+    */
+   s = (String) params.get(Proj4Keyword.a);
+   if (s != null) {
+     double a = Double.parseDouble(s);
+     datumParam.setA(a);
+   }
+   
+   s = (String) params.get(Proj4Keyword.es);
+   if (s != null) {
+     double es = Double.parseDouble(s);
+     datumParam.setES(es);
+   }
+
+   s = (String) params.get(Proj4Keyword.rf);
+   if (s != null) {
+     double rf = Double.parseDouble(s);
+     datumParam.setRF(rf);
+   }
+
+   s = (String) params.get(Proj4Keyword.f);
+   if (s != null) {
+     double f = Double.parseDouble(s);
+     datumParam.setF(f);
+   }
+
+   s = (String) params.get(Proj4Keyword.b);
+   if (s != null) {
+     b = Double.parseDouble(s);
+     datumParam.setB(b);
+   }
+
+   if (b == 0) {
+     b = datumParam.getA() * Math.sqrt(1. - datumParam.getES());
+   }
+
+   parseEllipsoidModifiers(params, datumParam);
+
+   /*
+    * // None of these appear to be supported by PROJ4 ??
+    * 
+    * s = (String)
+    * params.get(Proj4Param.R_A); if (s != null && Boolean.getBoolean(s)) { a *=
+    * 1. - es * (SIXTH + es * (RA4 + es * RA6)); } else { s = (String)
+    * params.get(Proj4Param.R_V); if (s != null && Boolean.getBoolean(s)) { a *=
+    * 1. - es * (SIXTH + es * (RV4 + es * RV6)); } else { s = (String)
+    * params.get(Proj4Param.R_a); if (s != null && Boolean.getBoolean(s)) { a =
+    * .5 * (a + b); } else { s = (String) params.get(Proj4Param.R_g); if (s !=
+    * null && Boolean.getBoolean(s)) { a = Math.sqrt(a * b); } else { s =
+    * (String) params.get(Proj4Param.R_h); if (s != null &&
+    * Boolean.getBoolean(s)) { a = 2. * a * b / (a + b); es = 0.; } else { s =
+    * (String) params.get(Proj4Param.R_lat_a); if (s != null) { double tmp =
+    * Math.sin(parseAngle(s)); if (Math.abs(tmp) > MapMath.HALFPI) throw new
+    * ProjectionException("-11"); tmp = 1. - es * tmp * tmp; a *= .5 * (1. - es +
+    * tmp) / (tmp * Math.sqrt(tmp)); es = 0.; } else { s = (String)
+    * params.get(Proj4Param.R_lat_g); if (s != null) { double tmp =
+    * Math.sin(parseAngle(s)); if (Math.abs(tmp) > MapMath.HALFPI) throw new
+    * ProjectionException("-11"); tmp = 1. - es * tmp * tmp; a *= Math.sqrt(1. -
+    * es) / tmp; es = 0.; } } } } } } } }
+    */
+ }
+ 
+ /**
+  * Parse ellipsoid modifiers.
+  * 
+  * @param params
+  * @param datumParam
+  */
+ private void parseEllipsoidModifiers(Map params, DatumParameters datumParam) 
+ {
+   /**
+    * Modifiers are mutually exclusive, so when one is detected method returns
+    */
+   if ( params.containsKey( Proj4Keyword.R_A ) ) {
+     datumParam.setR_A();
+     return;
+   }
+
+ }
+ 
+ private Map createParameterMap(String[] args) {
+   Map params = new HashMap();
+   for (int i = 0; i < args.length; i++) {
+     String arg = args[i];
+     if (arg.startsWith("+")) {
+       int index = arg.indexOf('=');
+       if (index != -1) {
+         // params of form +pppp=vvvv
+         String key = arg.substring(1, index);
+         String value = arg.substring(index + 1);
+         params.put(key, value);
+       } else {
+         // params of form +ppppp
+         String key = arg.substring(1);
+         params.put(key, null);
+       }
+     }
+   }
+   return params;
+ }
+
+ private static double parseAngle( String s ) {
+   return format.parse( s, null ).doubleValue();
+ }
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AiryProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AiryProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AiryProjection.java	(revision 26409)
@@ -0,0 +1,133 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class AiryProjection extends Projection {
+
+	private double p_halfpi;
+	private double sinph0;
+	private double cosph0;
+	private double Cb;
+	private int mode;
+	private boolean no_cut = true;	/* do not cut at hemisphere limit */
+
+	private final static double EPS = 1.e-10;
+	private final static int N_POLE = 0;
+	private final static int S_POLE = 1;
+	private final static int EQUIT = 2;
+	private final static int OBLIQ = 3;
+
+	public AiryProjection() {
+		minLatitude = Math.toRadians(-60);
+		maxLatitude = Math.toRadians(60);
+		minLongitude = Math.toRadians(-90);
+		maxLongitude = Math.toRadians(90);
+		initialize();
+	}
+	
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double sinlam, coslam, cosphi, sinphi, t, s, Krho, cosz;
+
+		sinlam = Math.sin(lplam);
+		coslam = Math.cos(lplam);
+		switch (mode) {
+		case EQUIT:
+		case OBLIQ:
+			sinphi = Math.sin(lpphi);
+			cosphi = Math.cos(lpphi);
+			cosz = cosphi * coslam;
+			if (mode == OBLIQ)
+				cosz = sinph0 * sinphi + cosph0 * cosz;
+			if (!no_cut && cosz < -EPS)
+				throw new ProjectionException("F");
+			s = 1. - cosz;
+			if (Math.abs(s) > EPS) {
+				t = 0.5 * (1. + cosz);
+				Krho = -Math.log(t)/s - Cb / t;
+			} else
+				Krho = 0.5 - Cb;
+			out.x = Krho * cosphi * sinlam;
+			if (mode == OBLIQ)
+				out.y = Krho * (cosph0 * sinphi -
+					sinph0 * cosphi * coslam);
+			else
+				out.y = Krho * sinphi;
+			break;
+		case S_POLE:
+		case N_POLE:
+			out.y = Math.abs(p_halfpi - lpphi);
+			if (!no_cut && (lpphi - EPS) > ProjectionMath.HALFPI)
+				throw new ProjectionException("F");
+			if ((out.y *= 0.5) > EPS) {
+				t = Math.tan(lpphi);
+				Krho = -2.*(Math.log(Math.cos(lpphi)) / t + t * Cb);
+				out.x = Krho * sinlam;
+				out.y = Krho * coslam;
+				if (mode == N_POLE)
+					out.y = -out.y;
+			} else
+				out.x = out.y = 0.;
+		}
+		return out;
+	}
+
+	public void initialize() { // airy
+		super.initialize();
+
+		double beta;
+
+//		no_cut = pj_param(params, "bno_cut").i;
+//		beta = 0.5 * (MapMath.HALFPI - pj_param(params, "rlat_b").f);
+		no_cut = false;//FIXME
+		beta = 0.5 * (ProjectionMath.HALFPI - 0);//FIXME
+		if (Math.abs(beta) < EPS)
+			Cb = -0.5;
+		else {
+			Cb = 1./Math.tan(beta);
+			Cb *= Cb * Math.log(Math.cos(beta));
+		}
+		if (Math.abs(Math.abs(projectionLatitude) - ProjectionMath.HALFPI) < EPS)
+			if (projectionLatitude < 0.) {
+				p_halfpi = -ProjectionMath.HALFPI;
+				mode = S_POLE;
+			} else {
+				p_halfpi =  ProjectionMath.HALFPI;
+				mode = N_POLE;
+			}
+		else {
+			if (Math.abs(projectionLatitude) < EPS)
+				mode = EQUIT;
+			else {
+				mode = OBLIQ;
+				sinph0 = Math.sin(projectionLatitude);
+				cosph0 = Math.cos(projectionLatitude);
+			}
+		}
+	}
+
+	public String toString() {
+		return "Airy";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AitoffProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AitoffProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AitoffProjection.java	(revision 26409)
@@ -0,0 +1,78 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+
+public class AitoffProjection extends PseudoCylindricalProjection {
+	
+	protected final static int AITOFF = 0;
+	protected final static int WINKEL = 1;
+
+	private boolean winkel = false;
+	private double cosphi1 = 0;
+
+	public AitoffProjection() {
+	}
+
+	public AitoffProjection(int type, double projectionLatitude) {
+		this.projectionLatitude = projectionLatitude;
+		winkel = type == WINKEL;
+	}
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double c = 0.5 * lplam;
+		double d = Math.acos(Math.cos(lpphi) * Math.cos(c));
+
+		if (d != 0) {
+			out.x = 2. * d * Math.cos(lpphi) * Math.sin(c) * (out.y = 1. / Math.sin(d));
+			out.y *= d * Math.sin(lpphi);
+		} else
+			out.x = out.y = 0.0;
+		if (winkel) {
+			out.x = (out.x + lplam * cosphi1) * 0.5;
+			out.y = (out.y + lpphi) * 0.5;
+		}
+		return out;
+	}
+
+	public void initialize() {
+		super.initialize();
+		if (winkel) {
+//FIXME
+//			if (pj_param(P->params, "tlat_1").i)
+//				if ((cosphi1 = Math.cos(pj_param(P->params, "rlat_1").f)) == 0.)
+//					throw new IllegalArgumentException("-22")
+//			else /* 50d28' or acos(2/pi) */
+				cosphi1 = 0.636619772367581343;
+		}
+	}
+	
+	public boolean hasInverse() {
+		return false;
+	}
+
+	public String toString() {
+		return winkel ? "Winkel Tripel" : "Aitoff";
+	}
+
+}
+
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AlbersProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AlbersProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AlbersProjection.java	(revision 26409)
@@ -0,0 +1,190 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class AlbersProjection extends Projection {
+
+	private final static double EPS10 = 1.e-10;
+	private final static double TOL7 = 1.e-7;
+	private double ec;
+	private double n;
+	private double c;
+	private double dd;
+	private double n2;
+	private double rho0;
+	private double phi1;
+	private double phi2;
+	private double[] en;
+
+	private final static int N_ITER = 15;
+	private final static double EPSILON = 1.0e-7;
+	private final static double TOL = 1.0e-10;
+
+	//protected double projectionLatitude1 = MapMath.degToRad(45.5);
+	//protected double projectionLatitude2 = MapMath.degToRad(29.5);
+
+	public AlbersProjection() {
+		minLatitude = Math.toRadians(0);
+		maxLatitude = Math.toRadians(80);
+		projectionLatitude1 = ProjectionMath.degToRad(45.5);
+		projectionLatitude2 = ProjectionMath.degToRad(29.5);
+		initialize();
+	}
+
+	private static double phi1_(double qs, double Te, double Tone_es) {
+		int i;
+		double Phi, sinpi, cospi, con, com, dphi;
+
+		Phi = Math.asin (.5 * qs);
+		if (Te < EPSILON)
+			return( Phi );
+		i = N_ITER;
+		do {
+			sinpi = Math.sin (Phi);
+			cospi = Math.cos (Phi);
+			con = Te * sinpi;
+			com = 1. - con * con;
+			dphi = .5 * com * com / cospi * (qs / Tone_es -
+			   sinpi / com + .5 / Te * Math.log ((1. - con) /
+			   (1. + con)));
+			Phi += dphi;
+		} while (Math.abs(dphi) > TOL && --i != 0);
+		return( i != 0 ? Phi : Double.MAX_VALUE );
+	}
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double rho;
+		if ((rho = c - (!spherical ? n * ProjectionMath.qsfn(Math.sin(lpphi), e, one_es) : n2 * Math.sin(lpphi))) < 0.)
+			throw new ProjectionException("F");
+		rho = dd * Math.sqrt(rho);
+		out.x = rho * Math.sin( lplam *= n );
+		out.y = rho0 - rho * Math.cos(lplam);
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double rho;
+		if ((rho = ProjectionMath.distance(xyx, xyy = rho0 - xyy)) != 0) {
+			double lpphi, lplam;
+			if (n < 0.) {
+				rho = -rho;
+				xyx = -xyx;
+				xyy = -xyy;
+			}
+			lpphi =  rho / dd;
+			if (!spherical) {
+				lpphi = (c - lpphi * lpphi) / n;
+				if (Math.abs(ec - Math.abs(lpphi)) > TOL7) {
+					if ((lpphi = phi1_(lpphi, e, one_es)) == Double.MAX_VALUE)
+						throw new ProjectionException("I");
+				} else
+					lpphi = lpphi < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+			} else if (Math.abs(out.y = (c - lpphi * lpphi) / n2) <= 1.)
+				lpphi = Math.asin(lpphi);
+			else
+				lpphi = lpphi < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+			lplam = Math.atan2(xyx, xyy) / n;
+			out.x = lplam;
+			out.y = lpphi;
+		} else {
+			out.x = 0.;
+			out.y = n > 0. ? ProjectionMath.HALFPI : - ProjectionMath.HALFPI;
+		}
+		return out;
+	}
+
+	public void initialize() {
+		super.initialize();
+		double cosphi, sinphi;
+		boolean secant;
+
+		phi1 = projectionLatitude1;
+		phi2 = projectionLatitude2;
+
+		if (Math.abs(phi1 + phi2) < EPS10)
+			throw new ProjectionException("-21");
+		n = sinphi = Math.sin(phi1);
+		cosphi = Math.cos(phi1);
+		secant = Math.abs(phi1 - phi2) >= EPS10;
+		//spherical = es > 0.0;
+		if (!spherical) {
+			double ml1, m1;
+
+			if ((en = ProjectionMath.enfn(es)) == null)
+				throw new ProjectionException("0");
+			m1 = ProjectionMath.msfn(sinphi, cosphi, es);
+			ml1 = ProjectionMath.qsfn(sinphi, e, one_es);
+			if (secant) { /* secant cone */
+				double ml2, m2;
+
+				sinphi = Math.sin(phi2);
+				cosphi = Math.cos(phi2);
+				m2 = ProjectionMath.msfn(sinphi, cosphi, es);
+				ml2 = ProjectionMath.qsfn(sinphi, e, one_es);
+				n = (m1 * m1 - m2 * m2) / (ml2 - ml1);
+			}
+			ec = 1. - .5 * one_es * Math.log((1. - e) /
+				(1. + e)) / e;
+			c = m1 * m1 + n * ml1;
+			dd = 1. / n;
+			rho0 = dd * Math.sqrt(c - n * ProjectionMath.qsfn(Math.sin(projectionLatitude),
+				e, one_es));
+		} else {
+			if (secant) n = .5 * (n + Math.sin(phi2));
+			n2 = n + n;
+			c = cosphi * cosphi + n2 * sinphi;
+			dd = 1. / n;
+			rho0 = dd * Math.sqrt(c - n2 * Math.sin(projectionLatitude));
+		}
+	}
+
+	/**
+	 * Returns true if this projection is equal area
+	 */
+	public boolean isEqualArea() {
+		return true;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	/**
+	 * Returns the ESPG code for this projection, or 0 if unknown.
+	 */
+	public int getEPSGCode() {
+		return 9822;
+	}
+
+	public String toString() {
+		return "Albers Equal Area";
+	}
+
+/*
+	public String toString() {
+		return "Lambert Equal Area Conic";
+	}
+*/
+}
+
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AugustProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AugustProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AugustProjection.java	(revision 26409)
@@ -0,0 +1,56 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class AugustProjection extends Projection {
+
+	private final static double M = 1.333333333333333;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double t, c1, c, x1, x12, y1, y12;
+
+		t = Math.tan(.5 * lpphi);
+		c1 = Math.sqrt(1. - t * t);
+		c = 1. + c1 * Math.cos(lplam *= .5);
+		x1 = Math.sin(lplam) *  c1 / c;
+		y1 =  t / c;
+		out.x = M * x1 * (3. + (x12 = x1 * x1) - 3. * (y12 = y1 *  y1));
+		out.y = M * y1 * (3. + 3. * x12 - y12);
+		return out;
+	}
+
+	/**
+	 * Returns true if this projection is conformal
+	 */
+	public boolean isConformal() {
+		return true;
+	}
+
+	public boolean hasInverse() {
+		return false;
+	}
+
+	public String toString() {
+		return "August Epicycloidal";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AzimuthalProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AzimuthalProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/AzimuthalProjection.java	(revision 26409)
@@ -0,0 +1,73 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.util.ProjectionMath;
+
+/**
+ * The superclass for all azimuthal map projections
+ */
+public abstract class AzimuthalProjection extends Projection {
+
+	public final static int NORTH_POLE = 1;
+	public final static int SOUTH_POLE = 2;
+	public final static int EQUATOR = 3;
+	public final static int OBLIQUE = 4;
+	
+	protected int mode;
+	protected double sinphi0, cosphi0;
+	private double mapRadius = 90.0;
+	
+	public AzimuthalProjection() {
+		this( Math.toRadians(45.0), Math.toRadians(45.0) );
+	}
+
+	public AzimuthalProjection(double projectionLatitude, double projectionLongitude) {
+		this.projectionLatitude = projectionLatitude;
+		this.projectionLongitude = projectionLongitude;
+		initialize();
+	}
+	
+	public void initialize() {
+		super.initialize();
+		if (Math.abs(Math.abs(projectionLatitude) - ProjectionMath.HALFPI) < EPS10)
+			mode = projectionLatitude < 0. ? SOUTH_POLE : NORTH_POLE;
+		else if (Math.abs(projectionLatitude) > EPS10) {
+			mode = OBLIQUE;
+			sinphi0 = Math.sin(projectionLatitude);
+			cosphi0 = Math.cos(projectionLatitude);
+		} else
+			mode = EQUATOR;
+	}
+
+	public boolean inside(double lon, double lat) {
+		return ProjectionMath.greatCircleDistance( Math.toRadians(lon), Math.toRadians(lat), projectionLongitude, projectionLatitude) < Math.toRadians(mapRadius);
+	}
+
+	/**
+	 * Set the map radius (in degrees). 180 shows a hemisphere, 360 shows the whole globe.
+	 */
+	public void setMapRadius(double mapRadius) {
+		this.mapRadius = mapRadius;
+	}
+
+	public double getMapRadius() {
+		return mapRadius;
+	}
+
+}
+
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/BipolarProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/BipolarProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/BipolarProjection.java	(revision 26409)
@@ -0,0 +1,178 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class BipolarProjection extends Projection {
+
+	private boolean	noskew;
+
+	private final static double EPS = 1e-10;
+	private final static double EPS10 = 1e-10;
+	private final static double ONEEPS = 1.000000001;
+	private final static int NITER = 10;
+	private final static double lamB = -.34894976726250681539;
+	private final static double n = .63055844881274687180;
+	private final static double F = 1.89724742567461030582;
+	private final static double Azab = .81650043674686363166;
+	private final static double Azba = 1.82261843856185925133;
+	private final static double T = 1.27246578267089012270;
+	private final static double rhoc = 1.20709121521568721927;
+	private final static double cAzc = .69691523038678375519;
+	private final static double sAzc = .71715351331143607555;
+	private final static double C45 = .70710678118654752469;
+	private final static double S45 = .70710678118654752410;
+	private final static double C20 = .93969262078590838411;
+	private final static double S20 = -.34202014332566873287;
+	private final static double R110 = 1.91986217719376253360;
+	private final static double R104 = 1.81514242207410275904;
+
+	public BipolarProjection() {
+		minLatitude = Math.toRadians(-80);
+		maxLatitude = Math.toRadians(80);
+		projectionLongitude = Math.toRadians(-90);
+		minLongitude = Math.toRadians(-90);
+		maxLongitude = Math.toRadians(90);
+	}
+	
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double cphi, sphi, tphi, t, al, Az, z, Av, cdlam, sdlam, r;
+		boolean tag;
+
+		cphi = Math.cos(lpphi);
+		sphi = Math.sin(lpphi);
+		cdlam = Math.cos(sdlam = lamB - lplam);
+		sdlam = Math.sin(sdlam);
+		if (Math.abs(Math.abs(lpphi) - ProjectionMath.HALFPI) < EPS10) {
+			Az = lpphi < 0. ? Math.PI : 0.;
+			tphi = Double.MAX_VALUE;
+		} else {
+			tphi = sphi / cphi;
+			Az = Math.atan2(sdlam , C45 * (tphi - cdlam));
+		}
+		if (tag = (Az > Azba)) {
+			cdlam = Math.cos(sdlam = lplam + R110);
+			sdlam = Math.sin(sdlam);
+			z = S20 * sphi + C20 * cphi * cdlam;
+			if (Math.abs(z) > 1.) {
+				if (Math.abs(z) > ONEEPS)
+					throw new ProjectionException("F");
+				else z = z < 0. ? -1. : 1.;
+			} else
+				z = Math.acos(z);
+			if (tphi != Double.MAX_VALUE)
+				Az = Math.atan2(sdlam, (C20 * tphi - S20 * cdlam));
+			Av = Azab;
+			out.y = rhoc;
+		} else {
+			z = S45 * (sphi + cphi * cdlam);
+			if (Math.abs(z) > 1.) {
+				if (Math.abs(z) > ONEEPS)
+					throw new ProjectionException("F");
+				else z = z < 0. ? -1. : 1.;
+			} else
+				z = Math.acos(z);
+			Av = Azba;
+			out.y = -rhoc;
+		}
+		if (z < 0.) throw new ProjectionException("F");
+		r = F * (t = Math.pow(Math.tan(.5 * z), n));
+		if ((al = .5 * (R104 - z)) < 0.)
+			throw new ProjectionException("F");
+		al = (t + Math.pow(al, n)) / T;
+		if (Math.abs(al) > 1.) {
+			if (Math.abs(al) > ONEEPS)
+				throw new ProjectionException("F");
+			else al = al < 0. ? -1. : 1.;
+		} else
+			al = Math.acos(al);
+		if (Math.abs(t = n * (Av - Az)) < al)
+			r /= Math.cos(al + (tag ? t : -t));
+		out.x = r * Math.sin(t);
+		out.y += (tag ? -r : r) * Math.cos(t);
+		if (noskew) {
+			t = out.x;
+			out.x = -out.x * cAzc - out.y * sAzc; 
+			out.y = -out.y * cAzc + t * sAzc; 
+		}
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double t, r, rp, rl, al, z = 0, fAz, Az, s, c, Av;
+		boolean neg;
+		int i;
+
+		if (noskew) {
+			t = xyx;
+			out.x = -xyx * cAzc + xyy * sAzc; 
+			out.y = -xyy * cAzc - t * sAzc; 
+		}
+		if (neg = (xyx < 0.)) {
+			out.y = rhoc - xyy;
+			s = S20;
+			c = C20;
+			Av = Azab;
+		} else {
+			out.y += rhoc;
+			s = S45;
+			c = C45;
+			Av = Azba;
+		}
+		rl = rp = r = ProjectionMath.distance(xyx, xyy);
+		fAz = Math.abs(Az = Math.atan2(xyx, xyy));
+		for (i = NITER; i > 0; --i) {
+			z = 2. * Math.atan(Math.pow(r / F,1 / n));
+			al = Math.acos((Math.pow(Math.tan(.5 * z), n) +
+			   Math.pow(Math.tan(.5 * (R104 - z)), n)) / T);
+			if (fAz < al)
+				r = rp * Math.cos(al + (neg ? Az : -Az));
+			if (Math.abs(rl - r) < EPS)
+				break;
+			rl = r;
+		}
+		if (i == 0) throw new ProjectionException("I");
+		Az = Av - Az / n;
+		out.y = Math.asin(s * Math.cos(z) + c * Math.sin(z) * Math.cos(Az));
+		out.x = Math.atan2(Math.sin(Az), c / Math.tan(z) - s * Math.cos(Az));
+		if (neg)
+			out.x -= R110;
+		else
+			out.x = lamB - out.x;
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public void initialize() { // bipc
+		super.initialize();
+//		noskew = pj_param(params, "bns").i;//FIXME
+	}
+
+	public String toString() {
+		return "Bipolar Conic of Western Hemisphere";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/BoggsProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/BoggsProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/BoggsProjection.java	(revision 26409)
@@ -0,0 +1,71 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class BoggsProjection extends PseudoCylindricalProjection {
+
+	private final static int NITER = 20;
+	private final static double EPS = 1e-7;
+	private final static double ONETOL = 1.000001;
+	private final static double FXC = 2.00276;
+	private final static double FXC2 = 1.11072;
+	private final static double FYC = 0.49931;
+	private final static double FYC2 = 1.41421356237309504880;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double theta, th1, c;
+		int i;
+
+		theta = lpphi;
+		if (Math.abs(Math.abs(lpphi) - ProjectionMath.HALFPI) < EPS)
+			out.x = 0.;
+		else {
+			c = Math.sin(theta) * Math.PI;
+			for (i = NITER; i > 0; --i) {
+				theta -= th1 = (theta + Math.sin(theta) - c) /
+					(1. + Math.cos(theta));
+				if (Math.abs(th1) < EPS) break;
+			}
+			theta *= 0.5;
+			out.x = FXC * lplam / (1. / Math.cos(lpphi) + FXC2 / Math.cos(theta));
+		}
+		out.y = FYC * (lpphi + FYC2 * Math.sin(theta));
+		return out;
+	}
+
+	/**
+	 * Returns true if this projection is equal area
+	 */
+	public boolean isEqualArea() {
+		return true;
+	}
+
+	public boolean hasInverse() {
+		return false;
+	}
+
+	public String toString() {
+		return "Boggs Eumorphic";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/BonneProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/BonneProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/BonneProjection.java	(revision 26409)
@@ -0,0 +1,118 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class BonneProjection extends Projection {
+	private double phi1;
+	private double cphi1;
+	private double am1;
+	private double m1;
+	private double[] en;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		if (spherical) {
+			double E, rh;
+
+			rh = cphi1 + phi1 - lpphi;
+			if (Math.abs(rh) > EPS10) {
+				out.x = rh * Math.sin(E = lplam * Math.cos(lpphi) / rh);
+				out.y = cphi1 - rh * Math.cos(E);
+			} else
+				out.x = out.y = 0.;
+		} else {
+			double rh, E, c;
+
+			rh = am1 + m1 - ProjectionMath.mlfn(lpphi, E = Math.sin(lpphi), c = Math.cos(lpphi), en);
+			E = c * lplam / (rh * Math.sqrt(1. - es * E * E));
+			out.x = rh * Math.sin(E);
+			out.y = am1 - rh * Math.cos(E);
+		}
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		if (spherical) {
+			double rh;
+
+			rh = ProjectionMath.distance(xyx, out.y = cphi1 - xyy);
+			out.y = cphi1 + phi1 - rh;
+			if (Math.abs(out.y) > ProjectionMath.HALFPI) throw new ProjectionException("I");
+			if (Math.abs(Math.abs(out.y) - ProjectionMath.HALFPI) <= EPS10)
+				out.x = 0.;
+			else
+				out.x = rh * Math.atan2(xyx, xyy) / Math.cos(out.y);
+		} else {
+			double s, rh;
+
+			rh = ProjectionMath.distance(xyx, out.y = am1 - xyy);
+			out.y = ProjectionMath.inv_mlfn(am1 + m1 - rh, es, en);
+			if ((s = Math.abs(out.y)) < ProjectionMath.HALFPI) {
+				s = Math.sin(out.y);
+				out.x = rh * Math.atan2(xyx, xyy) *
+				   Math.sqrt(1. - es * s * s) / Math.cos(out.y);
+			} else if (Math.abs(s - ProjectionMath.HALFPI) <= EPS10)
+				out.x = 0.;
+			else throw new ProjectionException("I");
+		}
+		return out;
+	}
+
+	/**
+	 * Returns true if this projection is equal area
+	 */
+	public boolean isEqualArea() {
+		return true;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public void initialize() {
+		super.initialize();
+
+		double c;
+
+//		phi1 = pj_param(params, "rlat_1").f;
+		phi1 = ProjectionMath.HALFPI;
+		if (Math.abs(phi1) < EPS10)
+			throw new ProjectionException("-23");
+		if (!spherical) {
+			en = ProjectionMath.enfn(es);
+			m1 = ProjectionMath.mlfn(phi1, am1 = Math.sin(phi1),
+				c = Math.cos(phi1), en);
+			am1 = c / (Math.sqrt(1. - es * am1 * am1) * am1);
+		} else {
+			if (Math.abs(phi1) + EPS10 >= ProjectionMath.HALFPI)
+				cphi1 = 0.;
+			else
+				cphi1 = 1. / Math.tan(phi1);
+		}
+	}
+
+	public String toString() {
+		return "Bonne";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CassiniProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CassiniProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CassiniProjection.java	(revision 26409)
@@ -0,0 +1,120 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.*;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class CassiniProjection extends Projection {
+
+	private double m0;
+	private double n;
+	private double t;
+	private double a1;
+	private double c;
+	private double r;
+	private double dd;
+	private double d2;
+	private double a2;
+	private double tn;
+	private double[] en;
+
+	private final static double EPS10 = 1e-10;
+	private final static double C1 = .16666666666666666666;
+	private final static double C2 = .00833333333333333333;
+	private final static double C3 = .04166666666666666666;
+	private final static double C4 = .33333333333333333333;
+	private final static double C5 = .06666666666666666666;
+
+	public CassiniProjection() {
+		projectionLatitude = Math.toRadians(0);
+		projectionLongitude = Math.toRadians(0);
+		minLongitude = Math.toRadians(-90);
+		maxLongitude = Math.toRadians(90);
+		initialize();
+	}
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate xy) {
+		if (spherical) {
+			xy.x = Math.asin(Math.cos(lpphi) * Math.sin(lplam));
+			xy.y = Math.atan2(Math.tan(lpphi) , Math.cos(lplam)) - projectionLatitude;
+		} else {
+			xy.y = ProjectionMath.mlfn(lpphi, n = Math.sin(lpphi), c = Math.cos(lpphi), en);
+			n = 1./Math.sqrt(1. - es * n * n);
+			tn = Math.tan(lpphi); t = tn * tn;
+			a1 = lplam * c;
+			c *= es * c / (1 - es);
+			a2 = a1 * a1;
+			xy.x = n * a1 * (1. - a2 * t *
+				(C1 - (8. - t + 8. * c) * a2 * C2));
+			xy.y -= m0 - n * tn * a2 *
+				(.5 + (5. - t + 6. * c) * a2 * C3);
+		}
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		if (spherical) {
+			out.y = Math.asin(Math.sin(dd = xyy + projectionLatitude) * Math.cos(xyx));
+			out.x = Math.atan2(Math.tan(xyx), Math.cos(dd));
+		} else {
+			double ph1;
+
+			ph1 = ProjectionMath.inv_mlfn(m0 + xyy, es, en);
+			tn = Math.tan(ph1); t = tn * tn;
+			n = Math.sin(ph1);
+			r = 1. / (1. - es * n * n);
+			n = Math.sqrt(r);
+			r *= (1. - es) * n;
+			dd = xyx / n;
+			d2 = dd * dd;
+			out.y = ph1 - (n * tn / r) * d2 *
+				(.5 - (1. + 3. * t) * d2 * C3);
+			out.x = dd * (1. + t * d2 *
+				(-C4 + (1. + 3. * t) * d2 * C5)) / Math.cos(ph1);
+		}
+		return out;
+	}
+
+	public void initialize() {
+		super.initialize();
+		if (!spherical) {
+			if ((en = ProjectionMath.enfn(es)) == null)
+				throw new ProjectionException();
+			m0 = ProjectionMath.mlfn(projectionLatitude, Math.sin(projectionLatitude), Math.cos(projectionLatitude), en);
+		}
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	/**
+	 * Returns the ESPG code for this projection, or 0 if unknown.
+	 */
+	public int getEPSGCode() {
+		return 9806;
+	}
+
+	public String toString() {
+		return "Cassini";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CentralCylindricalProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CentralCylindricalProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CentralCylindricalProjection.java	(revision 26409)
@@ -0,0 +1,58 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class CentralCylindricalProjection extends CylindricalProjection {
+
+	private double ap;
+
+	private final static double EPS10 = 1.e-10;
+
+	public CentralCylindricalProjection() {
+		minLatitude = Math.toRadians(-80);
+		maxLatitude = Math.toRadians(80);
+	}
+	
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		if (Math.abs(Math.abs(lpphi) - ProjectionMath.HALFPI) <= EPS10) throw new ProjectionException("F");
+		out.x = lplam;
+		out.y = Math.tan(lpphi);
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		out.y = Math.atan(xyy);
+		out.x = xyx;
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Central Cylindrical";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CollignonProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CollignonProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CollignonProjection.java	(revision 26409)
@@ -0,0 +1,71 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class CollignonProjection extends Projection {
+
+	private final static double FXC = 1.12837916709551257390;
+	private final static double FYC = 1.77245385090551602729;
+	private final static double ONEEPS = 1.0000001;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		if ((out.y = 1. - Math.sin(lpphi)) <= 0.)
+			out.y = 0.;
+		else
+			out.y = Math.sqrt(out.y);
+		out.x = FXC * lplam * out.y;
+		out.y = FYC * (1. - out.y);
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double lpphi = xyy / FYC - 1.;
+		if (Math.abs(out.y = 1. - lpphi * lpphi) < 1.)
+			out.y = Math.asin(lpphi);
+		else if (Math.abs(lpphi) > ONEEPS) throw new ProjectionException("I");
+		else	out.y = lpphi < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+		if ((out.x = 1. - Math.sin(lpphi)) <= 0.)
+			out.x = 0.;
+		else
+			out.x = xyx / (FXC * Math.sqrt(out.x));
+		out.y = lpphi;
+		return out;
+	}
+
+	/**
+	 * Returns true if this projection is equal area
+	 */
+	public boolean isEqualArea() {
+		return true;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Collignon";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/ConicProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/ConicProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/ConicProjection.java	(revision 26409)
@@ -0,0 +1,36 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.proj;
+
+
+
+/**
+ * A projection formed by projecting the sphere 
+ * onto a cone tangent, or secant, to the sphere 
+ * along any small circle (usually a mid-latitude parallel). 
+ * In the normal aspect (which is oblique for conic projections), 
+ * parallels are projected as concentric arcs of circles, 
+ * and meridians are projected as straight lines 
+ * radiating at uniform angular intervals from the apex of the flattened cone. 
+ */
+public abstract class ConicProjection extends Projection {
+	
+	public String toString() {
+		return "Conic";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CrasterProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CrasterProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CrasterProjection.java	(revision 26409)
@@ -0,0 +1,60 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class CrasterProjection extends Projection {
+
+	private final static double XM = 0.97720502380583984317;
+	private final static double RXM = 1.02332670794648848847;
+	private final static double YM = 3.06998012383946546542;
+	private final static double RYM = 0.32573500793527994772;
+	private final static double THIRD = 0.333333333333333333;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		lpphi *= THIRD;
+		out.x = XM * lplam * (2. * Math.cos(lpphi + lpphi) - 1.);
+		out.y = YM * Math.sin(lpphi);
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		out.y = 3. * Math.asin(xyy * RYM);
+		out.x = xyx * RXM / (2. * Math.cos((out.y + out.y) * THIRD) - 1);
+		return out;
+	}
+
+	/**
+	 * Returns true if this projection is equal area
+	 */
+	public boolean isEqualArea() {
+		return true;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Craster Parabolic (Putnins P4)";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CylindricalEqualAreaProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CylindricalEqualAreaProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CylindricalEqualAreaProjection.java	(revision 26409)
@@ -0,0 +1,94 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class CylindricalEqualAreaProjection extends Projection {
+
+	private double qp;
+	private double[] apa;
+	private double trueScaleLatitude;
+
+	public CylindricalEqualAreaProjection() {
+		this(0.0, 0.0, 0.0);
+	}
+	
+	public CylindricalEqualAreaProjection(double projectionLatitude, double projectionLongitude, double trueScaleLatitude) {
+		this.projectionLatitude = projectionLatitude;
+		this.projectionLongitude = projectionLongitude;
+		this.trueScaleLatitude = trueScaleLatitude;
+		initialize();
+	}
+	
+	public void initialize() {
+		super.initialize();
+		double t = trueScaleLatitude;
+
+		scaleFactor = Math.cos(t);
+		if (es != 0) {
+			t = Math.sin(t);
+			scaleFactor /= Math.sqrt(1. - es * t * t);
+			apa = ProjectionMath.authset(es);
+			qp = ProjectionMath.qsfn(1., e, one_es);
+		}
+	}
+	
+	public ProjCoordinate project(double lam, double phi, ProjCoordinate xy) {
+		if (spherical) {
+			xy.x = scaleFactor * lam;
+			xy.y = Math.sin(phi) / scaleFactor;
+		} else {
+			xy.x = scaleFactor * lam;
+			xy.y = .5 * ProjectionMath.qsfn(Math.sin(phi), e, one_es) / scaleFactor;
+		}
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate lp) {
+		if (spherical) {
+			double t;
+
+			if ((t = Math.abs(y *= scaleFactor)) - EPS10 <= 1.) {
+				if (t >= 1.)
+					lp.y = y < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+				else
+					lp.y = Math.asin(y);
+				lp.x = x / scaleFactor;
+			} else throw new ProjectionException();
+		} else {
+			lp.y = ProjectionMath.authlat(Math.asin( 2. * y * scaleFactor / qp), apa);
+			lp.x = x / scaleFactor;
+		}
+		return lp;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public boolean isRectilinear() {
+		return true;
+	}
+
+}
+
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CylindricalProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CylindricalProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/CylindricalProjection.java	(revision 26409)
@@ -0,0 +1,37 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.proj;
+
+
+
+/**
+ * A projection 
+ * in which meridians are mapped to equally spaced vertical lines 
+ * and circles of latitude (parallels) are mapped to horizontal lines.
+ */
+public abstract class CylindricalProjection extends Projection {
+	
+	public boolean isRectilinear() {
+		return true;
+	}
+
+	public String toString() {
+		return "Cylindrical";
+	}
+
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/DenoyerProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/DenoyerProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/DenoyerProjection.java	(revision 26409)
@@ -0,0 +1,54 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+
+public class DenoyerProjection extends Projection {
+
+	public final static double C0 = 0.95;
+	public final static double C1 = -.08333333333333333333;
+	public final static double C3 = 0.00166666666666666666;
+	public final static double D1 = 0.9;
+	public final static double D5 = 0.03;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		out.y = lpphi;
+		out.x = lplam;
+		double aphi = Math.abs(lplam);
+		out.x *= Math.cos((C0 + aphi * (C1 + aphi * aphi * C3)) *
+			(lpphi * (D1 + D5 * lpphi * lpphi * lpphi * lpphi)));
+		return out;
+	}
+
+	public boolean parallelsAreParallel() {
+		return true;
+	}
+
+	public boolean hasInverse() {
+		return false;
+	}
+
+	public String toString() {
+		return "Denoyer Semi-elliptical";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert1Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert1Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert1Projection.java	(revision 26409)
@@ -0,0 +1,49 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class Eckert1Projection extends Projection {
+
+	private final static double FC = .92131773192356127802;
+	private final static double RP = .31830988618379067154;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		out.x = FC * lplam * (1. - RP * Math.abs(lpphi));
+		out.y = FC * lpphi;
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		out.y = xyy / FC;
+		out.x = xyx / (FC * (1. - RP * Math.abs(out.y)));
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Eckert I";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert2Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert2Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert2Projection.java	(revision 26409)
@@ -0,0 +1,62 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class Eckert2Projection extends Projection {
+
+	private final static double FXC = 0.46065886596178063902;
+	private final static double FYC = 1.44720250911653531871;
+	private final static double C13 = 0.33333333333333333333;
+	private final static double ONEEPS = 1.0000001;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		out.x = FXC * lplam * (out.y = Math.sqrt(4. - 3. * Math.sin(Math.abs(lpphi))));
+		out.y = FYC * (2. - out.y);
+		if ( lpphi < 0.) out.y = -out.y;
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		out.x = xyx / (FXC * ( out.y = 2. - Math.abs(xyy) / FYC) );
+		out.y = (4. - out.y * out.y) * C13;
+		if (Math.abs(out.y) >= 1.) {
+			if (Math.abs(out.y) > ONEEPS)	throw new ProjectionException("I");
+			else
+				out.y = out.y < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+		} else
+			out.y = Math.asin(out.y);
+		if (xyy < 0)
+			out.y = -out.y;
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Eckert II";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert4Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert4Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert4Projection.java	(revision 26409)
@@ -0,0 +1,81 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class Eckert4Projection extends Projection {
+
+	private final static double C_x = .42223820031577120149;
+	private final static double C_y = 1.32650042817700232218;
+	private final static double RC_y = .75386330736002178205;
+	private final static double C_p = 3.57079632679489661922;
+	private final static double RC_p = .28004957675577868795;
+	private final static double EPS = 1e-7;
+	private final int NITER = 6;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double p, V, s, c;
+		int i;
+
+		p = C_p * Math.sin(lpphi);
+		V = lpphi * lpphi;
+		lpphi *= 0.895168 + V * ( 0.0218849 + V * 0.00826809 );
+		for (i = NITER; i > 0; --i) {
+			c = Math.cos(lpphi);
+			s = Math.sin(lpphi);
+			lpphi -= V = (lpphi + s * (c + 2.) - p) /
+				(1. + c * (c + 2.) - s * s);
+			if (Math.abs(V) < EPS)
+				break;
+		}
+		if (i == 0) {
+			out.x = C_x * lplam;
+			out.y = lpphi < 0. ? -C_y : C_y;
+		} else {
+			out.x = C_x * lplam * (1. + Math.cos(lpphi));
+			out.y = C_y * Math.sin(lpphi);
+		}
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double c;
+
+		out.y = ProjectionMath.asin(xyy / C_y);
+		out.x = xyx / (C_x * (1. + (c = Math.cos(out.y))));
+		out.y = ProjectionMath.asin((out.y + Math.sin(out.y) * (c + 2.)) / C_p);
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public boolean isEqualArea() {
+     return true;
+	}
+
+	public String toString() {
+		return "Eckert IV";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert5Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert5Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert5Projection.java	(revision 26409)
@@ -0,0 +1,50 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class Eckert5Projection extends Projection {
+
+	private final static double XF = 0.44101277172455148219;
+	private final static double RXF = 2.26750802723822639137;
+	private final static double YF = 0.88202554344910296438;
+	private final static double RYF = 1.13375401361911319568;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		out.x = XF * (1. + Math.cos(lpphi)) * lplam;
+		out.y = YF * lpphi;
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		out.x = RXF * xyx / (1. + Math.cos( out.y = RYF * xyy));
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Eckert V";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert6Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert6Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Eckert6Projection.java	(revision 26409)
@@ -0,0 +1,66 @@
+/*
+Copyright 2011 Martin Davis
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.*;
+
+public class Eckert6Projection extends PseudoCylindricalProjection {
+
+    private static final double n = 2.570796326794896619231321691;
+    private static final double C_y = Math.sqrt((2) / n);
+    private static final double C_x = C_y / 2;
+    private static final int MAX_ITER = 8;
+    private static final double LOOP_TOL = 1e-7;
+
+    public ProjCoordinate project(double lam, double phi, ProjCoordinate xy) {
+
+        int i;
+        double k, V;
+        k = n * Math.sin(phi);
+        for (i = MAX_ITER; i > 0;) {
+            phi -= V = (phi + Math.sin(phi) - k) / (1 + Math.cos(phi));
+            if (Math.abs(V) < LOOP_TOL) {
+                break;
+            }
+            --i;
+        }
+        if (i == 0) {
+            throw new ProjectionException("F_ERROR");
+        }
+
+        xy.x = C_x * lam * (1 + Math.cos(phi));
+        xy.y = C_y * phi;
+        return xy;
+    }
+
+    public ProjCoordinate projectInverse(double x, double y, ProjCoordinate lp) {
+        y /= C_y;
+        lp.y = Math.asin((y + Math.sin(y)) / n);
+        lp.x = x / (C_x * (1 + Math.cos(y)));
+        return lp;
+    }
+
+    public boolean hasInverse() {
+        return true;
+    }
+
+    public boolean isEqualArea() {
+        return true;
+    }
+
+    public String toString() {
+        return "Eckert VI";
+    }
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/EqualAreaAzimuthalProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/EqualAreaAzimuthalProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/EqualAreaAzimuthalProjection.java	(revision 26409)
@@ -0,0 +1,265 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import java.awt.Shape;
+import java.awt.geom.Ellipse2D;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class EqualAreaAzimuthalProjection extends AzimuthalProjection {
+
+	private double sinb1;
+	private double cosb1;
+	private double xmf;
+	private double ymf;
+	private double mmf;
+	private double qp;
+	private double dd;
+	private double rq;
+	private double[] apa;
+
+	public EqualAreaAzimuthalProjection() {
+		initialize();
+	}
+
+	public Object clone() {
+		EqualAreaAzimuthalProjection p = (EqualAreaAzimuthalProjection)super.clone();
+		if (apa != null)
+			p.apa = (double[])apa.clone();
+		return p;
+	}
+	
+	public void initialize() {
+		super.initialize();
+		if (spherical) {
+			if (mode == OBLIQUE) {
+				sinphi0 = Math.sin(projectionLatitude);
+				cosphi0 = Math.cos(projectionLatitude);
+			}
+		} else {
+			double sinphi;
+
+			qp = ProjectionMath.qsfn(1., e, one_es);
+			mmf = .5 / (1. - es);
+			apa = ProjectionMath.authset(es);
+			switch (mode) {
+			case NORTH_POLE:
+			case SOUTH_POLE:
+				dd = 1.;
+				break;
+			case EQUATOR:
+				dd = 1. / (rq = Math.sqrt(.5 * qp));
+				xmf = 1.;
+				ymf = .5 * qp;
+				break;
+			case OBLIQUE:
+				rq = Math.sqrt(.5 * qp);
+				sinphi = Math.sin(projectionLatitude);
+				sinb1 = ProjectionMath.qsfn(sinphi, e, one_es) / qp;
+				cosb1 = Math.sqrt(1. - sinb1 * sinb1);
+				dd = Math.cos(projectionLatitude) / (Math.sqrt(1. - es * sinphi * sinphi) *
+				   rq * cosb1);
+				ymf = (xmf = rq) / dd;
+				xmf *= dd;
+				break;
+			}
+		}
+	}
+
+	public ProjCoordinate project(double lam, double phi, ProjCoordinate xy) {
+		if (spherical) {
+			double  coslam, cosphi, sinphi;
+
+			sinphi = Math.sin(phi);
+			cosphi = Math.cos(phi);
+			coslam = Math.cos(lam);
+			switch (mode) {
+			case EQUATOR:
+				xy.y = 1. + cosphi * coslam;
+				if (xy.y <= EPS10) throw new ProjectionException();
+				xy.x = (xy.y = Math.sqrt(2. / xy.y)) * cosphi * Math.sin(lam);
+				xy.y *= mode == EQUATOR ? sinphi :
+				   cosphi0 * sinphi - sinphi0 * cosphi * coslam;
+				break;
+			case OBLIQUE:
+				xy.y = 1. + sinphi0 * sinphi + cosphi0 * cosphi * coslam;
+				if (xy.y <= EPS10) throw new ProjectionException();
+				xy.x = (xy.y = Math.sqrt(2. / xy.y)) * cosphi * Math.sin(lam);
+				xy.y *= mode == EQUATOR ? sinphi :
+				   cosphi0 * sinphi - sinphi0 * cosphi * coslam;
+				break;
+			case NORTH_POLE:
+				coslam = -coslam;
+			case SOUTH_POLE:
+				if (Math.abs(phi + projectionLatitude) < EPS10) throw new ProjectionException();
+				xy.y = ProjectionMath.QUARTERPI - phi * .5;
+				xy.y = 2. * (mode == SOUTH_POLE ? Math.cos(xy.y) : Math.sin(xy.y));
+				xy.x = xy.y * Math.sin(lam);
+				xy.y *= coslam;
+				break;
+			}
+		} else {
+			double coslam, sinlam, sinphi, q, sinb = 0, cosb = 0, b = 0;
+
+			coslam = Math.cos(lam);
+			sinlam = Math.sin(lam);
+			sinphi = Math.sin(phi);
+			q = ProjectionMath.qsfn(sinphi, e, one_es);
+			if (mode == OBLIQUE || mode == EQUATOR) {
+				sinb = q / qp;
+				cosb = Math.sqrt(1. - sinb * sinb);
+			}
+			switch (mode) {
+			case OBLIQUE:
+				b = 1. + sinb1 * sinb + cosb1 * cosb * coslam;
+				break;
+			case EQUATOR:
+				b = 1. + cosb * coslam;
+				break;
+			case NORTH_POLE:
+				b = ProjectionMath.HALFPI + phi;
+				q = qp - q;
+				break;
+			case SOUTH_POLE:
+				b = phi - ProjectionMath.HALFPI;
+				q = qp + q;
+				break;
+			}
+			if (Math.abs(b) < EPS10) throw new ProjectionException();
+			switch (mode) {
+			case OBLIQUE:
+				xy.y = ymf * ( b = Math.sqrt(2. / b) )
+				   * (cosb1 * sinb - sinb1 * cosb * coslam);
+				xy.x = xmf * b * cosb * sinlam;
+				break;
+			case EQUATOR:
+				xy.y = (b = Math.sqrt(2. / (1. + cosb * coslam))) * sinb * ymf; 
+				xy.x = xmf * b * cosb * sinlam;
+				break;
+			case NORTH_POLE:
+			case SOUTH_POLE:
+				if (q >= 0.) {
+					xy.x = (b = Math.sqrt(q)) * sinlam;
+					xy.y = coslam * (mode == SOUTH_POLE ? b : -b);
+				} else
+					xy.x = xy.y = 0.;
+				break;
+			}
+		}
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate lp) {
+		if (spherical) {
+			double  cosz = 0, rh, sinz = 0;
+
+			rh = ProjectionMath.distance(x, y);
+			if ((lp.y = rh * .5 ) > 1.) throw new ProjectionException();
+			lp.y = 2. * Math.asin(lp.y);
+			if (mode == OBLIQUE || mode == EQUATOR) {
+				sinz = Math.sin(lp.y);
+				cosz = Math.cos(lp.y);
+			}
+			switch (mode) {
+			case EQUATOR:
+				lp.y = Math.abs(rh) <= EPS10 ? 0. : Math.asin(y * sinz / rh);
+				x *= sinz;
+				y = cosz * rh;
+				break;
+			case OBLIQUE:
+				lp.y = Math.abs(rh) <= EPS10 ? projectionLatitude :
+				   Math.asin(cosz * sinphi0 + y * sinz * cosphi0 / rh);
+				x *= sinz * cosphi0;
+				y = (cosz - Math.sin(lp.y) * sinphi0) * rh;
+				break;
+			case NORTH_POLE:
+				y = -y;
+				lp.y = ProjectionMath.HALFPI - lp.y;
+				break;
+			case SOUTH_POLE:
+				lp.y -= ProjectionMath.HALFPI;
+				break;
+			}
+			lp.x = (y == 0. && (mode == EQUATOR || mode == OBLIQUE)) ?
+				0. : Math.atan2(x, y);
+		} else {
+			double cCe, sCe, q, rho, ab = 0;
+
+			switch (mode) {
+			case EQUATOR:
+			case OBLIQUE:
+				if ((rho = ProjectionMath.distance(x /= dd, y *=  dd)) < EPS10) {
+					lp.x = 0.;
+					lp.y = projectionLatitude;
+					return (lp);
+				}
+				cCe = Math.cos(sCe = 2. * Math.asin(.5 * rho / rq));
+				x *= (sCe = Math.sin(sCe));
+				if (mode == OBLIQUE) {
+					q = qp * (ab = cCe * sinb1 + y * sCe * cosb1 / rho);
+					y = rho * cosb1 * cCe - y * sinb1 * sCe;
+				} else {
+					q = qp * (ab = y * sCe / rho);
+					y = rho * cCe;
+				}
+				break;
+			case NORTH_POLE:
+				y = -y;
+			case SOUTH_POLE:
+				if ((q = (x * x + y * y)) == 0) {
+					lp.x = 0.;
+					lp.y = projectionLatitude;
+					return lp;
+				}
+				ab = 1. - q / qp;
+				if (mode == SOUTH_POLE)
+					ab = - ab;
+				break;
+			}
+			lp.x = Math.atan2(x, y);
+			lp.y = ProjectionMath.authlat(Math.asin(ab), apa);
+		}
+		return lp;
+	}
+
+	public Shape getBoundingShape() {
+		double r = 1.414 * a;
+		return new Ellipse2D.Double( -r, -r, 2*r, 2*r );
+	}
+
+	/**
+	 * Returns true if this projection is equal area
+	 */
+	public boolean isEqualArea() {
+		return true;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Lambert Equal Area Azimuthal";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/EquidistantAzimuthalProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/EquidistantAzimuthalProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/EquidistantAzimuthalProjection.java	(revision 26409)
@@ -0,0 +1,253 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import java.awt.Shape;
+import java.awt.geom.Ellipse2D;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class EquidistantAzimuthalProjection extends AzimuthalProjection {
+	
+	private final static double TOL = 1.e-8;
+
+	private int mode;
+	private double[] en;
+	private double M1;
+	private double N1;
+	private double Mp;
+	private double He;
+	private double G;
+	private double sinphi0, cosphi0;
+	
+	public EquidistantAzimuthalProjection() {
+		this(Math.toRadians(90.0), Math.toRadians(0.0));
+	}
+
+	public EquidistantAzimuthalProjection(double projectionLatitude, double projectionLongitude) {
+		super(projectionLatitude, projectionLongitude);
+		initialize();
+	}
+	
+	public Object clone() {
+		EquidistantAzimuthalProjection p = (EquidistantAzimuthalProjection)super.clone();
+		if (en != null)
+			p.en = (double[])en.clone();
+		return p;
+	}
+	
+	public void initialize() {
+		super.initialize();
+		if (Math.abs(Math.abs(projectionLatitude) - ProjectionMath.HALFPI) < EPS10) {
+			mode = projectionLatitude < 0. ? SOUTH_POLE : NORTH_POLE;
+			sinphi0 = projectionLatitude < 0. ? -1. : 1.;
+			cosphi0 = 0.;
+		} else if (Math.abs(projectionLatitude) < EPS10) {
+			mode = EQUATOR;
+			sinphi0 = 0.;
+			cosphi0 = 1.;
+		} else {
+			mode = OBLIQUE;
+			sinphi0 = Math.sin(projectionLatitude);
+			cosphi0 = Math.cos(projectionLatitude);
+		}
+		if (!spherical) {
+			en = ProjectionMath.enfn(es);
+			switch (mode) {
+			case NORTH_POLE:
+				Mp = ProjectionMath.mlfn(ProjectionMath.HALFPI, 1., 0., en);
+				break;
+			case SOUTH_POLE:
+				Mp = ProjectionMath.mlfn(-ProjectionMath.HALFPI, -1., 0., en);
+				break;
+			case EQUATOR:
+			case OBLIQUE:
+				N1 = 1. / Math.sqrt(1. - es * sinphi0 * sinphi0);
+				G = sinphi0 * (He = e / Math.sqrt(one_es));
+				He *= cosphi0;
+				break;
+			}
+		}
+	}
+
+	public ProjCoordinate project(double lam, double phi, ProjCoordinate xy) {
+		if (spherical) {
+			double  coslam, cosphi, sinphi;
+
+			sinphi = Math.sin(phi);
+			cosphi = Math.cos(phi);
+			coslam = Math.cos(lam);
+			switch (mode) {
+			case EQUATOR:
+			case OBLIQUE:
+				if (mode == EQUATOR)
+					xy.y = cosphi * coslam;
+				else
+					xy.y = sinphi0 * sinphi + cosphi0 * cosphi * coslam;
+				if (Math.abs(Math.abs(xy.y) - 1.) < TOL)
+					if (xy.y < 0.)
+						throw new ProjectionException(); 
+					else
+						xy.x = xy.y = 0.;
+				else {
+					xy.y = Math.acos(xy.y);
+					xy.y /= Math.sin(xy.y);
+					xy.x = xy.y * cosphi * Math.sin(lam);
+					xy.y *= (mode == EQUATOR) ? sinphi :
+				   		cosphi0 * sinphi - sinphi0 * cosphi * coslam;
+				}
+				break;
+			case NORTH_POLE:
+				phi = -phi;
+				coslam = -coslam;
+			case SOUTH_POLE:
+				if (Math.abs(phi - ProjectionMath.HALFPI) < EPS10)
+					throw new ProjectionException();
+				xy.x = (xy.y = (ProjectionMath.HALFPI + phi)) * Math.sin(lam);
+				xy.y *= coslam;
+				break;
+			}
+		} else {
+			double  coslam, cosphi, sinphi, rho, s, H, H2, c, Az, t, ct, st, cA, sA;
+
+			coslam = Math.cos(lam);
+			cosphi = Math.cos(phi);
+			sinphi = Math.sin(phi);
+			switch (mode) {
+			case NORTH_POLE:
+				coslam = - coslam;
+			case SOUTH_POLE:
+				xy.x = (rho = Math.abs(Mp - ProjectionMath.mlfn(phi, sinphi, cosphi, en))) *
+					Math.sin(lam);
+				xy.y = rho * coslam;
+				break;
+			case EQUATOR:
+			case OBLIQUE:
+				if (Math.abs(lam) < EPS10 && Math.abs(phi - projectionLatitude) < EPS10) {
+					xy.x = xy.y = 0.;
+					break;
+				}
+				t = Math.atan2(one_es * sinphi + es * N1 * sinphi0 *
+					Math.sqrt(1. - es * sinphi * sinphi), cosphi);
+				ct = Math.cos(t); st = Math.sin(t);
+				Az = Math.atan2(Math.sin(lam) * ct, cosphi0 * st - sinphi0 * coslam * ct);
+				cA = Math.cos(Az); sA = Math.sin(Az);
+				s = ProjectionMath.asin( Math.abs(sA) < TOL ?
+					(cosphi0 * st - sinphi0 * coslam * ct) / cA :
+					Math.sin(lam) * ct / sA );
+				H = He * cA;
+				H2 = H * H;
+				c = N1 * s * (1. + s * s * (- H2 * (1. - H2)/6. +
+					s * ( G * H * (1. - 2. * H2 * H2) / 8. +
+					s * ((H2 * (4. - 7. * H2) - 3. * G * G * (1. - 7. * H2)) /
+					120. - s * G * H / 48.))));
+				xy.x = c * sA;
+				xy.y = c * cA;
+				break;
+			}
+		}
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate lp) {
+		if (spherical) {
+			double cosc, c_rh, sinc;
+
+			if ((c_rh = ProjectionMath.distance(x, y)) > Math.PI) {
+				if (c_rh - EPS10 > Math.PI)
+					throw new ProjectionException(); 
+				c_rh = Math.PI;
+			} else if (c_rh < EPS10) {
+				lp.y = projectionLatitude;
+				lp.x = 0.;
+				return lp;
+			}
+			if (mode == OBLIQUE || mode == EQUATOR) {
+				sinc = Math.sin(c_rh);
+				cosc = Math.cos(c_rh);
+				if (mode == EQUATOR) {
+					lp.y = ProjectionMath.asin(y * sinc / c_rh);
+					x *= sinc;
+					y = cosc * c_rh;
+				} else {
+					lp.y = ProjectionMath.asin(cosc * sinphi0 + y * sinc * cosphi0 /
+						c_rh);
+					y = (cosc - sinphi0 * Math.sin(lp.y)) * c_rh;
+					x *= sinc * cosphi0;
+				}
+				lp.x = y == 0. ? 0. : Math.atan2(x, y);
+			} else if (mode == NORTH_POLE) {
+				lp.y = ProjectionMath.HALFPI - c_rh;
+				lp.x = Math.atan2(x, -y);
+			} else {
+				lp.y = c_rh - ProjectionMath.HALFPI;
+				lp.x = Math.atan2(x, y);
+			}
+		} else {
+			double c, Az, cosAz, A, B, D, E, F, psi, t;
+			int i;
+
+			if ((c = ProjectionMath.distance(x, y)) < EPS10) {
+				lp.y = projectionLatitude;
+				lp.x = 0.;
+				return (lp);
+			}
+			if (mode == OBLIQUE || mode == EQUATOR) {
+				cosAz = Math.cos(Az = Math.atan2(x, y));
+				t = cosphi0 * cosAz;
+				B = es * t / one_es;
+				A = - B * t;
+				B *= 3. * (1. - A) * sinphi0;
+				D = c / N1;
+				E = D * (1. - D * D * (A * (1. + A) / 6. + B * (1. + 3.*A) * D / 24.));
+				F = 1. - E * E * (A / 2. + B * E / 6.);
+				psi = ProjectionMath.asin(sinphi0 * Math.cos(E) + t * Math.sin(E));
+				lp.x = ProjectionMath.asin(Math.sin(Az) * Math.sin(E) / Math.cos(psi));
+				if ((t = Math.abs(psi)) < EPS10)
+					lp.y = 0.;
+				else if (Math.abs(t - ProjectionMath.HALFPI) < 0.)
+					lp.y = ProjectionMath.HALFPI;
+				else
+					lp.y = Math.atan((1. - es * F * sinphi0 / Math.sin(psi)) * Math.tan(psi) / one_es);
+			} else {
+				lp.y = ProjectionMath.inv_mlfn(mode == NORTH_POLE ? Mp - c : Mp + c, es, en);
+				lp.x = Math.atan2(x, mode == NORTH_POLE ? -y : y);
+			}
+		}
+		return lp;
+	}
+	
+	public Shape getBoundingShape() {
+		double r = ProjectionMath.HALFPI * a;
+		return new Ellipse2D.Double( -r, -r, 2*r, 2*r );
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Equidistant Azimuthal";
+	}
+	
+}
+
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/EquidistantConicProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/EquidistantConicProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/EquidistantConicProjection.java	(revision 26409)
@@ -0,0 +1,130 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+/**
+ * The Equidistant Conic projection.
+ */
+public class EquidistantConicProjection extends ConicProjection {
+
+	private double standardLatitude1;
+	private double standardLatitude2;
+	
+	private double eccentricity = 0.822719;
+	private double eccentricity2 = eccentricity*eccentricity;
+	private double eccentricity4 = eccentricity2*eccentricity2;
+	private double eccentricity6 = eccentricity2*eccentricity4;
+	private double radius = 1;
+
+	private boolean northPole;
+	private double f, n, rho0;
+
+	public EquidistantConicProjection() {
+		minLatitude = ProjectionMath.degToRad(10);
+		maxLatitude = ProjectionMath.degToRad(70);
+		minLongitude = ProjectionMath.degToRad(-90);
+		maxLongitude = ProjectionMath.degToRad(90);
+		standardLatitude1 = Math.toDegrees( 60 );
+		standardLatitude2 = Math.toDegrees( 20 );
+
+		initialize(ProjectionMath.degToRad(0), ProjectionMath.degToRad(37.5), standardLatitude1, standardLatitude2);
+	}
+
+	public ProjCoordinate project(ProjCoordinate in, ProjCoordinate out) {
+		double lon = ProjectionMath.normalizeLongitude(in.x-projectionLongitude);
+		double lat = in.y;
+		double rho,theta,hold1,hold2,hold3;
+		
+		hold2 = Math.pow(((1.0 - eccentricity * Math.sin(lat)) / (1.0 + eccentricity * Math.sin(lat))), 0.5 * eccentricity);
+		hold3 = Math.tan(ProjectionMath.QUARTERPI - 0.5 * lat);
+		hold1 = (hold3 == 0.0) ? 0.0 : Math.pow(hold3 / hold2, n);
+		rho = radius * f * hold1;
+		theta = n * lon;
+
+		out.x = rho * Math.sin(theta);
+		out.y = rho0 - rho * Math.cos(theta);
+		return out;
+	}
+
+	public ProjCoordinate inverseProject(ProjCoordinate in, ProjCoordinate out) {
+		double theta, temp, rho, t, tphi, phi = 0, delta;
+		
+		theta = Math.atan(in.x / (rho0 - in.y));
+		out.x = (theta / n) + projectionLongitude;
+		
+		temp = in.x * in.x + (rho0 - in.y) * (rho0 - in.y);
+		rho = Math.sqrt(temp);
+		if (n < 0)
+			rho = - rho;
+		t = Math.pow((rho / (radius * f)), 1./n);
+		tphi = ProjectionMath.HALFPI - 2.0 * Math.atan(t);
+		delta = 1.0;
+		for (int i = 0; i < 100 && delta > 1.0e-8; i++) {
+			temp = (1.0 - eccentricity * Math.sin(tphi)) / (1.0 + eccentricity * Math.sin(tphi));
+			phi = ProjectionMath.HALFPI - 2.0 * Math.atan(t * Math.pow(temp, 0.5 * eccentricity));
+			delta = Math.abs(Math.abs(tphi) - Math.abs(phi));
+			tphi = phi;
+		}
+		out.y = phi;
+		return out;
+	}
+
+	private void initialize(double rlong0, double rlat0, double standardLatitude1, double standardLatitude2) {
+		super.initialize();
+		double t_standardLatitude1, m_standardLatitude1, t_standardLatitude2, m_standardLatitude2, t_rlat0;
+		
+		northPole = rlat0 > 0.0;
+		projectionLatitude = northPole ? ProjectionMath.HALFPI : -ProjectionMath.HALFPI;
+		
+		t_standardLatitude1 = Math.tan(ProjectionMath.QUARTERPI - 0.5 * standardLatitude1) / Math.pow((1.0 - eccentricity * 
+			Math.sin(standardLatitude1)) /(1.0 + eccentricity * Math.sin(standardLatitude1)), 0.5 * eccentricity);
+		m_standardLatitude1 = Math.cos(standardLatitude1) / Math.sqrt(1.0 - eccentricity2 
+			* Math.pow(Math.sin(standardLatitude1), 2.0));
+		t_standardLatitude2 = Math.tan(ProjectionMath.QUARTERPI - 0.5 * standardLatitude2) / Math.pow((1.0 - eccentricity *
+			Math.sin(standardLatitude2)) /(1.0 + eccentricity * Math.sin(standardLatitude2)), 0.5 * eccentricity);
+		m_standardLatitude2 = Math.cos(standardLatitude2) / Math.sqrt(1.0 - eccentricity2 
+			* Math.pow(Math.sin(standardLatitude2), 2.0));
+		t_rlat0 = Math.tan(ProjectionMath.QUARTERPI - 0.5 * rlat0) /
+			Math.pow((1.0 - eccentricity * Math.sin(rlat0)) /
+			(1.0 + eccentricity * Math.sin(rlat0)), 0.5 * eccentricity);
+		
+		if (standardLatitude1 != standardLatitude2)
+			n = (Math.log(m_standardLatitude1) - Math.log(m_standardLatitude2))/(Math.log(t_standardLatitude1) - Math.log(t_standardLatitude2));
+		else
+			n = Math.sin(standardLatitude1);
+		
+		f = m_standardLatitude1/(n * Math.pow(t_standardLatitude1, n));
+		projectionLongitude = rlong0;
+		rho0 = radius * f * Math.pow(t_rlat0,n);
+	}
+	
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Equidistant Conic";
+	}
+
+}
+
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/EulerProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/EulerProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/EulerProjection.java	(revision 26409)
@@ -0,0 +1,32 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+public class EulerProjection extends SimpleConicProjection {
+
+	public EulerProjection() {
+		super( SimpleConicProjection.EULER );
+	}
+
+	public String toString() {
+		return "Euler";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/FaheyProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/FaheyProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/FaheyProjection.java	(revision 26409)
@@ -0,0 +1,53 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class FaheyProjection extends Projection {
+
+	private final static double TOL = 1e-6;
+	
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		out.y = 1.819152 * ( out.x = Math.tan(0.5 * lpphi) );
+		out.x = 0.819152 * lplam * asqrt(1 - out.x * out.x);
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		out.y = 2. * Math.atan(out.y /= 1.819152);
+		out.x = Math.abs(out.y = 1. - xyy * xyy) < TOL ? 0. :
+			xyx / (0.819152 * Math.sqrt(xyy));
+		return out;
+	}
+
+	private double asqrt(double v) {
+		return (v <= 0) ? 0. : Math.sqrt(v);
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Fahey";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/FoucautProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/FoucautProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/FoucautProjection.java	(revision 26409)
@@ -0,0 +1,32 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+public class FoucautProjection extends SineTangentSeriesProjection {
+
+	public FoucautProjection() {
+		super( 2., 2., true );
+	}
+	
+	public String toString() {
+		return "Foucaut";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/FoucautSinusoidalProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/FoucautSinusoidalProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/FoucautSinusoidalProjection.java	(revision 26409)
@@ -0,0 +1,78 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class FoucautSinusoidalProjection extends Projection {
+	private double n, n1;
+
+	private final static int MAX_ITER = 10;
+	private final static double LOOP_TOL = 1e-7;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double t;
+
+		t = Math.cos(lpphi);
+		out.x = lplam * t / (n + n1 * t);
+		out.y = n * lpphi + n1 * Math.sin(lpphi);
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double V;
+		int i;
+
+		if (n != 0) {
+			out.y = xyy;
+			for (i = MAX_ITER; i > 0; --i) {
+				out.y -= V = (n * out.y + n1 * Math.sin(out.y) - xyy ) /
+					(n + n1 * Math.cos(out.y));
+				if (Math.abs(V) < LOOP_TOL)
+					break;
+			}
+			if (i == 0)
+				out.y = xyy < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+		} else
+			out.y = ProjectionMath.asin(xyy);
+		V = Math.cos(out.y);
+		out.x = xyx * (n + n1 * V) / V;
+		return out;
+	}
+
+	public void initialize() {
+		super.initialize();
+//		n = pj_param(params, "dn").f;
+		if (n < 0. || n > 1.)
+			throw new ProjectionException("-99");
+		n1 = 1. - n;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Foucaut Sinusoidal";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/GallProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/GallProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/GallProjection.java	(revision 26409)
@@ -0,0 +1,51 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class GallProjection extends Projection {
+
+	private final static double YF = 1.70710678118654752440;
+	private final static double XF = 0.70710678118654752440;
+	private final static double RYF = 0.58578643762690495119;
+	private final static double RXF = 1.41421356237309504880;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		out.x = XF * lplam;
+		out.y = YF * Math.tan(.5 * lpphi);
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		out.x = RXF * xyx;
+		out.y = 2. * Math.atan(xyy * RYF);
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Gall (Gall Stereographic)";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/GaussProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/GaussProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/GaussProjection.java	(revision 26409)
@@ -0,0 +1,91 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class GaussProjection extends Projection {
+
+	private final static int MAX_ITER = 20;
+	private final static double DEL_TOL = 1.0e-14;
+
+  private double C;
+  private double K;
+//  private double e;
+  protected double rc;
+  protected double phic0;
+  private double ratexp;
+
+	public GaussProjection() {
+	}
+
+	public ProjCoordinate project(double x, double y, ProjCoordinate out) {
+    out.y = 2.0 * Math.atan( K * Math.pow(Math.tan(0.5 * y + ProjectionMath.QUARTERPI), this.C) * srat(this.e * Math.sin(y), this.ratexp) ) - ProjectionMath.HALFPI;
+    out.x = C * x;
+    return out;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate out) {
+    double lon = x / this.C;
+    double lat = y;
+    double num = Math.pow(Math.tan(0.5 * lat + ProjectionMath.QUARTERPI)/this.K, 1./this.C);
+    int i;
+    for (i = MAX_ITER; i > 0; --i) {
+      lat = 2.0 * Math.atan(num * srat(this.e * Math.sin(y), -0.5 * this.e)) - ProjectionMath.HALFPI;
+      if (Math.abs(lat - y) < DEL_TOL) break;
+      y = lat;
+    } 
+    /* convergence failed */
+    if (i <= 0) {
+      throw new ProjectionException(this, ProjectionException.ERR_17);
+    }
+    out.x = lon;
+    out.y = lat;
+		return out;
+	}
+
+	public void initialize() {
+		super.initialize();
+    double sphi = Math.sin(projectionLatitude);
+    double cphi = Math.cos(projectionLatitude);  
+    cphi *= cphi;
+    rc = Math.sqrt(1.0 - es) / (1.0 - es * sphi * sphi);
+    C = Math.sqrt(1.0 + es * cphi * cphi / (1.0 - es));
+    phic0 = Math.asin(sphi / C);
+    ratexp = 0.5 * C * e;
+    K = Math.tan(0.5 * phic0 + ProjectionMath.QUARTERPI) / (Math.pow(Math.tan(0.5*projectionLatitude + ProjectionMath.QUARTERPI), this.C) * srat(e*sphi, ratexp));
+	}
+
+  private static double srat(double esinp, double exp) {
+    return Math.pow((1.0 - esinp) / (1.0 + esinp), exp);
+}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Gauss";
+	}
+
+}
+
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Ginsburg8Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Ginsburg8Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Ginsburg8Projection.java	(revision 26409)
@@ -0,0 +1,44 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class Ginsburg8Projection extends Projection {
+
+	private final static double Cl = 0.000952426;
+	private final static double Cp = 0.162388;
+	private final static double C12 = 0.08333333333333333;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double t = lpphi * lpphi;
+
+		out.y = lpphi * (1. + t * C12);
+		out.x = lplam * (1. - Cp * t);
+		t = lplam * lplam;
+		out.x *= (0.87 - Cl * t * t);
+		return out;
+	}
+
+	public String toString() {
+		return "Ginsburg VIII (TsNIIGAiK)";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/GnomonicAzimuthalProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/GnomonicAzimuthalProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/GnomonicAzimuthalProjection.java	(revision 26409)
@@ -0,0 +1,131 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class GnomonicAzimuthalProjection extends AzimuthalProjection {
+	
+	public GnomonicAzimuthalProjection() {
+		this(Math.toRadians(90.0), Math.toRadians(0.0));
+	}
+
+	public GnomonicAzimuthalProjection(double projectionLatitude, double projectionLongitude) {
+		super(projectionLatitude, projectionLongitude);
+		minLatitude = Math.toRadians(0);
+		maxLatitude = Math.toRadians(90);
+		initialize();
+	}
+	
+	public void initialize() {
+		super.initialize();
+	}
+
+	public ProjCoordinate project(double lam, double phi, ProjCoordinate xy) {
+		double sinphi = Math.sin(phi);
+		double cosphi = Math.cos(phi);
+		double coslam = Math.cos(lam);
+
+		switch (mode) {
+		case EQUATOR:
+			xy.y = cosphi * coslam;
+			break;
+		case OBLIQUE:
+			xy.y = sinphi0 * sinphi + cosphi0 * cosphi * coslam;
+			break;
+		case SOUTH_POLE:
+			xy.y = -sinphi;
+			break;
+		case NORTH_POLE:
+			xy.y = sinphi;
+			break;
+		}
+		if (Math.abs(xy.y) <= EPS10)
+			throw new ProjectionException();
+		xy.x = (xy.y = 1. / xy.y) * cosphi * Math.sin(lam);
+		switch (mode) {
+		case EQUATOR:
+			xy.y *= sinphi;
+			break;
+		case OBLIQUE:
+			xy.y *= cosphi0 * sinphi - sinphi0 * cosphi * coslam;
+			break;
+		case NORTH_POLE:
+			coslam = -coslam;
+		case SOUTH_POLE:
+			xy.y *= cosphi * coslam;
+			break;
+		}
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate lp) {
+		double  rh, cosz, sinz;
+
+		rh = ProjectionMath.distance(x, y);
+		sinz = Math.sin(lp.y = Math.atan(rh));
+		cosz = Math.sqrt(1. - sinz * sinz);
+		if (Math.abs(rh) <= EPS10) {
+			lp.y = projectionLatitude;
+			lp.x = 0.;
+		} else {
+			switch (mode) {
+			case OBLIQUE:
+				lp.y = cosz * sinphi0 + y * sinz * cosphi0 / rh;
+				if (Math.abs(lp.y) >= 1.)
+					lp.y = lp.y > 0. ? ProjectionMath.HALFPI : - ProjectionMath.HALFPI;
+				else
+					lp.y = Math.asin(lp.y);
+				y = (cosz - sinphi0 * Math.sin(lp.y)) * rh;
+				x *= sinz * cosphi0;
+				break;
+			case EQUATOR:
+				lp.y = y * sinz / rh;
+				if (Math.abs(lp.y) >= 1.)
+					lp.y = lp.y > 0. ? ProjectionMath.HALFPI : - ProjectionMath.HALFPI;
+				else
+					lp.y = Math.asin(lp.y);
+				y = cosz * rh;
+				x *= sinz;
+				break;
+			case SOUTH_POLE:
+				lp.y -= ProjectionMath.HALFPI;
+				break;
+			case NORTH_POLE:
+				lp.y = ProjectionMath.HALFPI - lp.y;
+				y = -y;
+				break;
+			}
+			lp.x = Math.atan2(x, y);
+		}
+		return lp;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Gnomonic Azimuthal";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/GoodeProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/GoodeProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/GoodeProjection.java	(revision 26409)
@@ -0,0 +1,60 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class GoodeProjection extends Projection {
+
+	private final static double Y_COR = 0.05280;
+	private final static double PHI_LIM = .71093078197902358062;
+
+	private SinusoidalProjection sinu = new SinusoidalProjection();
+	private MolleweideProjection moll = new MolleweideProjection();
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		if (Math.abs(lpphi) <= PHI_LIM)
+			out = sinu.project(lplam, lpphi, out);
+		else {
+			out = moll.project(lplam, lpphi, out);
+			out.y -= lpphi >= 0.0 ? Y_COR : -Y_COR;
+		}
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		if (Math.abs(xyy) <= PHI_LIM)
+			out = sinu.projectInverse(xyx, xyy, out);
+		else {
+			xyy += xyy >= 0.0 ? Y_COR : -Y_COR;
+			out = moll.projectInverse(xyx, xyy, out);
+		}
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Goode Homolosine";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/HammerProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/HammerProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/HammerProjection.java	(revision 26409)
@@ -0,0 +1,86 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+
+public class HammerProjection extends PseudoCylindricalProjection {
+
+	private double w = 0.5;
+	private double m = 1;
+	private double rm;
+
+	public HammerProjection() {
+	}
+	
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate xy) {
+		double cosphi, d;
+
+		d = Math.sqrt(2./(1. + (cosphi = Math.cos(lpphi)) * Math.cos(lplam *= w)));
+		xy.x = m * d * cosphi * Math.sin(lplam);
+		xy.y = rm * d * Math.sin(lpphi);
+		return xy;
+	}
+
+	public void initialize() {
+		super.initialize();
+		if ((w = Math.abs(w)) <= 0.)
+			throw new ProjectionException("-27");
+		else
+			w = .5;
+		if ((m = Math.abs(m)) <= 0.)
+			throw new ProjectionException("-27");
+		else
+			m = 1.;
+		rm = 1. / m;
+		m /= w;
+		es = 0.;
+	}
+
+	/**
+	 * Returns true if this projection is equal area
+	 */
+	public boolean isEqualArea() {
+		return true;
+	}
+
+	// Properties
+	public void setW( double w ) {
+		this.w = w;
+	}
+	
+	public double getW() {
+		return w;
+	}
+	
+	public void setM( double m ) {
+		this.m = m;
+	}
+	
+	public double getM() {
+		return m;
+	}
+	
+	public String toString() {
+		return "Hammer & Eckert-Greifendorff";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/HatanoProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/HatanoProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/HatanoProjection.java	(revision 26409)
@@ -0,0 +1,84 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class HatanoProjection extends Projection {
+
+	private final static int NITER = 20;
+	private final static double EPS = 1e-7;
+	private final static double ONETOL = 1.000001;
+	private final static double CN = 2.67595;
+	private final static double CS = 2.43763;
+	private final static double RCN = 0.37369906014686373063;
+	private final static double RCS = 0.41023453108141924738;
+	private final static double FYCN = 1.75859;
+	private final static double FYCS = 1.93052;
+	private final static double RYCN = 0.56863737426006061674;
+	private final static double RYCS = 0.51799515156538134803;
+	private final static double FXC = 0.85;
+	private final static double RXC = 1.17647058823529411764;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double th1, c;
+		int i;
+
+		c = Math.sin(lpphi) * (lpphi < 0. ? CS : CN);
+		for (i = NITER; i > 0; --i) {
+			lpphi -= th1 = (lpphi + Math.sin(lpphi) - c) / (1. + Math.cos(lpphi));
+			if (Math.abs(th1) < EPS) break;
+		}
+		out.x = FXC * lplam * Math.cos(lpphi *= .5);
+		out.y = Math.sin(lpphi) * (lpphi < 0. ? FYCS : FYCN);
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double th;
+
+		th = xyy * ( xyy < 0. ? RYCS : RYCN);
+		if (Math.abs(th) > 1.)
+			if (Math.abs(th) > ONETOL)	throw new ProjectionException("I");
+			else			th = th > 0. ? ProjectionMath.HALFPI : - ProjectionMath.HALFPI;
+		else
+			th = Math.asin(th);
+		out.x = RXC * xyx / Math.cos(th);
+		th += th;
+		out.y = (th + Math.sin(th)) * (xyy < 0. ? RCS : RCN);
+		if (Math.abs(out.y) > 1.)
+			if (Math.abs(out.y) > ONETOL)	throw new ProjectionException("I");
+			else			out.y = out.y > 0. ? ProjectionMath.HALFPI : - ProjectionMath.HALFPI;
+		else
+			out.y = Math.asin(out.y);
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Hatano Asymmetrical Equal Area";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/KavraiskyVProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/KavraiskyVProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/KavraiskyVProjection.java	(revision 26409)
@@ -0,0 +1,32 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+public class KavraiskyVProjection extends SineTangentSeriesProjection {
+
+	public KavraiskyVProjection() {
+		super( 1.50488, 1.35439, false );
+	}
+	
+	public String toString() {
+		return "Kavraisky V";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LagrangeProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LagrangeProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LagrangeProjection.java	(revision 26409)
@@ -0,0 +1,87 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class LagrangeProjection extends Projection {
+
+	// Parameters
+	private double hrw;
+	private double rw = 1.4;
+	private double a1;
+	private double phi1;
+
+	private final static double TOL = 1e-10;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate xy) {
+		double v, c;
+
+		if ( Math.abs(Math.abs(lpphi) - ProjectionMath.HALFPI) < TOL) {
+			xy.x = 0;
+			xy.y = lpphi < 0 ? -2. : 2.;
+		} else {
+			lpphi = Math.sin(lpphi);
+			v = a1 * Math.pow((1. + lpphi)/(1. - lpphi), hrw);
+			if ((c = 0.5 * (v + 1./v) + Math.cos(lplam *= rw)) < TOL)
+				throw new ProjectionException();
+			xy.x = 2. * Math.sin(lplam) / c;
+			xy.y = (v - 1./v) / c;
+		}
+		return xy;
+	}
+
+	public void setW( double w ) {
+		this.rw = w;
+	}
+	
+	public double getW() {
+		return rw;
+	}
+
+	public void initialize() {
+		super.initialize();
+		if (rw <= 0)
+			throw new ProjectionException("-27");
+		hrw = 0.5 * (rw = 1. / rw);
+		phi1 = projectionLatitude1;
+		if (Math.abs(Math.abs(phi1 = Math.sin(phi1)) - 1.) < TOL)
+			throw new ProjectionException("-22");
+		a1 = Math.pow((1. - phi1)/(1. + phi1), hrw);
+	}
+
+	/**
+	 * Returns true if this projection is conformal
+	 */
+	public boolean isConformal() {
+		return true;
+	}
+	
+	public boolean hasInverse() {
+		return false;
+	}
+
+	public String toString() {
+		return "Lagrange";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LambertConformalConicProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LambertConformalConicProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LambertConformalConicProjection.java	(revision 26409)
@@ -0,0 +1,144 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.datum.Ellipsoid;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class LambertConformalConicProjection extends ConicProjection {
+
+	private double n;
+	private double rho0;
+	private double c;
+
+	public LambertConformalConicProjection() {
+		minLatitude = Math.toRadians(0);
+		maxLatitude = Math.toRadians(80.0);
+		projectionLatitude = ProjectionMath.QUARTERPI;
+		projectionLatitude1 = 0;
+		projectionLatitude2 = 0;
+		initialize();
+	}
+	
+	/**
+	* Set up a projection suitable for State Place Coordinates.
+	*/
+	public LambertConformalConicProjection(Ellipsoid ellipsoid, double lon_0, double lat_1, double lat_2, double lat_0, double x_0, double y_0) {
+		setEllipsoid(ellipsoid);
+		projectionLongitude = lon_0;
+		projectionLatitude = lat_0;
+		scaleFactor = 1.0;
+		falseEasting = x_0;
+		falseNorthing = y_0;
+		projectionLatitude1 = lat_1;
+		projectionLatitude2 = lat_2;
+		initialize();
+	}
+	
+	public ProjCoordinate project(double x, double y, ProjCoordinate out) {
+		double rho;
+		if (Math.abs(Math.abs(y) - ProjectionMath.HALFPI) < 1e-10)
+			rho = 0.0;
+		else {
+			rho = c * (spherical ? 
+			    Math.pow(Math.tan(ProjectionMath.QUARTERPI + .5 * y), -n) :
+			      Math.pow(ProjectionMath.tsfn(y, Math.sin(y), e), n));
+    }
+		out.x = scaleFactor * (rho * Math.sin(x *= n));
+		out.y = scaleFactor * (rho0 - rho * Math.cos(x));
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate out) {
+		x /= scaleFactor;
+		y /= scaleFactor;
+		double rho = ProjectionMath.distance(x, y = rho0 - y);
+		if (rho != 0) {
+			if (n < 0.0) {
+				rho = -rho;
+				x = -x;
+				y = -y;
+			}
+			if (spherical)
+				out.y = 2.0 * Math.atan(Math.pow(c / rho, 1.0/n)) - ProjectionMath.HALFPI;
+			else
+				out.y = ProjectionMath.phi2(Math.pow(rho / c, 1.0/n), e);
+			out.x = Math.atan2(x, y) / n;
+		} else {
+			out.x = 0.0;
+			out.y = n > 0.0 ? ProjectionMath.HALFPI : -ProjectionMath.HALFPI;
+		}
+		return out;
+	}
+
+	public void initialize() {
+		super.initialize();
+		double cosphi, sinphi;
+		boolean secant;
+
+		if ( projectionLatitude1 == 0 )
+			projectionLatitude1 = projectionLatitude2 = projectionLatitude;
+
+		if (Math.abs(projectionLatitude1 + projectionLatitude2) < 1e-10)
+			throw new ProjectionException();
+		n = sinphi = Math.sin(projectionLatitude1);
+		cosphi = Math.cos(projectionLatitude1);
+		secant = Math.abs(projectionLatitude1 - projectionLatitude2) >= 1e-10;
+		spherical = (es == 0.0);
+		if (!spherical) {
+			double ml1, m1;
+
+			m1 = ProjectionMath.msfn(sinphi, cosphi, es);
+			ml1 = ProjectionMath.tsfn(projectionLatitude1, sinphi, e);
+			if (secant) {
+				n = Math.log(m1 /
+				   ProjectionMath.msfn(sinphi = Math.sin(projectionLatitude2), Math.cos(projectionLatitude2), es));
+				n /= Math.log(ml1 / ProjectionMath.tsfn(projectionLatitude2, sinphi, e));
+			}
+			c = (rho0 = m1 * Math.pow(ml1, -n) / n);
+			rho0 *= (Math.abs(Math.abs(projectionLatitude) - ProjectionMath.HALFPI) < 1e-10) ? 0. :
+				Math.pow(ProjectionMath.tsfn(projectionLatitude, Math.sin(projectionLatitude), e), n);
+		} else {
+			if (secant)
+				n = Math.log(cosphi / Math.cos(projectionLatitude2)) /
+				   Math.log(Math.tan(ProjectionMath.QUARTERPI + .5 * projectionLatitude2) /
+				   Math.tan(ProjectionMath.QUARTERPI + .5 * projectionLatitude1));
+			c = cosphi * Math.pow(Math.tan(ProjectionMath.QUARTERPI + .5 * projectionLatitude1), n) / n;
+			rho0 = (Math.abs(Math.abs(projectionLatitude) - ProjectionMath.HALFPI) < 1e-10) ? 0. :
+				c * Math.pow(Math.tan(ProjectionMath.QUARTERPI + .5 * projectionLatitude), -n);
+		}
+	}
+	
+	/**
+	 * Returns true if this projection is conformal
+	 */
+	public boolean isConformal() {
+		return true;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Lambert Conformal Conic";
+	}
+
+}
+
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LambertEqualAreaConicProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LambertEqualAreaConicProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LambertEqualAreaConicProjection.java	(revision 26409)
@@ -0,0 +1,42 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class LambertEqualAreaConicProjection extends AlbersProjection {
+
+	public LambertEqualAreaConicProjection() {
+		this( false );
+	}
+
+	public LambertEqualAreaConicProjection( boolean south ) {
+		minLatitude = Math.toRadians(0);
+		maxLatitude = Math.toRadians(90);
+		projectionLatitude1 = south ? -ProjectionMath.QUARTERPI : ProjectionMath.QUARTERPI;
+		projectionLatitude2 = south ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+		initialize();
+	}
+
+	public String toString() {
+		return "Lambert Equal Area Conic";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LandsatProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LandsatProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LandsatProjection.java	(revision 26409)
@@ -0,0 +1,212 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class LandsatProjection extends Projection {
+
+	private double a2, a4, b, c1, c3;
+	private double q, t, u, w, p22, sa, ca, xj, rlm, rlm2;
+
+	private final static double TOL = 1e-7;
+	private final static double PI_HALFPI = 4.71238898038468985766;
+	private final static double TWOPI_HALFPI = 7.85398163397448309610;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate xy) {
+		int l, nn;
+		double lamt = 0, xlam, sdsq, c, d, s, lamdp = 0, phidp, lampp, tanph,
+			lamtp, cl, sd, sp, fac, sav, tanphi;
+
+		if (lpphi > ProjectionMath.HALFPI)
+			lpphi = ProjectionMath.HALFPI;
+		else if (lpphi < -ProjectionMath.HALFPI)
+			lpphi = -ProjectionMath.HALFPI;
+		lampp = lpphi >= 0. ? ProjectionMath.HALFPI : PI_HALFPI;
+		tanphi = Math.tan(lpphi);
+		for (nn = 0;;) {
+			sav = lampp;
+			lamtp = lplam + p22 * lampp;
+			cl = Math.cos(lamtp);
+			if (Math.abs(cl) < TOL)
+				lamtp -= TOL;
+			fac = lampp - Math.sin(lampp) * (cl < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI);
+			for (l = 50; l > 0; --l) {
+				lamt = lplam + p22 * sav;
+				if (Math.abs(c = Math.cos(lamt)) < TOL)
+					lamt -= TOL;
+				xlam = (one_es * tanphi * sa + Math.sin(lamt) * ca) / c;
+				lamdp = Math.atan(xlam) + fac;
+				if (Math.abs(Math.abs(sav) - Math.abs(lamdp)) < TOL)
+					break;
+				sav = lamdp;
+			}
+			if (l == 0 || ++nn >= 3 || (lamdp > rlm && lamdp < rlm2))
+				break;
+			if (lamdp <= rlm)
+				lampp = TWOPI_HALFPI;
+			else if (lamdp >= rlm2)
+				lampp = ProjectionMath.HALFPI;
+		}
+		if (l != 0) {
+			sp = Math.sin(lpphi);
+			phidp = ProjectionMath.asin((one_es * ca * sp - sa * Math.cos(lpphi) * 
+				Math.sin(lamt)) / Math.sqrt(1. - es * sp * sp));
+			tanph = Math.log(Math.tan(ProjectionMath.QUARTERPI + .5 * phidp));
+			sd = Math.sin(lamdp);
+			sdsq = sd * sd;
+			s = p22 * sa * Math.cos(lamdp) * Math.sqrt((1. + t * sdsq)
+				 / ((1. + w * sdsq) * (1. + q * sdsq)));
+			d = Math.sqrt(xj * xj + s * s);
+			xy.x = b * lamdp + a2 * Math.sin(2. * lamdp) + a4 *
+				Math.sin(lamdp * 4.) - tanph * s / d;
+			xy.y = c1 * sd + c3 * Math.sin(lamdp * 3.) + tanph * xj / d;
+		} else
+			xy.x = xy.y = Double.POSITIVE_INFINITY;
+		return xy;
+	}
+
+/*
+	public Point2D.Double projectInverse(double xyx, double xyy, Point2D.Double out) {
+		int nn;
+		double lamt, sdsq, s, lamdp, phidp, sppsq, dd, sd, sl, fac, scl, sav, spp;
+
+		lamdp = xy.x / b;
+		nn = 50;
+		do {
+			sav = lamdp;
+			sd = Math.sin(lamdp);
+			sdsq = sd * sd;
+			s = p22 * sa * Math.cos(lamdp) * sqrt((1. + t * sdsq)
+				 / ((1. + w * sdsq) * (1. + q * sdsq)));
+			lamdp = xy.x + xy.y * s / xj - a2 * Math.sin(
+				2. * lamdp) - a4 * Math.sin(lamdp * 4.) - s / xj * (
+				c1 * Math.sin(lamdp) + c3 * Math.sin(lamdp * 3.));
+			lamdp /= b;
+		} while (Math.abs(lamdp - sav) >= TOL && --nn);
+		sl = Math.sin(lamdp);
+		fac = exp(sqrt(1. + s * s / xj / xj) * (xy.y - 
+			c1 * sl - c3 * Math.sin(lamdp * 3.)));
+		phidp = 2. * (Math.atan(fac) - FORTPI);
+		dd = sl * sl;
+		if (Math.abs(Math.cos(lamdp)) < TOL)
+			lamdp -= TOL;
+		spp = Math.sin(phidp);
+		sppsq = spp * spp;
+		lamt = Math.atan(((1. - sppsq * rone_es) * Math.tan(lamdp) * 
+			ca - spp * sa * sqrt((1. + q * dd) * (
+			1. - sppsq) - sppsq * u) / Math.cos(lamdp)) / (1. - sppsq 
+			* (1. + u)));
+		sl = lamt >= 0. ? 1. : -1.;
+		scl = Math.cos(lamdp) >= 0. ? 1. : -1;
+		lamt -= HALFPI * (1. - scl) * sl;
+		lp.lam = lamt - p22 * lamdp;
+		if (Math.abs(sa) < TOL)
+			lp.phi = aasin(spp / sqrt(one_es * one_es + es * sppsq));
+		else
+			lp.phi = Math.atan((Math.tan(lamdp) * Math.cos(lamt) - ca * Math.sin(lamt)) /
+				(one_es * sa));
+		return lp;
+	}
+*/
+
+	private void seraz0(double lam, double mult) {
+		double sdsq, h, s, fc, sd, sq, d__1;
+
+		lam *= DTR;
+		sd = Math.sin(lam);
+		sdsq = sd * sd;
+		s = p22 * sa * Math.cos(lam) * Math.sqrt((1. + t * sdsq) / ((
+			1. + w * sdsq) * (1. + q * sdsq)));
+		d__1 = 1. + q * sdsq;
+		h = Math.sqrt((1. + q * sdsq) / (1. + w * sdsq)) * ((1. + 
+			w * sdsq) / (d__1 * d__1) - p22 * ca);
+		sq = Math.sqrt(xj * xj + s * s);
+		b += fc = mult * (h * xj - s * s) / sq;
+		a2 += fc * Math.cos(lam + lam);
+		a4 += fc * Math.cos(lam * 4.);
+		fc = mult * s * (h + xj) / sq;
+		c1 += fc * Math.cos(lam);
+		c3 += fc * Math.cos(lam * 3.);
+	}
+
+	public void initialize() {
+		super.initialize();
+		int land, path;
+		double lam, alf, esc, ess;
+
+//FIXME		land = pj_param(params, "ilsat").i;
+land = 1;
+		if (land <= 0 || land > 5)
+			throw new ProjectionException("-28");
+//FIXME		path = pj_param(params, "ipath").i;
+path = 120;
+		if (path <= 0 || path > (land <= 3 ? 251 : 233))
+			throw new ProjectionException("-29");
+		if (land <= 3) {
+			projectionLongitude = DTR * 128.87 - ProjectionMath.TWOPI / 251. * path;
+			p22 = 103.2669323;
+			alf = DTR * 99.092;
+		} else {
+			projectionLongitude = DTR * 129.3 - ProjectionMath.TWOPI / 233. * path;
+			p22 = 98.8841202;
+			alf = DTR * 98.2;
+		}
+		p22 /= 1440.;
+		sa = Math.sin(alf);
+		ca = Math.cos(alf);
+		if (Math.abs(ca) < 1e-9)
+			ca = 1e-9;
+		esc = es * ca * ca;
+		ess = es * sa * sa;
+		w = (1. - esc) * rone_es;
+		w = w * w - 1.;
+		q = ess * rone_es;
+		t = ess * (2. - es) * rone_es * rone_es;
+		u = esc * rone_es;
+		xj = one_es * one_es * one_es;
+		rlm = Math.PI * (1. / 248. + .5161290322580645);
+		rlm2 = rlm + ProjectionMath.TWOPI;
+		a2 = a4 = b = c1 = c3 = 0.;
+		seraz0(0., 1.);
+		for (lam = 9.; lam <= 81.0001; lam += 18.)
+			seraz0(lam, 4.);
+		for (lam = 18; lam <= 72.0001; lam += 18.)
+			seraz0(lam, 2.);
+		seraz0(90., 1.);
+		a2 /= 30.;
+		a4 /= 60.;
+		b /= 30.;
+		c1 /= 15.;
+		c3 /= 45.;
+	}
+	
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Landsat";
+	}
+
+}
+
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LarriveeProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LarriveeProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LarriveeProjection.java	(revision 26409)
@@ -0,0 +1,38 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class LarriveeProjection extends Projection {
+
+	private final static double SIXTH = .16666666666666666;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		out.x = 0.5 * lplam * (1. + Math.sqrt(Math.cos(lpphi)));
+		out.y = lpphi / (Math.cos(0.5 * lpphi) * Math.cos(SIXTH * lplam));
+		return out;
+	}
+
+	public String toString() {
+		return "Larrivee";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LaskowskiProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LaskowskiProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LaskowskiProjection.java	(revision 26409)
@@ -0,0 +1,53 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+
+public class LaskowskiProjection extends Projection {
+
+	private final static double a10 =  0.975534;
+	private final static double a12 = -0.119161;
+	private final static double a32 = -0.0143059;
+	private final static double a14 = -0.0547009;
+	private final static double b01 =  1.00384;
+	private final static double b21 =  0.0802894;
+	private final static double b03 =  0.0998909;
+	private final static double b41 =  0.000199025;
+	private final static double b23 = -0.0285500;
+	private final static double b05 = -0.0491032;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double l2, p2;
+
+		l2 = lplam * lplam;
+		p2 = lpphi * lpphi;
+		out.x = lplam * (a10 + p2 * (a12 + l2 * a32 + p2 * a14));
+		out.y = lpphi * (b01 + l2 * (b21 + p2 * b23 + l2 * b41) +
+			p2 * (b03 + p2 * b05));
+		return out;
+	}
+
+	public String toString() {
+		return "Laskowski";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LinearProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LinearProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LinearProjection.java	(revision 26409)
@@ -0,0 +1,62 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+
+public class LinearProjection extends Projection {
+	
+	public ProjCoordinate project(ProjCoordinate src, ProjCoordinate dst) {
+		dst.x = src.x;
+		dst.y = src.y;
+		return dst;
+	}
+
+	public void transform(double[] srcPoints, int srcOffset, double[] dstPoints, int dstOffset, int numPoints) {
+		for (int i = 0; i < numPoints; i++) {
+			dstPoints[dstOffset++] = srcPoints[srcOffset++];
+			dstPoints[dstOffset++] = srcPoints[srcOffset++];
+		}
+	}
+
+	public ProjCoordinate inverseProject(ProjCoordinate src, ProjCoordinate dst) {
+		dst.x = src.x;
+		dst.y = src.y;
+		return dst;
+	}
+
+	public void inverseTransform(double[] srcPoints, int srcOffset, double[] dstPoints, int dstOffset, int numPoints) {
+		for (int i = 0; i < numPoints; i++) {
+			dstPoints[dstOffset++] = srcPoints[srcOffset++];
+			dstPoints[dstOffset++] = srcPoints[srcOffset++];
+		}
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public boolean isRectilinear() {
+		return true;
+	}
+
+	public String toString() {
+		return "Linear";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LongLatProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LongLatProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LongLatProjection.java	(revision 26409)
@@ -0,0 +1,49 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.units.Units;
+
+/**
+ * A "projection" for geodetic coordinates in Decimal Degrees. 
+ */
+public class LongLatProjection extends Projection 
+{
+  // TODO: implement projection methods (which are basically just no-ops)
+	/*
+	
+	public Point2D.Double transformRadians( Point2D.Double src, Point2D.Double dst ) {
+		dst.x = src.x;
+		dst.y = src.y;
+		return dst;
+	}
+	
+	*/
+  
+	public String toString() {
+		return "LongLat";
+	}
+
+  public void initialize()
+  {
+    // units are always in Decimal Degrees
+    unit = Units.DEGREES;
+    totalScale = 1.0;
+  }
+  
+  
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LoximuthalProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LoximuthalProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/LoximuthalProjection.java	(revision 26409)
@@ -0,0 +1,82 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class LoximuthalProjection extends PseudoCylindricalProjection {
+
+	private final static double FC = .92131773192356127802;
+	private final static double RP = .31830988618379067154;
+	private final static double EPS = 1e-8;
+	
+	private double phi1;
+	private double cosphi1;
+	private double tanphi1;
+
+	public LoximuthalProjection() {
+		phi1 = Math.toRadians(40.0);//FIXME - param
+		cosphi1 = Math.cos(phi1);
+		tanphi1 = Math.tan(ProjectionMath.QUARTERPI + 0.5 * phi1);
+	}
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double x;
+		double y = lpphi - phi1;
+		if (y < EPS)
+			x = lplam * cosphi1;
+		else {
+			x = ProjectionMath.QUARTERPI + 0.5 * lpphi;
+			if (Math.abs(x) < EPS || Math.abs(Math.abs(x) - ProjectionMath.HALFPI) < EPS)
+				x = 0.;
+			else
+				x = lplam * y / Math.log( Math.tan(x) / tanphi1 );
+		}
+		out.x = x;
+		out.y = y;
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double latitude = xyy + phi1;
+		double longitude;
+		if (Math.abs(xyy) < EPS)
+			longitude = xyx / cosphi1;
+		else if (Math.abs( longitude = ProjectionMath.QUARTERPI + 0.5 * xyy ) < EPS ||
+			Math.abs(Math.abs(xyx) -ProjectionMath.HALFPI) < EPS)
+			longitude = 0.;
+		else
+			longitude = xyx * Math.log( Math.tan(longitude) / tanphi1 ) / xyy;
+
+		out.x = longitude;
+		out.y = latitude;
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Loximuthal";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/McBrydeThomasFlatPolarParabolicProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/McBrydeThomasFlatPolarParabolicProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/McBrydeThomasFlatPolarParabolicProjection.java	(revision 26409)
@@ -0,0 +1,66 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class McBrydeThomasFlatPolarParabolicProjection extends Projection {
+
+	private final static double CS = .95257934441568037152;
+	private final static double FXC = .92582009977255146156;
+	private final static double FYC = 3.40168025708304504493;
+	private final static double C23 = .66666666666666666666;
+	private final static double C13 = .33333333333333333333;
+	private final static double ONEEPS = 1.0000001;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		out.y = Math.asin(CS * Math.sin(lpphi));
+		out.x = FXC * lplam * (2. * Math.cos(C23 * lpphi) - 1.);
+		out.y = FYC * Math.sin(C13 * lpphi);
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		out.y = xyy / FYC;
+		if (Math.abs(out.y) >= 1.) {
+			if (Math.abs(out.y) > ONEEPS)	throw new ProjectionException("I");
+			else	out.y = (out.y < 0.) ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+		} else
+			out.y = Math.asin(out.y);
+		out.x = xyx / ( FXC * (2. * Math.cos(C23 * (out.y *= 3.)) - 1.) );
+		if (Math.abs(out.y = Math.sin(out.y) / CS) >= 1.) {
+			if (Math.abs(out.y) > ONEEPS)	throw new ProjectionException("I");
+			else	out.y = (out.y < 0.) ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+		} else
+			out.y = Math.asin(out.y);
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "McBride-Thomas Flat-Polar Parabolic";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/McBrydeThomasFlatPolarQuarticProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/McBrydeThomasFlatPolarQuarticProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/McBrydeThomasFlatPolarQuarticProjection.java	(revision 26409)
@@ -0,0 +1,88 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class McBrydeThomasFlatPolarQuarticProjection extends PseudoCylindricalProjection {
+
+	private final static int NITER = 20;
+	private final static double EPS = 1e-7;
+	private final static double ONETOL = 1.000001;
+	private final static double C = 1.70710678118654752440;
+	private final static double RC = 0.58578643762690495119;
+	private final static double FYC = 1.87475828462269495505;
+	private final static double RYC = 0.53340209679417701685;
+	private final static double FXC = 0.31245971410378249250;
+	private final static double RXC = 3.20041258076506210122;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double th1, c;
+		int i;
+
+		c = C * Math.sin(lpphi);
+		for (i = NITER; i > 0; --i) {
+			out.y -= th1 = (Math.sin(.5*lpphi) + Math.sin(lpphi) - c) /
+				(.5*Math.cos(.5*lpphi)  + Math.cos(lpphi));
+			if (Math.abs(th1) < EPS) break;
+		}
+		out.x = FXC * lplam * (1.0 + 2. * Math.cos(lpphi)/Math.cos(0.5 * lpphi));
+		out.y = FYC * Math.sin(0.5 * lpphi);
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double t = 0;
+
+		double lpphi = RYC * xyy;
+		if (Math.abs(lpphi) > 1.) {
+			if (Math.abs(lpphi) > ONETOL)	throw new ProjectionException("I");
+			else if (lpphi < 0.) { t = -1.; lpphi = -Math.PI; }
+			else { t = 1.; lpphi = Math.PI; }
+		} else
+			lpphi = 2. * Math.asin(t = lpphi);
+		out.x = RXC * xyx / (1. + 2. * Math.cos(lpphi)/Math.cos(0.5 * lpphi));
+		lpphi = RC * (t + Math.sin(lpphi));
+		if (Math.abs(lpphi) > 1.)
+			if (Math.abs(lpphi) > ONETOL)
+				throw new ProjectionException("I");
+			else
+				lpphi = lpphi < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+		else
+			lpphi = Math.asin(lpphi);
+		out.y = lpphi;
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public boolean isEqualArea() {
+     return true;
+	}
+
+	public String toString() {
+		return "McBryde-Thomas Flat-Polar Quartic";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/McBrydeThomasFlatPolarSine1Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/McBrydeThomasFlatPolarSine1Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/McBrydeThomasFlatPolarSine1Projection.java	(revision 26409)
@@ -0,0 +1,32 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+public class McBrydeThomasFlatPolarSine1Projection extends SineTangentSeriesProjection {
+
+	public McBrydeThomasFlatPolarSine1Projection() {
+		super( 1.48875, 1.36509, false );
+	}
+	
+	public String toString() {
+		return "McBryde-Thomas Flat-Polar Sine (No. 1)";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/McBrydeThomasFlatPolarSine2Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/McBrydeThomasFlatPolarSine2Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/McBrydeThomasFlatPolarSine2Projection.java	(revision 26409)
@@ -0,0 +1,71 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class McBrydeThomasFlatPolarSine2Projection extends Projection {
+
+	private final static int MAX_ITER = 10;
+	private final static double LOOP_TOL = 1e-7;
+	private final static double C1 = 0.45503;
+	private final static double C2 = 1.36509;
+	private final static double C3 = 1.41546;
+	private final static double C_x = 0.22248;
+	private final static double C_y = 1.44492;
+	private final static double C1_2 = 0.33333333333333333333333333;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double k, V, t;
+		int i;
+
+		k = C3 * Math.sin(lpphi);
+		for (i = MAX_ITER; i > 0; i--) {
+			t = lpphi / C2;
+			out.y -= V = (C1 * Math.sin(t) + Math.sin(lpphi) - k) /
+				(C1_2 * Math.cos(t) + Math.cos(lpphi));
+			if (Math.abs(V) < LOOP_TOL)
+				break;
+		}
+		t = lpphi / C2;
+		out.x = C_x * lplam * (1. + 3. * Math.cos(lpphi)/Math.cos(t) );
+		out.y = C_y * Math.sin(t);
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double t, s;
+
+		out.y = C2 * (t = ProjectionMath.asin(xyy / C_y));
+		out.x = xyx / (C_x * (1. + 3. * Math.cos(out.y)/Math.cos(t)));
+		out.y = ProjectionMath.asin((C1 * Math.sin(t) + Math.sin(out.y)) / C3);
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "McBryde-Thomas Flat-Pole Sine (No. 2)";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/MercatorProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/MercatorProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/MercatorProjection.java	(revision 26409)
@@ -0,0 +1,73 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class MercatorProjection extends CylindricalProjection {
+	
+	public MercatorProjection() {
+		minLatitude = ProjectionMath.degToRad(-85);
+		maxLatitude = ProjectionMath.degToRad(85);
+	}
+	
+	public ProjCoordinate project(double lam, double phi, ProjCoordinate out) {
+		if (spherical) {
+			out.x = scaleFactor * lam;
+			out.y = scaleFactor * Math.log(Math.tan(ProjectionMath.QUARTERPI + 0.5 * phi));
+		} else {
+			out.x = scaleFactor * lam;
+			out.y = -scaleFactor * Math.log(ProjectionMath.tsfn(phi, Math.sin(phi), e));
+		}
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate out) {
+		if (spherical) {
+			out.y = ProjectionMath.HALFPI - 2. * Math.atan(Math.exp(-y / scaleFactor));
+			out.x = x / scaleFactor;
+		} else {
+			out.y = ProjectionMath.phi2(Math.exp(-y / scaleFactor), e);
+			out.x = x / scaleFactor;
+		}
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public boolean isRectilinear() {
+		return true;
+	}
+
+	/**
+	 * Returns the ESPG code for this projection, or 0 if unknown.
+	 */
+	public int getEPSGCode() {
+		return 9804;
+	}
+
+	public String toString() {
+		return "Mercator";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/MillerProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/MillerProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/MillerProjection.java	(revision 26409)
@@ -0,0 +1,51 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+
+public class MillerProjection extends CylindricalProjection {
+
+	public MillerProjection() {
+	}
+	
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		out.x = lplam;
+		out.y = Math.log(Math.tan(ProjectionMath.QUARTERPI + lpphi * .4)) * 1.25;
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		out.x = xyx;
+		out.y = 2.5 * (Math.atan(Math.exp(.8 * xyy)) - ProjectionMath.QUARTERPI);
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Miller Cylindrical";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/ModStereoProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/ModStereoProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/ModStereoProjection.java	(revision 26409)
@@ -0,0 +1,236 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+
+//public class ModStereoProjection extends Projection {
+//
+//	private final static int MAX_ITER = 10;
+//	private final static double LOOP_TOL = 1e-7;
+//
+//	public Point2D.Double project(double lplam, double lpphi, Point2D.Double xy) {
+//		double sinlon, coslon, esphi, chi, schi, cchi, s;
+//		COMPLEX p;
+//
+//		sinlon = Math.sin(lplam);
+//		coslon = Math.cos(lplam);
+//		esphi = P->e * Math.sin(lpphi);
+//		chi = 2. * Math.atan(Math.tan((MapMath.HALFPI + lpphi) * .5) *
+//			pow((1. - esphi) / (1. + esphi), P->e * .5)) - MapMath.HALFPI;
+//		schi = sin(chi);
+//		cchi = cos(chi);
+//		s = 2. / (1. + P->schio * schi + P->cchio * cchi * coslon);
+//		p.r = s * cchi * sinlon;
+//		p.i = s * (P->cchio * schi - P->schio * cchi * coslon);
+//		p = pj_zpoly1(p, P->zcoeff, P->n);
+//		xy.x = p.r;
+//		xy.y = p.i;
+//		return xy;
+//	}
+//
+//	public Point2D.Double projectInverse(double xyx, double xyy, Point2D.Double lp) {
+//		int nn;
+//		COMPLEX p, fxy, fpxy, dp;
+//		double den, rh, z, sinz, cosz, chi, phi, dphi, esphi;
+//
+//		p.r = xy.x;
+//		p.i = xy.y;
+//		for (nn = 20; nn ;--nn) {
+//			fxy = pj_zpolyd1(p, P->zcoeff, P->n, &fpxy);
+//			fxy.r -= xy.x;
+//			fxy.i -= xy.y;
+//			den = fpxy.r * fpxy.r + fpxy.i * fpxy.i;
+//			dp.r = -(fxy.r * fpxy.r + fxy.i * fpxy.i) / den;
+//			dp.i = -(fxy.i * fpxy.r - fxy.r * fpxy.i) / den;
+//			p.r += dp.r;
+//			p.i += dp.i;
+//			if ((Math.abs(dp.r) + Math.abs(dp.i)) <= EPSLN)
+//				break;
+//		}
+//		if (nn) {
+//			rh = Math.hypot(p.r, p.i);
+//			z = 2. * Math.atan(.5 * rh);
+//			sinz = Math.sin(z);
+//			cosz = Math.cos(z);
+//			lp.lam = P->lam0;
+//			if (Math.abs(rh) <= EPSLN) {
+//				lp.phi = P->phi0;
+//				return lp;
+//			}
+//			chi = Math.asin(cosz * P->schio + p.i * sinz * P->cchio / rh);
+//			phi = chi;
+//			for (nn = 20; nn ;--nn) {
+//				esphi = P->e * sin(phi);
+//				dphi = 2. * Math.atan(Math.tan((MapMath.HALFPI + chi) * .5) *
+//					Math.pow((1. + esphi) / (1. - esphi), P->e * .5)) - HALFPI - phi;
+//				phi += dphi;
+//				if (fabs(dphi) <= EPSLN)
+//					break;
+//			}
+//		}
+//		if (nn) {
+//			lp.phi = phi;
+//			lp.lam = Math.atan2(p.r * sinz, rh * P->cchio * cosz - p.i * 
+//				P->schio * sinz);
+//		} else
+//			lp.lam = lp.phi = Double.POSITIVE_INFINITY;
+//		return lp;
+//	}
+//
+//	public void initialize() {
+//		super.initialize();
+//
+//		double esphi, chio;
+//
+//		if (P->es) {
+//			esphi = P->e * sin(P->phi0);
+//			chio = 2. * atan(tan((HALFPI + P->phi0) * .5) *
+//				pow((1. - esphi) / (1. + esphi), P->e * .5)) - HALFPI;
+//		} else
+//			chio = P->phi0;
+//		P->schio = sin(chio);
+//		P->cchio = cos(chio);
+//	}
+//
+//ENTRY0(mil_os)
+//	static COMPLEX /* Miller Oblated Stereographic */
+//AB[] = {
+//	0.924500,	0.,
+//	0.,			0.,
+//	0.019430,	0.
+//};
+//
+//	P->n = 2;
+//	P->lam0 = DEG_TO_RAD * 20.;
+//	P->phi0 = DEG_TO_RAD * 18.;
+//	P->zcoeff = AB;
+//	P->es = 0.;
+//ENDENTRY(setup(P))
+//ENTRY0(lee_os)
+//	static COMPLEX /* Lee Oblated Stereographic */
+//AB[] = {
+//	0.721316,	0.,
+//	0.,			0.,
+//	-0.0088162,	 -0.00617325
+//};
+//
+//	P->n = 2;
+//	P->lam0 = DEG_TO_RAD * -165.;
+//	P->phi0 = DEG_TO_RAD * -10.;
+//	P->zcoeff = AB;
+//	P->es = 0.;
+//ENDENTRY(setup(P))
+//ENTRY0(gs48)
+//	static COMPLEX /* 48 United States */
+//AB[] = {
+//	0.98879,	0.,
+//	0.,			0.,
+//	-0.050909,	0.,
+//	0.,			0.,
+//	0.075528,	0.
+//};
+//
+//	P->n = 4;
+//	P->lam0 = DEG_TO_RAD * -96.;
+//	P->phi0 = DEG_TO_RAD * -39.;
+//	P->zcoeff = AB;
+//	P->es = 0.;
+//	P->a = 6370997.;
+//ENDENTRY(setup(P))
+//ENTRY0(alsk)
+//	static COMPLEX
+//ABe[] = { /* Alaska ellipsoid */
+//	.9945303,	0.,
+//	.0052083,	-.0027404,
+//	.0072721,	.0048181,
+//	-.0151089,	-.1932526,
+//	.0642675,	-.1381226,
+//	.3582802,	-.2884586},
+//ABs[] = { /* Alaska sphere */
+//	.9972523,	0.,
+//	.0052513,	-.0041175,
+//	.0074606,	.0048125,
+//	-.0153783,	-.1968253,
+//	.0636871,	-.1408027,
+//	.3660976,	-.2937382
+//};
+//
+//	P->n = 5;
+//	P->lam0 = DEG_TO_RAD * -152.;
+//	P->phi0 = DEG_TO_RAD * 64.;
+//	if (P->es) { /* fixed ellipsoid/sphere */
+//		P->zcoeff = ABe;
+//		P->a = 6378206.4;
+//		P->e = sqrt(P->es = 0.00676866);
+//	} else {
+//		P->zcoeff = ABs;
+//		P->a = 6370997.;
+//	}
+//ENDENTRY(setup(P))
+//ENTRY0(gs50)
+//	static COMPLEX
+//ABe[] = { /* GS50 ellipsoid */
+//	.9827497,	0.,
+//	.0210669,	.0053804,
+//	-.1031415,	-.0571664,
+//	-.0323337,	-.0322847,
+//	.0502303,	.1211983,
+//	.0251805,	.0895678,
+//	-.0012315,	-.1416121,
+//	.0072202,	-.1317091,
+//	-.0194029,	.0759677,
+//	-.0210072,	.0834037
+//},
+//ABs[] = { /* GS50 sphere */
+//	.9842990,	0.,
+//	.0211642,	.0037608,
+//	-.1036018,	-.0575102,
+//	-.0329095,	-.0320119,
+//	.0499471,	.1223335,
+//	.0260460,	.0899805,
+//	.0007388,	-.1435792,
+//	.0075848,	-.1334108,
+//	-.0216473,	.0776645,
+//	-.0225161,	.0853673
+//};
+//
+//	P->n = 9;
+//	P->lam0 = DEG_TO_RAD * -120.;
+//	P->phi0 = DEG_TO_RAD * 45.;
+//	if (P->es) { /* fixed ellipsoid/sphere */
+//		P->zcoeff = ABe;
+//		P->a = 6378206.4;
+//		P->e = sqrt(P->es = 0.00676866);
+//	} else {
+//		P->zcoeff = ABs;
+//		P->a = 6370997.;
+//	}
+//ENDENTRY(setup(P))
+//	}
+//	
+//	public boolean hasInverse() {
+//		return true;
+//	}
+//
+//	public String toString() {
+//		return "Nell";
+//	}
+//
+//}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/MolleweideProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/MolleweideProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/MolleweideProjection.java	(revision 26409)
@@ -0,0 +1,126 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class MolleweideProjection extends PseudoCylindricalProjection {
+
+	public static final int MOLLEWEIDE = 0;
+	public static final int WAGNER4 = 1;
+	public static final int WAGNER5 = 2;
+
+	private static final int MAX_ITER = 10;
+	private static final double TOLERANCE = 1e-7;
+
+	private int type = MOLLEWEIDE;
+	private double cx, cy, cp;
+
+	public MolleweideProjection() {
+		this(Math.PI/2);
+	}
+	
+	public MolleweideProjection(int type) {
+		this.type = type;
+		switch (type) {
+		case MOLLEWEIDE:
+			init(Math.PI/2);
+			break;
+		case WAGNER4:
+			init(Math.PI/3);
+			break;
+		case WAGNER5:
+			init(Math.PI/2);
+			cx = 0.90977;
+			cy = 1.65014;
+			cp = 3.00896;
+			break;
+		}
+	}
+	
+	public MolleweideProjection(double p) {
+		init(p);
+	}
+	
+	public void init(double p) {
+		double r, sp, p2 = p + p;
+
+		sp = Math.sin(p);
+		r = Math.sqrt(Math.PI*2.0 * sp / (p2 + Math.sin(p2)));
+		cx = 2. * r / Math.PI;
+		cy = r / sp;
+		cp = p2 + Math.sin(p2);
+	}
+
+	public MolleweideProjection(double cx, double cy, double cp) {
+		this.cx = cx;
+		this.cy = cy;
+		this.cp = cp;
+	}
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate xy) {
+		double k, v;
+		int i;
+
+		k = cp * Math.sin(lpphi);
+		for (i = MAX_ITER; i != 0; i--) {
+			lpphi -= v = (lpphi + Math.sin(lpphi) - k) / (1. + Math.cos(lpphi));
+			if (Math.abs(v) < TOLERANCE)
+				break;
+		}
+		if (i == 0)
+			lpphi = (lpphi < 0.) ? -Math.PI/2 : Math.PI/2;
+		else
+			lpphi *= 0.5;
+		xy.x = cx * lplam * Math.cos(lpphi);
+		xy.y = cy * Math.sin(lpphi);
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate lp) {
+		double lat, lon;
+		
+		lat = Math.asin(y / cy);
+		lon = x / (cx * Math.cos(lat));
+		lat += lat;
+		lat = Math.asin((lat + Math.sin(lat)) / cp);
+		lp.x = lon;
+		lp.y = lat;
+		return lp;
+	}
+	
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public boolean isEqualArea() {
+	    return true;
+	}
+	 
+	public String toString() {
+		switch (type) {
+		case WAGNER4:
+			return "Wagner IV";
+		case WAGNER5:
+			return "Wagner V";
+		}
+		return "Molleweide";
+	}
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Murdoch1Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Murdoch1Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Murdoch1Projection.java	(revision 26409)
@@ -0,0 +1,32 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+public class Murdoch1Projection extends SimpleConicProjection {
+
+	public Murdoch1Projection() {
+		super( SimpleConicProjection.MURD1 );
+	}
+
+	public String toString() {
+		return "Murdoch I";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Murdoch2Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Murdoch2Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Murdoch2Projection.java	(revision 26409)
@@ -0,0 +1,32 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+public class Murdoch2Projection extends SimpleConicProjection {
+
+	public Murdoch2Projection() {
+		super( SimpleConicProjection.MURD2 );
+	}
+
+	public String toString() {
+		return "Murdoch II";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Murdoch3Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Murdoch3Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Murdoch3Projection.java	(revision 26409)
@@ -0,0 +1,32 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+public class Murdoch3Projection extends SimpleConicProjection {
+
+	public Murdoch3Projection() {
+		super( SimpleConicProjection.MURD3 );
+	}
+
+	public String toString() {
+		return "Murdoch III";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/NellHProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/NellHProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/NellHProjection.java	(revision 26409)
@@ -0,0 +1,63 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class NellHProjection extends Projection {
+
+	private final static int NITER = 9;
+	private final static double EPS = 1e-7;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		out.x = 0.5 * lplam * (1. + Math.cos(lpphi));
+		out.y = 2.0 * (lpphi - Math.tan(0.5 *lpphi));
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double V, c, p;
+		int i;
+
+		p = 0.5 * xyy;
+		for (i = NITER; i > 0 ; --i) {
+			c = Math.cos(0.5 * xyy);
+			out.y -= V = (xyy - Math.tan(xyy/2) - p)/(1. - 0.5/(c*c));
+			if (Math.abs(V) < EPS)
+				break;
+		}
+		if (i == 0) {
+			out.y = p < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+			out.x = 2. * xyx;
+		} else
+			out.x = 2. * xyx / (1. + Math.cos(xyy));
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Nell-Hammer";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/NellProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/NellProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/NellProjection.java	(revision 26409)
@@ -0,0 +1,64 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class NellProjection extends Projection {
+
+	private final static int MAX_ITER = 10;
+	private final static double LOOP_TOL = 1e-7;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double k, V;
+		int i;
+
+		k = 2. * Math.sin(lpphi);
+		V = lpphi * lpphi;
+		out.y *= 1.00371 + V * (-0.0935382 + V * -0.011412);
+		for (i = MAX_ITER; i > 0 ; --i) {
+			out.y -= V = (lpphi + Math.sin(lpphi) - k) /
+				(1. + Math.cos(lpphi));
+			if (Math.abs(V) < LOOP_TOL)
+				break;
+		}
+		out.x = 0.5 * lplam * (1. + Math.cos(lpphi));
+		out.y = lpphi;
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double th, s;
+
+		out.x = 2. * xyx / (1. + Math.cos(xyy));
+		out.y = ProjectionMath.asin(0.5 * (xyy + Math.sin(xyy)));
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Nell";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/NicolosiProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/NicolosiProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/NicolosiProjection.java	(revision 26409)
@@ -0,0 +1,66 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class NicolosiProjection extends Projection {
+
+	private final static double EPS = 1e-10;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		if (Math.abs(lplam) < EPS) {
+			out.x = 0;
+			out.y = lpphi;
+		} else if (Math.abs(lpphi) < EPS) {
+			out.x = lplam;
+			out.y = 0.;
+		} else if (Math.abs(Math.abs(lplam) - ProjectionMath.HALFPI) < EPS) {
+			out.x = lplam * Math.cos(lpphi);
+			out.y = ProjectionMath.HALFPI * Math.sin(lpphi);
+		} else if (Math.abs(Math.abs(lpphi) - ProjectionMath.HALFPI) < EPS) {
+			out.x = 0;
+			out.y = lpphi;
+		} else {
+			double tb, c, d, m, n, r2, sp;
+
+			tb = ProjectionMath.HALFPI / lplam - lplam / ProjectionMath.HALFPI;
+			c = lpphi / ProjectionMath.HALFPI;
+			d = (1 - c * c)/((sp = Math.sin(lpphi)) - c);
+			r2 = tb / d;
+			r2 *= r2;
+			m = (tb * sp / d - 0.5 * tb)/(1. + r2);
+			n = (sp / r2 + 0.5 * d)/(1. + 1./r2);
+			double x = Math.cos(lpphi);
+			x = Math.sqrt(m * m + x * x / (1. + r2));
+			out.x = ProjectionMath.HALFPI * ( m + (lplam < 0. ? -x : x));
+			double y = Math.sqrt(n * n - (sp * sp / r2 + d * sp - 1.) /
+				(1. + 1./r2));
+			out.y = ProjectionMath.HALFPI * ( n + (lpphi < 0. ? y : -y ));
+		}
+		return out;
+	}
+
+	public String toString() {
+		return "Nicolosi Globular";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/NullProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/NullProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/NullProjection.java	(revision 26409)
@@ -0,0 +1,65 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.proj;
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+
+/**
+ * A projection which does nothing. Use this for drawing non-geographical overlays.
+ */
+public class NullProjection extends Projection {
+  
+  public NullProjection()
+  {
+    initialize();
+  }
+	
+  public ProjCoordinate project( ProjCoordinate src, ProjCoordinate dst ) {
+    dst.x = src.x;
+    dst.y = src.y;
+    return dst;
+  }
+  
+  public ProjCoordinate projectInverse( ProjCoordinate src, ProjCoordinate dst ) {
+    dst.x = src.x;
+    dst.y = src.y;
+    return dst;
+  }
+  
+	public Shape projectPath(Shape path, AffineTransform t, boolean filled) {
+		if ( t != null )
+			t.createTransformedShape( path );
+		return path;
+	}
+	
+	public Shape getBoundingShape() {
+		return null;
+	}
+	
+	public boolean isRectilinear() {
+		return true;
+	}
+
+	public String toString() {
+		return "Null";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/ObliqueMercatorProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/ObliqueMercatorProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/ObliqueMercatorProjection.java	(revision 26409)
@@ -0,0 +1,227 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.datum.Ellipsoid;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+/**
+* Oblique Mercator Projection algorithm is taken from the USGS PROJ package.
+*/
+public class ObliqueMercatorProjection extends CylindricalProjection {
+
+	private final static double TOL	= 1.0e-7;
+
+	private double lamc, lam1, phi1, lam2, phi2, Gamma, al, bl, el, singam, cosgam, sinrot, cosrot, u_0;
+	private boolean ellips, rot;
+
+	public ObliqueMercatorProjection() {
+		ellipsoid = Ellipsoid.WGS84;
+		projectionLatitude = Math.toRadians(0);
+		projectionLongitude = Math.toRadians(0);
+		minLongitude = Math.toRadians(-60);
+		maxLongitude = Math.toRadians(60);
+		minLatitude = Math.toRadians(-80);
+		maxLatitude = Math.toRadians(80);
+		alpha = Math.toRadians(-45);//FIXME
+		initialize();
+	}
+	
+	/**
+	* Set up a projection suitable for State Plane Coordinates.
+	*/
+	public ObliqueMercatorProjection(Ellipsoid ellipsoid, double lon_0, double lat_0, double alpha, double k, double x_0, double y_0) {
+		setEllipsoid(ellipsoid);
+		lamc = lon_0;
+		projectionLatitude = lat_0;
+		this.alpha = alpha;
+		scaleFactor = k;
+		falseEasting = x_0;
+		falseNorthing = y_0;
+		initialize();
+	}
+	
+	public void initialize() {
+		super.initialize();
+		double con, com, cosphi0, d, f, h, l, sinphi0, p, j;
+
+		//FIXME-setup rot, alpha, longc,lon/lat1/2
+		rot = true;
+    lamc = lonc;
+    
+    // true if alpha provided
+    int azi = Double.isNaN(alpha) ? 0 : 1;
+		if (azi != 0) { // alpha specified
+			if (Math.abs(alpha) <= TOL ||
+				Math.abs(Math.abs(projectionLatitude) - ProjectionMath.HALFPI) <= TOL ||
+				Math.abs(Math.abs(alpha) - ProjectionMath.HALFPI) <= TOL)
+				throw new ProjectionException("Obl 1");
+		} else {
+			if (Math.abs(phi1 - phi2) <= TOL ||
+				(con = Math.abs(phi1)) <= TOL ||
+				Math.abs(con - ProjectionMath.HALFPI) <= TOL ||
+				Math.abs(Math.abs(projectionLatitude) - ProjectionMath.HALFPI) <= TOL ||
+				Math.abs(Math.abs(phi2) - ProjectionMath.HALFPI) <= TOL) throw new ProjectionException("Obl 2");
+		}
+		com = (spherical = es == 0.) ? 1 : Math.sqrt(one_es);
+		if (Math.abs(projectionLatitude) > EPS10) {
+			sinphi0 = Math.sin(projectionLatitude);
+			cosphi0 = Math.cos(projectionLatitude);
+			if (!spherical) {
+				con = 1. - es * sinphi0 * sinphi0;
+				bl = cosphi0 * cosphi0;
+				bl = Math.sqrt(1. + es * bl * bl / one_es);
+				al = bl * scaleFactor * com / con;
+				d = bl * com / (cosphi0 * Math.sqrt(con));
+			} else {
+				bl = 1.;
+				al = scaleFactor;
+				d = 1. / cosphi0;
+			}
+			if ((f = d * d - 1.) <= 0.)
+				f = 0.;
+			else {
+				f = Math.sqrt(f);
+				if (projectionLatitude < 0.)
+					f = -f;
+			}
+			el = f += d;
+			if (!spherical)
+				el *= Math.pow(ProjectionMath.tsfn(projectionLatitude, sinphi0, e), bl);
+			else
+				el *= Math.tan(.5 * (ProjectionMath.HALFPI - projectionLatitude));
+		} else {
+			bl = 1. / com;
+			al = scaleFactor;
+			el = d = f = 1.;
+		}
+		if (azi != 0) {
+			Gamma = Math.asin(Math.sin(alpha) / d);
+			projectionLongitude = lamc - Math.asin((.5 * (f - 1. / f)) *
+			   Math.tan(Gamma)) / bl;
+		} else {
+			if (!spherical) {
+				h = Math.pow(ProjectionMath.tsfn(phi1, Math.sin(phi1), e), bl);
+				l = Math.pow(ProjectionMath.tsfn(phi2, Math.sin(phi2), e), bl);
+			} else {
+				h = Math.tan(.5 * (ProjectionMath.HALFPI - phi1));
+				l = Math.tan(.5 * (ProjectionMath.HALFPI - phi2));
+			}
+			f = el / h;
+			p = (l - h) / (l + h);
+			j = el * el;
+			j = (j - l * h) / (j + l * h);
+			if ((con = lam1 - lam2) < -Math.PI)
+				lam2 -= ProjectionMath.TWOPI;
+			else if (con > Math.PI)
+				lam2 += ProjectionMath.TWOPI;
+			projectionLongitude = ProjectionMath.normalizeLongitude(.5 * (lam1 + lam2) - Math.atan(
+			   j * Math.tan(.5 * bl * (lam1 - lam2)) / p) / bl);
+			Gamma = Math.atan(2. * Math.sin(bl * ProjectionMath.normalizeLongitude(lam1 - projectionLongitude)) /
+			   (f - 1. / f));
+			alpha = Math.asin(d * Math.sin(Gamma));
+		}
+		singam = Math.sin(Gamma);
+		cosgam = Math.cos(Gamma);
+//		f = MapMath.param(params, "brot_conv").i ? Gamma : alpha;
+		f = alpha;//FIXME
+		sinrot = Math.sin(f);
+		cosrot = Math.cos(f);
+//		u_0 = MapMath.param(params, "bno_uoff").i ? 0. :
+		u_0 = false ? 0. ://FIXME
+			Math.abs(al * Math.atan(Math.sqrt(d * d - 1.) / cosrot) / bl);
+		if (projectionLatitude < 0.)
+			u_0 = - u_0;
+	}
+
+	public ProjCoordinate project(double lam, double phi, ProjCoordinate xy) {
+		double con, q, s, ul, us, vl, vs;
+
+		vl = Math.sin(bl * lam);
+		if (Math.abs(Math.abs(phi) - ProjectionMath.HALFPI) <= EPS10) {
+			ul = phi < 0. ? -singam : singam;
+			us = al * phi / bl;
+		} else {
+			q = el / (!spherical ? Math.pow(ProjectionMath.tsfn(phi, Math.sin(phi), e), bl)
+				: Math.tan(.5 * (ProjectionMath.HALFPI - phi)));
+			s = .5 * (q - 1. / q);
+			ul = 2. * (s * singam - vl * cosgam) / (q + 1. / q);
+			con = Math.cos(bl * lam);
+			if (Math.abs(con) >= TOL) {
+				us = al * Math.atan((s * cosgam + vl * singam) / con) / bl;
+				if (con < 0.)
+					us += Math.PI * al / bl;
+			} else
+				us = al * bl * lam;
+		}
+		if (Math.abs(Math.abs(ul) - 1.) <= EPS10) throw new ProjectionException("Obl 3");
+		vs = .5 * al * Math.log((1. - ul) / (1. + ul)) / bl;
+		us -= u_0;
+		if (!rot) {
+			xy.x = us;
+			xy.y = vs;
+		} else {
+			xy.x = vs * cosrot + us * sinrot;
+			xy.y = us * cosrot - vs * sinrot;
+		}
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate lp) {
+		double q, s, ul, us, vl, vs;
+
+		if (! rot) {
+			us = x;
+			vs = y;
+		} else {
+			vs = x * cosrot - y * sinrot;
+			us = y * cosrot + x * sinrot;
+		}
+		us += u_0;
+		q = Math.exp(- bl * vs / al);
+		s = .5 * (q - 1. / q);
+		vl = Math.sin(bl * us / al);
+		ul = 2. * (vl * cosgam + s * singam) / (q + 1. / q);
+		if (Math.abs(Math.abs(ul) - 1.) < EPS10) {
+			lp.x = 0.;
+			lp.y = ul < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+		} else {
+			lp.y = el / Math.sqrt((1. + ul) / (1. - ul));
+			if (!spherical) {
+				lp.y = ProjectionMath.phi2(Math.pow(lp.y, 1. / bl), e);
+			} else
+				lp.y = ProjectionMath.HALFPI - 2. * Math.atan(lp.y);
+			lp.x = - Math.atan2((s * cosgam -
+				vl * singam), Math.cos(bl * us / al)) / bl;
+		}
+		return lp;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Oblique Mercator";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/ObliqueStereographicAlternativeProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/ObliqueStereographicAlternativeProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/ObliqueStereographicAlternativeProjection.java	(revision 26409)
@@ -0,0 +1,96 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class ObliqueStereographicAlternativeProjection extends GaussProjection {
+
+  private double sinc0;
+  private double cosc0;
+  private double R2;
+  
+	public ObliqueStereographicAlternativeProjection() {
+	}
+	
+  public ProjCoordinate OLDproject(double x, double y, ProjCoordinate out) {
+    super.project(x, y, out);
+    double px = out.x;
+    double py = out.y;
+    double sinc = Math.sin(py);
+    double cosc = Math.cos(py);
+    double cosl = Math.cos(px);
+    double k = scaleFactor * R2 / (1.0 + sinc0 * sinc + cosc0 * cosc * cosl);
+    out.x = k * cosc * Math.sin(px);
+    out.y = k * (this.cosc0 * sinc - this.sinc0 * cosc * cosl);
+    return out;
+  }
+
+  public ProjCoordinate project(double lplamIn, double lpphiIn, ProjCoordinate out) {
+    super.project(lplamIn, lpphiIn, out);
+    double lplam = out.x;
+    double lpphi = out.y;
+    double sinc = Math.sin(lpphi);
+    double cosc = Math.cos(lpphi);
+    double cosl = Math.cos(lplam);
+    double k = scaleFactor * R2 / (1. + sinc0 * sinc + cosc0 * cosc * cosl);
+    out.x = k * cosc * Math.sin(lplam);
+    out.y = k * (cosc0 * sinc - sinc0 * cosc * cosl);
+    return out;
+  }
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate out) {
+	  double xyx = x / scaleFactor;
+	  double xyy = y / scaleFactor;
+	  double rho = Math.sqrt(xyx * xyx + xyy * xyy);
+	  double lpphi;
+	  double lplam;
+	  if (rho != 0) {
+	    double c = 2. * Math.atan2(rho, R2);
+	    double sinc = Math.sin(c);
+	    double cosc = Math.cos(c);
+	    lpphi = Math.asin(cosc * sinc0 + xyy * sinc * cosc0 / rho);
+	    lplam = Math.atan2(xyx * sinc, rho * cosc0 * cosc -
+	      xyy * sinc0 * sinc);
+	  } else {
+	    lpphi = phic0;
+	    lplam = 0.;
+	  }
+	  return super.projectInverse(lplam, lpphi, out);
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public void initialize() {
+		super.initialize();
+    sinc0 = Math.sin(phic0);
+    cosc0 = Math.cos(phic0);
+    R2 = 2.0 * rc;
+	}
+
+	public String toString() {
+		return "Oblique Stereographic Alternative";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/OrthographicAzimuthalProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/OrthographicAzimuthalProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/OrthographicAzimuthalProjection.java	(revision 26409)
@@ -0,0 +1,117 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+/**
+ * The Orthographic Azimuthal or Globe map projection.
+ */
+public class OrthographicAzimuthalProjection extends AzimuthalProjection {
+	
+	public OrthographicAzimuthalProjection() {
+		initialize();
+	}
+	
+	public ProjCoordinate project(double lam, double phi, ProjCoordinate xy) {
+		double sinphi;
+		double cosphi = Math.cos(phi);
+		double coslam = Math.cos(lam);
+
+		// Theoretically we should throw the ProjectionExceptions below, but for practical purposes
+		// it's better not to as they tend to crop up a lot up due to rounding errors.
+		switch (mode) {
+		case EQUATOR:
+//			if (cosphi * coslam < - EPS10)
+//				throw new ProjectionException();
+			xy.y = Math.sin(phi);
+			break;
+		case OBLIQUE:
+			sinphi = Math.sin(phi);
+//			if (sinphi0 * (sinphi) + cosphi0 * cosphi * coslam < - EPS10)
+//				;
+//			   throw new ProjectionException();
+			xy.y = cosphi0 * sinphi - sinphi0 * cosphi * coslam;
+			break;
+		case NORTH_POLE:
+			coslam = - coslam;
+		case SOUTH_POLE:
+//			if (Math.abs(phi - projectionLatitude) - EPS10 > MapMath.HALFPI)
+//				throw new ProjectionException();
+			xy.y = cosphi * coslam;
+			break;
+		}
+		xy.x = cosphi * Math.sin(lam);
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate lp) {
+		double  rh, cosc, sinc;
+
+		if ((sinc = (rh = ProjectionMath.distance(x, y))) > 1.) {
+			if ((sinc - 1.) > EPS10) throw new ProjectionException();
+				sinc = 1.;
+		}
+		cosc = Math.sqrt(1. - sinc * sinc); /* in this range OK */
+		if (Math.abs(rh) <= EPS10)
+			lp.y = projectionLatitude;
+		else switch (mode) {
+		case NORTH_POLE:
+			y = -y;
+			lp.y = Math.acos(sinc);
+			break;
+		case SOUTH_POLE:
+			lp.y = - Math.acos(sinc);
+			break;
+		case EQUATOR:
+			lp.y = y * sinc / rh;
+			x *= sinc;
+			y = cosc * rh;
+			if (Math.abs(lp.y) >= 1.)
+				lp.y = lp.y < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+			else
+				lp.y = Math.asin(lp.y);
+			break;
+		case OBLIQUE:
+			lp.y = cosc * sinphi0 + y * sinc * cosphi0 / rh;
+			y = (cosc - sinphi0 * lp.y) * rh;
+			x *= sinc * cosphi0;
+			if (Math.abs(lp.y) >= 1.)
+				lp.y = lp.y < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+			else
+				lp.y = Math.asin(lp.y);
+			break;
+		}
+		lp.x = (y == 0. && (mode == OBLIQUE || mode == EQUATOR)) ?
+			 (x == 0. ? 0. : x < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI) : Math.atan2(x, y);
+		return lp;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Orthographic Azimuthal";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PerspectiveConicProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PerspectiveConicProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PerspectiveConicProjection.java	(revision 26409)
@@ -0,0 +1,32 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+public class PerspectiveConicProjection extends SimpleConicProjection {
+
+	public PerspectiveConicProjection() {
+		super( SimpleConicProjection.PCONIC );
+	}
+
+	public String toString() {
+		return "Perspective Conic";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PerspectiveProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PerspectiveProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PerspectiveProjection.java	(revision 26409)
@@ -0,0 +1,189 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class PerspectiveProjection extends Projection {
+
+	private double height;
+	private double psinph0;
+	private double pcosph0;
+	private double p;
+	private double rp;
+	private double pn1;
+	private double pfact;
+	private double h;
+	private double cg;
+	private double sg;
+	private double sw;
+	private double cw;
+	private int mode;
+	private int tilt;
+
+	private final static double EPS10 = 1.e-10;
+	private final static int N_POLE = 0;
+	private final static int S_POLE = 1;
+	private final static int EQUIT = 2;
+	private final static int OBLIQ = 3;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate xy) {
+		double  coslam, cosphi, sinphi;
+
+		sinphi = Math.sin(lpphi);
+		cosphi = Math.cos(lpphi);
+		coslam = Math.cos(lplam);
+		switch (mode) {
+		case OBLIQ:
+			xy.y = psinph0 * sinphi + pcosph0 * cosphi * coslam;
+			break;
+		case EQUIT:
+			xy.y = cosphi * coslam;
+			break;
+		case S_POLE:
+			xy.y = - sinphi;
+			break;
+		case N_POLE:
+			xy.y = sinphi;
+			break;
+		}
+//		if (xy.y < rp)
+//			throw new ProjectionException("");
+		xy.y = pn1 / (p - xy.y);
+		xy.x = xy.y * cosphi * Math.sin(lplam);
+		switch (mode) {
+		case OBLIQ:
+			xy.y *= (pcosph0 * sinphi -
+			   psinph0 * cosphi * coslam);
+			break;
+		case EQUIT:
+			xy.y *= sinphi;
+			break;
+		case N_POLE:
+			coslam = - coslam;
+		case S_POLE:
+			xy.y *= cosphi * coslam;
+			break;
+		}
+		if (tilt != 0) {
+			double yt, ba;
+
+			yt = xy.y * cg + xy.x * sg;
+			ba = 1. / (yt * sw * h + cw);
+			xy.x = (xy.x * cg - xy.y * sg) * cw * ba;
+			xy.y = yt * ba;
+		}
+		return xy;
+	}
+
+	public boolean hasInverse() {
+		return false;
+	}
+
+/*FIXME
+INVERSE(s_inverse); /* spheroid * /
+	double  rh, cosz, sinz;
+
+	if (tilt) {
+		double bm, bq, yt;
+
+		yt = 1./(pn1 - xy.y * sw);
+		bm = pn1 * xy.x * yt;
+		bq = pn1 * xy.y * cw * yt;
+		xy.x = bm * cg + bq * sg;
+		xy.y = bq * cg - bm * sg;
+	}
+	rh = hypot(xy.x, xy.y);
+	if ((sinz = 1. - rh * rh * pfact) < 0.) I_ERROR;
+	sinz = (p - Math.sqrt(sinz)) / (pn1 / rh + rh / pn1);
+	cosz = sqrt(1. - sinz * sinz);
+	if (fabs(rh) <= EPS10) {
+		lp.lam = 0.;
+		lp.phi = phi0;
+	} else {
+		switch (mode) {
+		case OBLIQ:
+			lp.phi = Math.asin(cosz * sinph0 + xy.y * sinz * cosph0 / rh);
+			xy.y = (cosz - sinph0 * sin(lp.phi)) * rh;
+			xy.x *= sinz * cosph0;
+			break;
+		case EQUIT:
+			lp.phi = Math.asin(xy.y * sinz / rh);
+			xy.y = cosz * rh;
+			xy.x *= sinz;
+			break;
+		case N_POLE:
+			lp.phi = Math.asin(cosz);
+			xy.y = -xy.y;
+			break;
+		case S_POLE:
+			lp.phi = - Math.asin(cosz);
+			break;
+		}
+		lp.lam = Math.atan2(xy.x, xy.y);
+	}
+	return (lp);
+}
+*/
+
+	public void initialize() {
+		super.initialize();
+mode = EQUIT;
+height = a;
+tilt = 0;
+//		if ((height = pj_param(params, "dh").f) <= 0.) E_ERROR(-30);
+/*
+		if (fabs(fabs(phi0) - Math.HALFPI) < EPS10)
+			mode = phi0 < 0. ? S_POLE : N_POLE;
+		else if (fabs(phi0) < EPS10)
+			mode = EQUIT;
+		else {
+			mode = OBLIQ;
+			psinph0 = Math.sin(phi0);
+			pcosph0 = Math.cos(phi0);
+		}
+*/
+		pn1 = height / a; /* normalize by radius */
+		p = 1. + pn1;
+		rp = 1. / p;
+		h = 1. / pn1;
+		pfact = (p + 1.) * h;
+		es = 0.;
+	}
+/*FIXME
+ENTRY0(nsper)
+	tilt = 0;
+ENDENTRY(setup(P))
+ENTRY0(tpers)
+	double omega, gamma;
+
+	omega = pj_param(params, "dtilt").f * DEG_TO_RAD;
+	gamma = pj_param(params, "dazi").f * DEG_TO_RAD;
+	tilt = 1;
+	cg = cos(gamma); sg = sin(gamma);
+	cw = cos(omega); sw = sin(omega);
+ENDENTRY(setup(P))
+*/
+
+	public String toString() {
+		return "Perspective";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PlateCarreeProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PlateCarreeProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PlateCarreeProjection.java	(revision 26409)
@@ -0,0 +1,34 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.proj;
+
+
+public class PlateCarreeProjection extends CylindricalProjection {
+	
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public boolean isRectilinear() {
+		return true;
+	}
+
+	public String toString() {
+		return "Plate Carr\u00e9e";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PolyconicProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PolyconicProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PolyconicProjection.java	(revision 26409)
@@ -0,0 +1,150 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class PolyconicProjection extends Projection {
+
+	private double ml0;
+	private double[] en;
+
+	private final static double TOL = 1e-10;
+	private final static double CONV = 1e-10;
+	private final static int N_ITER = 10;
+	private final static int I_ITER = 20;
+	private final static double ITOL = 1.e-12;
+
+	public PolyconicProjection() {
+		minLatitude = ProjectionMath.degToRad(0);
+		maxLatitude = ProjectionMath.degToRad(80);
+		minLongitude = ProjectionMath.degToRad(-60);
+		maxLongitude = ProjectionMath.degToRad(60);
+		initialize();
+	}
+	
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		if (spherical) {
+			double  cot, E;
+
+			if (Math.abs(lpphi) <= TOL) {
+				out.x = lplam;
+				out.y = ml0;
+			} else {
+				cot = 1. / Math.tan(lpphi);
+				out.x = Math.sin(E = lplam * Math.sin(lpphi)) * cot;
+				out.y = lpphi - projectionLatitude + cot * (1. - Math.cos(E));
+			}
+		} else {
+			double  ms, sp, cp;
+
+			if (Math.abs(lpphi) <= TOL) {
+				out.x = lplam;
+				out.y = -ml0;
+			} else {
+				sp = Math.sin(lpphi);
+				ms = Math.abs(cp = Math.cos(lpphi)) > TOL ? ProjectionMath.msfn(sp, cp, es) / sp : 0.;
+				out.x = ms * Math.sin(out.x *= sp);
+				out.y = (ProjectionMath.mlfn(lpphi, sp, cp, en) - ml0) + ms * (1. - Math.cos(lplam));
+			}
+		}
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double lpphi;
+		if (spherical) {
+			double B, dphi, tp;
+			int i;
+
+			if (Math.abs(lpphi = projectionLatitude + xyy) <= TOL) {
+				out.x = xyx; out.y = 0.;
+			} else {
+				lpphi = xyy;
+				B = xyx * xyx + xyy * xyy;
+				i = N_ITER;
+				do {
+					tp = Math.tan(lpphi);
+					lpphi -= (dphi = (xyy * (lpphi * tp + 1.) - lpphi -
+						.5 * ( lpphi * lpphi + B) * tp) /
+						((lpphi - xyy) / tp - 1.));
+				} while (Math.abs(dphi) > CONV && --i > 0);
+				if (i == 0) throw new ProjectionException("I");
+				out.x = Math.asin(xyx * Math.tan(lpphi)) / Math.sin(lpphi);
+				out.y = lpphi;
+			}
+		} else {
+			xyy += ml0;
+			if (Math.abs(xyy) <= TOL) { out.x = xyx; out.y = 0.; }
+			else {
+				double r, c, sp, cp, s2ph, ml, mlb, mlp, dPhi;
+				int i;
+
+				r = xyy * xyy + xyx * xyx;
+				for (lpphi = xyy, i = I_ITER; i > 0; --i) {
+					sp = Math.sin(lpphi);
+					s2ph = sp * ( cp = Math.cos(lpphi));
+					if (Math.abs(cp) < ITOL)
+						throw new ProjectionException("I");
+					c = sp * (mlp = Math.sqrt(1. - es * sp * sp)) / cp;
+					ml = ProjectionMath.mlfn(lpphi, sp, cp, en);
+					mlb = ml * ml + r;
+					mlp = (1.0 / es) / (mlp * mlp * mlp);
+					lpphi += ( dPhi =
+						( ml + ml + c * mlb - 2. * xyy * (c * ml + 1.) ) / (
+						es * s2ph * (mlb - 2. * xyy * ml) / c +
+						2.* (xyy - ml) * (c * mlp - 1. / s2ph) - mlp - mlp ));
+					if (Math.abs(dPhi) <= ITOL)
+						break;
+				}
+				if (i == 0)
+					throw new ProjectionException("I");
+				c = Math.sin(lpphi);
+				out.x = Math.asin(xyx * Math.tan(lpphi) * Math.sqrt(1. - es * c * c)) / Math.sin(lpphi);
+				out.y = lpphi;
+			}
+		}
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public void initialize() {
+		super.initialize();
+spherical = true;//FIXME
+		if (!spherical) {
+			en = ProjectionMath.enfn(es);
+			if (en == null)
+				throw new ProjectionException("E");
+			ml0 = ProjectionMath.mlfn(projectionLatitude, Math.sin(projectionLatitude), Math.cos(projectionLatitude), en);
+		} else {
+			ml0 = -projectionLatitude;
+		}
+	}
+
+	public String toString() {
+		return "Polyconic (American)";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Projection.java	(revision 26409)
@@ -0,0 +1,761 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.*;
+import org.osgeo.proj4j.datum.Ellipsoid;
+import org.osgeo.proj4j.units.AngleFormat;
+import org.osgeo.proj4j.units.Unit;
+import org.osgeo.proj4j.units.Units;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+/**
+ * A map projection is a mathematical algorithm
+ * for representing a spheroidal surface 
+ * on a plane.
+ * A single projection
+ * defines a (usually infinite) family of
+ * {@link CoordinateReferenceSystem}s,
+ * distinguished by different values for the
+ * projection parameters.
+ */
+public abstract class Projection implements Cloneable {
+
+	/**
+	 * The minimum latitude of the bounds of this projection
+	 */
+	protected double minLatitude = -Math.PI/2;
+
+	/**
+	 * The minimum longitude of the bounds of this projection. This is relative to the projection centre.
+	 */
+	protected double minLongitude = -Math.PI;
+
+	/**
+	 * The maximum latitude of the bounds of this projection
+	 */
+	protected double maxLatitude = Math.PI/2;
+
+	/**
+	 * The maximum longitude of the bounds of this projection. This is relative to the projection centre.
+	 */
+	protected double maxLongitude = Math.PI;
+
+	/**
+	 * The latitude of the centre of projection
+	 */
+	protected double projectionLatitude = 0.0;
+
+	/**
+	 * The longitude of the centre of projection, in radians
+	 */
+	protected double projectionLongitude = 0.0;
+
+	/**
+	 * Standard parallel 1 (for projections which use it)
+	 */
+	protected double projectionLatitude1 = 0.0;
+
+	/**
+	 * Standard parallel 2 (for projections which use it)
+	 */
+	protected double projectionLatitude2 = 0.0;
+
+  /**
+   * The projection alpha value
+   */
+  protected double alpha = Double.NaN;
+
+  /**
+   * The projection lonc value
+   */
+  protected double lonc = Double.NaN;
+
+  /**
+   * The projection scale factor
+   */
+  protected double scaleFactor = 1.0;
+
+	/**
+	 * The false Easting of this projection
+	 */
+	protected double falseEasting = 0;
+
+	/**
+	 * The false Northing of this projection
+	 */
+	protected double falseNorthing = 0;
+
+  /**
+   * Indicates whether a Southern Hemisphere UTM zone
+   */
+  protected boolean isSouth = false;
+	/**
+	 * The latitude of true scale. Only used by specific projections.
+	 */
+	protected double trueScaleLatitude = 0.0;
+
+	/**
+	 * The equator radius
+	 */
+	protected double a = 0;
+
+	/**
+	 * The eccentricity
+	 */
+	protected double e = 0;
+
+	/**
+	 * The eccentricity squared
+	 */
+	protected double es = 0;
+
+	/**
+	 * 1-(eccentricity squared)
+	 */
+	protected double one_es = 0;
+
+	/**
+	 * 1/(1-(eccentricity squared))
+	 */
+	protected double rone_es = 0;
+
+	/**
+	 * The ellipsoid used by this projection
+	 */
+	protected Ellipsoid ellipsoid;
+
+	/**
+	 * True if this projection is using a sphere (es == 0)
+	 */
+	protected boolean spherical;
+
+	/**
+	 * True if this projection is geocentric
+	 */
+	protected boolean geocentric;
+
+	/**
+	 * The name of this projection
+	 */
+	protected String name = null;
+
+	/**
+	 * Conversion factor from metres to whatever units the projection uses.
+	 */
+	protected double fromMetres = 1;
+
+	/**
+	 * The total scale factor = Earth radius * units
+	 */
+	protected double totalScale = 0;
+
+	/**
+	 * falseEasting, adjusted to the appropriate units using fromMetres
+	 */
+	private double totalFalseEasting = 0;
+
+  /**
+   * falseNorthing, adjusted to the appropriate units using fromMetres
+   */
+  private double totalFalseNorthing = 0;
+
+  /**
+   * units of this projection.  Default is metres, but may be degrees
+   */
+  protected Unit unit = null;
+
+	// Some useful constants
+	protected final static double EPS10 = 1e-10;
+	protected final static double RTD = 180.0/Math.PI;
+	protected final static double DTR = Math.PI/180.0;
+	
+	protected Projection() {
+		setEllipsoid( Ellipsoid.SPHERE );
+	}
+	
+	public Object clone() {
+		try {
+			Projection e = (Projection)super.clone();
+			return e;
+		}
+		catch ( CloneNotSupportedException e ) {
+			throw new InternalError();
+		}
+	}
+	
+	/**
+	 * Projects a geographic point (in degrees), producing a projected result 
+	 * (in the units of the target coordinate system).
+	 * 
+   * @param src the input geographic coordinate (in degrees)
+   * @param dst the projected coordinate (in coordinate system units)
+   * @return the target coordinate 
+	 */
+	public ProjCoordinate project( ProjCoordinate src, ProjCoordinate dst ) {
+		double x = src.x*DTR;
+		if ( projectionLongitude != 0 )
+			x = ProjectionMath.normalizeLongitude( x-projectionLongitude );
+		return projectRadians(x, src.y*DTR, dst);
+	}
+
+	/**
+	 * Projects a geographic point (in radians), producing a projected result 
+	 * (in the units of the target coordinate system).
+	 * 
+   * @param src the input geographic coordinate (in radians)
+   * @param dst the projected coordinate (in coordinate system units)
+   * @return the target coordinate 
+	 * 
+	 */
+	public ProjCoordinate projectRadians( ProjCoordinate src, ProjCoordinate dst ) {
+		double x = src.x;
+		if ( projectionLongitude != 0 )
+			x = ProjectionMath.normalizeLongitude( x-projectionLongitude );
+		return projectRadians(x, src.y, dst);
+	}
+	
+	/**
+	 * Transform a geographic point (in radians), 
+	 * producing a projected result (in the units of the target coordinate system).
+	 * 
+	 * @param x the geographic x ordinate (in radians)
+	 * @param y the geographic y ordinate (in radians)
+   * @param dst the projected coordinate (in coordinate system units)
+	 * @return the target coordinate
+	 */
+	private ProjCoordinate projectRadians(double x, double y, ProjCoordinate dst ) {
+		project(x, y, dst);
+    if (unit == Units.DEGREES) {
+      // convert radians to DD
+      dst.x *= RTD;
+      dst.y *= RTD;
+    }
+    else {
+      // assume result is in metres
+      dst.x = totalScale * dst.x + totalFalseEasting;
+      dst.y = totalScale * dst.y + totalFalseNorthing;
+    }
+		return dst;
+	}
+
+	/**
+	 * Computes the projection of a given point 
+	 * (i.e. from geographics to projection space). 
+	 * This should be overridden for all projections.
+	 * 
+	 * @param x the geographic x ordinate (in radians)
+	 * @param y the geographic y ordinatee (in radians)
+   * @param dst the projected coordinate (in coordinate system units)
+	 * @return the target coordinate
+	 */
+	protected ProjCoordinate project(double x, double y, ProjCoordinate dst) {
+		dst.x = x;
+		dst.y = y;
+		return dst;
+	}
+
+	/**
+	 * Inverse-projects a point (in the units defined by the coordinate system), 
+	 * producing a geographic result (in degrees)
+	 * 
+   * @param src the input projected coordinate (in coordinate system units)
+   * @param dst the inverse-projected geographic coordinate (in degrees)
+   * @return the target coordinate
+	 */
+	public ProjCoordinate inverseProject(ProjCoordinate src, ProjCoordinate dst) {
+    inverseProjectRadians(src, dst);
+		dst.x *= RTD;
+		dst.y *= RTD;
+		return dst;
+	}
+
+	/**
+	 * Inverse-transforms a point (in the units defined by the coordinate system), 
+	 * producing a geographic result (in radians)
+	 * 
+	 * @param src the input projected coordinate (in coordinate system units)
+   * @param dst the inverse-projected geographic coordinate (in radians)
+   * @return the target coordinate
+	 * 
+	 */
+	public ProjCoordinate inverseProjectRadians(ProjCoordinate src, ProjCoordinate dst) {
+    double x;
+    double y;
+    if (unit == Units.DEGREES) {
+      // convert DD to radians
+      x = src.x * DTR;
+      y = src.y * DTR;
+    }
+    else {
+      x = (src.x - totalFalseEasting) / totalScale;
+      y = (src.y - totalFalseNorthing) / totalScale;
+    }
+		projectInverse(x, y, dst);
+		if (dst.x < -Math.PI)
+			dst.x = -Math.PI;
+		else if (dst.x > Math.PI)
+			dst.x = Math.PI;
+		if (projectionLongitude != 0)
+			dst.x = ProjectionMath.normalizeLongitude(dst.x+projectionLongitude);
+		return dst;
+	}
+
+	/**
+	 * Computes the inverse projection of a given point 
+	 * (i.e. from projection space to geographics). 
+	 * This should be overridden for all projections.
+	 * 
+	 * @param x the projected x ordinate (in coordinate system units)
+	 * @param y the projected y ordinate (in coordinate system units)
+	 * @param dst the inverse-projected geographic coordinate  (in radians)
+	 * @return the target coordinate
+	 */
+	protected ProjCoordinate projectInverse(double x, double y, ProjCoordinate dst) {
+		dst.x = x;
+		dst.y = y;
+		return dst;
+	}
+
+	
+	/**
+	 * Tests whether this projection is conformal.
+	 * A conformal projection preserves local angles.
+	 * 
+	 * @return true if this projection is conformal
+	 */
+	public boolean isConformal() {
+		return false;
+	}
+	
+	/**
+	 * Tests whether this projection is equal-area
+   * An equal-area projection preserves relative sizes
+   * of projected areas.
+   * 
+   * @return true if this projection is equal-area
+	 */
+	public boolean isEqualArea() {
+		return false;
+	}
+	
+	/**
+	 * Tests whether this projection has an inverse.
+	 * If this method returns <tt>true</tt>
+	 * then the {@link #inverseProject(ProjCoordinate, ProjCoordinate)}
+	 * and {@link #inverseProjectRadians(ProjCoordinate, ProjCoordinate)}
+	 * methods will return meaningful results.
+	 * 
+	 * @return true if this projection has an inverse
+	 */
+	public boolean hasInverse() {
+		return false;
+	}
+
+	/**
+	 * Tests whether under this projection lines of 
+	 * latitude and longitude form a rectangular grid
+	 */
+	public boolean isRectilinear() {
+		return false;
+	}
+
+	/**
+	 * Returns true if latitude lines are parallel for this projection
+	 */
+	public boolean parallelsAreParallel() {
+		return isRectilinear();
+	}
+
+	/**
+	 * Returns true if the given lat/long point is visible in this projection
+	 */
+	public boolean inside(double x, double y) {
+		x = normalizeLongitude( (float)(x*DTR-projectionLongitude) );
+		return minLongitude <= x && x <= maxLongitude && minLatitude <= y && y <= maxLatitude;
+	}
+
+	/**
+	 * Set the name of this projection.
+	 */
+	public void setName( String name ) {
+		this.name = name;
+	}
+	
+	public String getName() {
+		if ( name != null )
+			return name;
+		return toString();
+	}
+
+	/**
+	 * Get a string which describes this projection in PROJ.4 format.
+	 */
+	public String getPROJ4Description() {
+		AngleFormat format = new AngleFormat( AngleFormat.ddmmssPattern, false );
+		StringBuffer sb = new StringBuffer();
+		sb.append(
+			"+proj="+getName()+
+			" +a="+a
+		);
+		if ( es != 0 )
+			sb.append( " +es="+es );
+		sb.append( " +lon_0=" );
+		format.format( projectionLongitude, sb, null );
+		sb.append( " +lat_0=" );
+		format.format( projectionLatitude, sb, null );
+		if ( falseEasting != 1 )
+			sb.append( " +x_0="+falseEasting );
+		if ( falseNorthing != 1 )
+			sb.append( " +y_0="+falseNorthing );
+		if ( scaleFactor != 1 )
+			sb.append( " +k="+scaleFactor );
+		if ( fromMetres != 1 )
+			sb.append( " +fr_meters="+fromMetres );
+		return sb.toString();
+	}
+
+	public String toString() {
+		return "None";
+	}
+
+	/**
+	 * Set the minimum latitude. This is only used for Shape clipping and doesn't affect projection.
+	 */
+	public void setMinLatitude( double minLatitude ) {
+		this.minLatitude = minLatitude;
+	}
+	
+	public double getMinLatitude() {
+		return minLatitude;
+	}
+
+	/**
+	 * Set the maximum latitude. This is only used for Shape clipping and doesn't affect projection.
+	 */
+	public void setMaxLatitude( double maxLatitude ) {
+		this.maxLatitude = maxLatitude;
+	}
+	
+	public double getMaxLatitude() {
+		return maxLatitude;
+	}
+
+	public double getMaxLatitudeDegrees() {
+		return maxLatitude*RTD;
+	}
+
+	public double getMinLatitudeDegrees() {
+		return minLatitude*RTD;
+	}
+
+	public void setMinLongitude( double minLongitude ) {
+		this.minLongitude = minLongitude;
+	}
+	
+	public double getMinLongitude() {
+		return minLongitude;
+	}
+
+	public void setMinLongitudeDegrees( double minLongitude ) {
+		this.minLongitude = DTR*minLongitude;
+	}
+	
+	public double getMinLongitudeDegrees() {
+		return minLongitude*RTD;
+	}
+
+	public void setMaxLongitude( double maxLongitude ) {
+		this.maxLongitude = maxLongitude;
+	}
+	
+	public double getMaxLongitude() {
+		return maxLongitude;
+	}
+
+	public void setMaxLongitudeDegrees( double maxLongitude ) {
+		this.maxLongitude = DTR*maxLongitude;
+	}
+	
+	public double getMaxLongitudeDegrees() {
+		return maxLongitude*RTD;
+	}
+
+	/**
+	 * Set the projection latitude in radians.
+	 */
+	public void setProjectionLatitude( double projectionLatitude ) {
+		this.projectionLatitude = projectionLatitude;
+	}
+	
+	public double getProjectionLatitude() {
+		return projectionLatitude;
+	}
+	
+	/**
+	 * Set the projection latitude in degrees.
+	 */
+	public void setProjectionLatitudeDegrees( double projectionLatitude ) {
+		this.projectionLatitude = DTR*projectionLatitude;
+	}
+	
+	public double getProjectionLatitudeDegrees() {
+		return projectionLatitude*RTD;
+	}
+	
+	/**
+	 * Set the projection longitude in radians.
+	 */
+	public void setProjectionLongitude( double projectionLongitude ) {
+		this.projectionLongitude = normalizeLongitudeRadians( projectionLongitude );
+	}
+	
+	public double getProjectionLongitude() {
+		return projectionLongitude;
+	}
+	
+	/**
+	 * Set the projection longitude in degrees.
+	 */
+	public void setProjectionLongitudeDegrees( double projectionLongitude ) {
+		this.projectionLongitude = DTR*projectionLongitude;
+	}
+	
+	public double getProjectionLongitudeDegrees() {
+		return projectionLongitude*RTD;
+	}
+	
+	/**
+	 * Set the latitude of true scale in radians. This is only used by certain projections.
+	 */
+	public void setTrueScaleLatitude( double trueScaleLatitude ) {
+		this.trueScaleLatitude = trueScaleLatitude;
+	}
+	
+	public double getTrueScaleLatitude() {
+		return trueScaleLatitude;
+	}
+	
+	/**
+	 * Set the latitude of true scale in degrees. This is only used by certain projections.
+	 */
+	public void setTrueScaleLatitudeDegrees( double trueScaleLatitude ) {
+		this.trueScaleLatitude = DTR*trueScaleLatitude;
+	}
+	
+	public double getTrueScaleLatitudeDegrees() {
+		return trueScaleLatitude*RTD;
+	}
+	
+	/**
+	 * Set the projection latitude in radians.
+	 */
+	public void setProjectionLatitude1( double projectionLatitude1 ) {
+		this.projectionLatitude1 = projectionLatitude1;
+	}
+	
+	public double getProjectionLatitude1() {
+		return projectionLatitude1;
+	}
+	
+	/**
+	 * Set the projection latitude in degrees.
+	 */
+	public void setProjectionLatitude1Degrees( double projectionLatitude1 ) {
+		this.projectionLatitude1 = DTR*projectionLatitude1;
+	}
+	
+	public double getProjectionLatitude1Degrees() {
+		return projectionLatitude1*RTD;
+	}
+	
+	/**
+	 * Set the projection latitude in radians.
+	 */
+	public void setProjectionLatitude2( double projectionLatitude2 ) {
+		this.projectionLatitude2 = projectionLatitude2;
+	}
+	
+	public double getProjectionLatitude2() {
+		return projectionLatitude2;
+	}
+	
+	/**
+	 * Set the projection latitude in degrees.
+	 */
+	public void setProjectionLatitude2Degrees( double projectionLatitude2 ) {
+		this.projectionLatitude2 = DTR*projectionLatitude2;
+	}
+	
+	public double getProjectionLatitude2Degrees() {
+		return projectionLatitude2*RTD;
+	}
+	
+  /**
+   * Sets the alpha value.
+   */
+  public void setAlphaDegrees( double alpha ) {
+    this.alpha = DTR * alpha;
+  }
+  
+  /**
+   * Gets the alpha value, in radians.
+   * 
+   * @return the alpha value
+   */
+  public double getAlpha()
+  { 
+    return alpha;
+  }
+  
+  /**
+   * Sets the lonc value.
+   */
+  public void setLonCDegrees( double lonc ) {
+    this.lonc = DTR * lonc;
+  }
+  
+  /**
+   * Gets the lonc value, in radians.
+   * 
+   * @return the lonc value
+   */
+  public double getLonC()
+  { 
+    return lonc;
+  }
+  
+  /**
+   * Set the false Northing in projected units.
+   */
+  public void setFalseNorthing( double falseNorthing ) {
+    this.falseNorthing = falseNorthing;
+  }
+  
+	public double getFalseNorthing() {
+		return falseNorthing;
+	}
+	
+	/**
+	 * Set the false Easting in projected units.
+	 */
+	public void setFalseEasting( double falseEasting ) {
+		this.falseEasting = falseEasting;
+	}
+	
+	public double getFalseEasting() {
+		return falseEasting;
+	}
+	
+  public void setSouthernHemisphere(boolean isSouth)
+  {
+    this.isSouth = isSouth;
+  }
+  
+  public boolean getSouthernHemisphere() { return isSouth; }
+  
+	/**
+	 * Set the projection scale factor. This is set to 1 by default.
+	 * This value is called "k0" in PROJ.4.
+	 */
+	public void setScaleFactor( double scaleFactor ) {
+		this.scaleFactor = scaleFactor;
+	}
+
+	/**
+	 * Gets the projection scale factor.
+   * This value is called "k0" in PROJ.4.
+	 * 
+	 * @return
+	 */
+	public double getScaleFactor() {
+		return scaleFactor;
+	}
+
+	public double getEquatorRadius() {
+		return a;
+	}
+
+	/**
+	 * Set the conversion factor from metres to projected units. This is set to 1 by default.
+	 */
+	public void setFromMetres( double fromMetres ) {
+		this.fromMetres = fromMetres;
+	}
+	
+	public double getFromMetres() {
+		return fromMetres;
+	}
+	
+	public void setEllipsoid( Ellipsoid ellipsoid ) {
+		this.ellipsoid = ellipsoid;
+		a = ellipsoid.equatorRadius;
+		e = ellipsoid.eccentricity;
+		es = ellipsoid.eccentricity2;
+	}
+	
+	public Ellipsoid getEllipsoid() {
+		return ellipsoid;
+	}
+
+	/**
+	 * Returns the ESPG code for this projection, or 0 if unknown.
+	 */
+	public int getEPSGCode() {
+		return 0;
+	}
+	
+  public void setUnits(Unit unit)
+  {
+    this.unit = unit;
+  }
+  
+	/**
+	 * Initialize the projection. This should be called after setting parameters and before using the projection.
+	 * This is for performance reasons as initialization may be expensive.
+	 */
+	public void initialize() {
+		spherical = (e == 0.0);
+		one_es = 1-es;
+		rone_es = 1.0/one_es;
+		totalScale = a * fromMetres;
+		totalFalseEasting = falseEasting * fromMetres;
+		totalFalseNorthing = falseNorthing * fromMetres;		
+	}
+
+	public static float normalizeLongitude(float angle) {
+		if ( Double.isInfinite(angle) || Double.isNaN(angle) )
+			throw new InvalidValueException("Infinite or NaN longitude");
+		while (angle > 180)
+			angle -= 360;
+		while (angle < -180)
+			angle += 360;
+		return angle;
+	}
+
+	public static double normalizeLongitudeRadians( double angle ) {
+		if ( Double.isInfinite(angle) || Double.isNaN(angle) )
+			throw new InvalidValueException("Infinite or NaN longitude");
+		while (angle > Math.PI)
+			angle -= ProjectionMath.TWOPI;
+		while (angle < -Math.PI)
+			angle += ProjectionMath.TWOPI;
+		return angle;
+	}
+
+}
+
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PseudoCylindricalProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PseudoCylindricalProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PseudoCylindricalProjection.java	(revision 26409)
@@ -0,0 +1,34 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.proj;
+
+
+/**
+ * The superclass for all pseudo-cylindrical projections - eg. sinusoidal
+ * These are projections where parallels are straight, but meridians aren't
+ */
+public class PseudoCylindricalProjection extends CylindricalProjection {
+
+	public boolean isRectilinear() {
+		return false;
+	}
+
+	public String toString() {
+		return "Pseudo Cylindrical";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PutninsP2Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PutninsP2Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PutninsP2Projection.java	(revision 26409)
@@ -0,0 +1,73 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class PutninsP2Projection extends Projection {
+
+	private final static double C_x = 1.89490;
+	private final static double C_y = 1.71848;
+	private final static double C_p = 0.6141848493043784;
+	private final static double EPS = 1e-10;
+	private final static int NITER = 10;
+	private final static double PI_DIV_3 = 1.0471975511965977;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double p, c, s, V;
+		int i;
+
+		p = C_p * Math.sin(lpphi);
+		s = lpphi * lpphi;
+		out.y *= 0.615709 + s * ( 0.00909953 + s * 0.0046292 );
+		for (i = NITER; i > 0; --i) {
+			c = Math.cos(lpphi);
+			s = Math.sin(lpphi);
+			out.y -= V = (lpphi + s * (c - 1.) - p) /
+				(1. + c * (c - 1.) - s * s);
+			if (Math.abs(V) < EPS)
+				break;
+		}
+		if (i == 0)
+			out.y = lpphi < 0 ? - PI_DIV_3 : PI_DIV_3;
+		out.x = C_x * lplam * (Math.cos(lpphi) - 0.5);
+		out.y = C_y * Math.sin(lpphi);
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double c;
+
+		out.y = ProjectionMath.asin(xyy / C_y);
+		out.x = xyx / (C_x * ((c = Math.cos(out.y)) - 0.5));
+		out.y = ProjectionMath.asin((out.y + Math.sin(out.y) * (c - 1.)) / C_p);
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Putnins P2";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PutninsP4Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PutninsP4Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PutninsP4Projection.java	(revision 26409)
@@ -0,0 +1,67 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class PutninsP4Projection extends Projection {
+
+	protected double C_x;
+	protected double C_y;
+
+	public PutninsP4Projection() {
+		C_x = 0.874038744;
+		C_y = 3.883251825;
+	}
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate xy) {
+		lpphi = ProjectionMath.asin(0.883883476 * Math.sin(lpphi));
+		xy.x = C_x * lplam * Math.cos(lpphi);
+		xy.x /= Math.cos(lpphi *= 0.333333333333333);
+		xy.y = C_y * Math.sin(lpphi);
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate lp) {
+		lp.y = ProjectionMath.asin(xyy / C_y);
+		lp.x = xyx * Math.cos(lp.y) / C_x;
+		lp.y *= 3.;
+		lp.x /= Math.cos(lp.y);
+		lp.y = ProjectionMath.asin(1.13137085 * Math.sin(lp.y));
+		return lp;
+	}
+
+	/**
+	 * Returns true if this projection is equal area
+	 */
+	public boolean isEqualArea() {
+		return true;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Putnins P4";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PutninsP5PProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PutninsP5PProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PutninsP5PProjection.java	(revision 26409)
@@ -0,0 +1,34 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+
+public class PutninsP5PProjection extends PutninsP5Projection {
+
+	public PutninsP5PProjection() {
+		A = 1.5;
+		B = 0.5;
+	}
+
+	public String toString() {
+		return "Putnins P5P";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PutninsP5Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PutninsP5Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/PutninsP5Projection.java	(revision 26409)
@@ -0,0 +1,57 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class PutninsP5Projection extends Projection {
+
+	protected double A;
+	protected double B;
+
+	private final static double C = 1.01346;
+	private final static double D = 1.2158542;
+
+	public PutninsP5Projection() {
+		A = 2;
+		B = 1;
+	}
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate xy) {
+		xy.x = C * lplam * (A - B * Math.sqrt(1. + D * lpphi * lpphi));
+		xy.y = C * lpphi;
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate lp) {
+		lp.y = xyy / C;
+		lp.x = xyx / (C * (A - B * Math.sqrt(1. + D * lp.y * lp.y)));
+		return lp;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Putnins P5";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/QuarticAuthalicProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/QuarticAuthalicProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/QuarticAuthalicProjection.java	(revision 26409)
@@ -0,0 +1,32 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+public class QuarticAuthalicProjection extends SineTangentSeriesProjection {
+
+	public QuarticAuthalicProjection() {
+		super( 2., 2., false );
+	}
+	
+	public String toString() {
+		return "Quartic Authalic";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/RectangularPolyconicProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/RectangularPolyconicProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/RectangularPolyconicProjection.java	(revision 26409)
@@ -0,0 +1,66 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class RectangularPolyconicProjection extends Projection {
+
+	private double phi0;
+	private double phi1;
+	private double fxa;
+	private double fxb;
+	private boolean mode;
+
+	private final static double EPS = 1e-9;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double fa;
+
+		if (mode)
+			fa = Math.tan(lplam * fxb) * fxa;
+		else
+			fa = 0.5 * lplam;
+		if (Math.abs(lpphi) < EPS) {
+			out.x = fa + fa;
+			out.y = - phi0;
+		} else {
+			out.y = 1. / Math.tan(lpphi);
+			out.x = Math.sin(fa = 2. * Math.atan(fa * Math.sin(lpphi))) * out.y;
+			out.y = lpphi - phi0 + (1. - Math.cos(fa)) * out.y;
+		}
+		return out;
+	}
+
+	public void initialize() { // rpoly
+		super.initialize();
+/*FIXME
+		if ((mode = (phi1 = Math.abs(pj_param(params, "rlat_ts").f)) > EPS)) {
+			fxb = 0.5 * Math.sin(phi1);
+			fxa = 0.5 / fxb;
+		}
+*/
+	}
+
+	public String toString() {
+		return "Rectangular Polyconic";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/RobinsonProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/RobinsonProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/RobinsonProjection.java	(revision 26409)
@@ -0,0 +1,151 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class RobinsonProjection extends PseudoCylindricalProjection {
+
+	private final static double X[] = {
+		1,	-5.67239e-12,	-7.15511e-05,	3.11028e-06,
+		0.9986,	-0.000482241,	-2.4897e-05,	-1.33094e-06,
+		0.9954,	-0.000831031,	-4.4861e-05,	-9.86588e-07,
+		0.99,	-0.00135363,	-5.96598e-05,	3.67749e-06,
+		0.9822,	-0.00167442,	-4.4975e-06,	-5.72394e-06,
+		0.973,	-0.00214869,	-9.03565e-05,	1.88767e-08,
+		0.96,	-0.00305084,	-9.00732e-05,	1.64869e-06,
+		0.9427,	-0.00382792,	-6.53428e-05,	-2.61493e-06,
+		0.9216,	-0.00467747,	-0.000104566,	4.8122e-06,
+		0.8962,	-0.00536222,	-3.23834e-05,	-5.43445e-06,
+		0.8679,	-0.00609364,	-0.0001139,	3.32521e-06,
+		0.835,	-0.00698325,	-6.40219e-05,	9.34582e-07,
+		0.7986,	-0.00755337,	-5.00038e-05,	9.35532e-07,
+		0.7597,	-0.00798325,	-3.59716e-05,	-2.27604e-06,
+		0.7186,	-0.00851366,	-7.0112e-05,	-8.63072e-06,
+		0.6732,	-0.00986209,	-0.000199572,	1.91978e-05,
+		0.6213,	-0.010418,	8.83948e-05,	6.24031e-06,
+		0.5722,	-0.00906601,	0.000181999,	6.24033e-06,
+		0.5322, 0., 0., 0.
+	};
+
+	private final static double Y[] = {
+		0,	0.0124,	3.72529e-10,	1.15484e-09,
+		0.062,	0.0124001,	1.76951e-08,	-5.92321e-09,
+		0.124,	0.0123998,	-7.09668e-08,	2.25753e-08,
+		0.186,	0.0124008,	2.66917e-07,	-8.44523e-08,
+		0.248,	0.0123971,	-9.99682e-07,	3.15569e-07,
+		0.31,	0.0124108,	3.73349e-06,	-1.1779e-06,
+		0.372,	0.0123598,	-1.3935e-05,	4.39588e-06,
+		0.434,	0.0125501,	5.20034e-05,	-1.00051e-05,
+		0.4968,	0.0123198,	-9.80735e-05,	9.22397e-06,
+		0.5571,	0.0120308,	4.02857e-05,	-5.2901e-06,
+		0.6176,	0.0120369,	-3.90662e-05,	7.36117e-07,
+		0.6769,	0.0117015,	-2.80246e-05,	-8.54283e-07,
+		0.7346,	0.0113572,	-4.08389e-05,	-5.18524e-07,
+		0.7903,	0.0109099,	-4.86169e-05,	-1.0718e-06,
+		0.8435,	0.0103433,	-6.46934e-05,	5.36384e-09,
+		0.8936,	0.00969679,	-6.46129e-05,	-8.54894e-06,
+		0.9394,	0.00840949,	-0.000192847,	-4.21023e-06,
+		0.9761,	0.00616525,	-0.000256001,	-4.21021e-06,
+		1., 0., 0., 0
+	};
+
+	private final int NODES = 18;
+	private final static double FXC = 0.8487;
+	private final static double FYC = 1.3523;
+	private final static double C1 = 11.45915590261646417544;
+	private final static double RC1 = 0.08726646259971647884;
+	private final static double ONEEPS = 1.000001;
+	private final static double EPS = 1e-8;
+	
+	public RobinsonProjection() {
+	}
+
+	private double poly(double[] array, int offset, double z) {
+		return (array[offset] + z * (array[offset+1] + z * (array[offset+2] + z * array[offset+3])));
+	}
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate xy) {
+		double phi = Math.abs(lpphi);
+		int i = (int)Math.floor(phi * C1);
+		if (i >= NODES)
+			i = NODES - 1;
+		phi = Math.toDegrees(phi - RC1 * i);
+		i *= 4;
+		xy.x = poly(X, i, phi) * FXC * lplam;
+		xy.y = poly(Y, i, phi) * FYC;
+		if (lpphi < 0.0)
+			xy.y = -xy.y;
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate lp) {
+		int i;
+		double t, t1;
+
+		lp.x = x / FXC;
+		lp.y = Math.abs(y / FYC);
+		if (lp.y >= 1.0) {
+			if (lp.y > 1.000001) {
+				throw new ProjectionException();
+			} else {
+				lp.y = y < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+				lp.x /= X[4*NODES];
+			}
+		} else {
+			for (i = 4 * (int)Math.floor(lp.y * NODES);;) {
+				if (Y[i] > lp.y)
+					i -= 4;
+				else if (Y[i+4] <= lp.y)
+					i += 4;
+				else
+					break;
+			}
+			t = 5. * (lp.y - Y[i])/(Y[i+4] - Y[i]);
+			double Tc0 = Y[i];
+			double Tc1 = Y[i+1];
+			double Tc2 = Y[i+2];
+			double Tc3 = Y[i+3];
+			t = 5. * (lp.y - Tc0)/(Y[i+1] - Tc0);
+			Tc0 -= lp.y;
+			for (;;) { // Newton-Raphson
+				t -= t1 = (Tc0 + t * (Tc1 + t * (Tc2 + t * Tc3))) / (Tc1 + t * (Tc2 + Tc2 + t * 3. * Tc3));
+				if (Math.abs(t1) < EPS)
+					break;
+			}
+			lp.y = Math.toRadians(5 * i + t);
+			if (y < 0.)
+				lp.y = -lp.y;
+			lp.x /= poly(X, i, t);
+		}
+		return lp;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Robinson";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/SimpleConicProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/SimpleConicProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/SimpleConicProjection.java	(revision 26409)
@@ -0,0 +1,179 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class SimpleConicProjection extends ConicProjection {
+	private double n;
+	private double rho_c;
+	private double rho_0;
+	private double sig;
+	private double c1, c2;
+	private int	type;
+
+	public final static int EULER = 0;
+	public final static int MURD1 = 1;
+	public final static int MURD2 = 2;
+	public final static int MURD3 = 3;
+	public final static int PCONIC = 4;
+	public final static int TISSOT = 5;
+	public final static int VITK1 = 6;
+	private final static double EPS10 = 1.e-10;
+	private final static double EPS = 1e-10;
+
+	public SimpleConicProjection() {
+		this( EULER );
+	}
+	
+	public SimpleConicProjection(int type) {
+		this.type = type;
+		minLatitude = Math.toRadians(0);
+		maxLatitude = Math.toRadians(80);
+	}
+	
+	public String toString() {
+		return "Simple Conic";
+	}
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double rho;
+
+		switch (type) {
+		case MURD2:
+			rho = rho_c + Math.tan(sig - lpphi);
+			break;
+		case PCONIC:
+			rho = c2 * (c1 - Math.tan(lpphi));
+			break;
+		default:
+			rho = rho_c - lpphi;
+			break;
+		}
+		out.x = rho * Math.sin( lplam *= n );
+		out.y = rho_0 - rho * Math.cos(lplam);
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double rho;
+
+		rho = ProjectionMath.distance(xyx, out.y = rho_0 - xyy);
+		if (n < 0.) {
+			rho = - rho;
+			out.x = - xyx;
+			out.y = - xyy;
+		}
+		out.x = Math.atan2(xyx, xyy) / n;
+		switch (type) {
+		case PCONIC:
+			out.y = Math.atan(c1 - rho / c2) + sig;
+			break;
+		case MURD2:
+			out.y = sig - Math.atan(rho - rho_c);
+			break;
+		default:
+			out.y = rho_c - rho;
+		}
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public void initialize() {
+		super.initialize();
+		double del, cs, dummy;
+
+		/* get common factors for simple conics */
+		double p1, p2, d, s;
+		int err = 0;
+
+/*FIXME
+		if (!pj_param(params, "tlat_1").i ||
+			!pj_param(params, "tlat_2").i) {
+			err = -41;
+		} else {
+			p1 = pj_param(params, "rlat_1").f;
+			p2 = pj_param(params, "rlat_2").f;
+			*del = 0.5 * (p2 - p1);
+			sig = 0.5 * (p2 + p1);
+			err = (Math.abs(*del) < EPS || Math.abs(sig) < EPS) ? -42 : 0;
+			*del = *del;
+		}
+*/
+		p1 = Math.toRadians(30);//FIXME
+		p2 = Math.toRadians(60);//FIXME
+		del = 0.5 * (p2 - p1);
+		sig = 0.5 * (p2 + p1);
+		err = (Math.abs(del) < EPS || Math.abs(sig) < EPS) ? -42 : 0;
+		del = del;
+
+		if (err != 0)
+			throw new ProjectionException("Error "+err);
+
+		switch (type) {
+		case TISSOT:
+			n = Math.sin(sig);
+			cs = Math.cos(del);
+			rho_c = n / cs + cs / n;
+			rho_0 = Math.sqrt((rho_c - 2 * Math.sin(projectionLatitude))/n);
+			break;
+		case MURD1:
+			rho_c = Math.sin(del)/(del * Math.tan(sig)) + sig;
+			rho_0 = rho_c - projectionLatitude;
+			n = Math.sin(sig);
+			break;
+		case MURD2:
+			rho_c = (cs = Math.sqrt(Math.cos(del))) / Math.tan(sig);
+			rho_0 = rho_c + Math.tan(sig - projectionLatitude);
+			n = Math.sin(sig) * cs;
+			break;
+		case MURD3:
+			rho_c = del / (Math.tan(sig) * Math.tan(del)) + sig;
+			rho_0 = rho_c - projectionLatitude;
+			n = Math.sin(sig) * Math.sin(del) * Math.tan(del) / (del * del);
+			break;
+		case EULER:
+			n = Math.sin(sig) * Math.sin(del) / del;
+			del *= 0.5;
+			rho_c = del / (Math.tan(del) * Math.tan(sig)) + sig;	
+			rho_0 = rho_c - projectionLatitude;
+			break;
+		case PCONIC:
+			n = Math.sin(sig);
+			c2 = Math.cos(del);
+			c1 = 1./Math.tan(sig);
+			if (Math.abs(del = projectionLatitude - sig) - EPS10 >= ProjectionMath.HALFPI)
+				throw new ProjectionException("-43");
+			rho_0 = c2 * (c1 - Math.tan(del));
+maxLatitude = Math.toRadians(60);//FIXME
+			break;
+		case VITK1:
+			n = (cs = Math.tan(del)) * Math.sin(sig) / del;
+			rho_c = del / (cs * Math.tan(sig)) + sig;
+			rho_0 = rho_c - projectionLatitude;
+			break;
+		}
+	}
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/SineTangentSeriesProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/SineTangentSeriesProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/SineTangentSeriesProjection.java	(revision 26409)
@@ -0,0 +1,75 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+class SineTangentSeriesProjection extends ConicProjection {
+	private double C_x;
+	private double C_y;
+	private double C_p;
+	private boolean tan_mode;
+
+	protected SineTangentSeriesProjection( double p, double q, boolean mode ) {
+		es = 0.;
+		C_x = q / p;
+		C_y = p;
+		C_p = 1/ q;
+		tan_mode = mode;
+		initialize();
+	}
+	
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate xy) {
+		double c;
+
+		xy.x = C_x * lplam * Math.cos(lpphi);
+		xy.y = C_y;
+		lpphi *= C_p;
+		c = Math.cos(lpphi);
+		if (tan_mode) {
+			xy.x *= c * c;
+			xy.y *= Math.tan(lpphi);
+		} else {
+			xy.x /= c;
+			xy.y *= Math.sin(lpphi);
+		}
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate lp) {
+		double c;
+		
+		xyy /= C_y;
+		c = Math.cos(lp.y = tan_mode ? Math.atan(xyy) : ProjectionMath.asin(xyy));
+		lp.y /= C_p;
+		lp.x = xyx / (C_x * Math.cos(lp.y /= C_p));
+		if (tan_mode)
+			lp.x /= c * c;
+		else
+			lp.x *= c;
+		return lp;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/SinusoidalProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/SinusoidalProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/SinusoidalProjection.java	(revision 26409)
@@ -0,0 +1,55 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class SinusoidalProjection extends PseudoCylindricalProjection {
+	
+	public ProjCoordinate project(double lam, double phi, ProjCoordinate xy) {
+		xy.x = lam * Math.cos(phi);
+		xy.y = phi;
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate lp) {
+		lp.x = x / Math.cos(y);
+		lp.y = y;
+		return lp;
+	}
+
+	public double getWidth(double y) {
+		return ProjectionMath.normalizeLongitude(Math.PI) * Math.cos(y);
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public boolean isEqualArea() {
+     return true;
+	}
+
+	public String toString() {
+		return "Sinusoidal";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/StereographicAzimuthalProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/StereographicAzimuthalProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/StereographicAzimuthalProjection.java	(revision 26409)
@@ -0,0 +1,267 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.*;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class StereographicAzimuthalProjection extends AzimuthalProjection {
+
+	private final static double TOL = 1.e-8;
+	
+	private double akm1;
+	
+	public StereographicAzimuthalProjection() {
+		this(Math.toRadians(90.0), Math.toRadians(0.0));
+	}
+
+	public StereographicAzimuthalProjection(double projectionLatitude, double projectionLongitude) {
+		super(projectionLatitude, projectionLongitude);
+		initialize();
+	}
+	
+	public void setupUPS(int pole) {
+		projectionLatitude = (pole == SOUTH_POLE) ? -ProjectionMath.HALFPI: ProjectionMath.HALFPI;
+		projectionLongitude = 0.0;
+		scaleFactor = 0.994;
+		falseEasting = 2000000.0;
+		falseNorthing = 2000000.0;
+		trueScaleLatitude = ProjectionMath.HALFPI;
+		initialize();
+	}
+	
+	public void initialize() {
+		double t;
+
+		super.initialize();
+		if (Math.abs((t = Math.abs(projectionLatitude)) - ProjectionMath.HALFPI) < EPS10)
+			mode = projectionLatitude < 0. ? SOUTH_POLE : NORTH_POLE;
+		else
+			mode = t > EPS10 ? OBLIQUE : EQUATOR;
+		trueScaleLatitude = Math.abs(trueScaleLatitude);
+		if (! spherical) {
+			double X;
+
+			switch (mode) {
+			case NORTH_POLE:
+			case SOUTH_POLE:
+				if (Math.abs(trueScaleLatitude - ProjectionMath.HALFPI) < EPS10)
+					akm1 = 2. * scaleFactor /
+					   Math.sqrt(Math.pow(1+e,1+e)*Math.pow(1-e,1-e));
+				else {
+					akm1 = Math.cos(trueScaleLatitude) /
+					   ProjectionMath.tsfn(trueScaleLatitude, t = Math.sin(trueScaleLatitude), e);
+					t *= e;
+					akm1 /= Math.sqrt(1. - t * t);
+				}
+				break;
+			case EQUATOR:
+				akm1 = 2. * scaleFactor;
+				break;
+			case OBLIQUE:
+				t = Math.sin(projectionLatitude);
+				X = 2. * Math.atan(ssfn(projectionLatitude, t, e)) - ProjectionMath.HALFPI;
+				t *= e;
+				akm1 = 2. * scaleFactor * Math.cos(projectionLatitude) / Math.sqrt(1. - t * t);
+				sinphi0 = Math.sin(X);
+				cosphi0 = Math.cos(X);
+				break;
+			}
+		} else {
+			switch (mode) {
+			case OBLIQUE:
+				sinphi0 = Math.sin(projectionLatitude);
+				cosphi0 = Math.cos(projectionLatitude);
+			case EQUATOR:
+				akm1 = 2. * scaleFactor;
+				break;
+			case SOUTH_POLE:
+			case NORTH_POLE:
+				akm1 = Math.abs(trueScaleLatitude - ProjectionMath.HALFPI) >= EPS10 ?
+				   Math.cos(trueScaleLatitude) / Math.tan(ProjectionMath.QUARTERPI - .5 * trueScaleLatitude) :
+				   2. * scaleFactor ;
+				break;
+			}
+		}
+	}
+
+	public ProjCoordinate project(double lam, double phi, ProjCoordinate xy) {
+		double coslam = Math.cos(lam);
+		double sinlam = Math.sin(lam);
+		double sinphi = Math.sin(phi);
+
+		if (spherical) {
+			double cosphi = Math.cos(phi);
+
+			switch (mode) {
+			case EQUATOR:
+				xy.y = 1. + cosphi * coslam;
+				if (xy.y <= EPS10)
+					throw new ProjectionException();
+				xy.x = (xy.y = akm1 / xy.y) * cosphi * sinlam;
+				xy.y *= sinphi;
+				break;
+			case OBLIQUE:
+				xy.y = 1. + sinphi0 * sinphi + cosphi0 * cosphi * coslam;
+				if (xy.y <= EPS10)
+					throw new ProjectionException();
+				xy.x = (xy.y = akm1 / xy.y) * cosphi * sinlam;
+				xy.y *= cosphi0 * sinphi - sinphi0 * cosphi * coslam;
+				break;
+			case NORTH_POLE:
+				coslam = - coslam;
+				phi = - phi;
+			case SOUTH_POLE:
+				if (Math.abs(phi - ProjectionMath.HALFPI) < TOL)
+					throw new ProjectionException();
+				xy.x = sinlam * ( xy.y = akm1 * Math.tan(ProjectionMath.QUARTERPI + .5 * phi) );
+				xy.y *= coslam;
+				break;
+			}
+		} else {
+			double sinX = 0, cosX = 0, X, A;
+
+			if (mode == OBLIQUE || mode == EQUATOR) {
+				sinX = Math.sin(X = 2. * Math.atan(ssfn(phi, sinphi, e)) - ProjectionMath.HALFPI);
+				cosX = Math.cos(X);
+			}
+			switch (mode) {
+			case OBLIQUE:
+				A = akm1 / (cosphi0 * (1. + sinphi0 * sinX + cosphi0 * cosX * coslam));
+				xy.y = A * (cosphi0 * sinX - sinphi0 * cosX * coslam);
+				xy.x = A * cosX;
+				break;
+			case EQUATOR:
+				A = 2. * akm1 / (1. + cosX * coslam);
+				xy.y = A * sinX;
+				xy.x = A * cosX;
+				break;
+			case SOUTH_POLE:
+				phi = -phi;
+				coslam = -coslam;
+				sinphi = -sinphi;
+			case NORTH_POLE:
+				xy.x = akm1 * ProjectionMath.tsfn(phi, sinphi, e);
+				xy.y = - xy.x * coslam;
+				break;
+			}
+			xy.x = xy.x * sinlam;
+		}
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate lp) {
+		if (spherical) {
+			double  c, rh, sinc, cosc;
+
+			sinc = Math.sin(c = 2. * Math.atan((rh = ProjectionMath.distance(x, y)) / akm1));
+			cosc = Math.cos(c);
+			lp.x = 0.;
+			switch (mode) {
+			case EQUATOR:
+				if (Math.abs(rh) <= EPS10)
+					lp.y = 0.;
+				else
+					lp.y = Math.asin(y * sinc / rh);
+				if (cosc != 0. || x != 0.)
+					lp.x = Math.atan2(x * sinc, cosc * rh);
+				break;
+			case OBLIQUE:
+				if (Math.abs(rh) <= EPS10)
+					lp.y = projectionLatitude;
+				else
+					lp.y = Math.asin(cosc * sinphi0 + y * sinc * cosphi0 / rh);
+				if ((c = cosc - sinphi0 * Math.sin(lp.y)) != 0. || x != 0.)
+					lp.x = Math.atan2(x * sinc * cosphi0, c * rh);
+				break;
+			case NORTH_POLE:
+				y = -y;
+			case SOUTH_POLE:
+				if (Math.abs(rh) <= EPS10)
+					lp.y = projectionLatitude;
+				else
+					lp.y = Math.asin(mode == SOUTH_POLE ? - cosc : cosc);
+				lp.x = (x == 0. && y == 0.) ? 0. : Math.atan2(x, y);
+				break;
+			}
+		} else {
+			double cosphi, sinphi, tp, phi_l, rho, halfe, halfpi;
+
+			rho = ProjectionMath.distance(x, y);
+			switch (mode) {
+			case OBLIQUE:
+			case EQUATOR:
+			default:	// To prevent the compiler complaining about uninitialized vars.
+				cosphi = Math.cos( tp = 2. * Math.atan2(rho * cosphi0 , akm1) );
+				sinphi = Math.sin(tp);
+				phi_l = Math.asin(cosphi * sinphi0 + (y * sinphi * cosphi0 / rho));
+				tp = Math.tan(.5 * (ProjectionMath.HALFPI + phi_l));
+				x *= sinphi;
+				y = rho * cosphi0 * cosphi - y * sinphi0* sinphi;
+				halfpi = ProjectionMath.HALFPI;
+				halfe = .5 * e;
+				break;
+			case NORTH_POLE:
+				y = -y;
+			case SOUTH_POLE:
+				phi_l = ProjectionMath.HALFPI - 2. * Math.atan(tp = - rho / akm1);
+				halfpi = -ProjectionMath.HALFPI;
+				halfe = -.5 * e;
+				break;
+			}
+			for (int i = 8; i-- != 0; phi_l = lp.y) {
+				sinphi = e * Math.sin(phi_l);
+				lp.y = 2. * Math.atan(tp * Math.pow((1.+sinphi)/(1.-sinphi), halfe)) - halfpi;
+				if (Math.abs(phi_l - lp.y) < EPS10) {
+					if (mode == SOUTH_POLE)
+						lp.y = -lp.y;
+					lp.x = (x == 0. && y == 0.) ? 0. : Math.atan2(x, y);
+					return lp;
+				}
+			}
+			throw new ConvergenceFailureException("Iteration didn't converge");
+		}
+		return lp;
+	}
+	
+	/**
+	 * Returns true if this projection is conformal
+	 */
+	public boolean isConformal() {
+		return true;
+	}
+	
+	public boolean hasInverse() {
+		return true;
+	}
+
+	private double ssfn(double phit, double sinphi, double eccen) {
+		sinphi *= eccen;
+		return Math.tan (.5 * (ProjectionMath.HALFPI + phit)) *
+		   Math.pow((1. - sinphi) / (1. + sinphi), .5 * eccen);
+	}
+
+	public String toString() {
+		return "Stereographic Azimuthal";
+	}
+
+}
+
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/TissotProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/TissotProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/TissotProjection.java	(revision 26409)
@@ -0,0 +1,32 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+public class TissotProjection extends SimpleConicProjection {
+
+	public TissotProjection() {
+		super( SimpleConicProjection.TISSOT );
+	}
+
+	public String toString() {
+		return "Tissot";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/TransverseCylindricalEqualArea.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/TransverseCylindricalEqualArea.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/TransverseCylindricalEqualArea.java	(revision 26409)
@@ -0,0 +1,66 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class TransverseCylindricalEqualArea extends Projection {
+
+	private double rk0;
+
+	public TransverseCylindricalEqualArea() {
+		initialize();
+	}
+	
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		out.x = rk0 * Math.cos(lpphi) * Math.sin(lplam);
+		out.y = scaleFactor * (Math.atan2(Math.tan(lpphi), Math.cos(lplam)) - projectionLatitude);
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double t;
+
+		out.y = xyy * rk0 + projectionLatitude;
+		out.x *= scaleFactor;
+		t = Math.sqrt(1. - xyx * xyx);
+		out.y = Math.asin(t * Math.sin(xyy));
+		out.x = Math.atan2(xyx, t * Math.cos(xyy));
+		return out;
+	}
+
+	public void initialize() { // tcea
+		super.initialize();
+		rk0 = 1 / scaleFactor;
+	}
+
+	public boolean isRectilinear() {
+		return false;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Transverse Cylindrical Equal Area";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/TransverseMercatorProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/TransverseMercatorProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/TransverseMercatorProjection.java	(revision 26409)
@@ -0,0 +1,206 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.datum.Ellipsoid;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+/**
+* Transverse Mercator Projection algorithm is taken from the USGS PROJ package.
+*/
+public class TransverseMercatorProjection extends CylindricalProjection {
+	
+	private final static double FC1 = 1.0;
+	private final static double FC2 = 0.5;
+	private final static double FC3 = 0.16666666666666666666;
+	private final static double FC4 = 0.08333333333333333333;
+	private final static double FC5 = 0.05;
+	private final static double FC6 = 0.03333333333333333333;
+	private final static double FC7 = 0.02380952380952380952;
+	private final static double FC8 = 0.01785714285714285714;
+
+  private int utmZone = -1;
+	private double esp;
+	private double ml0;
+	private double[] en;
+
+	public TransverseMercatorProjection() {
+		ellipsoid = Ellipsoid.GRS80;
+		projectionLatitude = Math.toRadians(0);
+		projectionLongitude = Math.toRadians(0);
+		minLongitude = Math.toRadians(-90);
+		maxLongitude = Math.toRadians(90);
+		initialize();
+	}
+	
+	/**
+	* Set up a projection suitable for State Plane Coordinates.
+	*/
+	public TransverseMercatorProjection(Ellipsoid ellipsoid, double lon_0, double lat_0, double k, double x_0, double y_0) {
+		setEllipsoid(ellipsoid);
+		projectionLongitude = lon_0;
+		projectionLatitude = lat_0;
+		scaleFactor = k;
+		falseEasting = x_0;
+		falseNorthing = y_0;
+		initialize();
+	}
+	
+	public Object clone() {
+		TransverseMercatorProjection p = (TransverseMercatorProjection)super.clone();
+		if (en != null)
+			p.en = (double[])en.clone();
+		return p;
+	}
+	
+	public boolean isRectilinear() {
+		return false;
+	}
+
+	public void initialize() {
+		super.initialize();
+		if (spherical) {
+			esp = scaleFactor;
+			ml0 = .5 * esp;
+		} else {
+			en = ProjectionMath.enfn(es);
+			ml0 = ProjectionMath.mlfn(projectionLatitude, Math.sin(projectionLatitude), Math.cos(projectionLatitude), en);
+			esp = es / (1. - es);
+		}
+	}
+
+	public int getRowFromNearestParallel(double latitude) {
+		int degrees = (int)ProjectionMath.radToDeg(ProjectionMath.normalizeLatitude(latitude));
+		if (degrees < -80 || degrees > 84)
+			return 0;
+		if (degrees > 80)
+			return 24;
+		return (degrees + 80) / 8 + 3;
+	}
+	
+	public int getZoneFromNearestMeridian(double longitude) {
+		int zone = (int)Math.floor((ProjectionMath.normalizeLongitude(longitude) + Math.PI) * 30.0 / Math.PI) + 1;
+		if (zone < 1)
+			zone = 1;
+		else if (zone > 60)
+			zone = 60;
+		return zone;
+	}
+	
+	public void setUTMZone(int zone) {
+    utmZone = zone;
+		zone--;
+		projectionLongitude = (zone + .5) * Math.PI / 30. -Math.PI;
+		projectionLatitude = 0.0;
+		scaleFactor = 0.9996;
+    falseEasting = 500000;
+    falseNorthing = isSouth ? 10000000.0 : 0.0;
+		initialize();
+	}
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate xy) {
+		if (spherical) {
+			double cosphi = Math.cos(lpphi);
+			double b = cosphi * Math.sin(lplam);
+
+			xy.x = ml0 * scaleFactor * Math.log((1. + b) / (1. - b));
+			double ty = cosphi * Math.cos(lplam) / Math.sqrt(1. - b * b);
+			ty = ProjectionMath.acos(ty);
+			if (lpphi < 0.0)
+				ty = -ty;
+			xy.y = esp * (ty - projectionLatitude);
+		} else {
+			double al, als, n, t;
+			double sinphi = Math.sin(lpphi);
+			double cosphi = Math.cos(lpphi);
+			t = Math.abs(cosphi) > 1e-10 ? sinphi/cosphi : 0.0;
+			t *= t;
+			al = cosphi * lplam;
+			als = al * al;
+			al /= Math.sqrt(1. - es * sinphi * sinphi);
+			n = esp * cosphi * cosphi;
+			xy.x = scaleFactor * al * (FC1 +
+				FC3 * als * (1. - t + n +
+				FC5 * als * (5. + t * (t - 18.) + n * (14. - 58. * t)
+				+ FC7 * als * (61. + t * ( t * (179. - t) - 479. ) )
+			)));
+			xy.y = scaleFactor * (ProjectionMath.mlfn(lpphi, sinphi, cosphi, en) - ml0 +
+				sinphi * al * lplam * FC2 * ( 1. +
+				FC4 * als * (5. - t + n * (9. + 4. * n) +
+				FC6 * als * (61. + t * (t - 58.) + n * (270. - 330 * t)
+				+ FC8 * als * (1385. + t * ( t * (543. - t) - 3111.) )
+			))));
+		}
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate out) {
+		if (spherical) {
+			double h = Math.exp(x / scaleFactor);
+			double g = .5 * (h - 1. / h);
+			h = Math.cos(projectionLatitude + y / scaleFactor);
+			out.y = ProjectionMath.asin(Math.sqrt((1. - h*h) / (1. + g*g)));
+			if (y < 0)
+				out.y = -out.y;
+			out.x = Math.atan2(g, h);
+		} else {
+			double n, con, cosphi, d, ds, sinphi, t;
+
+			out.y = ProjectionMath.inv_mlfn(ml0 + y/scaleFactor, es, en);
+			if (Math.abs(y) >= ProjectionMath.HALFPI) {
+				out.y = y < 0. ? -ProjectionMath.HALFPI : ProjectionMath.HALFPI;
+				out.x = 0.;
+			} else {
+				sinphi = Math.sin(out.y);
+				cosphi = Math.cos(out.y);
+				t = Math.abs(cosphi) > 1e-10 ? sinphi/cosphi : 0.;
+				n = esp * cosphi * cosphi;
+				d = x * Math.sqrt(con = 1. - es * sinphi * sinphi) / scaleFactor;
+				con *= t;
+				t *= t;
+				ds = d * d;
+				out.y -= (con * ds / (1.-es)) * FC2 * (1. -
+					ds * FC4 * (5. + t * (3. - 9. *  n) + n * (1. - 4 * n) -
+					ds * FC6 * (61. + t * (90. - 252. * n +
+						45. * t) + 46. * n
+					- ds * FC8 * (1385. + t * (3633. + t * (4095. + 1574. * t)) )
+				)));
+				out.x = d*(FC1 -
+					ds*FC3*( 1. + 2.*t + n -
+					ds*FC5*(5. + t*(28. + 24.*t + 8.*n) + 6.*n
+					- ds * FC7 * (61. + t * (662. + t * (1320. + 720. * t)) )
+				))) / cosphi;
+			}
+		}
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+    if (utmZone >= 0)
+      return "Universal Tranverse Mercator";
+		return "Transverse Mercator";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/TranverseCentralCylindricalProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/TranverseCentralCylindricalProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/TranverseCentralCylindricalProjection.java	(revision 26409)
@@ -0,0 +1,52 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class TranverseCentralCylindricalProjection extends CylindricalProjection {
+
+	public TranverseCentralCylindricalProjection() {
+		minLongitude = ProjectionMath.degToRad(-60);
+		maxLongitude = ProjectionMath.degToRad(60);
+	}
+	
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double b, bt;
+
+		b = Math.cos(lpphi) * Math.sin(lplam);
+		if ((bt = 1. - b * b) < EPS10)
+			throw new ProjectionException("F");
+		out.x = b / Math.sqrt(bt);
+		out.y = Math.atan2(Math.tan(lpphi), Math.cos(lplam));
+		return out;
+	}
+
+	public boolean isRectilinear() {
+		return false;
+	}
+
+	public String toString() {
+		return "Transverse Central Cylindrical";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/UrmaevFlatPolarSinusoidalProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/UrmaevFlatPolarSinusoidalProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/UrmaevFlatPolarSinusoidalProjection.java	(revision 26409)
@@ -0,0 +1,75 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class UrmaevFlatPolarSinusoidalProjection extends Projection {
+
+	private final static double C_x = 0.8773826753;
+	private final static double Cy = 1.139753528477;
+
+	private double n = 0.8660254037844386467637231707;// wag1
+	private double C_y;
+
+	public UrmaevFlatPolarSinusoidalProjection() {
+	}
+	
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		out.y = ProjectionMath.asin(n * Math.sin(lpphi));
+		out.x = C_x * lplam * Math.cos(lpphi);
+		out.y = C_y * lpphi;
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		xyy /= C_y;
+		out.y = ProjectionMath.asin(Math.sin(xyy) / n);
+		out.x = xyx / (C_x * Math.cos(xyy));
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public void initialize() { // urmfps
+		super.initialize();
+		if (n <= 0. || n > 1.)
+			throw new ProjectionException("-40");
+		C_y = Cy / n;
+	}
+
+	// Properties
+	public void setN( double n ) {
+		this.n = n;
+	}
+	
+	public double getN() {
+		return n;
+	}
+	
+	public String toString() {
+		return "Urmaev Flat-Polar Sinusoidal";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/VanDerGrintenProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/VanDerGrintenProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/VanDerGrintenProjection.java	(revision 26409)
@@ -0,0 +1,114 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.ProjectionException;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class VanDerGrintenProjection extends Projection {
+
+	private final static double TOL = 1.e-10;
+	private final static double THIRD = .33333333333333333333;
+	private final static double TWO_THRD = .66666666666666666666;
+	private final static double C2_27 = .07407407407407407407;
+	private final static double PI4_3 = 4.18879020478639098458;
+	private final static double PISQ = 9.86960440108935861869;
+	private final static double TPISQ = 19.73920880217871723738;
+	private final static double HPISQ = 4.93480220054467930934;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double  al, al2, g, g2, p2;
+
+		p2 = Math.abs(lpphi / ProjectionMath.HALFPI);
+		if ((p2 - TOL) > 1.) throw new ProjectionException("F");
+		if (p2 > 1.)
+			p2 = 1.;
+		if (Math.abs(lpphi) <= TOL) {
+			out.x = lplam;
+			out.y = 0.;
+		} else if (Math.abs(lplam) <= TOL || Math.abs(p2 - 1.) < TOL) {
+			out.x = 0.;
+			out.y = Math.PI * Math.tan(.5 * Math.asin(p2));
+			if (lpphi < 0.) out.y = -out.y;
+		} else {
+			al = .5 * Math.abs(Math.PI / lplam - lplam / Math.PI);
+			al2 = al * al;
+			g = Math.sqrt(1. - p2 * p2);
+			g = g / (p2 + g - 1.);
+			g2 = g * g;
+			p2 = g * (2. / p2 - 1.);
+			p2 = p2 * p2;
+			out.x = g - p2; g = p2 + al2;
+			out.x = Math.PI * (al * out.x + Math.sqrt(al2 * out.x * out.x - g * (g2 - p2))) / g;
+			if (lplam < 0.) out.x = -out.x;
+			out.y = Math.abs(out.x / Math.PI);
+			out.y = 1. - out.y * (out.y + 2. * al);
+			if (out.y < -TOL) throw new ProjectionException("F");
+			if (out.y < 0.)
+				out.y = 0.;
+			else
+				out.y = Math.sqrt(out.y) * (lpphi < 0. ? -Math.PI : Math.PI);
+		}
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		double t, c0, c1, c2, c3, al, r2, r, m, d, ay, x2, y2;
+
+		x2 = xyx * xyx;
+		if ((ay = Math.abs(xyy)) < TOL) {
+			out.y = 0.;
+			t = x2 * x2 + TPISQ * (x2 + HPISQ);
+			out.x = Math.abs(xyx) <= TOL ? 0. :
+			   .5 * (x2 - PISQ + Math.sqrt(t)) / xyx;
+			return out;
+		}
+		y2 = xyy * xyy;
+		r = x2 + y2;	r2 = r * r;
+		c1 = - Math.PI * ay * (r + PISQ);
+		c3 = r2 + ProjectionMath.TWOPI * (ay * r + Math.PI * (y2 + Math.PI * (ay + ProjectionMath.HALFPI)));
+		c2 = c1 + PISQ * (r - 3. *  y2);
+		c0 = Math.PI * ay;
+		c2 /= c3;
+		al = c1 / c3 - THIRD * c2 * c2;
+		m = 2. * Math.sqrt(-THIRD * al);
+		d = C2_27 * c2 * c2 * c2 + (c0 * c0 - THIRD * c2 * c1) / c3;
+		if (((t = Math.abs(d = 3. * d / (al * m))) - TOL) <= 1.) {
+			d = t > 1. ? (d > 0. ? 0. : Math.PI) : Math.acos(d);
+			out.y = Math.PI * (m * Math.cos(d * THIRD + PI4_3) - THIRD * c2);
+			if (xyy < 0.) out.y = -out.y;
+			t = r2 + TPISQ * (x2 - y2 + HPISQ);
+			out.x = Math.abs(xyx) <= TOL ? 0. :
+			   .5 * (r - PISQ + (t <= 0. ? 0. : Math.sqrt(t))) / xyx;
+		} else
+			throw new ProjectionException("I");
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "van der Grinten (I)";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/VitkovskyProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/VitkovskyProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/VitkovskyProjection.java	(revision 26409)
@@ -0,0 +1,28 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+public class VitkovskyProjection extends SimpleConicProjection {
+
+	public VitkovskyProjection() {
+		super( SimpleConicProjection.VITK1 );
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner1Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner1Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner1Projection.java	(revision 26409)
@@ -0,0 +1,27 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+public class Wagner1Projection extends UrmaevFlatPolarSinusoidalProjection {
+
+	public String toString() {
+		return "Wagner I";
+	}
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner2Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner2Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner2Projection.java	(revision 26409)
@@ -0,0 +1,53 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class Wagner2Projection extends Projection {
+
+	private final static double C_x = 0.92483;
+	private final static double C_y = 1.38725;
+	private final static double C_p1 = 0.88022;
+	private final static double C_p2 = 0.88550;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		out.y = ProjectionMath.asin(C_p1 * Math.sin(C_p2 * lpphi));
+		out.x = C_x * lplam * Math.cos(lpphi);
+		out.y = C_y * lpphi;
+		return out;
+	}
+
+	public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) {
+		out.y = xyy / C_y;
+		out.x = xyx / (C_x * Math.cos(out.y));
+		out.y = ProjectionMath.asin(Math.sin(out.y) / C_p1) / C_p2;
+		return out;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Wagner II";
+	}
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner3Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner3Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner3Projection.java	(revision 26409)
@@ -0,0 +1,56 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class Wagner3Projection extends PseudoCylindricalProjection {
+	
+	private final static double TWOTHIRD = 0.6666666666666666666667;
+
+	private double C_x;
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate xy) {
+		xy.x = C_x * lplam * Math.cos(TWOTHIRD * lpphi);
+		xy.y = lpphi;
+		return xy;
+	}
+
+	public ProjCoordinate projectInverse(double x, double y, ProjCoordinate lp) {
+		lp.y = y;
+		lp.x = x / (C_x * Math.cos(TWOTHIRD * lp.y));
+		return lp;
+	}
+
+	public void initialize() {
+		super.initialize();
+		C_x = Math.cos(trueScaleLatitude) / Math.cos(2.*trueScaleLatitude/3.);
+		es = 0.;
+	}
+
+	public boolean hasInverse() {
+		return true;
+	}
+
+	public String toString() {
+		return "Wagner III";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner4Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner4Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner4Projection.java	(revision 26409)
@@ -0,0 +1,28 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+public class Wagner4Projection extends MolleweideProjection {
+
+	public Wagner4Projection() {
+		super( MolleweideProjection.WAGNER4 );
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner5Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner5Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner5Projection.java	(revision 26409)
@@ -0,0 +1,28 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+public class Wagner5Projection extends MolleweideProjection {
+
+	public Wagner5Projection() {
+		super( MolleweideProjection.WAGNER5 );
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner7Projection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner7Projection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/Wagner7Projection.java	(revision 26409)
@@ -0,0 +1,47 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class Wagner7Projection extends Projection {
+
+	public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate out) {
+		double theta, ct, D;
+
+		theta = Math.asin(out.y = 0.90630778703664996 * Math.sin(lpphi));
+		out.x = 2.66723 * (ct = Math.cos(theta)) * Math.sin(lplam /= 3.);
+		out.y *= 1.24104 * (D = 1/(Math.sqrt(0.5 * (1 + ct * Math.cos(lplam)))));
+		out.x *= D;
+		return out;
+	}
+
+	/**
+	 * Returns true if this projection is equal area
+	 */
+	public boolean isEqualArea() {
+		return true;
+	}
+
+	public String toString() {
+		return "Wagner VII";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/WerenskioldProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/WerenskioldProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/WerenskioldProjection.java	(revision 26409)
@@ -0,0 +1,34 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+
+public class WerenskioldProjection extends PutninsP4Projection {
+
+	public WerenskioldProjection() {
+		C_x = 1;
+		C_y = 4.442882938;
+	}
+
+	public String toString() {
+		return "Werenskiold I";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/WinkelTripelProjection.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/WinkelTripelProjection.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/WinkelTripelProjection.java	(revision 26409)
@@ -0,0 +1,33 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * This file was semi-automatically converted from the public-domain USGS PROJ source.
+ */
+package org.osgeo.proj4j.proj;
+
+
+public class WinkelTripelProjection extends AitoffProjection {
+
+	public WinkelTripelProjection() {
+		super( WINKEL, 0.636619772367581343 );
+	}
+
+	public String toString() {
+		return "Winkel Tripel";
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/AngleFormat.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/AngleFormat.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/AngleFormat.java	(revision 26409)
@@ -0,0 +1,189 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.units;
+
+import java.text.DecimalFormat;
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+
+import org.osgeo.proj4j.util.ProjectionMath;
+
+/**
+ * A NumberFormat for formatting Angles in various commonly-found mapping styles.
+ */
+public class AngleFormat extends NumberFormat {
+
+	public final static String ddmmssPattern = "DdM";
+	public final static String ddmmssPattern2 = "DdM'S\"";
+	public final static String ddmmssLongPattern = "DdM'S\"W";
+	public final static String ddmmssLatPattern = "DdM'S\"N";
+	public final static String ddmmssPattern4 = "DdMmSs";
+	public final static String decimalPattern = "D.F";
+
+	private DecimalFormat format;
+	private String pattern;
+	private boolean isDegrees;
+
+	public AngleFormat() {
+		this(ddmmssPattern);
+	}
+	
+	public AngleFormat(String pattern) {
+		this(pattern, false);
+	}
+	
+	public AngleFormat(String pattern, boolean isDegrees) {
+		this.pattern = pattern;
+		this.isDegrees = isDegrees;
+		format = new DecimalFormat();
+		format.setMaximumFractionDigits(0);
+		format.setGroupingUsed(false);
+	}
+	
+	public StringBuffer format(long number, StringBuffer result, FieldPosition fieldPosition) {
+		return format((double)number, result, fieldPosition);
+	}
+
+	public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) {
+		int length = pattern.length();
+		int f;
+		boolean negative = false;
+
+		if (number < 0) {
+			for (int i = length-1; i >= 0; i--) {
+				char c = pattern.charAt(i);
+				if (c == 'W' || c == 'N') {
+					number = -number;
+					negative = true;
+					break;
+				}
+			}
+		}
+		
+		double ddmmss = isDegrees ? number : Math.toDegrees(number);
+		int iddmmss = (int)Math.round(ddmmss * 3600);
+		if (iddmmss < 0)
+			iddmmss = -iddmmss;
+		int fraction = iddmmss % 3600;
+
+		for (int i = 0; i < length; i++) {
+			char c = pattern.charAt(i);
+			switch (c) {
+			case 'R':
+				result.append(number);
+				break;
+			case 'D':
+				result.append((int)ddmmss);
+				break;
+			case 'M':
+				f = fraction / 60;
+				if (f < 10)
+					result.append('0');
+				result.append(f);
+				break;
+			case 'S':
+				f = fraction % 60;
+				if (f < 10)
+					result.append('0');
+				result.append(f);
+				break;
+			case 'F':
+				result.append(fraction);
+				break;
+			case 'W':
+				if (negative)
+					result.append('W');
+				else
+					result.append('E');
+				break;
+			case 'N':
+				if (negative)
+					result.append('S');
+				else
+					result.append('N');
+				break;
+			default:
+				result.append(c);
+				break;
+			}
+		}
+		return result;
+	}
+	
+	public Number parse(String text, ParsePosition parsePosition) {
+		double d = 0, m = 0, s = 0;
+		double result;
+		boolean negate = false;
+		int length = text.length();
+		if (length > 0) {
+			char c = Character.toUpperCase(text.charAt(length-1));
+			switch (c) {
+			case 'W':
+			case 'S':
+				negate = true;
+				// Fall into...
+			case 'E':
+			case 'N':
+				text = text.substring(0, length-1);
+				break;
+			}
+		}
+		int i = text.indexOf('d');
+		if (i == -1)
+			i = text.indexOf('\u00b0');
+		if (i != -1) {
+			String dd = text.substring(0, i);
+			String mmss = text.substring(i+1);
+			d = Double.valueOf(dd).doubleValue();
+			i = mmss.indexOf('m');
+			if (i == -1)
+				i = mmss.indexOf('\'');
+			if (i != -1) {
+				if (i != 0) {
+					String mm = mmss.substring(0, i);
+					m = Double.valueOf(mm).doubleValue();
+				}
+				if (mmss.endsWith("s") || mmss.endsWith("\""))
+					mmss = mmss.substring(0, mmss.length()-1);
+				if (i != mmss.length()-1) {
+					String ss = mmss.substring(i+1);
+					s = Double.valueOf(ss).doubleValue();
+				}
+				if (m < 0 || m > 59)
+					throw new NumberFormatException("Minutes must be between 0 and 59");
+				if (s < 0 || s >= 60)
+					throw new NumberFormatException("Seconds must be between 0 and 59");
+			} else if (i != 0)
+				m = Double.valueOf(mmss).doubleValue();
+			if (isDegrees)
+				result = ProjectionMath.dmsToDeg(d, m, s);
+			else
+				result = ProjectionMath.dmsToRad(d, m, s);
+		} else {
+			result = Double.parseDouble(text);
+			if (!isDegrees)
+				result = Math.toRadians(result);
+		}
+		if (parsePosition != null)
+			parsePosition.setIndex(text.length());
+		if (negate)
+			result = -result;
+		return new Double(result);
+	}
+}
+
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/DegreeUnit.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/DegreeUnit.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/DegreeUnit.java	(revision 26409)
@@ -0,0 +1,55 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.units;
+
+
+public class DegreeUnit extends Unit {
+	
+	static final long serialVersionUID = -3212757578604686538L;
+	
+	private static AngleFormat format = new AngleFormat(AngleFormat.ddmmssPattern, true);
+	
+	public DegreeUnit() {
+		super("degree", "degrees", "deg", 1);
+	}
+	
+	public double parse(String s) throws NumberFormatException {
+		try {
+			return format.parse(s).doubleValue();
+		}
+		catch (java.text.ParseException e) {
+			throw new NumberFormatException(e.getMessage());
+		}
+	}
+	
+	public String format(double n) {
+		return format.format(n)+" "+abbreviation;
+	}
+	
+	public String format(double n, boolean abbrev) {
+		if (abbrev)
+			return format.format(n)+" "+abbreviation;
+		return format.format(n);
+	}
+	
+	public String format(double x, double y, boolean abbrev) {
+		if (abbrev)
+			return format.format(x)+"/"+format.format(y)+" "+abbreviation;
+		return format.format(x)+"/"+format.format(y);
+	}
+}
+
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/Unit.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/Unit.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/Unit.java	(revision 26409)
@@ -0,0 +1,96 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.units;
+
+import java.io.Serializable;
+import java.text.NumberFormat;
+
+public class Unit implements Serializable {
+
+	static final long serialVersionUID = -6704954923429734628L;
+	
+	public final static int ANGLE_UNIT = 0;
+	public final static int LENGTH_UNIT = 1;
+	public final static int AREA_UNIT = 2;
+	public final static int VOLUME_UNIT = 3;
+	
+	public String name, plural, abbreviation;
+	public double value;
+	public static final NumberFormat format;
+	
+	static {
+		format = NumberFormat.getNumberInstance();
+		format.setMaximumFractionDigits(2);
+		format.setGroupingUsed(false);
+	}
+	
+	public Unit(String name, String plural, String abbreviation, double value) {
+		this.name = name;
+		this.plural = plural;
+		this.abbreviation = abbreviation;
+		this.value = value;
+	}
+
+	public double toBase(double n) {
+		return n * value;
+	}
+
+	public double fromBase(double n) {
+		return n / value;
+	}
+	
+	public double parse(String s) throws NumberFormatException {
+		try {
+			return format.parse(s).doubleValue();
+		}
+		catch (java.text.ParseException e) {
+			throw new NumberFormatException(e.getMessage());
+		}
+	}
+	
+	public String format(double n) {
+		return format.format(n)+" "+abbreviation;
+	}
+	
+	public String format(double n, boolean abbrev) {
+		if (abbrev)
+			return format.format(n)+" "+abbreviation;
+		return format.format(n);
+	}
+	
+	public String format(double x, double y, boolean abbrev) {
+		if (abbrev)
+			return format.format(x)+"/"+format.format(y)+" "+abbreviation;
+		return format.format(x)+"/"+format.format(y);
+	}
+
+	public String format(double x, double y) {
+		return format(x, y, true);
+	}
+
+	public String toString() {
+		return plural;
+	}
+
+	public boolean equals(Object o) {
+		if (o instanceof Unit) {
+			return ((Unit)o).value == value;
+		}
+		return false;
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/Units.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/Units.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/Units.java	(revision 26409)
@@ -0,0 +1,79 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.units;
+
+public class Units {
+
+	// Angular units
+	public final static Unit DEGREES = new DegreeUnit();
+	public final static Unit RADIANS = new Unit("radian", "radians", "rad", Math.toDegrees(1));
+	public final static Unit ARC_MINUTES = new Unit("arc minute", "arc minutes", "min", 1/60.0);
+	public final static Unit ARC_SECONDS = new Unit("arc second", "arc seconds", "sec", 1/3600.0);
+
+	// Distance units
+	
+	// Metric units
+	public final static Unit KILOMETRES = new Unit("kilometre", "kilometres", "km", 1000);
+	public final static Unit METRES = new Unit("metre", "metres", "m", 1);
+	public final static Unit DECIMETRES = new Unit("decimetre", "decimetres", "dm", 0.1);
+	public final static Unit CENTIMETRES = new Unit("centimetre", "centimetres", "cm", 0.01);
+	public final static Unit MILLIMETRES = new Unit("millimetre", "millimetres", "mm", 0.001);
+
+	// International units
+	public final static Unit NAUTICAL_MILES = new Unit("nautical mile", "nautical miles", "kmi", 1852);
+	public final static Unit MILES = new Unit("mile", "miles", "mi", 1609.344);
+	public final static Unit CHAINS = new Unit("chain", "chains", "ch", 20.1168);
+	public final static Unit YARDS = new Unit("yard", "yards", "yd", 0.9144);
+	public final static Unit FEET = new Unit("foot", "feet", "ft", 0.3048);
+	public final static Unit INCHES = new Unit("inch", "inches", "in", 0.0254);
+
+	// U.S. units
+	public final static Unit US_MILES = new Unit("U.S. mile", "U.S. miles", "us-mi", 1609.347218694437);
+	public final static Unit US_CHAINS = new Unit("U.S. chain", "U.S. chains", "us-ch", 20.11684023368047);
+	public final static Unit US_YARDS = new Unit("U.S. yard", "U.S. yards", "us-yd", 0.914401828803658);
+	public final static Unit US_FEET = new Unit("U.S. foot", "U.S. feet", "us-ft", 0.304800609601219);
+	public final static Unit US_INCHES = new Unit("U.S. inch", "U.S. inches", "us-in", 1.0/39.37);
+
+	// Miscellaneous units
+	public final static Unit FATHOMS = new Unit("fathom", "fathoms", "fath", 1.8288);
+	public final static Unit LINKS = new Unit("link", "links", "link", 0.201168);
+
+	public final static Unit POINTS = new Unit("point", "points", "point", 0.0254/72.27);
+
+	public static Unit[] units = {
+		DEGREES,
+		KILOMETRES, METRES, DECIMETRES, CENTIMETRES, MILLIMETRES,
+		MILES, YARDS, FEET, INCHES,
+		US_MILES, US_YARDS, US_FEET, US_INCHES,
+		NAUTICAL_MILES
+	};
+
+	public static Unit findUnits(String name) {
+		for (int i = 0; i < units.length; i++) {
+			if (name.equals(units[i].name) || name.equals(units[i].plural) || name.equals(units[i].abbreviation))
+				return units[i];
+		}
+		return METRES;
+	}
+
+	public static double convert(double value, Unit from, Unit to) {
+		if (from == to)
+			return value;
+		return to.fromBase(from.toBase(value));
+	}
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/util/CRSCache.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/util/CRSCache.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/util/CRSCache.java	(revision 26409)
@@ -0,0 +1,29 @@
+package org.osgeo.proj4j.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.osgeo.proj4j.*;
+
+public class CRSCache 
+{
+  private static Map<String, CoordinateReferenceSystem> projCache = new HashMap<String, CoordinateReferenceSystem>();
+  private static CRSFactory crsFactory = new CRSFactory();
+
+// TODO: provide limit on number of items in cache (LRU)
+  
+  public CRSCache() {
+    super();
+  }
+
+  public CoordinateReferenceSystem createFromName(String name)
+  throws UnsupportedParameterException, InvalidValueException, UnknownAuthorityCodeException
+  {
+    CoordinateReferenceSystem proj = (CoordinateReferenceSystem) projCache.get(name);
+    if (proj == null) {
+      proj = crsFactory.createFromName(name);
+      projCache.put(name, proj);
+    }
+    return proj;
+  }
+
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/util/ProjectionMath.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/util/ProjectionMath.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/util/ProjectionMath.java	(revision 26409)
@@ -0,0 +1,473 @@
+/*
+Copyright 2006 Jerry Huxtable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package org.osgeo.proj4j.util;
+
+import java.awt.geom.Rectangle2D;
+
+import org.osgeo.proj4j.*;
+
+
+
+public class ProjectionMath {
+
+  public final static double PI = Math.PI;
+  public final static double HALFPI = Math.PI/2.0;
+	public final static double QUARTERPI = Math.PI/4.0;
+	public final static double TWOPI = Math.PI*2.0;
+	public final static double RTD = 180.0/Math.PI;
+	public final static double DTR = Math.PI/180.0;
+	public final static Rectangle2D WORLD_BOUNDS_RAD = new Rectangle2D.Double(-Math.PI, -Math.PI/2, Math.PI*2, Math.PI);
+	public final static Rectangle2D WORLD_BOUNDS = new Rectangle2D.Double(-180, -90, 360, 180);
+
+	/**
+	 * Degree versions of trigonometric functions
+	 */
+	public static double sind(double v) {
+		return Math.sin(v * DTR);
+	}
+	
+	public static double cosd(double v) {
+		return Math.cos(v * DTR);
+	}
+	
+	public static double tand(double v) {
+		return Math.tan(v * DTR);
+	}
+	
+	public static double asind(double v) {
+		return Math.asin(v) * RTD;
+	}
+	
+	public static double acosd(double v) {
+		return Math.acos(v) * RTD;
+	}
+	
+	public static double atand(double v) {
+		return Math.atan(v) * RTD;
+	}
+	
+	public static double atan2d(double y, double x) {
+		return Math.atan2(y, x) * RTD;
+	}
+	
+	public static double asin(double v) {
+		if (Math.abs(v) > 1.)
+			return v < 0.0 ? -Math.PI/2 : Math.PI/2;
+		return Math.asin(v);
+	}
+
+	public static double acos(double v) {
+		if (Math.abs(v) > 1.)
+			return v < 0.0 ? Math.PI : 0.0;
+		return Math.acos(v);
+	}
+
+	public static double sqrt(double v) {
+		return v < 0.0 ? 0.0 : Math.sqrt(v);
+	}
+	
+	public static double distance(double dx, double dy) {
+		return Math.sqrt(dx*dx+dy*dy);
+	}
+  
+	public static double hypot(double x, double y) {
+		if (x < 0.0)
+			x = -x;
+		else if (x == 0.0)
+			return y < 0.0 ? -y : y;
+		if (y < 0.0)
+			y = -y;
+		else if (y == 0.0)
+			return x;
+		if (x < y) {
+			x /= y;
+			return y * Math.sqrt(1.0 + x * x);
+		} else {
+			y /= x;
+			return x * Math.sqrt(1.0 + y * y);
+		}
+	}
+
+	public static double atan2(double y, double x) {
+		return Math.atan2(y, x);
+	}
+
+	public static double trunc(double v) {
+		return v < 0.0 ? Math.ceil(v) : Math.floor(v);
+	}
+	
+	public static double frac(double v) {
+		return v - trunc(v);
+	}
+	
+	public static double degToRad(double v) {
+		return v * Math.PI / 180.0;
+	}
+
+	public static double radToDeg(double v) {
+		return v * 180.0 / Math.PI;
+	}
+
+	// For negative angles, d should be negative, m & s positive.
+	public static double dmsToRad(double d, double m, double s) {
+		if (d >= 0)
+			return (d + m/60 + s/3600) * Math.PI / 180.0;
+		return (d - m/60 - s/3600) * Math.PI / 180.0;
+	}
+
+	// For negative angles, d should be negative, m & s positive.
+	public static double dmsToDeg(double d, double m, double s) {
+		if (d >= 0)
+			return (d + m/60 + s/3600);
+		return (d - m/60 - s/3600);
+	}
+
+	public static double normalizeLatitude(double angle) {
+		if (Double.isInfinite(angle) || Double.isNaN(angle))
+			throw new InvalidValueException("Infinite latitude");
+		while (angle > ProjectionMath.HALFPI)
+			angle -= Math.PI;
+		while (angle < -ProjectionMath.HALFPI)
+			angle += Math.PI;
+		return angle;
+//		return Math.IEEEremainder(angle, Math.PI);
+	}
+	
+	public static double normalizeLongitude(double angle) {
+		if (Double.isInfinite(angle) || Double.isNaN(angle))
+			throw new InvalidValueException("Infinite longitude");
+		while (angle > Math.PI)
+			angle -= TWOPI;
+		while (angle < -Math.PI)
+			angle += TWOPI;
+		return angle;
+//		return Math.IEEEremainder(angle, Math.PI);
+	}
+	
+	public static double normalizeAngle(double angle) {
+		if (Double.isInfinite(angle) || Double.isNaN(angle))
+			throw new InvalidValueException("Infinite angle");
+		while (angle > TWOPI)
+			angle -= TWOPI;
+		while (angle < 0)
+			angle += TWOPI;
+		return angle;
+	}
+	
+/*
+	public static void latLongToXYZ(Point2D.Double ll, Point3D xyz) {
+		double c = Math.cos(ll.y);
+		xyz.x = c * Math.cos(ll.x);
+		xyz.y = c * Math.sin(ll.x);
+		xyz.z = Math.sin(ll.y);
+	}
+
+	public static void xyzToLatLong(Point3D xyz, Point2D.Double ll) {
+		ll.y = MapMath.asin(xyz.z);
+		ll.x = MapMath.atan2(xyz.y, xyz.x);
+	}
+*/
+
+	public static double greatCircleDistance(double lon1, double lat1, double lon2, double lat2 ) {
+		double dlat = Math.sin((lat2-lat1)/2);
+		double dlon = Math.sin((lon2-lon1)/2);
+		double r = Math.sqrt(dlat*dlat + Math.cos(lat1)*Math.cos(lat2)*dlon*dlon);
+		return 2.0 * Math.asin(r);
+	}
+
+	public static double sphericalAzimuth(double lat0, double lon0, double lat, double lon) {
+		double diff = lon - lon0;
+		double coslat = Math.cos(lat);
+
+		return Math.atan2(
+			coslat * Math.sin(diff),
+			(Math.cos(lat0) * Math.sin(lat) -
+			Math.sin(lat0) * coslat * Math.cos(diff))
+		);
+	}
+
+	public static boolean sameSigns(double a, double b) {
+		return a < 0 == b < 0;
+	}
+	
+	public static boolean sameSigns(int a, int b) {
+		return a < 0 == b < 0;
+	}
+	
+	public static double takeSign(double a, double b) {
+		a = Math.abs(a);
+		if (b < 0)
+			return -a;
+		return a;
+	}
+
+	public static int takeSign(int a, int b) {
+		a = Math.abs(a);
+		if (b < 0)
+			return -a;
+		return a;
+	}
+/*
+  public static double distance(Point2D.Double a, Point2D.Double b) {
+    return distance(a.x-b.x, a.y-b.y);
+  }
+
+	public final static int DONT_INTERSECT = 0;
+	public final static int DO_INTERSECT = 1;
+	public final static int COLLINEAR = 2;
+
+	public static int intersectSegments(Point2D.Double aStart, Point2D.Double aEnd, Point2D.Double bStart, Point2D.Double bEnd, Point2D.Double p) {
+		double a1, a2, b1, b2, c1, c2;
+		double r1, r2, r3, r4;
+		double denom, offset, num;
+
+		a1 = aEnd.y-aStart.y;
+		b1 = aStart.x-aEnd.x;
+		c1 = aEnd.x*aStart.y - aStart.x*aEnd.y;
+		r3 = a1*bStart.x + b1*bStart.y + c1;
+		r4 = a1*bEnd.x + b1*bEnd.y + c1;
+
+		if (r3 != 0 && r4 != 0 && sameSigns(r3, r4))
+			return DONT_INTERSECT;
+
+		a2 = bEnd.y-bStart.y;
+		b2 = bStart.x-bEnd.x;
+		c2 = bEnd.x*bStart.y-bStart.x*bEnd.y;
+		r1 = a2*aStart.x + b2*aStart.y + c2;
+		r2 = a2*aEnd.x + b2*aEnd.y + c2;
+
+		if (r1 != 0 && r2 != 0 && sameSigns(r1, r2))
+			return DONT_INTERSECT;
+
+		denom = a1*b2 - a2*b1;
+		if (denom == 0)
+			return COLLINEAR;
+
+		offset = denom < 0 ? -denom/2 : denom/2;
+
+		num = b1*c2 - b2*c1;
+		p.x = (num < 0 ? num-offset : num+offset) / denom;
+
+		num = a2*c1 - a1*c2;
+		p.y = (num < 0 ? num-offset : num+offset) / denom;
+
+		return DO_INTERSECT;
+	}
+
+  /*
+	public static double dot(Point2D.Double a, Point2D.Double b) {
+		return a.x*b.x + a.y*b.y;
+	}
+	
+	public static Point2D.Double perpendicular(Point2D.Double a) {
+		return new Point2D.Double(-a.y, a.x);
+	}
+	
+	public static Point2D.Double add(Point2D.Double a, Point2D.Double b) {
+		return new Point2D.Double(a.x+b.x, a.y+b.y);
+	}
+	
+	public static Point2D.Double subtract(Point2D.Double a, Point2D.Double b) {
+		return new Point2D.Double(a.x-b.x, a.y-b.y);
+	}
+	
+	public static Point2D.Double multiply(Point2D.Double a, Point2D.Double b) {
+		return new Point2D.Double(a.x*b.x, a.y*b.y);
+	}
+	
+	public static double cross(Point2D.Double a, Point2D.Double b) {
+		return a.x*b.y - b.x*a.y;
+	}
+  
+  public static void normalize(Point2D.Double a) {
+    double d = distance(a.x, a.y);
+    a.x /= d;
+    a.y /= d;
+  }
+  
+  public static void negate(Point2D.Double a) {
+    a.x = -a.x;
+    a.y = -a.y;
+  }
+  
+
+*/
+  
+	public static double cross(double x1, double y1, double x2, double y2) {
+		return x1*y2 - x2*y1;
+	}
+
+	public static double longitudeDistance(double l1, double l2) {
+		return Math.min(
+			Math.abs(l1-l2), 
+			((l1 < 0) ? l1+Math.PI : Math.PI-l1) + ((l2 < 0) ? l2+Math.PI : Math.PI-l2)
+		);
+	}
+
+	public static double geocentricLatitude(double lat, double flatness) {
+		double f = 1.0 - flatness;
+		return Math.atan((f*f) * Math.tan(lat));
+	}
+
+	public static double geographicLatitude(double lat, double flatness) {
+		double f = 1.0 - flatness;
+		return Math.atan(Math.tan(lat) / (f*f));
+	}
+
+	public static double tsfn(double phi, double sinphi, double e) {
+		sinphi *= e;
+		return (Math.tan (.5 * (ProjectionMath.HALFPI - phi)) /
+		   Math.pow((1. - sinphi) / (1. + sinphi), .5 * e));
+	}
+
+	public static double msfn(double sinphi, double cosphi, double es) {
+		return cosphi / Math.sqrt(1.0 - es * sinphi * sinphi);
+	}
+
+	private final static int N_ITER = 15;
+
+	public static double phi2(double ts, double e) {
+		double eccnth, phi, con, dphi;
+		int i;
+
+		eccnth = .5 * e;
+		phi = ProjectionMath.HALFPI - 2. * Math.atan(ts);
+		i = N_ITER;
+		do {
+			con = e * Math.sin(phi);
+			dphi = ProjectionMath.HALFPI - 2. * Math.atan(ts * Math.pow((1. - con) / (1. + con), eccnth)) - phi;
+			phi += dphi;
+		} while (Math.abs(dphi) > 1e-10 && --i != 0);
+		if (i <= 0)
+			throw new ConvergenceFailureException("Computation of phi2 failed to converage after " + N_ITER + " iterations");
+		return phi;
+	}
+
+	private final static double C00 = 1.0;
+	private final static double C02 = .25;
+	private final static double C04 = .046875;
+	private final static double C06 = .01953125;
+	private final static double C08 = .01068115234375;
+	private final static double C22 = .75;
+	private final static double C44 = .46875;
+	private final static double C46 = .01302083333333333333;
+	private final static double C48 = .00712076822916666666;
+	private final static double C66 = .36458333333333333333;
+	private final static double C68 = .00569661458333333333;
+	private final static double C88 = .3076171875;
+	private final static int MAX_ITER = 10;
+
+	public static double[] enfn(double es) {
+		double t;
+		double[] en = new double[5];
+		en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08)));
+		en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08)));
+		en[2] = (t = es * es) * (C44 - es * (C46 + es * C48));
+		en[3] = (t *= es) * (C66 - es * C68);
+		en[4] = t * es * C88;
+		return en;
+	}
+
+	public static double mlfn(double phi, double sphi, double cphi, double[] en) {
+		cphi *= sphi;
+		sphi *= sphi;
+		return en[0] * phi - cphi * (en[1] + sphi*(en[2] + sphi*(en[3] + sphi*en[4])));
+	}
+
+	public static double inv_mlfn(double arg, double es, double[] en) {
+		double s, t, phi, k = 1./(1.-es);
+
+		phi = arg;
+		for (int i = MAX_ITER; i != 0; i--) {
+			s = Math.sin(phi);
+			t = 1. - es * s * s;
+			phi -= t = (mlfn(phi, s, Math.cos(phi), en) - arg) * (t * Math.sqrt(t)) * k;
+			if (Math.abs(t) < 1e-11)
+				return phi;
+		}
+		return phi;
+	}
+
+	private final static double P00 = .33333333333333333333;
+	private final static double P01 = .17222222222222222222;
+	private final static double P02 = .10257936507936507936;
+	private final static double P10 = .06388888888888888888;
+	private final static double P11 = .06640211640211640211;
+	private final static double P20 = .01641501294219154443;
+
+	public static double[] authset(double es) {
+		double t;
+		double[] APA = new double[3];
+		APA[0] = es * P00;
+		t = es * es;
+		APA[0] += t * P01;
+		APA[1] = t * P10;
+		t *= es;
+		APA[0] += t * P02;
+		APA[1] += t * P11;
+		APA[2] = t * P20;
+		return APA;
+	}
+
+	public static double authlat(double beta, double []APA) {
+		double t = beta+beta;
+		return(beta + APA[0] * Math.sin(t) + APA[1] * Math.sin(t+t) + APA[2] * Math.sin(t+t+t));
+	}
+	
+	public static double qsfn(double sinphi, double e, double one_es) {
+		double con;
+
+		if (e >= 1.0e-7) {
+			con = e * sinphi;
+			return (one_es * (sinphi / (1. - con * con) -
+			   (.5 / e) * Math.log ((1. - con) / (1. + con))));
+		} else
+			return (sinphi + sinphi);
+	}
+
+	/*
+	 * Java translation of "Nice Numbers for Graph Labels"
+	 * by Paul Heckbert
+	 * from "Graphics Gems", Academic Press, 1990
+	 */
+	public static double niceNumber(double x, boolean round) {
+		int expv;				/* exponent of x */
+		double f;				/* fractional part of x */
+		double nf;				/* nice, rounded fraction */
+
+		expv = (int)Math.floor(Math.log(x) / Math.log(10));
+		f = x/Math.pow(10., expv);		/* between 1 and 10 */
+		if (round) {
+			if (f < 1.5)
+				nf = 1.;
+			else if (f < 3.)
+				nf = 2.;
+			else if (f < 7.)
+				nf = 5.;
+			else
+				nf = 10.;
+		} else if (f <= 1.)
+			nf = 1.;
+		else if (f <= 2.)
+			nf = 2.;
+		else if (f <= 5.)
+			nf = 5.;
+		else
+			nf = 10.;
+		return nf*Math.pow(10., expv);
+	}
+}
Index: /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/util/ProjectionUtil.java
===================================================================
--- /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/util/ProjectionUtil.java	(revision 26409)
+++ /applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/util/ProjectionUtil.java	(revision 26409)
@@ -0,0 +1,12 @@
+package org.osgeo.proj4j.util;
+
+import org.osgeo.proj4j.ProjCoordinate;
+
+public class ProjectionUtil 
+{
+  public static String toString(ProjCoordinate p)
+  {
+    return "[" + p.x + ", " + p.y + "]";
+  }
+
+}
