Index: applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/Registry.java
===================================================================
--- applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/Registry.java	(revision 28495)
+++ applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/Registry.java	(revision 29325)
@@ -19,4 +19,5 @@
   public Registry() {
     super();
+    initialize();
   }
 
@@ -111,6 +112,6 @@
 
   public Projection getProjection( String name ) {
-    if ( projRegistry == null )
-      initialize();
+//    if ( projRegistry == null )
+//      initialize();
     Class cls = (Class)projRegistry.get( name );
     if ( cls != null ) {
@@ -131,5 +132,8 @@
   }
   
-  private void initialize() {
+  private synchronized void initialize() {
+    // guard against race condition
+    if (projRegistry != null) 
+      return;
     projRegistry = new HashMap();
     register( "aea", AlbersProjection.class, "Albers Equal Area" );
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 28495)
+++ applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/ParameterUtil.java	(revision 29325)
@@ -1,4 +1,5 @@
 package org.osgeo.proj4j.parser;
 
+import org.osgeo.proj4j.units.Angle;
 import org.osgeo.proj4j.units.AngleFormat;
 
@@ -7,4 +8,11 @@
   public static final AngleFormat format = new AngleFormat( AngleFormat.ddmmssPattern, true );
 
+  /**
+   * 
+   * @param s
+   * @return
+   * @deprecated
+   * @see Angle#parse(String)
+   */
   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 28495)
+++ applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/Proj4Keyword.java	(revision 29325)
@@ -54,5 +54,5 @@
   private static Set<String> supportedParams = null;
   
-  public static Set supportedParameters()
+  public static synchronized Set supportedParameters()
   {
     if (supportedParams == null) {
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 28495)
+++ applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/parser/Proj4Parser.java	(revision 29325)
@@ -5,19 +5,16 @@
 
 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.Angle;
 import org.osgeo.proj4j.units.AngleFormat;
 import org.osgeo.proj4j.units.Unit;
 import org.osgeo.proj4j.units.Units;
+import org.osgeo.proj4j.util.ProjectionMath;
 
 public class Proj4Parser 
 {
-  /* SECONDS_TO_RAD = Pi/180/3600 */
-  private static final double SECONDS_TO_RAD = 4.84813681109535993589914102357e-6;
-  private static final double MILLION = 1000000.0;
-  
   private Registry registry;
   
@@ -44,17 +41,5 @@
     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}
@@ -73,26 +58,9 @@
 
    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 );
+   // Should the exception be lib-specific?  (e.g. ParseException)
+   
    s = (String)params.get( Proj4Keyword.alpha );
    if ( s != null ) 
@@ -158,5 +126,5 @@
    // this must be done last, since behaviour depends on other params being set (eg +south)
    if (projection instanceof TransverseMercatorProjection) {
-     s = (String) params.get("zone");
+     s = (String) params.get(Proj4Keyword.zone);
      if (s != null)
        ((TransverseMercatorProjection) projection).setUTMZone(Integer
@@ -199,12 +167,13 @@
      param[i] = Double.parseDouble(numStr[i]);
    }
-   
-   // optimization to detect 3-parameter transform
-   if (param[3] == 0.0 
-       && param[4] == 0.0 
-       && param[5] == 0.0 
-       && param[6] == 0.0 
-       ) {
-     param = new double[] { param[0], param[1], param[2] };
+   if (param.length > 3) {
+     // optimization to detect 3-parameter transform
+     if (param[3] == 0.0 
+         && param[4] == 0.0 
+         && param[5] == 0.0 
+         && param[6] == 0.0 
+         ) {
+       param = new double[] { param[0], param[1], param[2] };
+     }
    }
    
@@ -216,8 +185,8 @@
     */
    if (param.length > 3) {
-     param[3] *= SECONDS_TO_RAD;
-     param[4] *= SECONDS_TO_RAD;
-     param[5] *= SECONDS_TO_RAD;
-     param[6] = (param[6]/MILLION) + 1;
+     param[3] *= ProjectionMath.SECONDS_TO_RAD;
+     param[4] *= ProjectionMath.SECONDS_TO_RAD;
+     param[5] *= ProjectionMath.SECONDS_TO_RAD;
+     param[6] = (param[6]/ProjectionMath.MILLION) + 1;
    }
    
@@ -328,17 +297,19 @@
    for (int i = 0; i < args.length; i++) {
      String arg = args[i];
+     // strip leading "+" if any
      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);
-       }
+       arg = arg.substring(1);
      }
+     int index = arg.indexOf('=');
+     if (index != -1) {
+       // param of form pppp=vvvv
+       String key = arg.substring(0, index);
+       String value = arg.substring(index + 1);
+       params.put(key, value);
+     } else {
+       // param of form ppppp
+       //String key = arg.substring(1);
+       params.put(arg, null);
+     }
    }
    return params;
@@ -346,5 +317,5 @@
 
  private static double parseAngle( String s ) {
-   return format.parse( s, null ).doubleValue();
+   return Angle.parse(s);
  }
 
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 28495)
+++ applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/RobinsonProjection.java	(revision 29325)
@@ -57,5 +57,5 @@
 		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.4958,	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,
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 28495)
+++ applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/SimpleConicProjection.java	(revision 29325)
@@ -64,5 +64,5 @@
 			break;
 		case PCONIC:
-			rho = c2 * (c1 - Math.tan(lpphi));
+			rho = c2 * (c1 - Math.tan(lpphi - sig));
 			break;
 		default:
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 28495)
+++ applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/SineTangentSeriesProjection.java	(revision 29325)
@@ -61,5 +61,5 @@
 		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));
+    lp.x = xyx / (C_x * Math.cos(lp.y));
 		if (tan_mode)
 			lp.x /= c * c;
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 28495)
+++ applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/StereographicAzimuthalProjection.java	(revision 29325)
@@ -213,5 +213,10 @@
 				cosphi = Math.cos( tp = 2. * Math.atan2(rho * cosphi0 , akm1) );
 				sinphi = Math.sin(tp);
-				phi_l = Math.asin(cosphi * sinphi0 + (y * sinphi * cosphi0 / rho));
+				if (rho <= 0) {
+				  phi_l = Math.asin(cosphi * sinphi0);
+				}
+				else {
+				  phi_l = Math.asin(cosphi * sinphi0 + (y * sinphi * cosphi0 / rho));
+				}
 				tp = Math.tan(.5 * (ProjectionMath.HALFPI + phi_l));
 				x *= sinphi;
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 28495)
+++ applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/proj/TransverseMercatorProjection.java	(revision 29325)
@@ -88,5 +88,5 @@
 	}
 
-	public int getRowFromNearestParallel(double latitude) {
+	public static int getRowFromNearestParallel(double latitude) {
 		int degrees = (int)ProjectionMath.radToDeg(ProjectionMath.normalizeLatitude(latitude));
 		if (degrees < -80 || degrees > 84)
@@ -97,5 +97,5 @@
 	}
 	
-	public int getZoneFromNearestMeridian(double longitude) {
+	public static int getZoneFromNearestMeridian(double longitude) {
 		int zone = (int)Math.floor((ProjectionMath.normalizeLongitude(longitude) + Math.PI) * 30.0 / Math.PI) + 1;
 		if (zone < 1)
Index: applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/Angle.java
===================================================================
--- applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/Angle.java	(revision 29325)
+++ applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/Angle.java	(revision 29325)
@@ -0,0 +1,86 @@
+package org.osgeo.proj4j.units;
+
+import org.osgeo.proj4j.util.ProjectionMath;
+
+public class Angle
+{
+
+  /**
+   * Parses a text representation of a degree angle in various formats.
+   * 
+   * Formats include DMS and DD in the forms
+   * supported by {@link AngleFormat},
+   * as in the following examples:
+   * <pre>
+   * 123.12
+   * -123.12
+   * 123.12W
+   * 
+   * 123d44m44.555s
+   * 123d44'44.555"
+   * 123d44mN
+   * </pre>
+   *  
+   * @param text
+   * @return the value of the angle, in degrees
+   */
+  public static double parse(String text) 
+    throws NumberFormatException
+  {
+    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 AngleFormat.CH_W:
+      case AngleFormat.CH_S:
+        negate = true;
+        // Fall into...
+      case AngleFormat.CH_E:
+      case AngleFormat.CH_N:
+        text = text.substring(0, length-1);
+        break;
+      }
+    }
+    int i = text.indexOf(AngleFormat.CH_DEG_ABBREV);
+    if (i == -1)
+      i = text.indexOf(AngleFormat.CH_DEG_SYMBOL);
+    if (i != -1) {
+      String dd = text.substring(0, i);
+      String mmss = text.substring(i+1);
+      d = Double.valueOf(dd).doubleValue();
+      i = mmss.indexOf(AngleFormat.CH_MIN_ABBREV);
+      if (i == -1)
+        i = mmss.indexOf(AngleFormat.CH_MIN_SYMBOL);
+      if (i != -1) {
+        if (i != 0) {
+          String mm = mmss.substring(0, i);
+          m = Double.valueOf(mm).doubleValue();
+        }
+        if (mmss.endsWith(AngleFormat.STR_SEC_ABBREV) || mmss.endsWith(AngleFormat.STR_SEC_SYMBOL))
+          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)
+        if (mmss.length() == 0)
+          m = 0;
+        else
+          m = Double.valueOf(mmss).doubleValue();
+        result = ProjectionMath.dmsToDeg(d, m, s);
+    } else {
+      result = Double.parseDouble(text);
+    }
+    if (negate)
+      result = -result;
+    return result;
+  }
+
+}
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 28495)
+++ applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/units/AngleFormat.java	(revision 29325)
@@ -28,4 +28,16 @@
  */
 public class AngleFormat extends NumberFormat {
+
+  public static final char CH_MIN_SYMBOL = '\'';
+  public static final String STR_SEC_SYMBOL = "\"";
+  public static final char CH_DEG_SYMBOL = '\u00b0';
+  public static final char CH_DEG_ABBREV = 'd';
+  public static final char CH_MIN_ABBREV = 'm';
+  public static final String STR_SEC_ABBREV = "s";
+  
+  public static final char CH_N = 'N';
+  public static final char CH_E = 'E';
+  public static final char CH_S = 'S';
+  public static final char CH_W = 'W';
 
 	public final static String ddmmssPattern = "DdM";
@@ -108,13 +120,13 @@
 			case 'W':
 				if (negative)
-					result.append('W');
+					result.append(CH_W);
 				else
-					result.append('E');
+					result.append(CH_E);
 				break;
 			case 'N':
 				if (negative)
-					result.append('S');
+					result.append(CH_S);
 				else
-					result.append('N');
+					result.append(CH_N);
 				break;
 			default:
@@ -126,4 +138,11 @@
 	}
 	
+  /**
+   * 
+   * @param s
+   * @return
+   * @deprecated
+   * @see Angle#parse(String)
+   */
 	public Number parse(String text, ParsePosition parsePosition) {
 		double d = 0, m = 0, s = 0;
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 28495)
+++ applications/editors/josm/plugins/proj4j/src/org/osgeo/proj4j/util/ProjectionMath.java	(revision 29325)
@@ -473,3 +473,7 @@
 		return nf*Math.pow(10., expv);
 	}
+
+  /* SECONDS_TO_RAD = Pi/180/3600 */
+  public static final double SECONDS_TO_RAD = 4.84813681109535993589914102357e-6;
+  public static final double MILLION = 1000000.0;
 }
